From 271e3ecde51e44128623d1601d2cbb42ab5a4562 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 15 Feb 2017 18:05:55 -0800 Subject: [PATCH 01/94] Fix tests from cli changes --- cmd/server-main_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/server-main_test.go b/cmd/server-main_test.go index 84416bb62..dde1aaad6 100644 --- a/cmd/server-main_test.go +++ b/cmd/server-main_test.go @@ -367,7 +367,7 @@ func TestCheckServerSyntax(t *testing.T) { app.Commands = []cli.Command{serverCmd} serverFlagSet := flag.NewFlagSet("server", 0) serverFlagSet.String("address", ":9000", "") - ctx := cli.NewContext(app, serverFlagSet, serverFlagSet) + ctx := cli.NewContext(app, serverFlagSet, nil) disksGen := func(n int) []string { disks, err := getRandomDisks(n) @@ -458,7 +458,7 @@ func TestInitServer(t *testing.T) { app.Commands = []cli.Command{serverCmd} serverFlagSet := flag.NewFlagSet("server", 0) serverFlagSet.String("address", ":9000", "") - ctx := cli.NewContext(app, serverFlagSet, serverFlagSet) + ctx := cli.NewContext(app, serverFlagSet, nil) root, err := newTestConfig(globalMinioDefaultRegion) if err != nil { From 8816b08aae9459b4fa1edb74971239b7d01320da Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 15 Feb 2017 21:28:06 -0800 Subject: [PATCH 02/94] Fix the systemd config path to the new URL --- docs/service/linux/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/service/linux/README.md b/docs/service/linux/README.md index 84780b329..35772d3d1 100644 --- a/docs/service/linux/README.md +++ b/docs/service/linux/README.md @@ -28,7 +28,7 @@ EOT Download `minio.service` into `/etc/systemd/system/` ``` -( cd /etc/systemd/system/; curl -O https://raw.githubusercontent.com/minio/minio-systemd/master/minio.service ) +( cd /etc/systemd/system/; curl -O https://raw.githubusercontent.com/minio/minio-service/master/linux-systemd/minio.service ) ``` ## Enable Minio service From 50b4e54a75fa7f12ba4d6be1d6f60c0fea660f57 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 16 Feb 2017 14:52:14 -0800 Subject: [PATCH 03/94] fs: Do not return reservedBucket names in ListBuckets() (#3754) Make sure to skip reserved bucket names in `ListBuckets()` current code didn't skip this properly and also generalize this behavior for both XL and FS. --- cmd/admin-rpc-client.go | 2 +- cmd/admin-rpc-server.go | 2 +- cmd/browser-peer-rpc.go | 2 +- cmd/browser-peer-rpc_test.go | 2 +- cmd/browser-rpc-router.go | 2 +- cmd/bucket-notification-utils.go | 14 +++++++------- cmd/errors.go | 4 ++-- cmd/fs-v1-multipart.go | 4 ++-- cmd/fs-v1.go | 23 +++++------------------ cmd/generic-handlers.go | 23 ++++++++++++----------- cmd/generic-handlers_test.go | 12 ++++++------ cmd/humanized-duration_test.go | 15 +++++++-------- cmd/lock-rpc-server.go | 6 +++--- cmd/object-api-common.go | 5 ++--- cmd/object-api-utils.go | 11 ++++++++++- cmd/posix.go | 7 +++---- cmd/s3-peer-client.go | 2 +- cmd/s3-peer-router.go | 2 +- cmd/s3-peer-rpc-handlers_test.go | 2 +- cmd/storage-rpc-client.go | 2 +- cmd/storage-rpc-server.go | 2 +- cmd/tree-walk_test.go | 13 ++++++------- cmd/web-handlers.go | 6 +----- cmd/web-router.go | 8 ++++---- cmd/xl-v1-bucket.go | 8 +------- cmd/xl-v1-list-objects-heal.go | 2 +- cmd/xl-v1-list-objects.go | 4 +--- cmd/xl-v1-multipart.go | 4 ++-- 28 files changed, 85 insertions(+), 104 deletions(-) diff --git a/cmd/admin-rpc-client.go b/cmd/admin-rpc-client.go index 6cb0709be..8604f18a6 100644 --- a/cmd/admin-rpc-client.go +++ b/cmd/admin-rpc-client.go @@ -150,7 +150,7 @@ func makeAdminPeers(eps []*url.URL) adminPeers { secretKey: serverCred.SecretKey, serverAddr: ep.Host, secureConn: globalIsSSL, - serviceEndpoint: path.Join(reservedBucket, adminPath), + serviceEndpoint: path.Join(minioReservedBucketPath, adminPath), serviceName: "Admin", } diff --git a/cmd/admin-rpc-server.go b/cmd/admin-rpc-server.go index d5f8178bd..b11eb8092 100644 --- a/cmd/admin-rpc-server.go +++ b/cmd/admin-rpc-server.go @@ -141,7 +141,7 @@ func registerAdminRPCRouter(mux *router.Router) error { if err != nil { return traceError(err) } - adminRouter := mux.NewRoute().PathPrefix(reservedBucket).Subrouter() + adminRouter := mux.NewRoute().PathPrefix(minioReservedBucketPath).Subrouter() adminRouter.Path(adminPath).Handler(adminRPCServer) return nil } diff --git a/cmd/browser-peer-rpc.go b/cmd/browser-peer-rpc.go index 398b907bf..f078c43d0 100644 --- a/cmd/browser-peer-rpc.go +++ b/cmd/browser-peer-rpc.go @@ -111,7 +111,7 @@ func updateCredsOnPeers(creds credential) map[string]error { secretKey: serverCred.SecretKey, serverAddr: peers[ix], secureConn: globalIsSSL, - serviceEndpoint: path.Join(reservedBucket, browserPeerPath), + serviceEndpoint: path.Join(minioReservedBucketPath, browserPeerPath), serviceName: "BrowserPeer", }) diff --git a/cmd/browser-peer-rpc_test.go b/cmd/browser-peer-rpc_test.go index 5554c4f32..ccf3301cf 100644 --- a/cmd/browser-peer-rpc_test.go +++ b/cmd/browser-peer-rpc_test.go @@ -36,7 +36,7 @@ func (s *TestRPCBrowserPeerSuite) SetUpSuite(c *testing.T) { serverAddr: s.testServer.Server.Listener.Addr().String(), accessKey: s.testServer.AccessKey, secretKey: s.testServer.SecretKey, - serviceEndpoint: path.Join(reservedBucket, browserPeerPath), + serviceEndpoint: path.Join(minioReservedBucketPath, browserPeerPath), serviceName: "BrowserPeer", } } diff --git a/cmd/browser-rpc-router.go b/cmd/browser-rpc-router.go index f7b762441..d88c5779d 100644 --- a/cmd/browser-rpc-router.go +++ b/cmd/browser-rpc-router.go @@ -45,7 +45,7 @@ func registerBrowserPeerRPCRouter(mux *router.Router) error { return traceError(err) } - bpRouter := mux.NewRoute().PathPrefix(reservedBucket).Subrouter() + bpRouter := mux.NewRoute().PathPrefix(minioReservedBucketPath).Subrouter() bpRouter.Path(browserPeerPath).Handler(bpRPCServer) return nil } diff --git a/cmd/bucket-notification-utils.go b/cmd/bucket-notification-utils.go index 8845c5cdb..39a719f12 100644 --- a/cmd/bucket-notification-utils.go +++ b/cmd/bucket-notification-utils.go @@ -253,19 +253,19 @@ func unmarshalSqsARN(queueARN string) (mSqs arnSQS) { } sqsType := strings.TrimPrefix(queueARN, minioSqs+serverConfig.GetRegion()+":") switch { - case strings.HasSuffix(sqsType, queueTypeAMQP): + case hasSuffix(sqsType, queueTypeAMQP): mSqs.Type = queueTypeAMQP - case strings.HasSuffix(sqsType, queueTypeNATS): + case hasSuffix(sqsType, queueTypeNATS): mSqs.Type = queueTypeNATS - case strings.HasSuffix(sqsType, queueTypeElastic): + case hasSuffix(sqsType, queueTypeElastic): mSqs.Type = queueTypeElastic - case strings.HasSuffix(sqsType, queueTypeRedis): + case hasSuffix(sqsType, queueTypeRedis): mSqs.Type = queueTypeRedis - case strings.HasSuffix(sqsType, queueTypePostgreSQL): + case hasSuffix(sqsType, queueTypePostgreSQL): mSqs.Type = queueTypePostgreSQL - case strings.HasSuffix(sqsType, queueTypeKafka): + case hasSuffix(sqsType, queueTypeKafka): mSqs.Type = queueTypeKafka - case strings.HasSuffix(sqsType, queueTypeWebhook): + case hasSuffix(sqsType, queueTypeWebhook): mSqs.Type = queueTypeWebhook } // Add more queues here. mSqs.AccountID = strings.TrimSuffix(sqsType, ":"+mSqs.Type) diff --git a/cmd/errors.go b/cmd/errors.go index b61685af8..0476a3231 100644 --- a/cmd/errors.go +++ b/cmd/errors.go @@ -86,10 +86,10 @@ func traceError(e error, errs ...error) error { fn := runtime.FuncForPC(pc) file, line := fn.FileLine(pc) name := fn.Name() - if strings.HasSuffix(name, "ServeHTTP") { + if hasSuffix(name, "ServeHTTP") { break } - if strings.HasSuffix(name, "runtime.") { + if hasSuffix(name, "runtime.") { break } diff --git a/cmd/fs-v1-multipart.go b/cmd/fs-v1-multipart.go index 4ae57635c..b28eaf24a 100644 --- a/cmd/fs-v1-multipart.go +++ b/cmd/fs-v1-multipart.go @@ -278,7 +278,7 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark } entry := strings.TrimPrefix(walkResult.entry, retainSlash(bucket)) - if strings.HasSuffix(walkResult.entry, slashSeparator) { + if hasSuffix(walkResult.entry, slashSeparator) { uploads = append(uploads, uploadMetadata{ Object: entry, }) @@ -314,7 +314,7 @@ func (fs fsObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark for _, upload := range uploads { var objectName string var uploadID string - if strings.HasSuffix(upload.Object, slashSeparator) { + if hasSuffix(upload.Object, slashSeparator) { // All directory entries are common prefixes. uploadID = "" // Upload ids are empty for CommonPrefixes. objectName = upload.Object diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index 16f3263a3..de778b32b 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -19,7 +19,6 @@ package cmd import ( "crypto/md5" "encoding/hex" - "errors" "fmt" "hash" "io" @@ -291,12 +290,11 @@ func (fs fsObjects) ListBuckets() ([]BucketInfo, error) { return nil, toObjectErr(traceError(errDiskNotFound)) } - var invalidBucketNames []string for _, entry := range entries { - if entry == minioMetaBucket+"/" || !strings.HasSuffix(entry, slashSeparator) { + // Ignore all reserved bucket names and invalid bucket names. + if isReservedOrInvalidBucket(entry) { continue } - var fi os.FileInfo fi, err = fsStatDir(pathJoin(fs.fsPath, entry)) if err != nil { @@ -310,24 +308,13 @@ func (fs fsObjects) ListBuckets() ([]BucketInfo, error) { return nil, err } - if !IsValidBucketName(fi.Name()) { - invalidBucketNames = append(invalidBucketNames, fi.Name()) - continue - } - bucketInfos = append(bucketInfos, BucketInfo{ Name: fi.Name(), - // As os.Stat() doesn't carry other than ModTime(), use ModTime() as CreatedTime. + // As os.Stat() doesnt carry CreatedTime, use ModTime() as CreatedTime. Created: fi.ModTime(), }) } - // Print a user friendly message if we indeed skipped certain directories which are - // incompatible with S3's bucket name restrictions. - if len(invalidBucketNames) > 0 { - errorIf(errors.New("One or more invalid bucket names found"), "Skipping %s", invalidBucketNames) - } - // Sort bucket infos by bucket name. sort.Sort(byBucketName(bucketInfos)) @@ -780,7 +767,7 @@ func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKey // Convert entry to ObjectInfo entryToObjectInfo := func(entry string) (objInfo ObjectInfo, err error) { - if strings.HasSuffix(entry, slashSeparator) { + if hasSuffix(entry, slashSeparator) { // Object name needs to be full path. objInfo.Name = entry objInfo.IsDir = true @@ -804,7 +791,7 @@ func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKey // bucket argument is unused as we don't need to StatFile // to figure if it's a file, just need to check that the // object string does not end with "/". - return !strings.HasSuffix(object, slashSeparator) + return !hasSuffix(object, slashSeparator) } listDir := fs.listDirFactory(isLeaf) walkResultCh = startTreeWalk(bucket, prefix, marker, recursive, listDir, isLeaf, endWalkCh) diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 0bf9fd9da..0b3c7f3dc 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -68,7 +68,8 @@ func (h requestSizeLimitHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques // Reserved bucket. const ( - reservedBucket = "/minio" + minioReservedBucket = "minio" + minioReservedBucketPath = "/" + minioReservedBucket ) // Adds redirect rules for incoming requests. @@ -86,8 +87,8 @@ func setBrowserRedirectHandler(h http.Handler) http.Handler { // serves only limited purpose on redirect-handler for // browser requests. func getRedirectLocation(urlPath string) (rLocation string) { - if urlPath == reservedBucket { - rLocation = reservedBucket + "/" + if urlPath == minioReservedBucketPath { + rLocation = minioReservedBucketPath + "/" } if contains([]string{ "/", @@ -95,7 +96,7 @@ func getRedirectLocation(urlPath string) (rLocation string) { "/login", "/favicon.ico", }, urlPath) { - rLocation = reservedBucket + urlPath + rLocation = minioReservedBucketPath + urlPath } return rLocation } @@ -143,8 +144,8 @@ func setBrowserCacheControlHandler(h http.Handler) http.Handler { func (h cacheControlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method == httpGET && guessIsBrowserReq(r) && globalIsBrowserEnabled { // For all browser requests set appropriate Cache-Control policies - if hasPrefix(r.URL.Path, reservedBucket+"/") { - if hasSuffix(r.URL.Path, ".js") || r.URL.Path == reservedBucket+"/favicon.ico" { + if hasPrefix(r.URL.Path, minioReservedBucketPath+"/") { + if hasSuffix(r.URL.Path, ".js") || r.URL.Path == minioReservedBucketPath+"/favicon.ico" { // For assets set cache expiry of one year. For each release, the name // of the asset name will change and hence it can not be served from cache. w.Header().Set("Cache-Control", "max-age=31536000") @@ -160,17 +161,17 @@ func (h cacheControlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Adds verification for incoming paths. type minioPrivateBucketHandler struct { - handler http.Handler - reservedBucket string + handler http.Handler + reservedBucketPath string } func setPrivateBucketHandler(h http.Handler) http.Handler { - return minioPrivateBucketHandler{handler: h, reservedBucket: reservedBucket} + return minioPrivateBucketHandler{h, minioReservedBucketPath} } func (h minioPrivateBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // For all non browser requests, reject access to 'reservedBucket'. - if !guessIsBrowserReq(r) && path.Clean(r.URL.Path) == reservedBucket { + // For all non browser requests, reject access to 'reservedBucketPath'. + if !guessIsBrowserReq(r) && path.Clean(r.URL.Path) == h.reservedBucketPath { writeErrorResponse(w, ErrAllAccessDisabled, r.URL) return } diff --git a/cmd/generic-handlers_test.go b/cmd/generic-handlers_test.go index f1645d030..f9872709e 100644 --- a/cmd/generic-handlers_test.go +++ b/cmd/generic-handlers_test.go @@ -29,28 +29,28 @@ func TestRedirectLocation(t *testing.T) { }{ { // 1. When urlPath is '/minio' - urlPath: reservedBucket, - location: reservedBucket + "/", + urlPath: minioReservedBucketPath, + location: minioReservedBucketPath + "/", }, { // 2. When urlPath is '/' urlPath: "/", - location: reservedBucket + "/", + location: minioReservedBucketPath + "/", }, { // 3. When urlPath is '/webrpc' urlPath: "/webrpc", - location: reservedBucket + "/webrpc", + location: minioReservedBucketPath + "/webrpc", }, { // 4. When urlPath is '/login' urlPath: "/login", - location: reservedBucket + "/login", + location: minioReservedBucketPath + "/login", }, { // 5. When urlPath is '/favicon.ico' urlPath: "/favicon.ico", - location: reservedBucket + "/favicon.ico", + location: minioReservedBucketPath + "/favicon.ico", }, { // 6. When urlPath is '/unknown' diff --git a/cmd/humanized-duration_test.go b/cmd/humanized-duration_test.go index 9f51b1296..193710767 100644 --- a/cmd/humanized-duration_test.go +++ b/cmd/humanized-duration_test.go @@ -17,7 +17,6 @@ package cmd import ( - "strings" "testing" "time" ) @@ -26,10 +25,10 @@ import ( func TestHumanizedDuration(t *testing.T) { duration := time.Duration(90487000000000) humanDuration := timeDurationToHumanizedDuration(duration) - if !strings.HasSuffix(humanDuration.String(), "seconds") { + if !hasSuffix(humanDuration.String(), "seconds") { t.Fatal("Stringer method for humanized duration should have seconds.", humanDuration.String()) } - if strings.HasSuffix(humanDuration.StringShort(), "seconds") { + if hasSuffix(humanDuration.StringShort(), "seconds") { t.Fatal("StringShorter method for humanized duration should not have seconds.", humanDuration.StringShort()) } @@ -42,9 +41,9 @@ func TestHumanizedDuration(t *testing.T) { t.Fatalf("Expected %#v, got %#v incorrect conversion of duration to humanized form", expectedHumanSecDuration, humanSecDuration) } - if strings.HasSuffix(humanSecDuration.String(), "days") || - strings.HasSuffix(humanSecDuration.String(), "hours") || - strings.HasSuffix(humanSecDuration.String(), "minutes") { + if hasSuffix(humanSecDuration.String(), "days") || + hasSuffix(humanSecDuration.String(), "hours") || + hasSuffix(humanSecDuration.String(), "minutes") { t.Fatal("Stringer method for humanized duration should have only seconds.", humanSecDuration.String()) } @@ -57,7 +56,7 @@ func TestHumanizedDuration(t *testing.T) { t.Fatalf("Expected %#v, got %#v incorrect conversion of duration to humanized form", expectedHumanMinDuration, humanMinDuration) } - if strings.HasSuffix(humanMinDuration.String(), "hours") { + if hasSuffix(humanMinDuration.String(), "hours") { t.Fatal("Stringer method for humanized duration should have only minutes.", humanMinDuration.String()) } @@ -70,7 +69,7 @@ func TestHumanizedDuration(t *testing.T) { t.Fatalf("Expected %#v, got %#v incorrect conversion of duration to humanized form", expectedHumanHourDuration, humanHourDuration) } - if strings.HasSuffix(humanHourDuration.String(), "days") { + if hasSuffix(humanHourDuration.String(), "days") { t.Fatal("Stringer method for humanized duration should have hours.", humanHourDuration.String()) } } diff --git a/cmd/lock-rpc-server.go b/cmd/lock-rpc-server.go index c1761dbd7..ad86b035d 100644 --- a/cmd/lock-rpc-server.go +++ b/cmd/lock-rpc-server.go @@ -30,7 +30,7 @@ import ( const ( // Lock rpc server endpoint. - lockRPCPath = "/minio/lock" + lockRPCPath = "/lock" // Lock maintenance interval. lockMaintenanceInterval = 1 * time.Minute // 1 minute. @@ -122,8 +122,8 @@ func registerStorageLockers(mux *router.Router, lockServers []*lockServer) error if err := lockRPCServer.RegisterName("Dsync", lockServer); err != nil { return traceError(err) } - lockRouter := mux.PathPrefix(reservedBucket).Subrouter() - lockRouter.Path(path.Join("/lock", lockServer.rpcPath)).Handler(lockRPCServer) + lockRouter := mux.PathPrefix(minioReservedBucketPath).Subrouter() + lockRouter.Path(path.Join(lockRPCPath, lockServer.rpcPath)).Handler(lockRPCServer) } return nil } diff --git a/cmd/object-api-common.go b/cmd/object-api-common.go index 0f0c4a414..e27131ac6 100644 --- a/cmd/object-api-common.go +++ b/cmd/object-api-common.go @@ -20,7 +20,6 @@ import ( "net" "net/url" "runtime" - "strings" "sync" "time" @@ -59,7 +58,7 @@ func isRemoteDisk(disk StorageAPI) bool { // if size == 0 and object ends with slashSeparator then // returns true. func isObjectDir(object string, size int64) bool { - return strings.HasSuffix(object, slashSeparator) && size == 0 + return hasSuffix(object, slashSeparator) && size == 0 } // Converts just bucket, object metadata into ObjectInfo datatype. @@ -284,7 +283,7 @@ func cleanupDir(storage StorageAPI, volume, dirPath string) error { var delFunc func(string) error // Function to delete entries recursively. delFunc = func(entryPath string) error { - if !strings.HasSuffix(entryPath, slashSeparator) { + if !hasSuffix(entryPath, slashSeparator) { // Delete the file entry. return traceError(storage.DeleteFile(volume, entryPath)) } diff --git a/cmd/object-api-utils.go b/cmd/object-api-utils.go index 206c0c1a0..4cf72acde 100644 --- a/cmd/object-api-utils.go +++ b/cmd/object-api-utils.go @@ -129,7 +129,7 @@ func retainSlash(s string) string { func pathJoin(elem ...string) string { trailingSlash := "" if len(elem) > 0 { - if strings.HasSuffix(elem[len(elem)-1], slashSeparator) { + if hasSuffix(elem[len(elem)-1], slashSeparator) { trailingSlash = "/" } } @@ -180,6 +180,15 @@ func hasSuffix(s string, suffix string) bool { return strings.HasSuffix(s, suffix) } +// Ignores all reserved bucket names or invalid bucket names. +func isReservedOrInvalidBucket(bucketEntry string) bool { + bucketEntry = strings.TrimSuffix(bucketEntry, slashSeparator) + if !IsValidBucketName(bucketEntry) { + return true + } + return bucketEntry == minioMetaBucket || bucketEntry == minioReservedBucket +} + // byBucketName is a collection satisfying sort.Interface. type byBucketName []BucketInfo diff --git a/cmd/posix.go b/cmd/posix.go index 89d1c77ed..12d9045ae 100644 --- a/cmd/posix.go +++ b/cmd/posix.go @@ -24,7 +24,6 @@ import ( slashpath "path" "path/filepath" "runtime" - "strings" "sync" "sync/atomic" "syscall" @@ -319,7 +318,7 @@ func listVols(dirPath string) ([]VolInfo, error) { } var volsInfo []VolInfo for _, entry := range entries { - if !strings.HasSuffix(entry, slashSeparator) || !isValidVolname(slashpath.Clean(entry)) { + if !hasSuffix(entry, slashSeparator) || !isValidVolname(slashpath.Clean(entry)) { // Skip if entry is neither a directory not a valid volume name. continue } @@ -917,8 +916,8 @@ func (s *posix) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) (err e } } - srcIsDir := strings.HasSuffix(srcPath, slashSeparator) - dstIsDir := strings.HasSuffix(dstPath, slashSeparator) + srcIsDir := hasSuffix(srcPath, slashSeparator) + dstIsDir := hasSuffix(dstPath, slashSeparator) // Either src and dst have to be directories or files, else return error. if !(srcIsDir && dstIsDir || !srcIsDir && !dstIsDir) { return errFileAccessDenied diff --git a/cmd/s3-peer-client.go b/cmd/s3-peer-client.go index 6358f5881..a90022eb4 100644 --- a/cmd/s3-peer-client.go +++ b/cmd/s3-peer-client.go @@ -66,7 +66,7 @@ func makeS3Peers(eps []*url.URL) s3Peers { accessKey: serverCred.AccessKey, secretKey: serverCred.SecretKey, serverAddr: ep.Host, - serviceEndpoint: path.Join(reservedBucket, s3Path), + serviceEndpoint: path.Join(minioReservedBucketPath, s3Path), secureConn: globalIsSSL, serviceName: "S3", } diff --git a/cmd/s3-peer-router.go b/cmd/s3-peer-router.go index e843c17bb..3701bc8ab 100644 --- a/cmd/s3-peer-router.go +++ b/cmd/s3-peer-router.go @@ -45,7 +45,7 @@ func registerS3PeerRPCRouter(mux *router.Router) error { return traceError(err) } - s3PeerRouter := mux.NewRoute().PathPrefix(reservedBucket).Subrouter() + s3PeerRouter := mux.NewRoute().PathPrefix(minioReservedBucketPath).Subrouter() s3PeerRouter.Path(s3Path).Handler(s3PeerRPCServer) return nil } diff --git a/cmd/s3-peer-rpc-handlers_test.go b/cmd/s3-peer-rpc-handlers_test.go index a9e813cb7..4e7378cb9 100644 --- a/cmd/s3-peer-rpc-handlers_test.go +++ b/cmd/s3-peer-rpc-handlers_test.go @@ -36,7 +36,7 @@ func (s *TestRPCS3PeerSuite) SetUpSuite(t *testing.T) { serverAddr: s.testServer.Server.Listener.Addr().String(), accessKey: s.testServer.AccessKey, secretKey: s.testServer.SecretKey, - serviceEndpoint: path.Join(reservedBucket, s3Path), + serviceEndpoint: path.Join(minioReservedBucketPath, s3Path), serviceName: "S3", } } diff --git a/cmd/storage-rpc-client.go b/cmd/storage-rpc-client.go index 4020b6382..0064fe35d 100644 --- a/cmd/storage-rpc-client.go +++ b/cmd/storage-rpc-client.go @@ -34,7 +34,7 @@ type networkStorage struct { } const ( - storageRPCPath = reservedBucket + "/storage" + storageRPCPath = minioReservedBucketPath + "/storage" ) // Converts rpc.ServerError to underlying error. This function is diff --git a/cmd/storage-rpc-server.go b/cmd/storage-rpc-server.go index 6ad287868..c1e9ab787 100644 --- a/cmd/storage-rpc-server.go +++ b/cmd/storage-rpc-server.go @@ -233,7 +233,7 @@ func registerStorageRPCRouters(mux *router.Router, srvCmdConfig serverCmdConfig) return traceError(err) } // Add minio storage routes. - storageRouter := mux.PathPrefix(reservedBucket).Subrouter() + storageRouter := mux.PathPrefix(minioReservedBucketPath).Subrouter() storageRouter.Path(path.Join("/storage", stServer.path)).Handler(storageRPCServer) } return nil diff --git a/cmd/tree-walk_test.go b/cmd/tree-walk_test.go index 9490c6c56..211630d05 100644 --- a/cmd/tree-walk_test.go +++ b/cmd/tree-walk_test.go @@ -21,7 +21,6 @@ import ( "io/ioutil" "reflect" "sort" - "strings" "testing" "time" ) @@ -187,7 +186,7 @@ func TestTreeWalk(t *testing.T) { } isLeaf := func(volume, prefix string) bool { - return !strings.HasSuffix(prefix, slashSeparator) + return !hasSuffix(prefix, slashSeparator) } listDir := listDirFactory(isLeaf, xlTreeWalkIgnoredErrs, disk) // Simple test for prefix based walk. @@ -225,7 +224,7 @@ func TestTreeWalkTimeout(t *testing.T) { } isLeaf := func(volume, prefix string) bool { - return !strings.HasSuffix(prefix, slashSeparator) + return !hasSuffix(prefix, slashSeparator) } listDir := listDirFactory(isLeaf, xlTreeWalkIgnoredErrs, disk) @@ -304,7 +303,7 @@ func TestListDir(t *testing.T) { // create listDir function. listDir := listDirFactory(func(volume, prefix string) bool { - return !strings.HasSuffix(prefix, slashSeparator) + return !hasSuffix(prefix, slashSeparator) }, xlTreeWalkIgnoredErrs, disk1, disk2) // Create file1 in fsDir1 and file2 in fsDir2. @@ -376,7 +375,7 @@ func TestRecursiveTreeWalk(t *testing.T) { // Simple isLeaf check, returns true if there is no trailing "/" isLeaf := func(volume, prefix string) bool { - return !strings.HasSuffix(prefix, slashSeparator) + return !hasSuffix(prefix, slashSeparator) } // Create listDir function. @@ -486,7 +485,7 @@ func TestSortedness(t *testing.T) { // Simple isLeaf check, returns true if there is no trailing "/" isLeaf := func(volume, prefix string) bool { - return !strings.HasSuffix(prefix, slashSeparator) + return !hasSuffix(prefix, slashSeparator) } // Create listDir function. listDir := listDirFactory(isLeaf, xlTreeWalkIgnoredErrs, disk1) @@ -563,7 +562,7 @@ func TestTreeWalkIsEnd(t *testing.T) { } isLeaf := func(volume, prefix string) bool { - return !strings.HasSuffix(prefix, slashSeparator) + return !hasSuffix(prefix, slashSeparator) } // Create listDir function. listDir := listDirFactory(isLeaf, xlTreeWalkIgnoredErrs, disk1) diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index c988ab835..3f092c6d4 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -161,10 +161,6 @@ func (web *webAPIHandlers) ListBuckets(r *http.Request, args *WebGenericArgs, re return toJSONError(err) } for _, bucket := range buckets { - if bucket.Name == path.Base(reservedBucket) { - continue - } - reply.Buckets = append(reply.Buckets, WebBucketInfo{ Name: bucket.Name, CreationDate: bucket.Created, @@ -584,7 +580,7 @@ func (web *webAPIHandlers) DownloadZip(w http.ResponseWriter, r *http.Request) { return objectAPI.GetObject(args.BucketName, objectName, 0, info.Size, writer) } - if !strings.HasSuffix(object, "/") { + if !hasSuffix(object, slashSeparator) { // If not a directory, compress the file and write it to response. err := zipit(pathJoin(args.Prefix, object)) if err != nil { diff --git a/cmd/web-router.go b/cmd/web-router.go index c4fdfbb2c..66505bdff 100644 --- a/cmd/web-router.go +++ b/cmd/web-router.go @@ -39,7 +39,7 @@ type indexHandler struct { } func (h indexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - r.URL.Path = reservedBucket + "/" + r.URL.Path = minioReservedBucketPath + "/" h.handler.ServeHTTP(w, r) } @@ -68,7 +68,7 @@ func registerWebRouter(mux *router.Router) error { codec := json2.NewCodec() // Minio browser router. - webBrowserRouter := mux.NewRoute().PathPrefix(reservedBucket).Subrouter() + webBrowserRouter := mux.NewRoute().PathPrefix(minioReservedBucketPath).Subrouter() // Initialize json rpc handlers. webRPC := jsonrpc.NewServer() @@ -87,13 +87,13 @@ func registerWebRouter(mux *router.Router) error { webBrowserRouter.Methods("GET").Path("/zip").Queries("token", "{token:.*}").HandlerFunc(web.DownloadZip) // Add compression for assets. - compressedAssets := handlers.CompressHandler(http.StripPrefix(reservedBucket, http.FileServer(assetFS()))) + compressedAssets := handlers.CompressHandler(http.StripPrefix(minioReservedBucketPath, http.FileServer(assetFS()))) // Serve javascript files and favicon from assets. webBrowserRouter.Path(fmt.Sprintf("/{assets:[^/]+.js|%s}", specialAssets)).Handler(compressedAssets) // Serve index.html for rest of the requests. - webBrowserRouter.Path("/{index:.*}").Handler(indexHandler{http.StripPrefix(reservedBucket, http.FileServer(assetFS()))}) + webBrowserRouter.Path("/{index:.*}").Handler(indexHandler{http.StripPrefix(minioReservedBucketPath, http.FileServer(assetFS()))}) return nil } diff --git a/cmd/xl-v1-bucket.go b/cmd/xl-v1-bucket.go index 4078b7292..f2b9a5af7 100644 --- a/cmd/xl-v1-bucket.go +++ b/cmd/xl-v1-bucket.go @@ -165,13 +165,7 @@ func (xl xlObjects) listBuckets() (bucketsInfo []BucketInfo, err error) { // should take care of this. var bucketsInfo []BucketInfo for _, volInfo := range volsInfo { - // StorageAPI can send volume names which are incompatible - // with buckets, handle it and skip them. - if !IsValidBucketName(volInfo.Name) { - continue - } - // Ignore the volume special bucket. - if volInfo.Name == minioMetaBucket { + if isReservedOrInvalidBucket(volInfo.Name) { continue } bucketsInfo = append(bucketsInfo, BucketInfo{ diff --git a/cmd/xl-v1-list-objects-heal.go b/cmd/xl-v1-list-objects-heal.go index 1fb6702ac..2fcb02c3c 100644 --- a/cmd/xl-v1-list-objects-heal.go +++ b/cmd/xl-v1-list-objects-heal.go @@ -114,7 +114,7 @@ func (xl xlObjects) listObjectsHeal(bucket, prefix, marker, delimiter string, ma } entry := walkResult.entry var objInfo ObjectInfo - if strings.HasSuffix(entry, slashSeparator) { + if hasSuffix(entry, slashSeparator) { // Object name needs to be full path. objInfo.Bucket = bucket objInfo.Name = entry diff --git a/cmd/xl-v1-list-objects.go b/cmd/xl-v1-list-objects.go index b9fff36ee..480f5359c 100644 --- a/cmd/xl-v1-list-objects.go +++ b/cmd/xl-v1-list-objects.go @@ -16,8 +16,6 @@ package cmd -import "strings" - // Returns function "listDir" of the type listDirFunc. // isLeaf - is used by listDir function to check if an entry is a leaf or non-leaf entry. // disks - used for doing disk.ListDir(). FS passes single disk argument, XL passes a list of disks. @@ -83,7 +81,7 @@ func (xl xlObjects) listObjects(bucket, prefix, marker, delimiter string, maxKey } entry := walkResult.entry var objInfo ObjectInfo - if strings.HasSuffix(entry, slashSeparator) { + if hasSuffix(entry, slashSeparator) { // Object name needs to be full path. objInfo.Bucket = bucket objInfo.Name = entry diff --git a/cmd/xl-v1-multipart.go b/cmd/xl-v1-multipart.go index 51624784c..491223f13 100644 --- a/cmd/xl-v1-multipart.go +++ b/cmd/xl-v1-multipart.go @@ -356,7 +356,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark entry := strings.TrimPrefix(walkResult.entry, retainSlash(bucket)) // For an entry looking like a directory, store and // continue the loop not need to fetch uploads. - if strings.HasSuffix(walkResult.entry, slashSeparator) { + if hasSuffix(walkResult.entry, slashSeparator) { uploads = append(uploads, uploadMetadata{ Object: entry, }) @@ -409,7 +409,7 @@ func (xl xlObjects) listMultipartUploads(bucket, prefix, keyMarker, uploadIDMark for _, upload := range uploads { var objectName string var uploadID string - if strings.HasSuffix(upload.Object, slashSeparator) { + if hasSuffix(upload.Object, slashSeparator) { // All directory entries are common prefixes. uploadID = "" // For common prefixes, upload ids are empty. objectName = upload.Object From 34d9a6b46a91cdf5924a51f7487d25739a57374d Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 18 Feb 2017 02:52:11 -0800 Subject: [PATCH 04/94] Make sure client initializes to proper lock RPC path. (#3763) Fixes a regression introduced in previous commit. --- cmd/namespace-lock.go | 2 +- cmd/storage-rpc-client.go | 4 ++-- cmd/storage-rpc-server.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/namespace-lock.go b/cmd/namespace-lock.go index 492e45ac4..36bd8e71c 100644 --- a/cmd/namespace-lock.go +++ b/cmd/namespace-lock.go @@ -51,7 +51,7 @@ func initDsyncNodes(eps []*url.URL) error { accessKey: cred.AccessKey, secretKey: cred.SecretKey, serverAddr: ep.Host, - serviceEndpoint: pathutil.Join(lockRPCPath, getPath(ep)), + serviceEndpoint: pathutil.Join(minioReservedBucketPath, lockRPCPath, getPath(ep)), secureConn: globalIsSSL, serviceName: "Dsync", }) diff --git a/cmd/storage-rpc-client.go b/cmd/storage-rpc-client.go index 0064fe35d..af90744cd 100644 --- a/cmd/storage-rpc-client.go +++ b/cmd/storage-rpc-client.go @@ -34,7 +34,7 @@ type networkStorage struct { } const ( - storageRPCPath = minioReservedBucketPath + "/storage" + storageRPCPath = "/storage" ) // Converts rpc.ServerError to underlying error. This function is @@ -102,7 +102,7 @@ func newStorageRPC(ep *url.URL) (StorageAPI, error) { } // Dial minio rpc storage http path. - rpcPath := path.Join(storageRPCPath, getPath(ep)) + rpcPath := path.Join(minioReservedBucketPath, storageRPCPath, getPath(ep)) rpcAddr := ep.Host serverCred := serverConfig.GetCredential() diff --git a/cmd/storage-rpc-server.go b/cmd/storage-rpc-server.go index c1e9ab787..1a02cd266 100644 --- a/cmd/storage-rpc-server.go +++ b/cmd/storage-rpc-server.go @@ -234,7 +234,7 @@ func registerStorageRPCRouters(mux *router.Router, srvCmdConfig serverCmdConfig) } // Add minio storage routes. storageRouter := mux.PathPrefix(minioReservedBucketPath).Subrouter() - storageRouter.Path(path.Join("/storage", stServer.path)).Handler(storageRPCServer) + storageRouter.Path(path.Join(storageRPCPath, stServer.path)).Handler(storageRPCServer) } return nil } From 0137ff498aaf392a2ad583a266a6e398e43210cb Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 18 Feb 2017 03:15:42 -0800 Subject: [PATCH 05/94] auth/rpc: Token can be concurrently edited protect it. (#3764) Make sure we protect when we access `authToken` in authClient. Fixes #3761 --- cmd/auth-rpc-client.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/auth-rpc-client.go b/cmd/auth-rpc-client.go index 74c7815b6..f59fb8b5f 100644 --- a/cmd/auth-rpc-client.go +++ b/cmd/auth-rpc-client.go @@ -115,8 +115,10 @@ func (authClient *AuthRPCClient) call(serviceMethod string, args interface { }, reply interface{}) (err error) { // On successful login, execute RPC call. if err = authClient.Login(); err == nil { + authClient.Lock() // Set token and timestamp before the rpc call. args.SetAuthToken(authClient.authToken) + authClient.Unlock() args.SetRequestTime(time.Now().UTC()) // Do RPC call. From d12f3e06b16e46cbf64c989ae743afef763085a7 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Sun, 19 Feb 2017 00:15:37 +0530 Subject: [PATCH 06/94] config-old: Use interface to avoid code repetition. (#3769) --- cmd/config-old.go | 202 ++++++++++++++++------------------------------ 1 file changed, 69 insertions(+), 133 deletions(-) diff --git a/cmd/config-old.go b/cmd/config-old.go index 2914dd597..c3cc6113c 100644 --- a/cmd/config-old.go +++ b/cmd/config-old.go @@ -1,3 +1,19 @@ +/* + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package cmd import ( @@ -8,6 +24,23 @@ import ( "github.com/minio/minio/pkg/quick" ) +func loadOldConfig(configFile string, config interface{}) (interface{}, error) { + if _, err := os.Stat(configFile); err != nil { + return nil, err + } + + qc, err := quick.New(config) + if err != nil { + return nil, err + } + + if err = qc.Load(configFile); err != nil { + return nil, err + } + + return config, nil +} + /////////////////// Config V1 /////////////////// type configV1 struct { Version string `json:"version"` @@ -22,19 +55,11 @@ func loadConfigV1() (*configV1, error) { return nil, err } configFile := filepath.Join(configPath, "fsUsers.json") - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &configV1{Version: "1"}) + if config == nil { return nil, err } - c := &configV1{} - c.Version = "1" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*configV1), err } /////////////////// Config V2 /////////////////// @@ -65,19 +90,11 @@ func loadConfigV2() (*configV2, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &configV2{Version: "2"}) + if config == nil { return nil, err } - c := &configV2{} - c.Version = "2" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*configV2), err } /////////////////// Config V3 /////////////////// @@ -139,19 +156,11 @@ func loadConfigV3() (*configV3, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &configV3{Version: "3"}) + if config == nil { return nil, err } - c := &configV3{} - c.Version = "3" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*configV3), err } // logger type representing version '4' logger config. @@ -190,19 +199,11 @@ func loadConfigV4() (*configV4, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &configV4{Version: "4"}) + if config == nil { return nil, err } - c := &configV4{} - c.Version = "4" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*configV4), err } // logger type representing version '5' logger config. @@ -268,19 +269,11 @@ func loadConfigV5() (*configV5, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &configV5{Version: "5"}) + if config == nil { return nil, err } - c := &configV5{} - c.Version = "5" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*configV5), err } type loggerV6 struct { @@ -310,19 +303,11 @@ func loadConfigV6() (*configV6, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &configV6{Version: "6"}) + if config == nil { return nil, err } - c := &configV6{} - c.Version = "6" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*configV6), err } // Notifier represents collection of supported notification queues in version @@ -371,19 +356,11 @@ func loadConfigV7() (*serverConfigV7, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &serverConfigV7{Version: "7"}) + if config == nil { return nil, err } - c := &serverConfigV7{} - c.Version = "7" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*serverConfigV7), err } // serverConfigV8 server configuration version '8'. Adds NATS notifier @@ -411,19 +388,11 @@ func loadConfigV8() (*serverConfigV8, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &serverConfigV8{Version: "8"}) + if config == nil { return nil, err } - c := &serverConfigV8{} - c.Version = "8" - qc, err := quick.New(c) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return c, nil + return config.(*serverConfigV8), err } // serverConfigV9 server configuration version '9'. Adds PostgreSQL @@ -450,20 +419,11 @@ func loadConfigV9() (*serverConfigV9, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &serverConfigV9{Version: "9"}) + if config == nil { return nil, err } - srvCfg := &serverConfigV9{} - srvCfg.Version = "9" - srvCfg.rwMutex = &sync.RWMutex{} - qc, err := quick.New(srvCfg) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return srvCfg, nil + return config.(*serverConfigV9), err } // serverConfigV10 server configuration version '10' which is like @@ -488,19 +448,11 @@ func loadConfigV10() (*serverConfigV10, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &serverConfigV10{Version: "10"}) + if config == nil { return nil, err } - srvCfg := &serverConfigV10{} - srvCfg.Version = "10" - qc, err := quick.New(srvCfg) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return srvCfg, nil + return config.(*serverConfigV10), err } // natsNotifyV1 - structure was valid until config V 11 @@ -536,19 +488,11 @@ func loadConfigV11() (*serverConfigV11, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &serverConfigV11{Version: "11"}) + if config == nil { return nil, err } - srvCfg := &serverConfigV11{} - srvCfg.Version = "11" - qc, err := quick.New(srvCfg) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return srvCfg, nil + return config.(*serverConfigV11), err } // serverConfigV12 server configuration version '12' which is like @@ -572,17 +516,9 @@ func loadConfigV12() (*serverConfigV12, error) { if err != nil { return nil, err } - if _, err = os.Stat(configFile); err != nil { + config, err := loadOldConfig(configFile, &serverConfigV12{Version: "12"}) + if config == nil { return nil, err } - srvCfg := &serverConfigV12{} - srvCfg.Version = "12" - qc, err := quick.New(srvCfg) - if err != nil { - return nil, err - } - if err := qc.Load(configFile); err != nil { - return nil, err - } - return srvCfg, nil + return config.(*serverConfigV12), err } From 7e84c7427d08f9112241d820bfdca2825d0f895a Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Sat, 18 Feb 2017 22:28:54 +0100 Subject: [PATCH 07/94] server-mux: Rewrite graceful shutdown mechanism (#3771) Old code uses waitgroup Add() and Wait() in different threads, which eventually can lead to a race. --- cmd/server-mux.go | 64 ++++++++++++++++++++++++++---------------- cmd/server-mux_test.go | 16 +++++++---- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/cmd/server-mux.go b/cmd/server-mux.go index 8ea33a3d5..4208a5807 100644 --- a/cmd/server-mux.go +++ b/cmd/server-mux.go @@ -26,9 +26,14 @@ import ( "net/url" "strings" "sync" + "sync/atomic" "time" ) +const ( + serverShutdownPoll = 500 * time.Millisecond +) + // The value chosen below is longest word chosen // from all the http verbs comprising of // "PRI", "OPTIONS", "GET", "HEAD", "POST", @@ -324,11 +329,13 @@ type ServerMux struct { handler http.Handler listeners []*ListenerMux - gracefulWait *sync.WaitGroup + // Current number of concurrent http requests + currentReqs int32 + // Time to wait before forcing server shutdown gracefulTimeout time.Duration - mu sync.Mutex // guards closed, and listener - closed bool + mu sync.Mutex // guards closing, and listeners + closing bool } // NewServerMux constructor to create a ServerMux @@ -339,7 +346,6 @@ func NewServerMux(addr string, handler http.Handler) *ServerMux { // Wait for 5 seconds for new incoming connnections, otherwise // forcibly close them during graceful stop or restart. gracefulTimeout: 5 * time.Second, - gracefulWait: &sync.WaitGroup{}, } // Returns configured HTTP server. @@ -452,11 +458,22 @@ func (m *ServerMux) ListenAndServe(certFile, keyFile string) (err error) { } http.Redirect(w, r, u.String(), http.StatusTemporaryRedirect) } else { - // Execute registered handlers, protect with a waitgroup - // to accomplish a graceful shutdown when the user asks to quit - m.gracefulWait.Add(1) + + // Return ServiceUnavailable for clients which are sending requests + // in shutdown phase + m.mu.Lock() + closing := m.closing + m.mu.Unlock() + if closing { + w.WriteHeader(http.StatusServiceUnavailable) + return + } + + // Execute registered handlers, update currentReqs to keep + // tracks of current requests currently processed by the server + atomic.AddInt32(&m.currentReqs, 1) m.handler.ServeHTTP(w, r) - m.gracefulWait.Done() + atomic.AddInt32(&m.currentReqs, -1) } }) @@ -481,12 +498,12 @@ func (m *ServerMux) ListenAndServe(certFile, keyFile string) (err error) { func (m *ServerMux) Close() error { m.mu.Lock() - if m.closed { + if m.closing { m.mu.Unlock() return errors.New("Server has been closed") } // Closed completely. - m.closed = true + m.closing = true // Close the listeners. for _, listener := range m.listeners { @@ -497,19 +514,18 @@ func (m *ServerMux) Close() error { } m.mu.Unlock() - // Prepare for a graceful shutdown - waitSignal := make(chan struct{}) - go func() { - defer close(waitSignal) - m.gracefulWait.Wait() - }() - - select { - // Wait for everything to be properly closed - case <-waitSignal: - // Forced shutdown - case <-time.After(m.gracefulTimeout): + // Starting graceful shutdown. Check if all requests are finished + // in regular interval or force the shutdown + ticker := time.NewTicker(serverShutdownPoll) + defer ticker.Stop() + for { + select { + case <-time.After(m.gracefulTimeout): + return nil + case <-ticker.C: + if atomic.LoadInt32(&m.currentReqs) <= 0 { + return nil + } + } } - - return nil } diff --git a/cmd/server-mux_test.go b/cmd/server-mux_test.go index 1a24473a6..24802abed 100644 --- a/cmd/server-mux_test.go +++ b/cmd/server-mux_test.go @@ -198,21 +198,27 @@ func TestServerMux(t *testing.T) { time.Sleep(1 * time.Second) // Check if one listener is ready m.mu.Lock() - if len(m.listeners) == 0 { - m.mu.Unlock() + listenersCount := len(m.listeners) + m.mu.Unlock() + if listenersCount == 0 { continue } + m.mu.Lock() + listenerAddr := m.listeners[0].Addr().String() m.mu.Unlock() // Issue the GET request client := http.Client{} - m.mu.Lock() - res, err = client.Get("http://" + m.listeners[0].Addr().String()) - m.mu.Unlock() + res, err = client.Get("http://" + listenerAddr) if err != nil { continue } // Read the request response got, err = ioutil.ReadAll(res.Body) + if err != nil { + continue + } + // We've got a response, quit the loop + break } // Check for error persisted after 5 times From 54a18592e9a2177a96ce13031de42820fd8c0e04 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Sat, 18 Feb 2017 22:41:33 +0100 Subject: [PATCH 08/94] flags: Fix --version output (#3772) --- cmd/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/main.go b/cmd/main.go index 75b8d531e..cf091f677 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -107,6 +107,7 @@ func registerApp() *cli.App { app := cli.NewApp() app.Name = "Minio" app.Author = "Minio.io" + app.Version = Version app.Usage = "Cloud Storage Server." app.Description = `Minio is an Amazon S3 compatible object storage server. Use it to store photos, videos, VMs, containers, log files, or any blob of data as objects.` app.Flags = globalFlags From 7ea1de8245cca42748e4cb4725f75342d34f651a Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 18 Feb 2017 13:41:59 -0800 Subject: [PATCH 09/94] copyObject: Be case sensitive for windows only server. (#3766) For case sensitive platforms we should honor case. Fixes #3765 ``` 1) python s3cmd -c s3cfg_localminio put logo.png s3://testbucket/xyz/etc2/logo.PNG 2) python s3cmd -c s3cfg_localminio ls s3://testbucket/xyz/etc2/ 2017-02-18 10:58 22059 s3://testbucket/xyz/etc2/logo.PNG 3) python s3cmd -c s3cfg_localminio cp s3://testbucket/xyz/etc2/logo.PNG s3://testbucket/xyz/etc2/logo.png remote copy: 's3://testbucket/xyz/etc2/logo.PNG' -> 's3://testbucket/xyz/etc2/logo.png' 4) python s3cmd -c s3cfg_localminio ls s3://testbucket/xyz/etc2/ 2017-02-18 10:58 22059 s3://testbucket/xyz/etc2/logo.PNG 2017-02-18 11:10 22059 s3://testbucket/xyz/etc2/logo.png ``` --- cmd/fs-v1.go | 3 +-- cmd/object-api-utils.go | 12 ++++++++++-- cmd/xl-v1-object.go | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index de778b32b..530a81c39 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -26,7 +26,6 @@ import ( "path/filepath" "runtime" "sort" - "strings" "syscall" "github.com/minio/minio/pkg/disk" @@ -367,7 +366,7 @@ func (fs fsObjects) CopyObject(srcBucket, srcObject, dstBucket, dstObject string } // Check if this request is only metadata update. - cpMetadataOnly := strings.EqualFold(pathJoin(srcBucket, srcObject), pathJoin(dstBucket, dstObject)) + cpMetadataOnly := isStringEqual(pathJoin(srcBucket, srcObject), pathJoin(dstBucket, dstObject)) if cpMetadataOnly { fsMetaPath := pathJoin(fs.fsPath, minioMetaBucket, bucketMetaPrefix, srcBucket, srcObject, fsMetaJSONFile) var wlk *lock.LockedFile diff --git a/cmd/object-api-utils.go b/cmd/object-api-utils.go index 4cf72acde..9c1878a23 100644 --- a/cmd/object-api-utils.go +++ b/cmd/object-api-utils.go @@ -164,7 +164,7 @@ func getCompleteMultipartMD5(parts []completePart) (string, error) { // For example on windows since its case insensitive we are supposed // to do case insensitive checks. func hasPrefix(s string, prefix string) bool { - if runtime.GOOS == "windows" { + if runtime.GOOS == globalWindowsOSName { return strings.HasPrefix(strings.ToLower(s), strings.ToLower(prefix)) } return strings.HasPrefix(s, prefix) @@ -174,12 +174,20 @@ func hasPrefix(s string, prefix string) bool { // For example on windows since its case insensitive we are supposed // to do case insensitive checks. func hasSuffix(s string, suffix string) bool { - if runtime.GOOS == "windows" { + if runtime.GOOS == globalWindowsOSName { return strings.HasSuffix(strings.ToLower(s), strings.ToLower(suffix)) } return strings.HasSuffix(s, suffix) } +// Validates if two strings are equal. +func isStringEqual(s1 string, s2 string) bool { + if runtime.GOOS == globalWindowsOSName { + return strings.EqualFold(s1, s2) + } + return s1 == s2 +} + // Ignores all reserved bucket names or invalid bucket names. func isReservedOrInvalidBucket(bucketEntry string) bool { bucketEntry = strings.TrimSuffix(bucketEntry, slashSeparator) diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index 1ac3f23fe..0381f0946 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -64,7 +64,7 @@ func (xl xlObjects) CopyObject(srcBucket, srcObject, dstBucket, dstObject string length := xlMeta.Stat.Size // Check if this request is only metadata update. - cpMetadataOnly := strings.EqualFold(pathJoin(srcBucket, srcObject), pathJoin(dstBucket, dstObject)) + cpMetadataOnly := isStringEqual(pathJoin(srcBucket, srcObject), pathJoin(dstBucket, dstObject)) if cpMetadataOnly { xlMeta.Meta = metadata partsMetadata := make([]xlMetaV1, len(xl.storageDisks)) From 9eb8e375c50283b875fa635034c93499b7325ac6 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sun, 19 Feb 2017 20:46:06 -0800 Subject: [PATCH 10/94] cli: Make sure to add --help flag for subcommands. (#3773) --help is now back and prints properly with command help template. --- cmd/main.go | 6 ++++++ cmd/server-main.go | 1 - cmd/update-main.go | 8 +++++--- cmd/version-main.go | 13 +++++++++---- vendor/github.com/minio/cli/app.go | 20 +++++++++++++------- vendor/github.com/minio/cli/command.go | 15 +++++++++++++-- vendor/vendor.json | 6 +++--- 7 files changed, 49 insertions(+), 20 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index cf091f677..1516cd086 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -104,6 +104,10 @@ func registerApp() *cli.App { registerCommand(updateCmd) // Set up app. + cli.HelpFlag = cli.BoolFlag{ + Name: "help, h", + Usage: "Show help.", + } app := cli.NewApp() app.Name = "Minio" app.Author = "Minio.io" @@ -111,6 +115,8 @@ func registerApp() *cli.App { app.Usage = "Cloud Storage Server." app.Description = `Minio is an Amazon S3 compatible object storage server. Use it to store photos, videos, VMs, containers, log files, or any blob of data as objects.` app.Flags = globalFlags + app.HideVersion = true // Hide `--version` flag, we already have `minio version`. + app.HideHelpCommand = true // Hide `help, h` command, we already have `minio --help`. app.Commands = commands app.CustomAppHelpTemplate = minioHelpTemplate app.CommandNotFound = func(ctx *cli.Context, command string) { diff --git a/cmd/server-main.go b/cmd/server-main.go index b4e063696..d4b4a7852 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -79,7 +79,6 @@ EXAMPLES: $ export MINIO_SECRET_KEY=miniostorage $ {{.HelpName}} http://192.168.1.11/mnt/export/ http://192.168.1.12/mnt/export/ \ http://192.168.1.13/mnt/export/ http://192.168.1.14/mnt/export/ - `, } diff --git a/cmd/update-main.go b/cmd/update-main.go index 23721fb2b..ef8716d75 100644 --- a/cmd/update-main.go +++ b/cmd/update-main.go @@ -46,7 +46,7 @@ var updateCmd = cli.Command{ {{.HelpName}} - {{.Usage}} USAGE: - {{.HelpName}} {{if .VisibleFlags}}[FLAGS]{{end}} + {{.HelpName}}{{if .VisibleFlags}} [FLAGS]{{end}} {{if .VisibleFlags}} FLAGS: {{range .VisibleFlags}}{{.}} @@ -56,8 +56,10 @@ EXIT STATUS: 1 - New update is available. -1 - Error in getting update information. -VERSION: - ` + Version + `{{"\n"}}`, +EXAMPLES: + 1. Check if there is a new update available: + $ {{.HelpName}} +`, } const releaseTagTimeLayout = "2006-01-02T15-04-05Z" diff --git a/cmd/version-main.go b/cmd/version-main.go index f3d547c4f..9e1b1ea71 100644 --- a/cmd/version-main.go +++ b/cmd/version-main.go @@ -29,10 +29,15 @@ var versionCmd = cli.Command{ {{.HelpName}} - {{.Usage}} USAGE: - {{.HelpName}} - -VERSION: - ` + Version + `{{"\n"}}`, + {{.HelpName}}{{if .VisibleFlags}} [FLAGS]{{end}} +{{if .VisibleFlags}} +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}}{{end}} +EXAMPLES: + 1. Prints server version: + $ {{.HelpName}} +`, } func mainVersion(ctx *cli.Context) { diff --git a/vendor/github.com/minio/cli/app.go b/vendor/github.com/minio/cli/app.go index 26a4d4d92..ce5f89f9a 100644 --- a/vendor/github.com/minio/cli/app.go +++ b/vendor/github.com/minio/cli/app.go @@ -45,8 +45,10 @@ type App struct { Flags []Flag // Boolean to enable bash completion commands EnableBashCompletion bool - // Boolean to hide built-in help command + // Boolean to hide built-in help flag HideHelp bool + // Boolean to hide built-in help command + HideHelpCommand bool // Boolean to hide built-in version flag and the VERSION section of help HideVersion bool // Populate on app startup, only gettable through method Categories() @@ -144,9 +146,11 @@ func (a *App) Setup() { } a.Commands = newCmds - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { + if a.Command(helpCommand.Name) == nil { + if !a.HideHelpCommand { + a.Commands = append(a.Commands, helpCommand) + } + if !a.HideHelp && (HelpFlag != BoolFlag{}) { a.appendFlag(HelpFlag) } } @@ -285,9 +289,11 @@ func (a *App) RunAndExitOnError() { func (a *App) RunAsSubcommand(ctx *Context) (err error) { // append help to commands if len(a.Commands) > 0 { - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - a.Commands = append(a.Commands, helpCommand) - if (HelpFlag != BoolFlag{}) { + if a.Command(helpCommand.Name) == nil { + if !a.HideHelpCommand { + a.Commands = append(a.Commands, helpCommand) + } + if !a.HideHelp && (HelpFlag != BoolFlag{}) { a.appendFlag(HelpFlag) } } diff --git a/vendor/github.com/minio/cli/command.go b/vendor/github.com/minio/cli/command.go index 1e4ca5cc4..e10e68811 100644 --- a/vendor/github.com/minio/cli/command.go +++ b/vendor/github.com/minio/cli/command.go @@ -51,8 +51,10 @@ type Command struct { // removed n version 2 since it only works under specific conditions so we // backport here by exposing it as an option for compatibility. SkipArgReorder bool - // Boolean to hide built-in help command + // Boolean to hide built-in help flag HideHelp bool + // Boolean to hide built-in help command + HideHelpCommand bool // Boolean to hide this command from help or completion Hidden bool @@ -261,6 +263,7 @@ func (c Command) startApp(ctx *Context) error { app.Commands = c.Subcommands app.Flags = c.Flags app.HideHelp = c.HideHelp + app.HideHelpCommand = c.HideHelpCommand app.Version = ctx.App.Version app.HideVersion = ctx.App.HideVersion @@ -301,5 +304,13 @@ func (c Command) startApp(ctx *Context) error { // VisibleFlags returns a slice of the Flags with Hidden=false func (c Command) VisibleFlags() []Flag { - return visibleFlags(c.Flags) + flags := c.Flags + if !c.HideHelp && (HelpFlag != BoolFlag{}) { + // append help to flags + flags = append( + flags, + HelpFlag, + ) + } + return visibleFlags(flags) } diff --git a/vendor/vendor.json b/vendor/vendor.json index a1ed690cf..ff87684b6 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -163,10 +163,10 @@ "revisionTime": "2016-07-23T06:10:19Z" }, { - "checksumSHA1": "iDDGi0/U33hxoaQBgM3ww882lmU=", + "checksumSHA1": "7PcmjItrQSx/1sZ6Q395LCzT+iw=", "path": "github.com/minio/cli", - "revision": "cea7bbb0e52ac4d24c1de3f450545f38246075a2", - "revisionTime": "2017-02-15T09:44:04Z" + "revision": "06bb2061ef1493532baf0444818eb5fb4c83caac", + "revisionTime": "2017-02-20T03:57:28Z" }, { "checksumSHA1": "NBGyq2+iTtJvJ+ElG4FzHLe1WSY=", From 0a905e1a8a243d03ed3b823821bad7881b43e3ff Mon Sep 17 00:00:00 2001 From: Aditya Manthramurthy Date: Tue, 21 Feb 2017 01:35:21 +0530 Subject: [PATCH 11/94] Fix rabbitmq reconnect problem (#3778) --- cmd/notify-amqp.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmd/notify-amqp.go b/cmd/notify-amqp.go index 9168cc959..f3b09379c 100644 --- a/cmd/notify-amqp.go +++ b/cmd/notify-amqp.go @@ -18,6 +18,7 @@ package cmd import ( "io/ioutil" + "net" "github.com/Sirupsen/logrus" "github.com/streadway/amqp" @@ -87,7 +88,14 @@ func (q amqpConn) Fire(entry *logrus.Entry) error { ch, err := q.Connection.Channel() if err != nil { // Any other error other than connection closed, return. - if err != amqp.ErrClosed { + isClosedErr := false + if neterr, ok := err.(*net.OpError); ok && + neterr.Err.Error() == "use of closed network connection" { + isClosedErr = true + } else if err == amqp.ErrClosed { + isClosedErr = true + } + if !isClosedErr { return err } // Attempt to connect again. From 6b68c0170f7270658514932d3676e5f864bb9953 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 20 Feb 2017 12:07:03 -0800 Subject: [PATCH 12/94] For streaming signature do not save content-encoding in PutObject() (#3776) Content-Encoding is set to "aws-chunked" which is an S3 specific API value which is no meaning for an object. This is how S3 behaves as well for a streaming signature uploaded object. --- cmd/auth-handler.go | 4 +++- cmd/auth-handler_test.go | 1 + cmd/object-handlers.go | 7 +++++++ cmd/object-handlers_test.go | 7 +++++++ cmd/streaming-signature-v4.go | 7 ++++--- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/cmd/auth-handler.go b/cmd/auth-handler.go index a48989f12..a979ae961 100644 --- a/cmd/auth-handler.go +++ b/cmd/auth-handler.go @@ -63,7 +63,9 @@ func isRequestPostPolicySignatureV4(r *http.Request) bool { // Verify if the request has AWS Streaming Signature Version '4'. This is only valid for 'PUT' operation. func isRequestSignStreamingV4(r *http.Request) bool { - return r.Header.Get("x-amz-content-sha256") == streamingContentSHA256 && r.Method == httpPUT + return r.Header.Get("x-amz-content-sha256") == streamingContentSHA256 && + r.Header.Get("content-encoding") == streamingContentEncoding && + r.Method == httpPUT } // Authorization type. diff --git a/cmd/auth-handler_test.go b/cmd/auth-handler_test.go index fbb78d4e2..b67398bdf 100644 --- a/cmd/auth-handler_test.go +++ b/cmd/auth-handler_test.go @@ -43,6 +43,7 @@ func TestGetRequestAuthType(t *testing.T) { Header: http.Header{ "Authorization": []string{"AWS4-HMAC-SHA256 "}, "X-Amz-Content-Sha256": []string{streamingContentSHA256}, + "Content-Encoding": []string{streamingContentEncoding}, }, Method: "PUT", }, diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index a3ef52f9f..ff00f034a 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -421,6 +421,13 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Extract metadata to be saved from incoming HTTP header. metadata := extractMetadataFromHeader(r.Header) + if rAuthType == authTypeStreamingSigned { + // Make sure to delete the content-encoding parameter + // for a streaming signature which is set to value + // "aws-chunked" + delete(metadata, "content-encoding") + } + // Make sure we hex encode md5sum here. metadata["md5Sum"] = hex.EncodeToString(md5Bytes) diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index 95e126202..e68a80ae4 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -682,6 +682,13 @@ func testAPIPutObjectStreamSigV4Handler(obj ObjectLayer, instanceType, bucketNam continue } + objInfo, err := obj.GetObjectInfo(testCase.bucketName, testCase.objectName) + if err != nil { + t.Fatalf("Test %d: %s: Failed to fetch the copied object: %s", i+1, instanceType, err) + } + if objInfo.ContentEncoding == streamingContentEncoding { + t.Fatalf("Test %d: %s: ContentEncoding is set to \"aws-chunked\" which is unexpected", i+1, instanceType) + } buffer := new(bytes.Buffer) err = obj.GetObject(testCase.bucketName, testCase.objectName, 0, int64(testCase.dataLen), buffer) if err != nil { diff --git a/cmd/streaming-signature-v4.go b/cmd/streaming-signature-v4.go index 9383c17a0..4fc4eca21 100644 --- a/cmd/streaming-signature-v4.go +++ b/cmd/streaming-signature-v4.go @@ -34,9 +34,10 @@ import ( // Streaming AWS Signature Version '4' constants. const ( - emptySHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - streamingContentSHA256 = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" - signV4ChunkedAlgorithm = "AWS4-HMAC-SHA256-PAYLOAD" + emptySHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + streamingContentSHA256 = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" + signV4ChunkedAlgorithm = "AWS4-HMAC-SHA256-PAYLOAD" + streamingContentEncoding = "aws-chunked" ) // getChunkSignature - get chunk signature. From 70d825c608cf950168c43e1500012c0567a09c1e Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Mon, 20 Feb 2017 21:07:27 +0100 Subject: [PATCH 13/94] doc: Small rewrite of bucket events notif intro (#3775) --- docs/bucket/notifications/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/bucket/notifications/README.md b/docs/bucket/notifications/README.md index 82e299342..59cdeefc9 100644 --- a/docs/bucket/notifications/README.md +++ b/docs/bucket/notifications/README.md @@ -1,6 +1,7 @@ # Minio Bucket Notification Guide [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) -Minio server supports Amazon S3 compatible bucket event notification for the following targets +Changes in a bucket, such as object uploads and removal, can be monitored using bucket event notification +mechanism and can be published to the following targets: | Notification Targets| |:---| From 2745bf2f1ff8012672e21670eba5c8052887365f Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Tue, 21 Feb 2017 02:28:50 +0530 Subject: [PATCH 14/94] Implement ServerConfig admin REST API (#3741) Returns a valid config.json of the setup. In case of distributed setup, it checks if quorum or more number of nodes have the same config.json. --- cmd/admin-handlers.go | 29 ++++ cmd/admin-handlers_test.go | 45 +++++ cmd/admin-router.go | 5 + cmd/admin-rpc-client.go | 153 +++++++++++++++++ cmd/admin-rpc-client_test.go | 260 +++++++++++++++++++++++++++++ cmd/admin-rpc-server.go | 26 +++ cmd/admin-rpc-server_test.go | 44 +++++ pkg/madmin/API.md | 35 +++- pkg/madmin/config-commands.go | 49 ++++++ pkg/madmin/examples/get-config.go | 52 ++++++ pkg/madmin/examples/heal-bucket.go | 3 - 11 files changed, 691 insertions(+), 10 deletions(-) create mode 100644 cmd/admin-rpc-client_test.go create mode 100644 pkg/madmin/config-commands.go create mode 100644 pkg/madmin/examples/get-config.go diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 016db0a24..dce7d812d 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -672,3 +672,32 @@ func (adminAPI adminAPIHandlers) HealFormatHandler(w http.ResponseWriter, r *htt // Return 200 on success. writeSuccessResponseHeadersOnly(w) } + +// GetConfigHandler - GET /?config +// - x-minio-operation = get +// Get config.json of this minio setup. +func (adminAPI adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Request) { + // Validate request signature. + adminAPIErr := checkRequestAuthType(r, "", "", "") + if adminAPIErr != ErrNone { + writeErrorResponse(w, adminAPIErr, r.URL) + return + } + + // check if objectLayer is initialized, if not return. + if newObjectLayerFn() == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + // Get config.json from all nodes. In a single node setup, it + // returns local config.json. + configBytes, err := getPeerConfig(globalAdminPeers) + if err != nil { + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + errorIf(err, "Failed to get config from peers") + return + } + + writeSuccessResponseJSON(w, configBytes) +} diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index e309e3f27..7c7bb1b54 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -988,3 +988,48 @@ func TestHealFormatHandler(t *testing.T) { t.Errorf("Expected to succeed but failed with %d", rec.Code) } } + +// TestGetConfigHandler - test for GetConfigHandler. +func TestGetConfigHandler(t *testing.T) { + adminTestBed, err := prepareAdminXLTestBed() + if err != nil { + t.Fatal("Failed to initialize a single node XL backend for admin handler tests.") + } + defer adminTestBed.TearDown() + + // Initialize admin peers to make admin RPC calls. + eps, err := parseStorageEndpoints([]string{"http://127.0.0.1"}) + if err != nil { + t.Fatalf("Failed to parse storage end point - %v", err) + } + + // Set globalMinioAddr to be able to distinguish local endpoints from remote. + globalMinioAddr = eps[0].Host + initGlobalAdminPeers(eps) + + // Prepare query params for get-config mgmt REST API. + queryVal := url.Values{} + queryVal.Set("config", "") + + req, err := newTestRequest("GET", "/?"+queryVal.Encode(), 0, nil) + if err != nil { + t.Fatalf("Failed to construct get-config object request - %v", err) + } + + // Set x-minio-operation header to get. + req.Header.Set(minioAdminOpHeader, "get") + + // Sign the request using signature v4. + cred := serverConfig.GetCredential() + err = signRequestV4(req, cred.AccessKey, cred.SecretKey) + if err != nil { + t.Fatalf("Failed to sign heal object request - %v", err) + } + + rec := httptest.NewRecorder() + adminTestBed.mux.ServeHTTP(rec, req) + if rec.Code != http.StatusOK { + t.Errorf("Expected to succeed but failed with %d", rec.Code) + } + +} diff --git a/cmd/admin-router.go b/cmd/admin-router.go index b22794c97..6bdcc8dc6 100644 --- a/cmd/admin-router.go +++ b/cmd/admin-router.go @@ -62,4 +62,9 @@ func registerAdminRouter(mux *router.Router) { adminRouter.Methods("POST").Queries("heal", "").Headers(minioAdminOpHeader, "object").HandlerFunc(adminAPI.HealObjectHandler) // Heal Format. adminRouter.Methods("POST").Queries("heal", "").Headers(minioAdminOpHeader, "format").HandlerFunc(adminAPI.HealFormatHandler) + + /// Config operations + + // Get config + adminRouter.Methods("GET").Queries("config", "").Headers(minioAdminOpHeader, "get").HandlerFunc(adminAPI.GetConfigHandler) } diff --git a/cmd/admin-rpc-client.go b/cmd/admin-rpc-client.go index 8604f18a6..392f62c51 100644 --- a/cmd/admin-rpc-client.go +++ b/cmd/admin-rpc-client.go @@ -17,8 +17,11 @@ package cmd import ( + "encoding/json" + "errors" "net/url" "path" + "reflect" "sort" "sync" "time" @@ -41,6 +44,7 @@ type adminCmdRunner interface { ListLocks(bucket, prefix string, duration time.Duration) ([]VolumeLockInfo, error) ReInitDisks() error Uptime() (time.Duration, error) + GetConfig() ([]byte, error) } // Restart - Sends a message over channel to the go-routine @@ -112,6 +116,25 @@ func (rc remoteAdminClient) Uptime() (time.Duration, error) { return reply.Uptime, nil } +// GetConfig - returns config.json of the local server. +func (lc localAdminClient) GetConfig() ([]byte, error) { + if serverConfig == nil { + return nil, errors.New("config not present") + } + + return json.Marshal(serverConfig) +} + +// GetConfig - returns config.json of the remote server. +func (rc remoteAdminClient) GetConfig() ([]byte, error) { + args := AuthRPCArgs{} + reply := ConfigReply{} + if err := rc.Call("Admin.GetConfig", &args, &reply); err != nil { + return nil, err + } + return reply.Config, nil +} + // adminPeer - represents an entity that implements Restart methods. type adminPeer struct { addr string @@ -336,3 +359,133 @@ func getPeerUptimes(peers adminPeers) (time.Duration, error) { return latestUptime, nil } + +// getPeerConfig - Fetches config.json from all nodes in the setup and +// returns the one that occurs in a majority of them. +func getPeerConfig(peers adminPeers) ([]byte, error) { + if !globalIsDistXL { + return peers[0].cmdRunner.GetConfig() + } + + errs := make([]error, len(peers)) + configs := make([][]byte, len(peers)) + + // Get config from all servers. + wg := sync.WaitGroup{} + for i, peer := range peers { + wg.Add(1) + go func(idx int, peer adminPeer) { + defer wg.Done() + configs[idx], errs[idx] = peer.cmdRunner.GetConfig() + }(i, peer) + } + wg.Wait() + + // Find the maximally occurring config among peers in a + // distributed setup. + + serverConfigs := make([]serverConfigV13, len(peers)) + for i, configBytes := range configs { + if errs[i] != nil { + continue + } + + // Unmarshal the received config files. + err := json.Unmarshal(configBytes, &serverConfigs[i]) + if err != nil { + errorIf(err, "Failed to unmarshal serverConfig from ", peers[i].addr) + return nil, err + } + } + + configJSON, err := getValidServerConfig(serverConfigs, errs) + if err != nil { + errorIf(err, "Unable to find a valid server config") + return nil, traceError(err) + } + + // Return the config.json that was present quorum or more + // number of disks. + return json.Marshal(configJSON) +} + +// getValidServerConfig - finds the server config that is present in +// quorum or more number of servers. +func getValidServerConfig(serverConfigs []serverConfigV13, errs []error) (serverConfigV13, error) { + // majority-based quorum + quorum := len(serverConfigs)/2 + 1 + + // Count the number of disks a config.json was found in. + configCounter := make([]int, len(serverConfigs)) + + // We group equal serverConfigs by the lowest index of the + // same value; e.g, let us take the following serverConfigs + // in a 4-node setup, + // serverConfigs == [c1, c2, c1, c1] + // configCounter == [3, 1, 0, 0] + // c1, c2 are the only distinct values that appear. c1 is + // identified by 0, the lowest index it appears in and c2 is + // identified by 1. So, we need to find the number of times + // each of these distinct values occur. + + // Invariants: + + // 1. At the beginning of the i-th iteration, the number of + // unique configurations seen so far is equal to the number of + // non-zero counter values in config[:i]. + + // 2. At the beginning of the i-th iteration, the sum of + // elements of configCounter[:i] is equal to the number of + // non-error configurations seen so far. + + // For each of the serverConfig ... + for i := range serverConfigs { + // Skip nodes where getConfig failed. + if errs[i] != nil { + continue + } + // Check if it is equal to any of the configurations + // seen so far. If j == i is reached then we have an + // unseen configuration. + for j := 0; j <= i; j++ { + if j < i && configCounter[j] == 0 { + // serverConfigs[j] is known to be + // equal to a value that was already + // seen. See example above for + // clarity. + continue + } else if j < i && reflect.DeepEqual(serverConfigs[i], serverConfigs[j]) { + // serverConfigs[i] is equal to + // serverConfigs[j], update + // serverConfigs[j]'s counter since it + // is the lower index. + configCounter[j]++ + break + } else if j == i { + // serverConfigs[i] is equal to no + // other value seen before. It is + // unique so far. + configCounter[i] = 1 + break + } // else invariants specified above are violated. + } + } + + // We find the maximally occurring server config and check if + // there is quorum. + var configJSON serverConfigV13 + maxOccurrence := 0 + for i, count := range configCounter { + if maxOccurrence < count { + maxOccurrence = count + configJSON = serverConfigs[i] + } + } + + // If quorum nodes don't agree. + if maxOccurrence < quorum { + return serverConfigV13{}, errXLWriteQuorum + } + + return configJSON, nil +} diff --git a/cmd/admin-rpc-client_test.go b/cmd/admin-rpc-client_test.go new file mode 100644 index 000000000..2c09d758c --- /dev/null +++ b/cmd/admin-rpc-client_test.go @@ -0,0 +1,260 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "encoding/json" + "reflect" + "testing" +) + +var ( + config1 = []byte(`{ + "version": "13", + "credential": { + "accessKey": "minio", + "secretKey": "minio123" + }, + "region": "us-east-1", + "logger": { + "console": { + "enable": true, + "level": "debug" + }, + "file": { + "enable": false, + "fileName": "", + "level": "" + } + }, + "notify": { + "amqp": { + "1": { + "enable": false, + "url": "", + "exchange": "", + "routingKey": "", + "exchangeType": "", + "mandatory": false, + "immediate": false, + "durable": false, + "internal": false, + "noWait": false, + "autoDeleted": false + } + }, + "nats": { + "1": { + "enable": false, + "address": "", + "subject": "", + "username": "", + "password": "", + "token": "", + "secure": false, + "pingInterval": 0, + "streaming": { + "enable": false, + "clusterID": "", + "clientID": "", + "async": false, + "maxPubAcksInflight": 0 + } + } + }, + "elasticsearch": { + "1": { + "enable": false, + "url": "", + "index": "" + } + }, + "redis": { + "1": { + "enable": false, + "address": "", + "password": "", + "key": "" + } + }, + "postgresql": { + "1": { + "enable": false, + "connectionString": "", + "table": "", + "host": "", + "port": "", + "user": "", + "password": "", + "database": "" + } + }, + "kafka": { + "1": { + "enable": false, + "brokers": null, + "topic": "" + } + }, + "webhook": { + "1": { + "enable": false, + "endpoint": "" + } + } + } +} +`) + // diff from config1 - amqp.Enable is True + config2 = []byte(`{ + "version": "13", + "credential": { + "accessKey": "minio", + "secretKey": "minio123" + }, + "region": "us-east-1", + "logger": { + "console": { + "enable": true, + "level": "debug" + }, + "file": { + "enable": false, + "fileName": "", + "level": "" + } + }, + "notify": { + "amqp": { + "1": { + "enable": true, + "url": "", + "exchange": "", + "routingKey": "", + "exchangeType": "", + "mandatory": false, + "immediate": false, + "durable": false, + "internal": false, + "noWait": false, + "autoDeleted": false + } + }, + "nats": { + "1": { + "enable": false, + "address": "", + "subject": "", + "username": "", + "password": "", + "token": "", + "secure": false, + "pingInterval": 0, + "streaming": { + "enable": false, + "clusterID": "", + "clientID": "", + "async": false, + "maxPubAcksInflight": 0 + } + } + }, + "elasticsearch": { + "1": { + "enable": false, + "url": "", + "index": "" + } + }, + "redis": { + "1": { + "enable": false, + "address": "", + "password": "", + "key": "" + } + }, + "postgresql": { + "1": { + "enable": false, + "connectionString": "", + "table": "", + "host": "", + "port": "", + "user": "", + "password": "", + "database": "" + } + }, + "kafka": { + "1": { + "enable": false, + "brokers": null, + "topic": "" + } + }, + "webhook": { + "1": { + "enable": false, + "endpoint": "" + } + } + } +} +`) +) + +// TestGetValidServerConfig - test for getValidServerConfig. +func TestGetValidServerConfig(t *testing.T) { + var c1, c2 serverConfigV13 + err := json.Unmarshal(config1, &c1) + if err != nil { + t.Fatalf("json unmarshal of %s failed: %v", string(config1), err) + } + + err = json.Unmarshal(config2, &c2) + if err != nil { + t.Fatalf("json unmarshal of %s failed: %v", string(config2), err) + } + + // Valid config. + noErrs := []error{nil, nil, nil, nil} + serverConfigs := []serverConfigV13{c1, c2, c1, c1} + validConfig, err := getValidServerConfig(serverConfigs, noErrs) + if err != nil { + t.Errorf("Expected a valid config but received %v instead", err) + } + + if !reflect.DeepEqual(validConfig, c1) { + t.Errorf("Expected valid config to be %v but received %v", config1, validConfig) + } + + // Invalid config - no quorum. + serverConfigs = []serverConfigV13{c1, c2, c2, c1} + validConfig, err = getValidServerConfig(serverConfigs, noErrs) + if err != errXLWriteQuorum { + t.Errorf("Expected to fail due to lack of quorum but received %v", err) + } + + // All errors + allErrs := []error{errDiskNotFound, errDiskNotFound, errDiskNotFound, errDiskNotFound} + serverConfigs = []serverConfigV13{serverConfigV13{}, serverConfigV13{}, serverConfigV13{}, serverConfigV13{}} + validConfig, err = getValidServerConfig(serverConfigs, allErrs) + if err != errXLWriteQuorum { + t.Errorf("Expected to fail due to lack of quorum but received %v", err) + } +} diff --git a/cmd/admin-rpc-server.go b/cmd/admin-rpc-server.go index b11eb8092..213fbdd8e 100644 --- a/cmd/admin-rpc-server.go +++ b/cmd/admin-rpc-server.go @@ -17,6 +17,7 @@ package cmd import ( + "encoding/json" "errors" "net/rpc" "time" @@ -54,6 +55,12 @@ type UptimeReply struct { Uptime time.Duration } +// ConfigReply - wraps the server config response over RPC. +type ConfigReply struct { + AuthRPCReply + Config []byte // json-marshalled bytes of serverConfigV13 +} + // Restart - Restart this instance of minio server. func (s *adminCmd) Restart(args *AuthRPCArgs, reply *AuthRPCReply) error { if err := args.IsAuthenticated(); err != nil { @@ -132,6 +139,25 @@ func (s *adminCmd) Uptime(args *AuthRPCArgs, reply *UptimeReply) error { return nil } +// GetConfig - returns the config.json of this server. +func (s *adminCmd) GetConfig(args *AuthRPCArgs, reply *ConfigReply) error { + if err := args.IsAuthenticated(); err != nil { + return err + } + + if serverConfig == nil { + return errors.New("config not present") + } + + jsonBytes, err := json.Marshal(serverConfig) + if err != nil { + return err + } + + reply.Config = jsonBytes + return nil +} + // registerAdminRPCRouter - registers RPC methods for service status, // stop and restart commands. func registerAdminRPCRouter(mux *router.Router) error { diff --git a/cmd/admin-rpc-server_test.go b/cmd/admin-rpc-server_test.go index 32d1dd288..dbc097a8d 100644 --- a/cmd/admin-rpc-server_test.go +++ b/cmd/admin-rpc-server_test.go @@ -17,6 +17,7 @@ package cmd import ( + "encoding/json" "net/url" "testing" "time" @@ -144,3 +145,46 @@ func TestReInitDisks(t *testing.T) { errUnsupportedBackend, err) } } + +func TestGetConfig(t *testing.T) { + // Reset global variables to start afresh. + resetTestGlobals() + + rootPath, err := newTestConfig("us-east-1") + if err != nil { + t.Fatalf("Unable to initialize server config. %s", err) + } + defer removeAll(rootPath) + + adminServer := adminCmd{} + creds := serverConfig.GetCredential() + args := LoginRPCArgs{ + Username: creds.AccessKey, + Password: creds.SecretKey, + Version: Version, + RequestTime: time.Now().UTC(), + } + reply := LoginRPCReply{} + err = adminServer.Login(&args, &reply) + if err != nil { + t.Fatalf("Failed to login to admin server - %v", err) + } + + authArgs := AuthRPCArgs{ + AuthToken: reply.AuthToken, + RequestTime: time.Now().UTC(), + } + + configReply := ConfigReply{} + + err = adminServer.GetConfig(&authArgs, &configReply) + if err != nil { + t.Errorf("Expected GetConfig to pass but failed with %v", err) + } + + var config serverConfigV13 + err = json.Unmarshal(configReply.Config, &config) + if err != nil { + t.Errorf("Expected json unmarshal to pass but failed with %v", err) + } +} diff --git a/pkg/madmin/API.md b/pkg/madmin/API.md index 506690783..84ba1e924 100644 --- a/pkg/madmin/API.md +++ b/pkg/madmin/API.md @@ -36,13 +36,13 @@ func main() { ``` -| Service operations|LockInfo operations|Healing operations| -|:---|:---|:---| -|[`ServiceStatus`](#ServiceStatus)| [`ListLocks`](#ListLocks)| [`ListObjectsHeal`](#ListObjectsHeal)| -|[`ServiceRestart`](#ServiceRestart)| [`ClearLocks`](#ClearLocks)| [`ListBucketsHeal`](#ListBucketsHeal)| -| | |[`HealBucket`](#HealBucket) | -| | |[`HealObject`](#HealObject)| -| | |[`HealFormat`](#HealFormat)| +| Service operations|LockInfo operations|Healing operations|Config operations| +|:---|:---|:---|:---| +|[`ServiceStatus`](#ServiceStatus)| [`ListLocks`](#ListLocks)| [`ListObjectsHeal`](#ListObjectsHeal)|[`GetConfig`](#GetConfig)| +|[`ServiceRestart`](#ServiceRestart)| [`ClearLocks`](#ClearLocks)| [`ListBucketsHeal`](#ListBucketsHeal)|| +| | |[`HealBucket`](#HealBucket) || +| | |[`HealObject`](#HealObject)|| +| | |[`HealFormat`](#HealFormat)|| ## 1. Constructor @@ -272,3 +272,24 @@ __Example__ log.Println("successfully healed storage format on available disks.") ``` + +### GetConfig() ([]byte, error) +Get config.json of a minio setup. + +__Example__ + +``` go + configBytes, err := madmClnt.GetConfig() + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + // Pretty-print config received as json. + var buf bytes.Buffer + err = json.Indent(buf, configBytes, "", "\t") + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + log.Println("config received successfully: ", string(buf.Bytes())) +``` diff --git a/pkg/madmin/config-commands.go b/pkg/madmin/config-commands.go new file mode 100644 index 000000000..2e839bac3 --- /dev/null +++ b/pkg/madmin/config-commands.go @@ -0,0 +1,49 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package madmin + +import ( + "io/ioutil" + "net/http" + "net/url" +) + +// GetConfig - returns the config.json of a minio setup. +func (adm *AdminClient) GetConfig() ([]byte, error) { + queryVal := make(url.Values) + queryVal.Set("config", "") + + hdrs := make(http.Header) + hdrs.Set(minioAdminOpHeader, "get") + + reqData := requestData{ + queryValues: queryVal, + customHeaders: hdrs, + } + + // Execute GET on /?lock to list locks. + resp, err := adm.executeMethod("GET", reqData) + + defer closeResponse(resp) + if err != nil { + return nil, err + } + + // Return the JSON marshalled bytes to user. + return ioutil.ReadAll(resp.Body) +} diff --git a/pkg/madmin/examples/get-config.go b/pkg/madmin/examples/get-config.go new file mode 100644 index 000000000..87e6790a0 --- /dev/null +++ b/pkg/madmin/examples/get-config.go @@ -0,0 +1,52 @@ +/* +build ignore + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "bytes" + "encoding/json" + "log" + + "github.com/minio/minio/pkg/madmin" +) + +func main() { + // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are + // dummy values, please replace them with original values. + + // API requests are secure (HTTPS) if secure=true and insecure (HTTPS) otherwise. + // New returns an Minio Admin client object. + madmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true) + if err != nil { + log.Fatalln(err) + } + + configBytes, err := madmClnt.GetConfig() + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + // Pretty-print config received as json. + var buf bytes.Buffer + err = json.Indent(&buf, configBytes, "", "\t") + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + log.Println("config received successfully: ", string(buf.Bytes())) +} diff --git a/pkg/madmin/examples/heal-bucket.go b/pkg/madmin/examples/heal-bucket.go index cb2559dcf..64767e6a6 100644 --- a/pkg/madmin/examples/heal-bucket.go +++ b/pkg/madmin/examples/heal-bucket.go @@ -29,9 +29,6 @@ func main() { // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are // dummy values, please replace them with original values. - // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are - // dummy values, please replace them with original values. - // API requests are secure (HTTPS) if secure=true and insecure (HTTPS) otherwise. // New returns an Minio Admin client object. madmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true) From a7d3ea8c152b234ad6135b2bc5c3fed0f2b9430b Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Tue, 21 Feb 2017 09:42:21 +0530 Subject: [PATCH 15/94] Update erasure code image (#3782) --- docs/erasure/README.md | 12 ++++++------ docs/screenshots/erasure-code.png | Bin 0 -> 226006 bytes 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 docs/screenshots/erasure-code.png diff --git a/docs/erasure/README.md b/docs/erasure/README.md index 9016026c7..48cc12a29 100644 --- a/docs/erasure/README.md +++ b/docs/erasure/README.md @@ -8,27 +8,27 @@ Install Minio - [Minio Quickstart Guide](https://docs.minio.io/docs/minio-quicks ## What is Erasure Code? -Erasure code is a mathematical algorithm to reconstruct missing or corrupted data. Minio uses Reed-Solomon code to shard objects into N/2 data and N/2 parity blocks. This means that in a 12 drive setup, an object is sharded across as 6 data and 6 parity blocks. You can lose as many as 6 drives (be it parity or data) and still reconstruct the data reliably from the remaining drives. +Erasure code is a mathematical algorithm to reconstruct missing or corrupted data. Minio uses Reed-Solomon code to shard objects into N/2 data and N/2 parity blocks. This means that in a 12 drive setup, an object is sharded across as 6 data and 6 parity blocks. You can lose as many as 6 drives (be it parity or data) and still reconstruct the data reliably from the remaining drives. ## Why is Erasure Code useful? Erasure code protects data from multiple drives failure unlike RAID or replication. For eg RAID6 can protect against 2 drive failure whereas in Minio erasure code you can lose as many as half number of drives and still the data remains safe. Further Minio's erasure code is at object level and can heal one object at a time. For RAID, healing can only be performed at volume level which translates into huge down time. As Minio encodes each object individually with a high parity count. Storage servers once deployed should not require drive replacement or healing for the lifetime of the server. Minio's erasure coded backend is designed for operational efficiency and takes full advantage of hardware acceleration whenever available. -![Erasure](https://raw.githubusercontent.com/minio/minio/master/docs/screenshots/erasure-code.jpg?raw=true) +![Erasure](https://raw.githubusercontent.com/minio/minio/master/docs/screenshots/erasure-code.png?raw=true) ## What is Bit Rot protection? -Bit Rot also known as Data Rot or Silent Data Corruption is a serious data loss issue faced by disk drives today. Data on the drive may silently get corrupted without signalling an error has occurred. This makes Bit Rot more dangerous than permanent hard drive failure. +Bit Rot also known as Data Rot or Silent Data Corruption is a serious data loss issue faced by disk drives today. Data on the drive may silently get corrupted without signalling an error has occurred. This makes Bit Rot more dangerous than permanent hard drive failure. Minio's erasure coded backend uses high speed [BLAKE2](https://blog.minio.io/accelerating-blake2b-by-4x-using-simd-in-go-assembly-33ef16c8a56b#.jrp1fdwer) hash based checksums to protect against Bit Rot. ## Deployment Scenarios -Minio server runs on a variety of hardware, operating systems and virtual/container environments. +Minio server runs on a variety of hardware, operating systems and virtual/container environments. -Minio erasure code backend is limited by design to a minimum of 4 drives and a maximum of 16 drives. The hard limit of 16 drives comes from operational experience. Failure domain becomes too large beyond 16 drives. If you need to scale beyond 16 drives, you may run multiple instances of Minio server on different ports. +Minio erasure code backend is limited by design to a minimum of 4 drives and a maximum of 16 drives. The hard limit of 16 drives comes from operational experience. Failure domain becomes too large beyond 16 drives. If you need to scale beyond 16 drives, you may run multiple instances of Minio server on different ports. -#### Reference Physical Hardware: +#### Reference Physical Hardware: * [SMC 5018A-AR12L (Intel Atom)](http://www.supermicro.com/products/system/1U/5018/SSG-5018A-AR12L.cfm?parts=SHOW) - SMC 1U SoC Atom C2750 platform with 12x 3.5” drive bays * [Quanta Grid D51B-2U (OCP Compliant) ](http://www.qct.io/Product/Servers/Rackmount-Servers/2U/QuantaGrid-D51B-2U-p256c77c70c83c118)- Quanta 2U DP E5-2600v3 platform with 12x 3.5” drive bays diff --git a/docs/screenshots/erasure-code.png b/docs/screenshots/erasure-code.png new file mode 100644 index 0000000000000000000000000000000000000000..61d8bcbcc1cdfc7e69d88a85799642029b4fe155 GIT binary patch literal 226006 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 z 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%0D_RcI1(h0v{J&Ii0GX6 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 literal 0 HcmV?d00001 From 097dd7418abc7d45024b3479810c129f721eea88 Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Tue, 21 Feb 2017 10:31:08 +0530 Subject: [PATCH 16/94] Remove unused erasure diagram (#3783) --- docs/screenshots/erasure-code.jpg | Bin 82979 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/screenshots/erasure-code.jpg diff --git a/docs/screenshots/erasure-code.jpg b/docs/screenshots/erasure-code.jpg deleted file mode 100644 index 4963e26cc46df7a1b66733c1ffb90d36135cbceb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82979 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

Ad_;pIz}V8(#>Q(%Jv!FUI2BZ^lAp4Ny#_ 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 Yw54T4F6rK%?utG?{wGsF>qGDV0bV|i+5i9m From 99a12613a3616756259b90b16360acfd9c4e4050 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 21 Feb 2017 01:32:05 -0800 Subject: [PATCH 17/94] update: For source builds look for absolute path. (#3780) os.Args[0] doesn't point to absolute path we need use exec.LookPath to find the absolute path before sending os.Stat(). --- .travis.yml | 2 +- appveyor.yml | 6 ++-- cmd/admin-rpc-client_test.go | 2 +- cmd/logger.go | 1 + cmd/update-main.go | 19 ++++++++--- cmd/update-main_test.go | 66 ++++++++++++++++++++++++++++-------- 6 files changed, 72 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 979a61bed..d6976a5b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ env: script: - make -- make test GOFLAGS="-timeout 20m -race -v" +- make test GOFLAGS="-timeout 15m -race -v" - make coverage after_success: diff --git a/appveyor.yml b/appveyor.yml index 68a87aa07..2e1dfd420 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -35,9 +35,9 @@ test_script: # Unit tests - ps: Add-AppveyorTest "Unit Tests" -Outcome Running - mkdir build\coverage - - go test -timeout 20m -v -race github.com/minio/minio/cmd... - - go test -v -race github.com/minio/minio/pkg... - - go test -timeout 15m -coverprofile=build\coverage\coverage.txt -covermode=atomic github.com/minio/minio/cmd + - go test -timeout 15m -race github.com/minio/minio/cmd... + - go test -race github.com/minio/minio/pkg... + - go test -coverprofile=build\coverage\coverage.txt -covermode=atomic github.com/minio/minio/cmd - ps: Update-AppveyorTest "Unit Tests" -Outcome Passed after_test: diff --git a/cmd/admin-rpc-client_test.go b/cmd/admin-rpc-client_test.go index 2c09d758c..6bd360a72 100644 --- a/cmd/admin-rpc-client_test.go +++ b/cmd/admin-rpc-client_test.go @@ -252,7 +252,7 @@ func TestGetValidServerConfig(t *testing.T) { // All errors allErrs := []error{errDiskNotFound, errDiskNotFound, errDiskNotFound, errDiskNotFound} - serverConfigs = []serverConfigV13{serverConfigV13{}, serverConfigV13{}, serverConfigV13{}, serverConfigV13{}} + serverConfigs = []serverConfigV13{{}, {}, {}, {}} validConfig, err = getValidServerConfig(serverConfigs, allErrs) if err != errXLWriteQuorum { t.Errorf("Expected to fail due to lack of quorum but received %v", err) diff --git a/cmd/logger.go b/cmd/logger.go index 4aba14543..a0f999fcf 100644 --- a/cmd/logger.go +++ b/cmd/logger.go @@ -119,6 +119,7 @@ func fatalIf(err error, msg string, data ...interface{}) { if e, ok := err.(*Error); ok { fields["stack"] = strings.Join(e.Trace(), " ") } + for _, log := range log.loggers { log.WithFields(fields).Fatalf(msg, data...) } diff --git a/cmd/update-main.go b/cmd/update-main.go index ef8716d75..e1348a3a8 100644 --- a/cmd/update-main.go +++ b/cmd/update-main.go @@ -22,6 +22,8 @@ import ( "io/ioutil" "net/http" "os" + "os/exec" + "path/filepath" "runtime" "strings" "time" @@ -62,15 +64,24 @@ EXAMPLES: `, } -const releaseTagTimeLayout = "2006-01-02T15-04-05Z" - -const minioReleaseURL = "https://dl.minio.io/server/minio/release/" + runtime.GOOS + "-" + runtime.GOARCH + "/" +const ( + minioReleaseTagTimeLayout = "2006-01-02T15-04-05Z" + minioReleaseURL = "https://dl.minio.io/server/minio/release/" + runtime.GOOS + "-" + runtime.GOARCH + "/" +) func getCurrentReleaseTime(minioVersion, minioBinaryPath string) (releaseTime time.Time, err error) { if releaseTime, err = time.Parse(time.RFC3339, minioVersion); err == nil { return releaseTime, err } + if !filepath.IsAbs(minioBinaryPath) { + // Make sure to look for the absolute path of the binary. + minioBinaryPath, err = exec.LookPath(minioBinaryPath) + if err != nil { + return releaseTime, err + } + } + // Looks like version is minio non-standard, we use minio binary's ModTime as release time. fi, err := os.Stat(minioBinaryPath) if err != nil { @@ -190,7 +201,7 @@ func parseReleaseData(data string) (releaseTime time.Time, err error) { return releaseTime, err } - releaseTime, err = time.Parse(releaseTagTimeLayout, fields[2]) + releaseTime, err = time.Parse(minioReleaseTagTimeLayout, fields[2]) if err != nil { err = fmt.Errorf("Unknown release time format. %s", err) } diff --git a/cmd/update-main_test.go b/cmd/update-main_test.go index 364e698c5..dc0b7be7e 100644 --- a/cmd/update-main_test.go +++ b/cmd/update-main_test.go @@ -17,11 +17,14 @@ package cmd import ( + "errors" "fmt" "io/ioutil" "net/http" "net/http/httptest" "os" + "os/exec" + "path/filepath" "runtime" "testing" "time" @@ -32,29 +35,59 @@ func TestGetCurrentReleaseTime(t *testing.T) { releaseTime1, _ := time.Parse(time.RFC3339, minioVersion1) minioVersion2 := "DEVELOPMENT.GOGET" - tmpfile, err := ioutil.TempFile("", "get-current-release-time-testcase") + tmpfile1, err := ioutil.TempFile("", "get-current-release-time-testcase-1") if err != nil { t.Fatalf("Unable to create temporary file. %s", err) } - defer os.Remove(tmpfile.Name()) - minioBinaryPath2 := tmpfile.Name() - fi, err := tmpfile.Stat() + defer os.Remove(tmpfile1.Name()) + + minioBinaryPath2 := tmpfile1.Name() + fi, err := tmpfile1.Stat() if err != nil { t.Fatalf("Unable to get temporary file info. %s", err) } - if err = tmpfile.Close(); err != nil { + if err = tmpfile1.Close(); err != nil { t.Fatalf("Unable to create temporary file. %s", err) } releaseTime2 := fi.ModTime().UTC() - errorMessage1 := "Unable to get ModTime of . stat : no such file or directory" - if runtime.GOOS == "windows" { - errorMessage1 = "Unable to get ModTime of . Lstat : The system cannot find the path specified." + minioBinaryPath3 := "go" + if runtime.GOOS == globalWindowsOSName { + minioBinaryPath3 = "go.exe" } + goBinAbsPath, err := exec.LookPath(minioBinaryPath3) + if err != nil { + t.Fatal(err) + } + fi, err = os.Stat(goBinAbsPath) + if err != nil { + t.Fatal(err) + } + releaseTime3 := fi.ModTime().UTC() - errorMessage2 := "Unable to get ModTime of non-existing-file. stat non-existing-file: no such file or directory" + // Get a non-absolute binary path. + minioBinaryPath4 := filepath.Base(tmpfile1.Name()) + + // Get a non-existent absolute binary path + minioBinaryPath5 := "/tmp/non-existent-file" + if runtime.GOOS == globalWindowsOSName { + minioBinaryPath5 = "C:\\tmp\\non-existent-file" + } + errorMessage1 := "exec: \"\": executable file not found in $PATH" + if runtime.GOOS == globalWindowsOSName { + errorMessage1 = "exec: \"\": executable file not found in %PATH%" + } + errorMessage2 := "exec: \"non-existent-file\": executable file not found in $PATH" + if runtime.GOOS == globalWindowsOSName { + errorMessage2 = "exec: \"non-existent-file\": executable file not found in %PATH%" + } + errorMessage3 := fmt.Sprintf("exec: \"%s\": executable file not found in $PATH", minioBinaryPath4) + if runtime.GOOS == globalWindowsOSName { + errorMessage3 = "exec: \"" + minioBinaryPath4 + "\": executable file not found in %PATH%" + } + errorMessage4 := "Unable to get ModTime of /tmp/non-existent-file. stat /tmp/non-existent-file: no such file or directory" if runtime.GOOS == "windows" { - errorMessage2 = "Unable to get ModTime of non-existing-file. GetFileAttributesEx non-existing-file: The system cannot find the file specified." + errorMessage4 = "Unable to get ModTime of C:\\tmp\\non-existent-file. GetFileAttributesEx C:\\tmp\\non-existent-file: The system cannot find the path specified." } testCases := []struct { @@ -66,11 +99,14 @@ func TestGetCurrentReleaseTime(t *testing.T) { {minioVersion1, "", releaseTime1, nil}, {minioVersion1, minioBinaryPath2, releaseTime1, nil}, {minioVersion2, minioBinaryPath2, releaseTime2, nil}, + {minioVersion2, minioBinaryPath3, releaseTime3, nil}, {"junk", minioBinaryPath2, releaseTime2, nil}, {"3.2.0", minioBinaryPath2, releaseTime2, nil}, - {minioVersion2, "", time.Time{}, fmt.Errorf(errorMessage1)}, - {"junk", "non-existing-file", time.Time{}, fmt.Errorf(errorMessage2)}, - {"3.2.0", "non-existing-file", time.Time{}, fmt.Errorf(errorMessage2)}, + {minioVersion2, "", time.Time{}, errors.New(errorMessage1)}, + {"junk", "non-existent-file", time.Time{}, errors.New(errorMessage2)}, + {"3.2.0", "non-existent-file", time.Time{}, errors.New(errorMessage2)}, + {minioVersion2, minioBinaryPath4, time.Time{}, errors.New(errorMessage3)}, + {minioVersion2, minioBinaryPath5, time.Time{}, errors.New(errorMessage4)}, } if runtime.GOOS == "linux" { @@ -79,7 +115,7 @@ func TestGetCurrentReleaseTime(t *testing.T) { minioBinaryPath string expectedResult time.Time expectedErr error - }{"3.2a", "/proc/1/cwd", time.Time{}, fmt.Errorf("Unable to get ModTime of /proc/1/cwd. stat /proc/1/cwd: permission denied")}) + }{"3.2a", "/proc/1/cwd", time.Time{}, errors.New("Unable to get ModTime of /proc/1/cwd. stat /proc/1/cwd: permission denied")}) } for _, testCase := range testCases { @@ -242,7 +278,7 @@ func TestDownloadReleaseData(t *testing.T) { } func TestParseReleaseData(t *testing.T) { - releaseTime, _ := time.Parse(releaseTagTimeLayout, "2016-10-07T01-16-39Z") + releaseTime, _ := time.Parse(minioReleaseTagTimeLayout, "2016-10-07T01-16-39Z") testCases := []struct { data string expectedResult time.Time From fe86319c567c6d75bf86244a0323482128a10df8 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 21 Feb 2017 17:24:11 -0800 Subject: [PATCH 18/94] ci: For windows builds stick to go1.7.5 (#3786) --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 2e1dfd420..cdb5719cb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,11 +11,12 @@ clone_folder: c:\gopath\src\github.com\minio\minio # Environment variables environment: + GOROOT: c:\go17 GOPATH: c:\gopath # scripts that run after cloning repository install: - - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - set PATH=%GOPATH%\bin;c:\go17\bin;%PATH% - go version - go env - python --version From cc28765025be0d3857ae8e4a45c921f048535bf8 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 21 Feb 2017 19:43:44 -0800 Subject: [PATCH 19/94] xl/multipart: Make sure to delete temp renamed object. (#3785) Existing objects before overwrites are renamed to temp location in completeMultipart. We make sure that we delete it even if subsequenty calls fail. Additionally move verifying of parent dir is a file earlier to fail the entire operation. Ref #3784 --- cmd/object-handlers.go | 2 +- cmd/xl-v1-multipart.go | 34 +++++++++++++++++++--------------- cmd/xl-v1-object.go | 29 +++++++++++++++++++---------- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index ff00f034a..06e385596 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -483,7 +483,7 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req objInfo, err = objectAPI.PutObject(bucket, object, size, r.Body, metadata, sha256sum) } if err != nil { - errorIf(err, "Unable to create an object.") + errorIf(err, "Unable to create an object. %s", r.URL.Path) writeErrorResponse(w, toAPIErrorCode(err), r.URL) return } diff --git a/cmd/xl-v1-multipart.go b/cmd/xl-v1-multipart.go index 491223f13..ff166e05d 100644 --- a/cmd/xl-v1-multipart.go +++ b/cmd/xl-v1-multipart.go @@ -499,15 +499,15 @@ func (xl xlObjects) newMultipartUpload(bucket string, object string, meta map[st // success. defer xl.deleteObject(minioMetaTmpBucket, tempUploadIDPath) - // Attempt to rename temp upload object to actual upload path - // object - if rErr := renameObject(xl.storageDisks, minioMetaTmpBucket, tempUploadIDPath, minioMetaMultipartBucket, uploadIDPath, xl.writeQuorum); rErr != nil { + // Attempt to rename temp upload object to actual upload path object + rErr := renameObject(xl.storageDisks, minioMetaTmpBucket, tempUploadIDPath, minioMetaMultipartBucket, uploadIDPath, xl.writeQuorum) + if rErr != nil { return "", toObjectErr(rErr, minioMetaMultipartBucket, uploadIDPath) } initiated := time.Now().UTC() // Create or update 'uploads.json' - if err := xl.addUploadID(bucket, object, uploadID, initiated); err != nil { + if err = xl.addUploadID(bucket, object, uploadID, initiated); err != nil { return "", err } // Return success. @@ -885,6 +885,13 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload if !xl.isUploadIDExists(bucket, object, uploadID) { return ObjectInfo{}, traceError(InvalidUploadID{UploadID: uploadID}) } + + // Check if an object is present as one of the parent dir. + // -- FIXME. (needs a new kind of lock). + if xl.parentDirIsObject(bucket, path.Dir(object)) { + return ObjectInfo{}, toObjectErr(traceError(errFileAccessDenied), bucket, object) + } + // Calculate s3 compatible md5sum for complete multipart. s3MD5, err := getCompleteMultipartMD5(parts) if err != nil { @@ -964,11 +971,6 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload } } - // Check if an object is present as one of the parent dir. - if xl.parentDirIsObject(bucket, path.Dir(object)) { - return ObjectInfo{}, toObjectErr(traceError(errFileAccessDenied), bucket, object) - } - // Save the final object size and modtime. xlMeta.Stat.Size = objectSize xlMeta.Stat.ModTime = time.Now().UTC() @@ -990,6 +992,7 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload if err = writeUniqueXLMetadata(onlineDisks, minioMetaTmpBucket, tempUploadIDPath, partsMetadata, xl.writeQuorum); err != nil { return ObjectInfo{}, toObjectErr(err, minioMetaTmpBucket, tempUploadIDPath) } + rErr := commitXLMetadata(onlineDisks, minioMetaTmpBucket, tempUploadIDPath, minioMetaMultipartBucket, uploadIDPath, xl.writeQuorum) if rErr != nil { return ObjectInfo{}, toObjectErr(rErr, minioMetaMultipartBucket, uploadIDPath) @@ -1008,13 +1011,17 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload } }() - // Rename if an object already exists to temporary location. - uniqueID := mustGetUUID() if xl.isObject(bucket, object) { + // Rename if an object already exists to temporary location. + newUniqueID := mustGetUUID() + + // Delete success renamed object. + defer xl.deleteObject(minioMetaTmpBucket, newUniqueID) + // NOTE: Do not use online disks slice here. // The reason is that existing object should be purged // regardless of `xl.json` status and rolled back in case of errors. - err = renameObject(xl.storageDisks, bucket, object, minioMetaTmpBucket, uniqueID, xl.writeQuorum) + err = renameObject(xl.storageDisks, bucket, object, minioMetaTmpBucket, newUniqueID, xl.writeQuorum) if err != nil { return ObjectInfo{}, toObjectErr(err, bucket, object) } @@ -1038,9 +1045,6 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload return ObjectInfo{}, toObjectErr(err, bucket, object) } - // Delete the previously successfully renamed object. - xl.deleteObject(minioMetaTmpBucket, uniqueID) - // Hold the lock so that two parallel // complete-multipart-uploads do not leave a stale // uploads.json behind. diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index 0381f0946..c544e93da 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -439,11 +439,25 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io. // a slash separator, we treat it like a valid operation and // return success. if isObjectDir(object, size) { + // Check if an object is present as one of the parent dir. + // -- FIXME. (needs a new kind of lock). + if xl.parentDirIsObject(bucket, path.Dir(object)) { + return ObjectInfo{}, toObjectErr(traceError(errFileAccessDenied), bucket, object) + } return dirObjectInfo(bucket, object, size, metadata), nil } + + // Validate put object input args. if err = checkPutObjectArgs(bucket, object, xl); err != nil { return ObjectInfo{}, err } + + // Check if an object is present as one of the parent dir. + // -- FIXME. (needs a new kind of lock). + if xl.parentDirIsObject(bucket, path.Dir(object)) { + return ObjectInfo{}, toObjectErr(traceError(errFileAccessDenied), bucket, object) + } + // No metadata is set, allocate a new one. if metadata == nil { metadata = make(map[string]string) @@ -526,7 +540,7 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io. // Compute part name partName := "part." + strconv.Itoa(partIdx) // Compute the path of current part - tempErasureObj := path.Join(uniqueID, partName) + tempErasureObj := pathJoin(uniqueID, partName) // Calculate the size of the current part, if size is unknown, curPartSize wil be unknown too. // allowEmptyPart will always be true if this is the first part and false otherwise. @@ -645,16 +659,11 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io. } } - // Check if an object is present as one of the parent dir. - // -- FIXME. (needs a new kind of lock). - if xl.parentDirIsObject(bucket, path.Dir(object)) { - return ObjectInfo{}, toObjectErr(traceError(errFileAccessDenied), bucket, object) - } - - // Rename if an object already exists to temporary location. - newUniqueID := mustGetUUID() if xl.isObject(bucket, object) { - // Delete the temporary copy of the object that existed before this PutObject request. + // Rename if an object already exists to temporary location. + newUniqueID := mustGetUUID() + + // Delete successfully renamed object. defer xl.deleteObject(minioMetaTmpBucket, newUniqueID) // NOTE: Do not use online disks slice here. From d8950ba7c5319a372c5998543b751d564aff411b Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Wed, 22 Feb 2017 15:42:03 +0530 Subject: [PATCH 20/94] Added server times note and fix Notes rendering for Doctor. (#3787) --- docs/distributed/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/distributed/README.md b/docs/distributed/README.md index de8ba314b..59dafe7af 100644 --- a/docs/distributed/README.md +++ b/docs/distributed/README.md @@ -39,9 +39,11 @@ Install Minio - [Minio Quickstart Guide](https://docs.minio.io/docs/minio-quicks To start a distributed Minio instance, you just need to pass drive locations as parameters to the minio server command. Then, you’ll need to run the same command on all the participating nodes. *Note* + - All the nodes running distributed Minio need to have same access key and secret key for the nodes to connect. To achieve this, you need to export access key and secret key as environment variables on all the nodes before executing Minio server command. - Disks used for Minio distributed should be fresh with no pre-existing data. - The IP addresses and drive paths below are for demonstration purposes only, you need to replace these with the actual IP addresses and drive paths/folders. +- Servers running distributed Minio instances should be less than 3 seconds apart. You can use [NTP](http://www.ntp.org/) as a best practice to ensure consistent times across servers. Example 1: Start distributed Minio instance with 1 drive each on 8 nodes, by running this command on all the 8 nodes. From 52d6678bf0d1442d0ab9b7bc63b47ceda69d0e4a Mon Sep 17 00:00:00 2001 From: Rushan Date: Thu, 23 Feb 2017 04:21:38 +0530 Subject: [PATCH 21/94] Browser: Implement multi select user interface for object listings (#3730) --- browser/app/js/actions.js | 57 +++- browser/app/js/components/Browse.js | 43 ++- browser/app/js/components/Dropzone.js | 3 +- browser/app/js/components/ObjectsList.js | 25 +- browser/app/js/components/Policy.js | 2 +- browser/app/js/components/PolicyInput.js | 2 +- browser/app/js/reducers.js | 17 +- browser/app/less/inc/buttons.less | 4 + browser/app/less/inc/header.less | 8 +- browser/app/less/inc/list.less | 337 ++++++++++++++++------- browser/app/less/inc/misc.less | 14 + browser/app/less/inc/mixin.less | 2 +- browser/app/less/inc/variables.less | 11 +- browser/webpack.config.js | 4 + cmd/web-handlers_test.go | 2 +- cmd/web-router.go | 2 +- 16 files changed, 392 insertions(+), 141 deletions(-) diff --git a/browser/app/js/actions.js b/browser/app/js/actions.js index c9b2f72bf..83b6e9f61 100644 --- a/browser/app/js/actions.js +++ b/browser/app/js/actions.js @@ -28,7 +28,6 @@ export const SET_CURRENT_BUCKET = 'SET_CURRENT_BUCKET' export const SET_CURRENT_PATH = 'SET_CURRENT_PATH' export const SET_BUCKETS = 'SET_BUCKETS' export const ADD_BUCKET = 'ADD_BUCKET' -export const ADD_OBJECT = 'ADD_OBJECT' export const SET_VISIBLE_BUCKETS = 'SET_VISIBLE_BUCKETS' export const SET_OBJECTS = 'SET_OBJECTS' export const SET_STORAGE_INFO = 'SET_STORAGE_INFO' @@ -57,6 +56,9 @@ export const SET_SHARE_OBJECT = 'SET_SHARE_OBJECT' export const DELETE_CONFIRMATION = 'DELETE_CONFIRMATION' export const SET_PREFIX_WRITABLE = 'SET_PREFIX_WRITABLE' export const REMOVE_OBJECT = 'REMOVE_OBJECT' +export const CHECKED_OBJECTS_ADD = 'CHECKED_OBJECTS_ADD' +export const CHECKED_OBJECTS_REMOVE = 'CHECKED_OBJECTS_REMOVE' +export const CHECKED_OBJECTS_RESET = 'CHECKED_OBJECTS_RESET' export const showDeleteConfirmation = (object) => { return { @@ -304,13 +306,13 @@ export const listObjects = () => { marker: marker }) .then(res => { - let objects = res.objects + let objects = res.objects if (!objects) objects = [] objects = objects.map(object => { - object.name = object.name.replace(`${currentPath}`, ''); - return object - }) + object.name = object.name.replace(`${currentPath}`, ''); + return object + }) dispatch(setObjects(objects, res.nextmarker, res.istruncated)) dispatch(setPrefixWritable(res.writable)) dispatch(setLoadBucket('')) @@ -344,9 +346,9 @@ export const selectPrefix = prefix => { if (!objects) objects = [] objects = objects.map(object => { - object.name = object.name.replace(`${prefix}`, ''); - return object - }) + object.name = object.name.replace(`${prefix}`, ''); + return object + }) dispatch(setObjects( objects, res.nextmarker, @@ -410,6 +412,24 @@ export const setLoginError = () => { } } +export const downloadAllasZip = (url, req, xhr) => { + return (dispatch) => { + xhr.open('POST', url, true) + xhr.responseType = 'blob' + + xhr.onload = function(e) { + if (this.status == 200) { + var blob = new Blob([this.response], { + type: 'application/zip' + }) + var blobUrl = window.URL.createObjectURL(blob); + window.location = blobUrl + } + }; + xhr.send(JSON.stringify(req)); + } +} + export const uploadFile = (file, xhr) => { return (dispatch, getState) => { const {currentBucket, currentPath} = getState() @@ -563,3 +583,24 @@ export const setPolicies = (policies) => { policies } } + +export const checkedObjectsAdd = (objectName) => { + return { + type: CHECKED_OBJECTS_ADD, + objectName + } +} + +export const checkedObjectsRemove = (objectName) => { + return { + type: CHECKED_OBJECTS_REMOVE, + objectName + } +} + +export const checkedObjectsReset = (objectName) => { + return { + type: CHECKED_OBJECTS_RESET, + objectName + } +} \ No newline at end of file diff --git a/browser/app/js/components/Browse.js b/browser/app/js/components/Browse.js index 6458ad22b..ab2c9e0bd 100644 --- a/browser/app/js/components/Browse.js +++ b/browser/app/js/components/Browse.js @@ -27,7 +27,6 @@ import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger' import Tooltip from 'react-bootstrap/lib/Tooltip' import Dropdown from 'react-bootstrap/lib/Dropdown' import MenuItem from 'react-bootstrap/lib/MenuItem' - import InputGroup from '../components/InputGroup' import Dropzone from '../components/Dropzone' import ObjectsList from '../components/ObjectsList' @@ -363,9 +362,27 @@ export default class Browse extends React.Component { } } + checkObject(e, objectName) { + const {dispatch} = this.props + e.target.checked ? dispatch(actions.checkedObjectsAdd(objectName)) : dispatch(actions.checkedObjectsRemove(objectName)) + } + + downloadAll() { + const {dispatch} = this.props + let req = { + bucketName: this.props.currentBucket, + objects: this.props.checkedObjects, + prefix: this.props.currentPath + } + let requestUrl = location.origin + "/minio/zip?token=" + localStorage.token + + this.xhr = new XMLHttpRequest() + dispatch(actions.downloadAllasZip(requestUrl, req, this.xhr)) + } + render() { const {total, free} = this.props.storageInfo - const {showMakeBucketModal, alert, sortNameOrder, sortSizeOrder, sortDateOrder, showAbout, showBucketPolicy} = this.props + const {showMakeBucketModal, alert, sortNameOrder, sortSizeOrder, sortDateOrder, showAbout, showBucketPolicy, checkedObjects} = this.props const {version, memory, platform, runtime} = this.props.serverInfo const {sidebarStatus} = this.props const {showSettings} = this.props @@ -435,7 +452,6 @@ export default class Browse extends React.Component { - } let createButton = '' @@ -490,6 +506,12 @@ export default class Browse extends React.Component { clickOutside={ this.hideSidebar.bind(this) } showPolicy={ this.showBucketPolicy.bind(this) } />

+
0 + })) }> + { checkedObjects.length } Objects selected + +
{ alertBox }
@@ -515,7 +537,8 @@ export default class Browse extends React.Component {
-
+
+
Name
-
+
Size
-
+
Last Modified
-
+
@@ -553,7 +576,9 @@ export default class Browse extends React.Component { + shareObject={ this.shareObject.bind(this) } + checkObject={ this.checkObject.bind(this) } + checkedObjectsArray={ checkedObjects } />
Loading... @@ -734,4 +759,4 @@ export default class Browse extends React.Component {
) } -} +} \ No newline at end of file diff --git a/browser/app/js/components/Dropzone.js b/browser/app/js/components/Dropzone.js index 0ddab2661..f1ff9cc6c 100644 --- a/browser/app/js/components/Dropzone.js +++ b/browser/app/js/components/Dropzone.js @@ -39,11 +39,12 @@ export default class Dropzone extends React.Component { // won't handle child elements correctly. const style = { height: '100%', - borderWidth: '2px', + borderWidth: '0', borderStyle: 'dashed', borderColor: '#fff' } const activeStyle = { + borderWidth: '2px', borderColor: '#777' } const rejectStyle = { diff --git a/browser/app/js/components/ObjectsList.js b/browser/app/js/components/ObjectsList.js index 623594218..a19b7be94 100644 --- a/browser/app/js/components/ObjectsList.js +++ b/browser/app/js/components/ObjectsList.js @@ -20,8 +20,7 @@ import humanize from 'humanize' import connect from 'react-redux/lib/components/connect' import Dropdown from 'react-bootstrap/lib/Dropdown' - -let ObjectsList = ({objects, currentPath, selectPrefix, dataType, showDeleteConfirmation, shareObject, loadPath}) => { +let ObjectsList = ({objects, currentPath, selectPrefix, dataType, showDeleteConfirmation, shareObject, loadPath, checkObject, checkedObjectsArray}) => { const list = objects.map((object, i) => { let size = object.name.endsWith('/') ? '-' : humanize.filesize(object.size) let lastModified = object.name.endsWith('/') ? '-' : Moment(object.lastModified).format('lll') @@ -39,20 +38,30 @@ let ObjectsList = ({objects, currentPath, selectPrefix, dataType, showDeleteConf } + + let activeClass = checkedObjectsArray.indexOf(object.name) > -1 ? ' fesl-row-selected' : '' + return ( -
-
+
+
+
+ checkObject(e, object.name) } /> + + +
+
+ -
+
{ size }
-
+
{ lastModified }
-
+
{ actionButtons }
@@ -72,4 +81,4 @@ export default connect(state => { currentPath: state.currentPath, loadPath: state.loadPath } -})(ObjectsList) +})(ObjectsList) \ No newline at end of file diff --git a/browser/app/js/components/Policy.js b/browser/app/js/components/Policy.js index 65930ad64..cdf95eedf 100644 --- a/browser/app/js/components/Policy.js +++ b/browser/app/js/components/Policy.js @@ -77,4 +77,4 @@ class Policy extends Component { } } -export default connect(state => state)(Policy) +export default connect(state => state)(Policy) \ No newline at end of file diff --git a/browser/app/js/components/PolicyInput.js b/browser/app/js/components/PolicyInput.js index 75809df96..9353bde41 100644 --- a/browser/app/js/components/PolicyInput.js +++ b/browser/app/js/components/PolicyInput.js @@ -80,4 +80,4 @@ class PolicyInput extends Component { } } -export default connect(state => state)(PolicyInput) +export default connect(state => state)(PolicyInput) \ No newline at end of file diff --git a/browser/app/js/reducers.js b/browser/app/js/reducers.js index ca312fbe7..5d80d563b 100644 --- a/browser/app/js/reducers.js +++ b/browser/app/js/reducers.js @@ -56,7 +56,8 @@ export default (state = { url: '', expiry: 604800 }, - prefixWritable: false + prefixWritable: false, + checkedObjects: [] }, action) => { let newState = Object.assign({}, state) switch (action.type) { @@ -185,6 +186,20 @@ export default (state = { if (idx == -1) break newState.objects = [...newState.objects.slice(0, idx), ...newState.objects.slice(idx + 1)] break + + case actions.CHECKED_OBJECTS_ADD: + newState.checkedObjects = [...newState.checkedObjects, action.objectName] + break + case actions.CHECKED_OBJECTS_REMOVE: + let index = newState.checkedObjects.indexOf(action.objectName) + if (index == -1) break + newState.checkedObjects = [...newState.checkedObjects.slice(0, index), ...newState.checkedObjects.slice(index + 1)] + break + case actions.CHECKED_OBJECTS_RESET: + newState.checkedObjects = [] + break } + console.log(newState.checkedObjects) + return newState } diff --git a/browser/app/less/inc/buttons.less b/browser/app/less/inc/buttons.less index 28131641a..6c04a95da 100644 --- a/browser/app/less/inc/buttons.less +++ b/browser/app/less/inc/buttons.less @@ -35,6 +35,10 @@ width: 100%; } +.btn-white { + .btn-variant(#fff, darken(@text-color, 20%)); +} + .btn-link { .btn-variant(#eee, #545454); } diff --git a/browser/app/less/inc/header.less b/browser/app/less/inc/header.less index e95f05d66..50c619bc1 100644 --- a/browser/app/less/inc/header.less +++ b/browser/app/less/inc/header.less @@ -2,14 +2,13 @@ Header ----------------------------*/ .fe-header { - padding: 45px 55px 20px; - - @media(min-width: @screen-md-min) { + @media(min-width: (@screen-sm-min - 100)) { position: relative; + padding: 40px 40px 20px 45px; } @media(max-width: (@screen-xs-max - 100)) { - padding: 25px 25px 20px; + padding: 20px; } h2 { @@ -239,4 +238,3 @@ } - diff --git a/browser/app/less/inc/list.less b/browser/app/less/inc/list.less index d3ee399b1..c38dd2c66 100644 --- a/browser/app/less/inc/list.less +++ b/browser/app/less/inc/list.less @@ -2,17 +2,19 @@ Row ----------------------------*/ .fesl-row { - padding-right: 40px; - padding-top: 5px; - padding-bottom: 5px; position: relative; @media (min-width: (@screen-sm-min - 100px)) { + padding: 5px 20px 5px 40px; display: flex; flex-flow: row nowrap; justify-content: space-between; } + @media(max-width: (@screen-xs-max - 100px)) { + padding: 5px 20px; + } + .clearfix(); } @@ -20,7 +22,7 @@ header.fesl-row { @media (min-width:(@screen-sm-min - 100px)) { margin-bottom: 20px; border-bottom: 1px solid lighten(@text-muted-color, 20%); - padding-left: 40px; + padding-left: 30px; .fesl-item, .fesli-sort { @@ -42,7 +44,7 @@ header.fesl-row { font-size: 14px; } - &:hover:not(.fi-actions) { + &:hover:not(.fesl-item-actions) { background: lighten(@text-muted-color, 22%); color: @dark-gray; @@ -58,54 +60,42 @@ header.fesl-row { } } +.list-type(@background, @icon) { + .fis-icon { + background-color: @background; + + &:before { + content: @icon; + } + } +} + div.fesl-row { - padding-left: 85px; border-bottom: 1px solid transparent; cursor: default; + .transition(background-color); + .transition-duration(500ms); @media (max-width: (@screen-xs-max - 100px)) { - padding-left: 70px; - padding-right: 45px; + padding: 5px 20px; } - &:nth-child(even) { - background-color: #fafafa; - } - - &:hover { - background-color: #fbf7dc; - } - - &[data-type]:before { - font-family: @font-family-icon; - width: 35px; - height: 35px; - text-align: center; - line-height: 35px; - position: absolute; - border-radius: 50%; - font-size: 16px; - left: 50px; - top: 9px; - color: @white; - - @media (max-width: (@screen-xs-max - 100px)) { - left: 20px; + &:not(.fesl-row-selected) { + &:nth-child(even) { + background-color: @list-row-even-bg; } } - &[data-type="folder"] { - @media (max-width: (@screen-xs-max - 100px)) { - .fesl-item { - &.fi-name { - padding-top: 10px; - padding-bottom: 7px; - } + &:hover { + .fis-icon { + &:before { + .opacity(0) + } + } - &.fi-size, - &.fi-modified { - display: none; - } + .fis-helper { + &:before { + .opacity(1); } } } @@ -113,54 +103,18 @@ div.fesl-row { /*-------------------------- Icons ----------------------------*/ - &[data-type=folder]:before { - content: '\f114'; - background-color: #a1d6dd; - } - &[data-type=pdf]:before { - content: "\f1c1"; - background-color: #fa7775; - } - &[data-type=zip]:before { - content: "\f1c6"; - background-color: #427089; - } - &[data-type=audio]:before { - content: "\f1c7"; - background-color: #009688 - } - &[data-type=code]:before { - content: "\f1c9"; - background-color: #997867; - } - &[data-type=excel]:before { - content: "\f1c3"; - background-color: #64c866; - } - &[data-type=image]:before { - content: "\f1c5"; - background-color: #f06292; - } - &[data-type=video]:before { - content: "\f1c8"; - background-color: #f8c363; - } - &[data-type=other]:before { - content: "\f016"; - background-color: #afafaf; - } - &[data-type=text]:before { - content: "\f0f6"; - background-color: #8a8a8a; - } - &[data-type=doc]:before { - content: "\f1c2"; - background-color: #2196f5; - } - &[data-type=presentation]:before { - content: "\f1c4"; - background-color: #896ea6; - } + &[data-type=folder] { .list-type(#a1d6dd, '\f114'); } + &[data-type=pdf] {.list-type(#fa7775, '\f1c1'); } + &[data-type=zip] { .list-type(#427089, '\f1c6'); } + &[data-type=audio] { .list-type(#009688, '\f1c7'); } + &[data-type=code] { .list-type(#997867, "\f1c9"); } + &[data-type=excel] { .list-type(#f1c3, '\f1c3'); } + &[data-type=image] { .list-type(#f06292, '\f1c5'); } + &[data-type=video] { .list-type(#f8c363, '\f1c8'); } + &[data-type=other] { .list-type(#afafaf, '\f016'); } + &[data-type=text] { .list-type(#8a8a8a, '\f0f6'); } + &[data-type=doc] { .list-type(#2196f5, '\f1c2'); } + &[data-type=presentation] { .list-type(#896ea6, '\f1c4'); } &.fesl-loading{ &:before { @@ -180,6 +134,113 @@ div.fesl-row { } } +.fesl-row-selected { + background-color: @list-row-selected-bg; + + &, .fesl-item a { + color: darken(@text-color, 10%); + } +} + +.fi-select { + float: left; + position: relative; + width: 35px; + height: 35px; + margin: 3px 0; + + @media(max-width: (@screen-xs-max - 100px)) { + margin-right: 15px; + } + + input { + position: absolute; + left: 0; + top: 0; + width: 35px; + height: 35px; + z-index: 20; + opacity: 0; + cursor: pointer; + + &:checked { + & ~ .fis-icon { + background-color: #32393F; + + &:before { + opacity: 0; + } + } + + & ~ .fis-helper { + &:before { + .scale(0); + } + + &:after { + .scale(1); + } + } + } + } +} + +.fis-icon { + display: inline-block; + vertical-align: top; + border-radius: 50%; + width: 35px; + height: 35px; + .transition(background-color); + .transition-duration(250ms); + + &:before { + width: 100%; + height: 100%; + text-align: center; + position: absolute; + border-radius: 50%; + font-family: @font-family-icon; + line-height: 35px; + font-size: 16px; + color: @white; + .transition(all); + .transition-duration(300ms); + font-style: normal; + } +} + +.fis-helper { + &:before, + &:after { + position: absolute; + .transition(all); + .transition-duration(250ms); + } + + &:before { + content: ''; + width: 15px; + height: 15px; + border: 2px solid @white; + z-index: 10; + border-radius: 2px; + top: 10px; + left: 10px; + opacity: 0; + } + + &:after { + font-family: @font-family-icon; + content: '\f00c'; + top: 8px; + left: 9px; + color: @white; + font-size: 14px; + .scale(0); + } +} + /*-------------------------- Files and Folders @@ -192,26 +253,26 @@ div.fesl-row { } @media(min-width: (@screen-sm-min - 100px)) { - &:not(.fi-actions) { + &:not(.fesl-item-actions):not(.fesl-item-icon) { text-overflow: ellipsis; padding: 10px 15px; white-space: nowrap; overflow: hidden; } - &.fi-name { + &.fesl-item-name { flex: 3; } - &.fi-size { + &.fesl-item-size { width: 140px; } - &.fi-modified { + &.fesl-item-modified { width: 190px; } - &.fi-actions { + &.fesl-item-actions { width: 40px; } } @@ -219,29 +280,29 @@ div.fesl-row { @media(max-width: (@screen-xs-max - 100px)) { padding: 0; - &.fi-name { + &.fesl-item-name { width: 100%; margin-bottom: 3px; } - &.fi-size, - &.fi-modified { + &.fesl-item-size, + &.fesl-item-modified { font-size: 12px; color: #B5B5B5; float: left; } - &.fi-modified { + &.fesl-item-modified { max-width: 72px; white-space: nowrap; overflow: hidden; } - &.fi-size { + &.fesl-item-size { margin-right: 10px; } - &.fi-actions { + &.fesl-item-actions { position: absolute; top: 5px; right: 10px; @@ -266,7 +327,7 @@ div.fesl-row { } } -.fi-actions { +.fesl-item-actions { .dropdown-menu { background-color: transparent; box-shadow: none; @@ -324,6 +385,78 @@ div.fesl-row { } } +.list-actions { + position: fixed; + .translate3d(0, -100%, 0); + .opacity(0); + .transition(all); + .transition-duration(200ms); + padding: 20px 25px; + top: 0; + left: 0; + width: 100%; + background-color: @brand-primary; + z-index: 20; + box-shadow: 0 0 10px rgba(0,0,0,0.3); + text-align: center; + + &.list-actions-toggled { + .translate3d(0, 0, 0); + .opacity(1); + } +} + +.la-close { + position: absolute; + right: 20px; + top: 0; + color: #fff; + width: 30px; + height: 30px; + border-radius: 50%; + text-align: center; + line-height: 30px !important; + background: rgba(255, 255, 255, 0.1); + font-weight: normal; + bottom: 0; + margin: auto; + cursor: pointer; + + &:hover { + background-color: rgba(255, 255, 255, 0.2); + } +} + +.la-label { + color: @white; + float: left; + padding: 4px 0; + + .fa { + font-size: 22px; + vertical-align: top; + margin-right: 10px; + margin-top: -1px; + } +} + +.la-actions { + button { + background-color: transparent; + border: 2px solid rgba(255,255,255,0.9); + color: @white; + border-radius: 2px; + padding: 5px 10px; + font-size: 13px; + .transition(all); + .transition-duration(300ms); + + &:hover { + background-color: @white; + color: @brand-primary; + } + } +} @-webkit-keyframes fiad-action-anim { from { diff --git a/browser/app/less/inc/misc.less b/browser/app/less/inc/misc.less index dba1b43b5..8359d426d 100644 --- a/browser/app/less/inc/misc.less +++ b/browser/app/less/inc/misc.less @@ -99,4 +99,18 @@ content: '7 days'; right: 0; } +} + + +.modal-aheader { + height: 100px; + + &:before { + height: 0 !important; + } + + .modal-dialog { + margin: 0; + vertical-align: top; + } } \ No newline at end of file diff --git a/browser/app/less/inc/mixin.less b/browser/app/less/inc/mixin.less index 528f2f26b..27a764817 100644 --- a/browser/app/less/inc/mixin.less +++ b/browser/app/less/inc/mixin.less @@ -49,4 +49,4 @@ z-index: 1; -webkit-animation: zoomIn 250ms, spin 700ms 250ms infinite linear; animation: zoomIn 250ms, spin 700ms 250ms infinite linear; -} \ No newline at end of file +} diff --git a/browser/app/less/inc/variables.less b/browser/app/less/inc/variables.less index de6589994..8ad938e3d 100644 --- a/browser/app/less/inc/variables.less +++ b/browser/app/less/inc/variables.less @@ -81,7 +81,7 @@ /*------------------------- Colors --------------------------*/ -@brand-primary: #2196F3; +@brand-primary: #2298f7; @brand-success: #4CAF50; @brand-info: #00BCD4; @brand-warning: #FF9800; @@ -91,4 +91,11 @@ /*------------------------- Form --------------------------*/ -@input-border: #eee; \ No newline at end of file +@input-border: #eee; + + +/*------------------------- + List +--------------------------*/ +@list-row-selected-bg: #fbf2bf; +@list-row-even-bg: #fafafa; \ No newline at end of file diff --git a/browser/webpack.config.js b/browser/webpack.config.js index 3ccdaba0b..3c84b329d 100644 --- a/browser/webpack.config.js +++ b/browser/webpack.config.js @@ -71,6 +71,10 @@ var exports = { target: 'http://localhost:9000', secure: false }, + '/minio/zip': { + target: 'http://localhost:9000', + secure: false + } } }, plugins: [ diff --git a/cmd/web-handlers_test.go b/cmd/web-handlers_test.go index 66f7cbd52..912200624 100644 --- a/cmd/web-handlers_test.go +++ b/cmd/web-handlers_test.go @@ -849,7 +849,7 @@ func testWebHandlerDownloadZip(obj ObjectLayer, instanceType string, t TestErrHa return 0, nil } var req *http.Request - req, err = http.NewRequest("GET", path, bytes.NewBuffer(argsData)) + req, err = http.NewRequest("POST", path, bytes.NewBuffer(argsData)) if err != nil { t.Fatalf("Cannot create upload request, %v", err) diff --git a/cmd/web-router.go b/cmd/web-router.go index 66505bdff..333e102ba 100644 --- a/cmd/web-router.go +++ b/cmd/web-router.go @@ -84,7 +84,7 @@ func registerWebRouter(mux *router.Router) error { webBrowserRouter.Methods("POST").Path("/webrpc").Handler(webRPC) webBrowserRouter.Methods("PUT").Path("/upload/{bucket}/{object:.+}").HandlerFunc(web.Upload) webBrowserRouter.Methods("GET").Path("/download/{bucket}/{object:.+}").Queries("token", "{token:.*}").HandlerFunc(web.Download) - webBrowserRouter.Methods("GET").Path("/zip").Queries("token", "{token:.*}").HandlerFunc(web.DownloadZip) + webBrowserRouter.Methods("POST").Path("/zip").Queries("token", "{token:.*}").HandlerFunc(web.DownloadZip) // Add compression for assets. compressedAssets := handlers.CompressHandler(http.StripPrefix(minioReservedBucketPath, http.FileServer(assetFS()))) From 25b5a0534fe0c489ebda01608664a7bd7f5beea1 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 22 Feb 2017 17:27:26 -0800 Subject: [PATCH 22/94] browser: Update ui-assets and fix the copyright header. (#3790) --- browser/app/index.js | 2 +- browser/app/js/__tests__/jsonrpc-test.js | 2 +- browser/app/js/actions.js | 2 +- browser/app/js/components/Browse.js | 2 +- browser/app/js/components/BrowserDropdown.js | 4 +- browser/app/js/components/BrowserUpdate.js | 2 +- browser/app/js/components/ConfirmModal.js | 2 +- browser/app/js/components/Dropzone.js | 2 +- browser/app/js/components/InputGroup.js | 2 +- browser/app/js/components/Login.js | 2 +- browser/app/js/components/ObjectsList.js | 2 +- browser/app/js/components/Path.js | 2 +- browser/app/js/components/SettingsModal.js | 2 +- browser/app/js/components/SideBar.js | 2 +- browser/app/js/components/UploadModal.js | 2 +- .../app/js/components/__tests__/Login-test.js | 2 +- browser/app/js/constants.js | 2 +- browser/app/js/jsonrpc.js | 2 +- browser/app/js/mime.js | 2 +- browser/app/js/reducers.js | 2 +- browser/app/js/utils.js | 2 +- browser/app/js/web.js | 2 +- browser/build.js | 6 +- browser/package.json | 8 +- browser/ui-assets.go | 80 +++++++++---------- browser/webpack.config.js | 2 +- cmd/web-handlers.go | 32 ++++---- cmd/web-router.go | 6 +- 28 files changed, 90 insertions(+), 90 deletions(-) diff --git a/browser/app/index.js b/browser/app/index.js index d750577bc..26a1cc1d3 100644 --- a/browser/app/index.js +++ b/browser/app/index.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/__tests__/jsonrpc-test.js b/browser/app/js/__tests__/jsonrpc-test.js index 341d0c286..7e5b52f76 100644 --- a/browser/app/js/__tests__/jsonrpc-test.js +++ b/browser/app/js/__tests__/jsonrpc-test.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/actions.js b/browser/app/js/actions.js index 83b6e9f61..cb2518f09 100644 --- a/browser/app/js/actions.js +++ b/browser/app/js/actions.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/Browse.js b/browser/app/js/components/Browse.js index ab2c9e0bd..e09540b15 100644 --- a/browser/app/js/components/Browse.js +++ b/browser/app/js/components/Browse.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/BrowserDropdown.js b/browser/app/js/components/BrowserDropdown.js index 171e6f3e7..aa4dc9ac9 100644 --- a/browser/app/js/components/BrowserDropdown.js +++ b/browser/app/js/components/BrowserDropdown.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016, 2017 Minio, Inc. + * Minio Cloud Storage (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ let BrowserDropdown = ({fullScreenFunc, aboutFunc, settingsFunc, logoutFunc}) =>
  • - Github + Github
  • Fullscreen diff --git a/browser/app/js/components/BrowserUpdate.js b/browser/app/js/components/BrowserUpdate.js index be4c7af3a..5eaae8233 100644 --- a/browser/app/js/components/BrowserUpdate.js +++ b/browser/app/js/components/BrowserUpdate.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/ConfirmModal.js b/browser/app/js/components/ConfirmModal.js index fd98fa313..3677c3bbd 100644 --- a/browser/app/js/components/ConfirmModal.js +++ b/browser/app/js/components/ConfirmModal.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/Dropzone.js b/browser/app/js/components/Dropzone.js index f1ff9cc6c..32a139d7f 100644 --- a/browser/app/js/components/Dropzone.js +++ b/browser/app/js/components/Dropzone.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/InputGroup.js b/browser/app/js/components/InputGroup.js index c2b0e2ab2..9aee63f4c 100644 --- a/browser/app/js/components/InputGroup.js +++ b/browser/app/js/components/InputGroup.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/Login.js b/browser/app/js/components/Login.js index b5db1a872..5293e73d6 100644 --- a/browser/app/js/components/Login.js +++ b/browser/app/js/components/Login.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/ObjectsList.js b/browser/app/js/components/ObjectsList.js index a19b7be94..44a0ea086 100644 --- a/browser/app/js/components/ObjectsList.js +++ b/browser/app/js/components/ObjectsList.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/Path.js b/browser/app/js/components/Path.js index 901f094aa..55484da70 100644 --- a/browser/app/js/components/Path.js +++ b/browser/app/js/components/Path.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/SettingsModal.js b/browser/app/js/components/SettingsModal.js index 51bd4333b..9d3263a46 100644 --- a/browser/app/js/components/SettingsModal.js +++ b/browser/app/js/components/SettingsModal.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/SideBar.js b/browser/app/js/components/SideBar.js index d92bfbceb..b06571e2b 100644 --- a/browser/app/js/components/SideBar.js +++ b/browser/app/js/components/SideBar.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/UploadModal.js b/browser/app/js/components/UploadModal.js index 6658ab225..f68b32ee8 100644 --- a/browser/app/js/components/UploadModal.js +++ b/browser/app/js/components/UploadModal.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/components/__tests__/Login-test.js b/browser/app/js/components/__tests__/Login-test.js index 1397fb637..ac3b3dd6d 100644 --- a/browser/app/js/components/__tests__/Login-test.js +++ b/browser/app/js/components/__tests__/Login-test.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/constants.js b/browser/app/js/constants.js index 35c20f418..8f2dc34c2 100644 --- a/browser/app/js/constants.js +++ b/browser/app/js/constants.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/jsonrpc.js b/browser/app/js/jsonrpc.js index 99e1d1102..ece92ee1b 100644 --- a/browser/app/js/jsonrpc.js +++ b/browser/app/js/jsonrpc.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/mime.js b/browser/app/js/mime.js index 9c8ed40fa..aed2e753d 100644 --- a/browser/app/js/mime.js +++ b/browser/app/js/mime.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/reducers.js b/browser/app/js/reducers.js index 5d80d563b..9deec34cb 100644 --- a/browser/app/js/reducers.js +++ b/browser/app/js/reducers.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/utils.js b/browser/app/js/utils.js index 3aee71a1b..91afff20c 100644 --- a/browser/app/js/utils.js +++ b/browser/app/js/utils.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/app/js/web.js b/browser/app/js/web.js index a4c241137..96b37ba05 100644 --- a/browser/app/js/web.js +++ b/browser/app/js/web.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/browser/build.js b/browser/build.js index f612b7d02..ff12e0238 100644 --- a/browser/build.js +++ b/browser/build.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,9 +70,9 @@ async.waterfall([ commitId = stdout.replace('\n', '') if (commitId.length !== 40) throw new Error('commitId invalid : ' + commitId) assetsFileName = 'ui-assets.go'; - var cmd = 'go-bindata-assetfs -pkg miniobrowser -nocompress=true production/...' + var cmd = 'go-bindata-assetfs -pkg browser -nocompress=true production/...' if (!isProduction) { - cmd = 'go-bindata-assetfs -pkg miniobrowser -nocompress=true dev/...' + cmd = 'go-bindata-assetfs -pkg browser -nocompress=true dev/...' } console.log('Running', cmd) exec(cmd, cb) diff --git a/browser/package.json b/browser/package.json index 583d87621..9f792974d 100644 --- a/browser/package.json +++ b/browser/package.json @@ -1,5 +1,5 @@ { - "name": "minio-browser", + "name": "browser", "version": "0.0.1", "description": "Minio Browser", "scripts": { @@ -11,14 +11,14 @@ }, "repository": { "type": "git", - "url": "https://github.com/minio/miniobrowser" + "url": "https://github.com/minio/minio" }, "author": "Minio Inc", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/minio/miniobrowser/issues" + "url": "https://github.com/minio/minio/issues" }, - "homepage": "https://github.com/minio/miniobrowser", + "homepage": "https://github.com/minio/minio", "devDependencies": { "async": "^1.5.2", "babel-cli": "^6.14.0", diff --git a/browser/ui-assets.go b/browser/ui-assets.go index 773e9288b..ce79853d2 100644 --- a/browser/ui-assets.go +++ b/browser/ui-assets.go @@ -4,13 +4,13 @@ // production/favicon.ico // production/firefox.png // production/index.html -// production/index_bundle-2017-02-15T22-41-23Z.js +// production/index_bundle-2017-02-23T00-44-42Z.js // production/loader.css // production/logo.svg // production/safari.png // DO NOT EDIT! -package miniobrowser +package browser import ( "fmt" @@ -65,7 +65,7 @@ func productionChromePng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -82,7 +82,7 @@ func productionFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -99,7 +99,7 @@ func productionFirefoxPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -156,8 +156,8 @@ var _productionIndexHTML = []byte(`
  • - - + + `) @@ -172,21 +172,21 @@ func productionIndexHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _productionIndex_bundle20170215t224123zJs = []byte(`!function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){A.exports=t(240)},function(A,M,t){"use strict";A.exports=t(440)},function(A,M,t){"use strict";function I(A,M,t,I,g,e,i,T){if(!A){var E;if(void 0===M)E=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var N=[t,I,g,e,i,T],o=0;E=new Error(M.replace(/%s/g,function(){return N[o++]})),E.name="Invariant Violation"}throw E.framesToPop=1,E}}A.exports=I},function(A,M,t){"use strict";var I=t(20),g=I;A.exports=g},function(A,M){"use strict";function t(A,M){if(null==A)throw new TypeError("Object.assign target cannot be null or undefined");for(var t=Object(A),I=Object.prototype.hasOwnProperty,g=1;g2?t-2:0),g=2;g1){for(var c=Array(C),D=0;D1){for(var a=Array(D),B=0;B3&&void 0!==arguments[3]?arguments[3]:{},N=Boolean(A),C=A||w,D=void 0;D="function"==typeof M?M:M?(0,Q.default)(M):L;var B=t||l,r=I.pure,s=void 0===r||r,x=I.withRef,y=void 0!==x&&x,h=s&&B!==l,S=d++;return function(A){function M(A,M,t){var I=B(A,M,t);return I}var t="Connect("+T(A)+")",I=function(I){function T(A,M){g(this,T);var i=e(this,I.call(this,A,M));i.version=S,i.store=A.store||M.store,(0,u.default)(i.store,'Could not find "store" in either the context or '+('props of "'+t+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+t+'".'));var E=i.store.getState();return i.state={storeState:E},i.clearCache(),i}return i(T,I),T.prototype.shouldComponentUpdate=function(){return!s||this.haveOwnPropsChanged||this.hasStoreStateChanged},T.prototype.computeStateProps=function(A,M){if(!this.finalMapStateToProps)return this.configureFinalMapState(A,M);var t=A.getState(),I=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(t,M):this.finalMapStateToProps(t);return I},T.prototype.configureFinalMapState=function(A,M){var t=C(A.getState(),M),I="function"==typeof t;return this.finalMapStateToProps=I?t:C,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,I?this.computeStateProps(A,M):t},T.prototype.computeDispatchProps=function(A,M){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(A,M);var t=A.dispatch,I=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(t,M):this.finalMapDispatchToProps(t);return I},T.prototype.configureFinalMapDispatch=function(A,M){var t=D(A.dispatch,M),I="function"==typeof t;return this.finalMapDispatchToProps=I?t:D,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,I?this.computeDispatchProps(A,M):t},T.prototype.updateStatePropsIfNeeded=function(){var A=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,a.default)(A,this.stateProps))&&(this.stateProps=A,!0)},T.prototype.updateDispatchPropsIfNeeded=function(){var A=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,a.default)(A,this.dispatchProps))&&(this.dispatchProps=A,!0)},T.prototype.updateMergedPropsIfNeeded=function(){var A=M(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&h&&(0,a.default)(A,this.mergedProps))&&(this.mergedProps=A,!0)},T.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},T.prototype.trySubscribe=function(){N&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},T.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},T.prototype.componentDidMount=function(){this.trySubscribe()},T.prototype.componentWillReceiveProps=function(A){s&&(0,a.default)(A,this.props)||(this.haveOwnPropsChanged=!0)},T.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},T.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},T.prototype.handleChange=function(){if(this.unsubscribe){var A=this.store.getState(),M=this.state.storeState;if(!s||M!==A){if(s&&!this.doStatePropsDependOnOwnProps){var t=E(this.updateStatePropsIfNeeded,this);if(!t)return;t===Y&&(this.statePropsPrecalculationError=Y.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:A})}}},T.prototype.getWrappedInstance=function(){return(0,u.default)(y,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},T.prototype.render=function(){var M=this.haveOwnPropsChanged,t=this.hasStoreStateChanged,I=this.haveStatePropsBeenPrecalculated,g=this.statePropsPrecalculationError,e=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,g)throw g;var i=!0,T=!0;s&&e&&(i=t||M&&this.doStatePropsDependOnOwnProps,T=M&&this.doDispatchPropsDependOnOwnProps);var E=!1,N=!1;I?E=!0:i&&(E=this.updateStatePropsIfNeeded()),T&&(N=this.updateDispatchPropsIfNeeded());var C=!0;return C=!!(E||N||M)&&this.updateMergedPropsIfNeeded(),!C&&e?e:(y?this.renderedElement=(0,n.createElement)(A,o({},this.mergedProps,{ref:"wrappedInstance"})):this.renderedElement=(0,n.createElement)(A,this.mergedProps),this.renderedElement)},T}(n.Component);return I.displayName=t,I.WrappedComponent=A,I.contextTypes={store:c.default},I.propTypes={store:c.default},(0,j.default)(I,A)}}M.__esModule=!0;var o=Object.assign||function(A){for(var M=1;M should not have a "'+M+'" prop')}M.__esModule=!0,M.routes=M.route=M.components=M.component=M.history=void 0,M.falsy=I;var g=t(1),e=g.PropTypes.func,i=g.PropTypes.object,T=g.PropTypes.arrayOf,E=g.PropTypes.oneOfType,N=g.PropTypes.element,o=g.PropTypes.shape,n=g.PropTypes.string,C=(M.history=o({listen:e.isRequired,push:e.isRequired,replace:e.isRequired,go:e.isRequired,goBack:e.isRequired,goForward:e.isRequired}),M.component=E([e,n])),c=(M.components=E([C,i]),M.route=E([i,N]));M.routes=E([c,T(c)])},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){var M=A.match(/^https?:\/\/[^\/]*/);return null==M?A:A.substring(M[0].length)}function e(A){var M=g(A),t="",I="",e=M.indexOf("#");e!==-1&&(I=M.substring(e),M=M.substring(0,e));var i=M.indexOf("?");return i!==-1&&(t=M.substring(i),M=M.substring(0,i)),""===M&&(M="/"),{pathname:M,search:t,hash:I}}M.__esModule=!0,M.extractPath=g,M.parsePath=e;var i=t(23);I(i)},function(A,M,t){"use strict";function I(){g.attachRefs(this,this._currentElement)}var g=t(459),e={mountComponent:function(A,M,t,g){var e=A.mountComponent(M,t,g);return A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A),e},unmountComponent:function(A){g.detachRefs(A,A._currentElement),A.unmountComponent()},receiveComponent:function(A,M,t,e){var i=A._currentElement;if(M!==i||e!==A._context){var T=g.shouldUpdateRefs(i,M);T&&g.detachRefs(A,i),A.receiveComponent(M,t,e),T&&A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A)}},performUpdateIfNecessary:function(A,M){A.performUpdateIfNecessary(M)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t,I){this.dispatchConfig=A,this.dispatchMarker=M,this.nativeEvent=t;var g=this.constructor.Interface;for(var e in g)if(g.hasOwnProperty(e)){var T=g[e];T?this[e]=T(t):"target"===e?this.target=I:this[e]=t[e]}var E=null!=t.defaultPrevented?t.defaultPrevented:t.returnValue===!1;E?this.isDefaultPrevented=i.thatReturnsTrue:this.isDefaultPrevented=i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse}var g=t(31),e=t(4),i=t(20),T=(t(3),{type:null,target:null,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(A){return A.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null});e(I.prototype,{preventDefault:function(){this.defaultPrevented=!0;var A=this.nativeEvent;A&&(A.preventDefault?A.preventDefault():A.returnValue=!1,this.isDefaultPrevented=i.thatReturnsTrue)},stopPropagation:function(){var A=this.nativeEvent;A&&(A.stopPropagation?A.stopPropagation():A.cancelBubble=!0,this.isPropagationStopped=i.thatReturnsTrue)},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var A=this.constructor.Interface;for(var M in A)this[M]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),I.Interface=T,I.augmentClass=function(A,M){var t=this,I=Object.create(t.prototype);e(I,A.prototype),A.prototype=I,A.prototype.constructor=A,A.Interface=e({},t.Interface,M),A.augmentClass=t.augmentClass,g.addPoolingTo(A,g.fourArgumentPooler)},g.addPoolingTo(I,g.fourArgumentPooler),A.exports=I},function(A,M){"use strict";M.default=function(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t},M.__esModule=!0},function(A,M){"use strict";function t(A){return A&&A.ownerDocument||document}M.__esModule=!0,M.default=t,A.exports=M.default},function(A,M,t){"use strict";var I=t(32),g=function(){var A=I&&document.documentElement;return A&&A.contains?function(A,M){return A.contains(M)}:A&&A.compareDocumentPosition?function(A,M){return A===M||!!(16&A.compareDocumentPosition(M))}:function(A,M){if(M)do if(M===A)return!0;while(M=M.parentNode);return!1}}();A.exports=g},function(A,M){function t(A){return"number"==typeof A&&A>-1&&A%1==0&&A<=I}var I=9007199254740991;A.exports=t},function(A,M,t){(function(A){!function(M,t){A.exports=t()}(this,function(){"use strict";function M(){return aI.apply(null,arguments)}function t(A){aI=A}function I(A){return A instanceof Array||"[object Array]"===Object.prototype.toString.call(A)}function g(A){return null!=A&&"[object Object]"===Object.prototype.toString.call(A)}function e(A){var M;for(M in A)return!1;return!0}function i(A){return"number"==typeof A||"[object Number]"===Object.prototype.toString.call(A)}function T(A){return A instanceof Date||"[object Date]"===Object.prototype.toString.call(A)}function E(A,M){var t,I=[];for(t=0;t0)for(t in rI)I=rI[t],g=M[I],B(g)||(A[I]=g);return A}function r(A){Q(this,A),this._d=new Date(null!=A._d?A._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),sI===!1&&(sI=!0,M.updateOffset(this),sI=!1)}function s(A){return A instanceof r||null!=A&&null!=A._isAMomentObject}function x(A){return A<0?Math.ceil(A)||0:Math.floor(A)}function j(A){var M=+A,t=0;return 0!==M&&isFinite(M)&&(t=x(M)),t}function y(A,M,t){var I,g=Math.min(A.length,M.length),e=Math.abs(A.length-M.length),i=0;for(I=0;I0?"future":"past"];return l(t)?t(M):t.replace(/%s/i,M)}function F(A,M){var t=A.toLowerCase();SI[t]=SI[t+"s"]=SI[M]=A}function f(A){return"string"==typeof A?SI[A]||SI[A.toLowerCase()]:void 0}function k(A){var M,t,I={};for(t in A)N(A,t)&&(M=f(t),M&&(I[M]=A[t]));return I}function R(A,M){zI[A]=M}function J(A){var M=[];for(var t in A)M.push({unit:t,priority:zI[t]});return M.sort(function(A,M){return A.priority-M.priority}),M}function G(A,t){return function(I){return null!=I?(b(this,A,I),M.updateOffset(this,t),this):H(this,A)}}function H(A,M){return A.isValid()?A._d["get"+(A._isUTC?"UTC":"")+M]():NaN}function b(A,M,t){A.isValid()&&A._d["set"+(A._isUTC?"UTC":"")+M](t)}function X(A){return A=f(A),l(this[A])?this[A]():this}function v(A,M){if("object"==typeof A){A=k(A);for(var t=J(A),I=0;I=0;return(e?t?"+":"":"-")+Math.pow(10,Math.max(0,g)).toString().substr(1)+I}function V(A,M,t,I){var g=I;"string"==typeof I&&(g=function(){return this[I]()}),A&&(mI[A]=g),M&&(mI[M[0]]=function(){return W(g.apply(this,arguments),M[1],M[2])}),t&&(mI[t]=function(){return this.localeData().ordinal(g.apply(this,arguments),A)})}function P(A){return A.match(/\[[\s\S]/)?A.replace(/^\[|\]$/g,""):A.replace(/\\/g,"")}function Z(A){var M,t,I=A.match(pI);for(M=0,t=I.length;M=0&&UI.test(A);)A=A.replace(UI,t),UI.lastIndex=0,I-=1;return A}function _(A,M,t){$I[A]=l(M)?M:function(A,I){return A&&t?t:M}}function $(A,M){return N($I,A)?$I[A](M._strict,M._locale):new RegExp(AA(A))}function AA(A){return MA(A.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(A,M,t,I,g){return M||t||I||g}))}function MA(A){return A.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tA(A,M){var t,I=M;for("string"==typeof A&&(A=[A]),i(M)&&(I=function(A,t){t[M]=j(A)}),t=0;t=0&&isFinite(T.getFullYear())&&T.setFullYear(A),T}function xA(A){var M=new Date(Date.UTC.apply(null,arguments));return A<100&&A>=0&&isFinite(M.getUTCFullYear())&&M.setUTCFullYear(A),M}function jA(A,M,t){var I=7+M-t,g=(7+xA(A,0,I).getUTCDay()-M)%7;return-g+I-1}function yA(A,M,t,I,g){var e,i,T=(7+t-I)%7,E=jA(A,I,g),N=1+7*(M-1)+T+E;return N<=0?(e=A-1,i=BA(e)+N):N>BA(A)?(e=A+1,i=N-BA(A)):(e=A,i=N),{year:e,dayOfYear:i}}function uA(A,M,t){var I,g,e=jA(A.year(),M,t),i=Math.floor((A.dayOfYear()-e-1)/7)+1;return i<1?(g=A.year()-1,I=i+wA(g,M,t)):i>wA(A.year(),M,t)?(I=i-wA(A.year(),M,t),g=A.year()+1):(g=A.year(),I=i),{week:I,year:g}}function wA(A,M,t){var I=jA(A,M,t),g=jA(A+1,M,t);return(BA(A)-I+g)/7}function LA(A){return uA(A,this._week.dow,this._week.doy).week}function lA(){return this._week.dow}function YA(){return this._week.doy}function dA(A){var M=this.localeData().week(this);return null==A?M:this.add(7*(A-M),"d")}function hA(A){var M=uA(this,1,4).week;return null==A?M:this.add(7*(A-M),"d")}function SA(A,M){return"string"!=typeof A?A:isNaN(A)?(A=M.weekdaysParse(A),"number"==typeof A?A:null):parseInt(A,10)}function zA(A,M){return"string"==typeof A?M.weekdaysParse(A)%7||7:isNaN(A)?null:A}function pA(A,M){return A?I(this._weekdays)?this._weekdays[A.day()]:this._weekdays[this._weekdays.isFormat.test(M)?"format":"standalone"][A.day()]:this._weekdays}function UA(A){return A?this._weekdaysShort[A.day()]:this._weekdaysShort}function OA(A){return A?this._weekdaysMin[A.day()]:this._weekdaysMin}function mA(A,M,t){var I,g,e,i=A.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],I=0;I<7;++I)e=n([2e3,1]).day(I),this._minWeekdaysParse[I]=this.weekdaysMin(e,"").toLocaleLowerCase(),this._shortWeekdaysParse[I]=this.weekdaysShort(e,"").toLocaleLowerCase(),this._weekdaysParse[I]=this.weekdays(e,"").toLocaleLowerCase();return t?"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:null):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null):"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null)))}function FA(A,M,t){var I,g,e;if(this._weekdaysParseExact)return mA.call(this,A,M,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),I=0;I<7;I++){if(g=n([2e3,1]).day(I),t&&!this._fullWeekdaysParse[I]&&(this._fullWeekdaysParse[I]=new RegExp("^"+this.weekdays(g,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[I]=new RegExp("^"+this.weekdaysShort(g,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[I]=new RegExp("^"+this.weekdaysMin(g,"").replace(".",".?")+"$","i")),this._weekdaysParse[I]||(e="^"+this.weekdays(g,"")+"|^"+this.weekdaysShort(g,"")+"|^"+this.weekdaysMin(g,""),this._weekdaysParse[I]=new RegExp(e.replace(".",""),"i")),t&&"dddd"===M&&this._fullWeekdaysParse[I].test(A))return I;if(t&&"ddd"===M&&this._shortWeekdaysParse[I].test(A))return I;if(t&&"dd"===M&&this._minWeekdaysParse[I].test(A))return I;if(!t&&this._weekdaysParse[I].test(A))return I}}function fA(A){if(!this.isValid())return null!=A?this:NaN;var M=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=A?(A=SA(A,this.localeData()),this.add(A-M,"d")):M}function kA(A){if(!this.isValid())return null!=A?this:NaN;var M=(this.day()+7-this.localeData()._week.dow)%7;return null==A?M:this.add(A-M,"d")}function RA(A){if(!this.isValid())return null!=A?this:NaN;if(null!=A){var M=zA(A,this.localeData());return this.day(this.day()%7?M:M-7)}return this.day()||7}function JA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysStrictRegex:this._weekdaysRegex):(N(this,"_weekdaysRegex")||(this._weekdaysRegex=jg),this._weekdaysStrictRegex&&A?this._weekdaysStrictRegex:this._weekdaysRegex)}function GA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(N(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=yg),this._weekdaysShortStrictRegex&&A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function HA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(N(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ug),this._weekdaysMinStrictRegex&&A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function bA(){function A(A,M){return M.length-A.length}var M,t,I,g,e,i=[],T=[],E=[],N=[];for(M=0;M<7;M++)t=n([2e3,1]).day(M),I=this.weekdaysMin(t,""),g=this.weekdaysShort(t,""),e=this.weekdays(t,""),i.push(I),T.push(g),E.push(e),N.push(I),N.push(g),N.push(e);for(i.sort(A),T.sort(A),E.sort(A),N.sort(A),M=0;M<7;M++)T[M]=MA(T[M]),E[M]=MA(E[M]),N[M]=MA(N[M]);this._weekdaysRegex=new RegExp("^("+N.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+E.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+T.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function XA(){return this.hours()%12||12}function vA(){return this.hours()||24}function WA(A,M){V(A,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),M)})}function VA(A,M){return M._meridiemParse}function PA(A){return"p"===(A+"").toLowerCase().charAt(0)}function ZA(A,M,t){return A>11?t?"pm":"PM":t?"am":"AM"}function KA(A){return A?A.toLowerCase().replace("_","-"):A}function qA(A){for(var M,t,I,g,e=0;e0;){if(I=_A(g.slice(0,M).join("-")))return I;if(t&&t.length>=M&&y(g,t,!0)>=M-1)break;M--}e++}return null}function _A(M){var t=null;if(!dg[M]&&"undefined"!=typeof A&&A&&A.exports)try{t=wg._abbr,!function(){var A=new Error('Cannot find module "./locale"');throw A.code="MODULE_NOT_FOUND",A}(),$A(t)}catch(A){}return dg[M]}function $A(A,M){var t;return A&&(t=B(M)?tM(A):AM(A,M),t&&(wg=t)),wg._abbr}function AM(A,M){if(null!==M){var t=Yg;if(M.abbr=A,null!=dg[A])L("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),t=dg[A]._config;else if(null!=M.parentLocale){if(null==dg[M.parentLocale])return hg[M.parentLocale]||(hg[M.parentLocale]=[]),hg[M.parentLocale].push({name:A,config:M}),null;t=dg[M.parentLocale]._config}return dg[A]=new h(d(t,M)),hg[A]&&hg[A].forEach(function(A){AM(A.name,A.config)}),$A(A),dg[A]}return delete dg[A],null}function MM(A,M){if(null!=M){var t,I=Yg;null!=dg[A]&&(I=dg[A]._config),M=d(I,M),t=new h(M),t.parentLocale=dg[A],dg[A]=t,$A(A)}else null!=dg[A]&&(null!=dg[A].parentLocale?dg[A]=dg[A].parentLocale:null!=dg[A]&&delete dg[A]);return dg[A]}function tM(A){var M;if(A&&A._locale&&A._locale._abbr&&(A=A._locale._abbr),!A)return wg;if(!I(A)){if(M=_A(A))return M;A=[A]}return qA(A)}function IM(){return uI(dg)}function gM(A){var M,t=A._a;return t&&c(A).overflow===-2&&(M=t[tg]<0||t[tg]>11?tg:t[Ig]<1||t[Ig]>eA(t[Mg],t[tg])?Ig:t[gg]<0||t[gg]>24||24===t[gg]&&(0!==t[eg]||0!==t[ig]||0!==t[Tg])?gg:t[eg]<0||t[eg]>59?eg:t[ig]<0||t[ig]>59?ig:t[Tg]<0||t[Tg]>999?Tg:-1,c(A)._overflowDayOfYear&&(MIg)&&(M=Ig),c(A)._overflowWeeks&&M===-1&&(M=Eg),c(A)._overflowWeekday&&M===-1&&(M=Ng),c(A).overflow=M),A}function eM(A){var M,t,I,g,e,i,T=A._i,E=Sg.exec(T)||zg.exec(T);if(E){for(c(A).iso=!0,M=0,t=Ug.length;MBA(g)&&(c(A)._overflowDayOfYear=!0),t=xA(g,0,A._dayOfYear),A._a[tg]=t.getUTCMonth(),A._a[Ig]=t.getUTCDate()),M=0;M<3&&null==A._a[M];++M)A._a[M]=e[M]=I[M];for(;M<7;M++)A._a[M]=e[M]=null==A._a[M]?2===M?1:0:A._a[M];24===A._a[gg]&&0===A._a[eg]&&0===A._a[ig]&&0===A._a[Tg]&&(A._nextDay=!0,A._a[gg]=0),A._d=(A._useUTC?xA:sA).apply(null,e),null!=A._tzm&&A._d.setUTCMinutes(A._d.getUTCMinutes()-A._tzm),A._nextDay&&(A._a[gg]=24)}}function oM(A){var M,t,I,g,e,i,T,E;if(M=A._w,null!=M.GG||null!=M.W||null!=M.E)e=1,i=4,t=TM(M.GG,A._a[Mg],uA(sM(),1,4).year),I=TM(M.W,1),g=TM(M.E,1),(g<1||g>7)&&(E=!0);else{e=A._locale._week.dow,i=A._locale._week.doy;var N=uA(sM(),e,i);t=TM(M.gg,A._a[Mg],N.year),I=TM(M.w,N.week),null!=M.d?(g=M.d,(g<0||g>6)&&(E=!0)):null!=M.e?(g=M.e+e,(M.e<0||M.e>6)&&(E=!0)):g=e}I<1||I>wA(t,e,i)?c(A)._overflowWeeks=!0:null!=E?c(A)._overflowWeekday=!0:(T=yA(t,I,g,e,i),A._a[Mg]=T.year,A._dayOfYear=T.dayOfYear)}function nM(A){if(A._f===M.ISO_8601)return void eM(A);A._a=[],c(A).empty=!0;var t,I,g,e,i,T=""+A._i,E=T.length,N=0;for(g=q(A._f,A._locale).match(pI)||[],t=0;t0&&c(A).unusedInput.push(i),T=T.slice(T.indexOf(I)+I.length),N+=I.length),mI[e]?(I?c(A).empty=!1:c(A).unusedTokens.push(e),gA(e,I,A)):A._strict&&!I&&c(A).unusedTokens.push(e);c(A).charsLeftOver=E-N,T.length>0&&c(A).unusedInput.push(T),A._a[gg]<=12&&c(A).bigHour===!0&&A._a[gg]>0&&(c(A).bigHour=void 0),c(A).parsedDateParts=A._a.slice(0),c(A).meridiem=A._meridiem,A._a[gg]=CM(A._locale,A._a[gg],A._meridiem),NM(A),gM(A)}function CM(A,M,t){var I;return null==t?M:null!=A.meridiemHour?A.meridiemHour(M,t):null!=A.isPM?(I=A.isPM(t),I&&M<12&&(M+=12),I||12!==M||(M=0),M):M}function cM(A){var M,t,I,g,e;if(0===A._f.length)return c(A).invalidFormat=!0,void(A._d=new Date(NaN));for(g=0;gthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function fM(){if(!B(this._isDSTShifted))return this._isDSTShifted;var A={};if(Q(A,this),A=BM(A),A._a){var M=A._isUTC?n(A._a):sM(A._a);this._isDSTShifted=this.isValid()&&y(A._a,M.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function kM(){return!!this.isValid()&&!this._isUTC}function RM(){return!!this.isValid()&&this._isUTC}function JM(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function GM(A,M){var t,I,g,e=A,T=null;return wM(A)?e={ms:A._milliseconds,d:A._days,M:A._months}:i(A)?(e={},M?e[M]=A:e.milliseconds=A):(T=Jg.exec(A))?(t="-"===T[1]?-1:1,e={y:0,d:j(T[Ig])*t,h:j(T[gg])*t,m:j(T[eg])*t,s:j(T[ig])*t,ms:j(LM(1e3*T[Tg]))*t}):(T=Gg.exec(A))?(t="-"===T[1]?-1:1,e={y:HM(T[2],t),M:HM(T[3],t),w:HM(T[4],t),d:HM(T[5],t),h:HM(T[6],t),m:HM(T[7],t),s:HM(T[8],t)}):null==e?e={}:"object"==typeof e&&("from"in e||"to"in e)&&(g=XM(sM(e.from),sM(e.to)),e={},e.ms=g.milliseconds,e.M=g.months),I=new uM(e),wM(A)&&N(A,"_locale")&&(I._locale=A._locale),I}function HM(A,M){var t=A&&parseFloat(A.replace(",","."));return(isNaN(t)?0:t)*M}function bM(A,M){var t={milliseconds:0,months:0};return t.months=M.month()-A.month()+12*(M.year()-A.year()),A.clone().add(t.months,"M").isAfter(M)&&--t.months,t.milliseconds=+M-+A.clone().add(t.months,"M"),t}function XM(A,M){var t;return A.isValid()&&M.isValid()?(M=dM(M,A),A.isBefore(M)?t=bM(A,M):(t=bM(M,A),t.milliseconds=-t.milliseconds,t.months=-t.months),t):{milliseconds:0,months:0}}function vM(A,M){return function(t,I){var g,e;return null===I||isNaN(+I)||(L(M,"moment()."+M+"(period, number) is deprecated. Please use moment()."+M+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),e=t,t=I,I=e),t="string"==typeof t?+t:t,g=GM(t,I),WM(this,g,A),this}}function WM(A,t,I,g){var e=t._milliseconds,i=LM(t._days),T=LM(t._months);A.isValid()&&(g=null==g||g,e&&A._d.setTime(A._d.valueOf()+e*I),i&&b(A,"Date",H(A,"Date")+i*I),T&&oA(A,H(A,"Month")+T*I),g&&M.updateOffset(A,i||T))}function VM(A,M){var t=A.diff(M,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"}function PM(A,t){var I=A||sM(),g=dM(I,this).startOf("day"),e=M.calendarFormat(this,g)||"sameElse",i=t&&(l(t[e])?t[e].call(this,I):t[e]);return this.format(i||this.localeData().calendar(e,this,sM(I)))}function ZM(){return new r(this)}function KM(A,M){var t=s(A)?A:sM(A);return!(!this.isValid()||!t.isValid())&&(M=f(B(M)?"millisecond":M),"millisecond"===M?this.valueOf()>t.valueOf():t.valueOf()e&&(M=e),pt.call(this,A,M,t,I,g))}function pt(A,M,t,I,g){var e=yA(A,M,t,I,g),i=xA(e.year,0,e.dayOfYear);return this.year(i.getUTCFullYear()),this.month(i.getUTCMonth()),this.date(i.getUTCDate()),this}function Ut(A){return null==A?Math.ceil((this.month()+1)/3):this.month(3*(A-1)+this.month()%3)}function Ot(A){var M=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==A?M:this.add(A-M,"d")}function mt(A,M){M[Tg]=j(1e3*("0."+A))}function Ft(){return this._isUTC?"UTC":""}function ft(){return this._isUTC?"Coordinated Universal Time":""}function kt(A){return sM(1e3*A)}function Rt(){return sM.apply(null,arguments).parseZone()}function Jt(A){return A}function Gt(A,M,t,I){var g=tM(),e=n().set(I,M);return g[t](e,A)}function Ht(A,M,t){if(i(A)&&(M=A,A=void 0),A=A||"",null!=M)return Gt(A,M,t,"month");var I,g=[];for(I=0;I<12;I++)g[I]=Gt(A,I,t,"month");return g}function bt(A,M,t,I){"boolean"==typeof A?(i(M)&&(t=M,M=void 0),M=M||""):(M=A,t=M,A=!1,i(M)&&(t=M,M=void 0),M=M||"");var g=tM(),e=A?g._week.dow:0;if(null!=t)return Gt(M,(t+e)%7,I,"day");var T,E=[];for(T=0;T<7;T++)E[T]=Gt(M,(T+e)%7,I,"day");return E}function Xt(A,M){return Ht(A,M,"months")}function vt(A,M){return Ht(A,M,"monthsShort")}function Wt(A,M,t){return bt(A,M,t,"weekdays")}function Vt(A,M,t){return bt(A,M,t,"weekdaysShort")}function Pt(A,M,t){return bt(A,M,t,"weekdaysMin")}function Zt(){var A=this._data;return this._milliseconds=_g(this._milliseconds),this._days=_g(this._days),this._months=_g(this._months),A.milliseconds=_g(A.milliseconds),A.seconds=_g(A.seconds),A.minutes=_g(A.minutes),A.hours=_g(A.hours),A.months=_g(A.months),A.years=_g(A.years),this}function Kt(A,M,t,I){var g=GM(M,t);return A._milliseconds+=I*g._milliseconds,A._days+=I*g._days,A._months+=I*g._months,A._bubble()}function qt(A,M){return Kt(this,A,M,1)}function _t(A,M){return Kt(this,A,M,-1)}function $t(A){return A<0?Math.floor(A):Math.ceil(A)}function AI(){var A,M,t,I,g,e=this._milliseconds,i=this._days,T=this._months,E=this._data;return e>=0&&i>=0&&T>=0||e<=0&&i<=0&&T<=0||(e+=864e5*$t(tI(T)+i),i=0,T=0),E.milliseconds=e%1e3,A=x(e/1e3),E.seconds=A%60,M=x(A/60),E.minutes=M%60,t=x(M/60),E.hours=t%24,i+=x(t/24),g=x(MI(i)),T+=g,i-=$t(tI(g)),I=x(T/12),T%=12,E.days=i,E.months=T,E.years=I,this}function MI(A){return 4800*A/146097}function tI(A){return 146097*A/4800}function II(A){var M,t,I=this._milliseconds;if(A=f(A),"month"===A||"year"===A)return M=this._days+I/864e5,t=this._months+MI(M),"month"===A?t:t/12;switch(M=this._days+Math.round(tI(this._months)),A){case"week":return M/7+I/6048e5;case"day":return M+I/864e5;case"hour":return 24*M+I/36e5;case"minute":return 1440*M+I/6e4;case"second":return 86400*M+I/1e3;case"millisecond":return Math.floor(864e5*M)+I;default:throw new Error("Unknown unit "+A)}}function gI(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*j(this._months/12)}function eI(A){return function(){return this.as(A)}}function iI(A){return A=f(A),this[A+"s"]()}function TI(A){return function(){return this._data[A]}}function EI(){return x(this.days()/7)}function NI(A,M,t,I,g){return g.relativeTime(M||1,!!t,A,I)}function oI(A,M,t){var I=GM(A).abs(),g=De(I.as("s")),e=De(I.as("m")),i=De(I.as("h")),T=De(I.as("d")),E=De(I.as("M")),N=De(I.as("y")),o=g0,o[4]=t,NI.apply(null,o)}function nI(A){return void 0===A?De:"function"==typeof A&&(De=A,!0)}function CI(A,M){return void 0!==ae[A]&&(void 0===M?ae[A]:(ae[A]=M,!0))}function cI(A){var M=this.localeData(),t=oI(this,!A,M);return A&&(t=M.pastFuture(+this,t)),M.postformat(t)}function DI(){var A,M,t,I=Be(this._milliseconds)/1e3,g=Be(this._days),e=Be(this._months);A=x(I/60),M=x(A/60),I%=60,A%=60,t=x(e/12),e%=12;var i=t,T=e,E=g,N=M,o=A,n=I,C=this.asSeconds();return C?(C<0?"-":"")+"P"+(i?i+"Y":"")+(T?T+"M":"")+(E?E+"D":"")+(N||o||n?"T":"")+(N?N+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"}var aI,BI;BI=Array.prototype.some?Array.prototype.some:function(A){for(var M=Object(this),t=M.length>>>0,I=0;I68?1900:2e3)};var Bg=G("FullYear",!0);V("w",["ww",2],"wo","week"),V("W",["WW",2],"Wo","isoWeek"),F("week","w"),F("isoWeek","W"),R("week",5),R("isoWeek",5),_("w",GI),_("ww",GI,fI),_("W",GI),_("WW",GI,fI),IA(["w","ww","W","WW"],function(A,M,t,I){M[I.substr(0,1)]=j(A)});var Qg={dow:0,doy:6};V("d",0,"do","day"),V("dd",0,0,function(A){return this.localeData().weekdaysMin(this,A)}),V("ddd",0,0,function(A){return this.localeData().weekdaysShort(this,A)}),V("dddd",0,0,function(A){return this.localeData().weekdays(this,A)}),V("e",0,0,"weekday"),V("E",0,0,"isoWeekday"),F("day","d"),F("weekday","e"),F("isoWeekday","E"),R("day",11),R("weekday",11),R("isoWeekday",11),_("d",GI),_("e",GI),_("E",GI),_("dd",function(A,M){return M.weekdaysMinRegex(A)}),_("ddd",function(A,M){return M.weekdaysShortRegex(A)}),_("dddd",function(A,M){return M.weekdaysRegex(A)}),IA(["dd","ddd","dddd"],function(A,M,t,I){var g=t._locale.weekdaysParse(A,I,t._strict);null!=g?M.d=g:c(t).invalidWeekday=A}),IA(["d","e","E"],function(A,M,t,I){M[I]=j(A)});var rg="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),sg="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xg="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),jg=_I,yg=_I,ug=_I;V("H",["HH",2],0,"hour"),V("h",["hh",2],0,XA),V("k",["kk",2],0,vA),V("hmm",0,0,function(){return""+XA.apply(this)+W(this.minutes(),2)}),V("hmmss",0,0,function(){return""+XA.apply(this)+W(this.minutes(),2)+W(this.seconds(),2)}),V("Hmm",0,0,function(){return""+this.hours()+W(this.minutes(),2)}),V("Hmmss",0,0,function(){return""+this.hours()+W(this.minutes(),2)+W(this.seconds(),2)}),WA("a",!0),WA("A",!1),F("hour","h"),R("hour",13),_("a",VA),_("A",VA),_("H",GI),_("h",GI),_("HH",GI,fI),_("hh",GI,fI),_("hmm",HI),_("hmmss",bI),_("Hmm",HI),_("Hmmss",bI),tA(["H","HH"],gg),tA(["a","A"],function(A,M,t){t._isPm=t._locale.isPM(A),t._meridiem=A}),tA(["h","hh"],function(A,M,t){M[gg]=j(A),c(t).bigHour=!0}),tA("hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I)),c(t).bigHour=!0}),tA("hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g)),c(t).bigHour=!0}),tA("Hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I))}),tA("Hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g))});var wg,Lg=/[ap]\.?m?\.?/i,lg=G("Hours",!0),Yg={calendar:wI,longDateFormat:LI,invalidDate:lI,ordinal:YI,ordinalParse:dI,relativeTime:hI,months:Cg,monthsShort:cg,week:Qg,weekdays:rg,weekdaysMin:xg,weekdaysShort:sg,meridiemParse:Lg},dg={},hg={},Sg=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,zg=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pg=/Z|[+-]\d\d(?::?\d\d)?/,Ug=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Og=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mg=/^\/?Date\((\-?\d+)/i;M.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(A){A._d=new Date(A._i+(A._useUTC?" UTC":""))}),M.ISO_8601=function(){};var Fg=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var A=sM.apply(null,arguments);return this.isValid()&&A.isValid()?Athis?this:A:a()}),kg=function(){return Date.now?Date.now():+new Date};lM("Z",":"),lM("ZZ",""),_("Z",KI),_("ZZ",KI),tA(["Z","ZZ"],function(A,M,t){t._useUTC=!0,t._tzm=YM(KI,A)});var Rg=/([\+\-]|\d\d)/gi;M.updateOffset=function(){};var Jg=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Gg=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;GM.fn=uM.prototype;var Hg=vM(1,"add"),bg=vM(-1,"subtract");M.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",M.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xg=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(A){return void 0===A?this.localeData():this.locale(A)});V(0,["gg",2],0,function(){return this.weekYear()%100}),V(0,["GG",2],0,function(){return this.isoWeekYear()%100}),lt("gggg","weekYear"),lt("ggggg","weekYear"),lt("GGGG","isoWeekYear"),lt("GGGGG","isoWeekYear"),F("weekYear","gg"),F("isoWeekYear","GG"),R("weekYear",1),R("isoWeekYear",1),_("G",PI),_("g",PI),_("GG",GI,fI),_("gg",GI,fI),_("GGGG",vI,RI),_("gggg",vI,RI),_("GGGGG",WI,JI),_("ggggg",WI,JI),IA(["gggg","ggggg","GGGG","GGGGG"],function(A,M,t,I){M[I.substr(0,2)]=j(A)}),IA(["gg","GG"],function(A,t,I,g){t[g]=M.parseTwoDigitYear(A)}),V("Q",0,"Qo","quarter"),F("quarter","Q"),R("quarter",7),_("Q",FI),tA("Q",function(A,M){M[tg]=3*(j(A)-1)}),V("D",["DD",2],"Do","date"),F("date","D"),R("date",9),_("D",GI),_("DD",GI,fI),_("Do",function(A,M){return A?M._ordinalParse:M._ordinalParseLenient}),tA(["D","DD"],Ig),tA("Do",function(A,M){M[Ig]=j(A.match(GI)[0],10)});var vg=G("Date",!0);V("DDD",["DDDD",3],"DDDo","dayOfYear"),F("dayOfYear","DDD"),R("dayOfYear",4),_("DDD",XI),_("DDDD",kI),tA(["DDD","DDDD"],function(A,M,t){t._dayOfYear=j(A)}),V("m",["mm",2],0,"minute"),F("minute","m"),R("minute",14),_("m",GI),_("mm",GI,fI),tA(["m","mm"],eg);var Wg=G("Minutes",!1);V("s",["ss",2],0,"second"),F("second","s"),R("second",15),_("s",GI),_("ss",GI,fI),tA(["s","ss"],ig);var Vg=G("Seconds",!1);V("S",0,0,function(){return~~(this.millisecond()/100)}),V(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),V(0,["SSS",3],0,"millisecond"),V(0,["SSSS",4],0,function(){return 10*this.millisecond()}),V(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),V(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),V(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),V(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),V(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),F("millisecond","ms"),R("millisecond",16),_("S",XI,FI),_("SS",XI,fI),_("SSS",XI,kI);var Pg;for(Pg="SSSS";Pg.length<=9;Pg+="S")_(Pg,VI);for(Pg="S";Pg.length<=9;Pg+="S")tA(Pg,mt);var Zg=G("Milliseconds",!1);V("z",0,0,"zoneAbbr"),V("zz",0,0,"zoneName");var Kg=r.prototype;Kg.add=Hg,Kg.calendar=PM,Kg.clone=ZM,Kg.diff=tt,Kg.endOf=at,Kg.format=Tt,Kg.from=Et,Kg.fromNow=Nt,Kg.to=ot,Kg.toNow=nt,Kg.get=X,Kg.invalidAt=wt,Kg.isAfter=KM,Kg.isBefore=qM,Kg.isBetween=_M,Kg.isSame=$M,Kg.isSameOrAfter=At,Kg.isSameOrBefore=Mt,Kg.isValid=yt,Kg.lang=Xg,Kg.locale=Ct,Kg.localeData=ct,Kg.max=fg,Kg.min=Fg,Kg.parsingFlags=ut,Kg.set=v,Kg.startOf=Dt,Kg.subtract=bg,Kg.toArray=st,Kg.toObject=xt,Kg.toDate=rt,Kg.toISOString=et,Kg.inspect=it,Kg.toJSON=jt,Kg.toString=gt,Kg.unix=Qt,Kg.valueOf=Bt,Kg.creationData=Lt,Kg.year=Bg,Kg.isLeapYear=rA,Kg.weekYear=Yt,Kg.isoWeekYear=dt,Kg.quarter=Kg.quarters=Ut,Kg.month=nA,Kg.daysInMonth=CA,Kg.week=Kg.weeks=dA,Kg.isoWeek=Kg.isoWeeks=hA,Kg.weeksInYear=St,Kg.isoWeeksInYear=ht,Kg.date=vg,Kg.day=Kg.days=fA,Kg.weekday=kA,Kg.isoWeekday=RA,Kg.dayOfYear=Ot,Kg.hour=Kg.hours=lg,Kg.minute=Kg.minutes=Wg,Kg.second=Kg.seconds=Vg,Kg.millisecond=Kg.milliseconds=Zg,Kg.utcOffset=SM,Kg.utc=pM,Kg.local=UM,Kg.parseZone=OM,Kg.hasAlignedHourOffset=mM,Kg.isDST=FM,Kg.isLocal=kM,Kg.isUtcOffset=RM,Kg.isUtc=JM,Kg.isUTC=JM,Kg.zoneAbbr=Ft,Kg.zoneName=ft,Kg.dates=w("dates accessor is deprecated. Use date instead.",vg),Kg.months=w("months accessor is deprecated. Use month instead",nA),Kg.years=w("years accessor is deprecated. Use year instead",Bg),Kg.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",zM),Kg.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",fM);var qg=h.prototype;qg.calendar=S,qg.longDateFormat=z,qg.invalidDate=p,qg.ordinal=U,qg.preparse=Jt,qg.postformat=Jt,qg.relativeTime=O,qg.pastFuture=m,qg.set=Y,qg.months=iA,qg.monthsShort=TA,qg.monthsParse=NA,qg.monthsRegex=DA,qg.monthsShortRegex=cA,qg.week=LA,qg.firstDayOfYear=YA,qg.firstDayOfWeek=lA,qg.weekdays=pA,qg.weekdaysMin=OA,qg.weekdaysShort=UA,qg.weekdaysParse=FA,qg.weekdaysRegex=JA,qg.weekdaysShortRegex=GA,qg.weekdaysMinRegex=HA,qg.isPM=PA,qg.meridiem=ZA,$A("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(A){var M=A%10,t=1===j(A%100/10)?"th":1===M?"st":2===M?"nd":3===M?"rd":"th";return A+t}}),M.lang=w("moment.lang is deprecated. Use moment.locale instead.",$A),M.langData=w("moment.langData is deprecated. Use moment.localeData instead.",tM);var _g=Math.abs,$g=eI("ms"),Ae=eI("s"),Me=eI("m"),te=eI("h"),Ie=eI("d"),ge=eI("w"),ee=eI("M"),ie=eI("y"),Te=TI("milliseconds"),Ee=TI("seconds"),Ne=TI("minutes"),oe=TI("hours"),ne=TI("days"),Ce=TI("months"),ce=TI("years"),De=Math.round,ae={s:45,m:45,h:22,d:26,M:11},Be=Math.abs,Qe=uM.prototype;return Qe.abs=Zt,Qe.add=qt,Qe.subtract=_t,Qe.as=II,Qe.asMilliseconds=$g,Qe.asSeconds=Ae,Qe.asMinutes=Me,Qe.asHours=te,Qe.asDays=Ie,Qe.asWeeks=ge,Qe.asMonths=ee,Qe.asYears=ie,Qe.valueOf=gI,Qe._bubble=AI,Qe.get=iI,Qe.milliseconds=Te,Qe.seconds=Ee,Qe.minutes=Ne,Qe.hours=oe,Qe.days=ne,Qe.weeks=EI,Qe.months=Ce,Qe.years=ce,Qe.humanize=cI,Qe.toISOString=DI,Qe.toString=DI,Qe.toJSON=DI,Qe.locale=Ct,Qe.localeData=ct,Qe.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",DI),Qe.lang=Xg,V("X",0,0,"unix"),V("x",0,0,"valueOf"),_("x",PI),_("X",qI),tA("X",function(A,M,t){t._d=new Date(1e3*parseFloat(A,10))}),tA("x",function(A,M,t){t._d=new Date(j(A))}),M.version="2.17.1",t(sM),M.fn=Kg,M.min=jM,M.max=yM,M.now=kg,M.utc=n,M.unix=kt,M.months=Xt,M.isDate=T,M.locale=$A,M.invalid=a,M.duration=GM,M.isMoment=s,M.weekdays=Wt,M.parseZone=Rt,M.localeData=tM,M.isDuration=wM,M.monthsShort=vt,M.weekdaysMin=Pt,M.defineLocale=AM,M.updateLocale=MM,M.locales=IM,M.weekdaysShort=Vt,M.normalizeUnits=f,M.relativeTimeRounding=nI,M.relativeTimeThreshold=CI,M.calendarFormat=VM,M.prototype=Kg,M})}).call(M,t(128)(A))},function(A,M,t){"use strict";var I=t(132).default,g=t(133).default,e=t(78).default;M.__esModule=!0;var i=function(A){return I(g({values:function(){var A=this;return e(this).map(function(M){return A[M]})}}),A)},T={SIZES:{large:"lg",medium:"md",small:"sm",xsmall:"xs",lg:"lg",md:"md",sm:"sm",xs:"xs"},GRID_COLUMNS:12},E=i({LARGE:"large",MEDIUM:"medium",SMALL:"small",XSMALL:"xsmall"});M.Sizes=E;var N=i({SUCCESS:"success",WARNING:"warning",DANGER:"danger",INFO:"info"});M.State=N;var o="default";M.DEFAULT=o;var n="primary";M.PRIMARY=n;var C="link";M.LINK=C;var c="inverse";M.INVERSE=c,M.default=T},function(A,M){"use strict";function t(){for(var A=arguments.length,M=Array(A),t=0;t0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURI(o))):"("===E?g+=1:")"===E?g-=1:":"===E.charAt(0)?(N=E.substring(1),o=M[N],null!=o||g>0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURIComponent(o))):e+=E;return e.replace(/\/+/g,"/")}M.__esModule=!0,M.compilePattern=i,M.matchPattern=T,M.getParamNames=E,M.getParams=N,M.formatPattern=o;var n=t(8),C=I(n),c=Object.create(null)},function(A,M){"use strict";M.__esModule=!0;var t="PUSH";M.PUSH=t;var I="REPLACE";M.REPLACE=I;var g="POP";M.POP=g,M.default={PUSH:t,REPLACE:I,POP:g}},function(A,M,t){"use strict";function I(A,M){return(A&M)===M}var g=t(2),e={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(A){var M=e,t=A.Properties||{},i=A.DOMAttributeNamespaces||{},E=A.DOMAttributeNames||{},N=A.DOMPropertyNames||{},o=A.DOMMutationMethods||{};A.isCustomAttribute&&T._isCustomAttributeFunctions.push(A.isCustomAttribute);for(var n in t){T.properties.hasOwnProperty(n)?g(!1):void 0;var C=n.toLowerCase(),c=t[n],D={attributeName:C,attributeNamespace:null,propertyName:n,mutationMethod:null,mustUseAttribute:I(c,M.MUST_USE_ATTRIBUTE),mustUseProperty:I(c,M.MUST_USE_PROPERTY),hasSideEffects:I(c,M.HAS_SIDE_EFFECTS),hasBooleanValue:I(c,M.HAS_BOOLEAN_VALUE),hasNumericValue:I(c,M.HAS_NUMERIC_VALUE),hasPositiveNumericValue:I(c,M.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:I(c,M.HAS_OVERLOADED_BOOLEAN_VALUE)};if(D.mustUseAttribute&&D.mustUseProperty?g(!1):void 0,!D.mustUseProperty&&D.hasSideEffects?g(!1):void 0,D.hasBooleanValue+D.hasNumericValue+D.hasOverloadedBooleanValue<=1?void 0:g(!1),E.hasOwnProperty(n)){var a=E[n];D.attributeName=a}i.hasOwnProperty(n)&&(D.attributeNamespace=i[n]),N.hasOwnProperty(n)&&(D.propertyName=N[n]),o.hasOwnProperty(n)&&(D.mutationMethod=o[n]),T.properties[n]=D}}},i={},T={ID_ATTRIBUTE_NAME:"data-reactid",properties:{},getPossibleStandardName:null,_isCustomAttributeFunctions:[],isCustomAttribute:function(A){for(var M=0;M1){var M=A.indexOf(c,1);return M>-1?A.substr(0,M):A}return null},traverseEnterLeave:function(A,M,t,I,g){var e=N(A,M);e!==A&&o(A,e,t,I,!1,!0),e!==M&&o(e,M,t,g,!0,!1)},traverseTwoPhase:function(A,M,t){A&&(o("",A,M,t,!0,!1),o(A,"",M,t,!1,!0))},traverseTwoPhaseSkipTarget:function(A,M,t){A&&(o("",A,M,t,!0,!0),o(A,"",M,t,!0,!0))},traverseAncestors:function(A,M,t){o("",A,M,t,!0,!1)},getFirstCommonAncestorID:N,_getNextDescendantID:E,isAncestorIDOf:i,SEPARATOR:c};A.exports=B},function(A,M){var t=A.exports={version:"1.2.6"};"number"==typeof __e&&(__e=t)},function(A,M,t){"use strict";var I={};A.exports=I},function(A,M,t){"use strict";function I(A,M,t){var I=0;return n.default.Children.map(A,function(A){if(n.default.isValidElement(A)){var g=I;return I++,M.call(t,A,g)}return A})}function g(A,M,t){var I=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I),I++)})}function e(A){var M=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&M++}),M}function i(A){var M=!1;return n.default.Children.forEach(A,function(A){!M&&n.default.isValidElement(A)&&(M=!0)}),M}function T(A,M){var t=void 0;return g(A,function(I,g){!t&&M(I,g,A)&&(t=I)}),t}function E(A,M,t){var I=0,g=[];return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I)&&g.push(A),I++)}),g}var N=t(6).default;M.__esModule=!0;var o=t(1),n=N(o);M.default={map:I,forEach:g,numberOf:e,find:T,findValidComponents:E,hasValidComponent:i},A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=function(A){return(0,T.default)(e.default.findDOMNode(A))};var g=t(16),e=I(g),i=t(39),T=I(i);A.exports=M.default},function(A,M,t){"use strict";var I=t(204),g=t(437),e=t(217),i=t(226),T=t(227),E=t(2),N=(t(3),{}),o=null,n=function(A,M){A&&(g.executeDispatchesInOrder(A,M),A.isPersistent()||A.constructor.release(A))},C=function(A){return n(A,!0)},c=function(A){return n(A,!1)},D=null,a={injection:{injectMount:g.injection.injectMount,injectInstanceHandle:function(A){D=A},getInstanceHandle:function(){return D},injectEventPluginOrder:I.injectEventPluginOrder,injectEventPluginsByName:I.injectEventPluginsByName},eventNameDispatchConfigs:I.eventNameDispatchConfigs,registrationNameModules:I.registrationNameModules,putListener:function(A,M,t){"function"!=typeof t?E(!1):void 0;var g=N[M]||(N[M]={});g[A]=t;var e=I.registrationNameModules[M];e&&e.didPutListener&&e.didPutListener(A,M,t)},getListener:function(A,M){var t=N[M];return t&&t[A]},deleteListener:function(A,M){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M);var g=N[M];g&&delete g[A]},deleteAllListeners:function(A){for(var M in N)if(N[M][A]){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M),delete N[M][A]}},extractEvents:function(A,M,t,g,e){for(var T,E=I.plugins,N=0;N1?I-1:0),e=1;e":">","<":"<",'"':""","'":"'"},e=/[&><"']/g;A.exports=I},function(A,M,t){"use strict";var I=t(10),g=/^[ \r\n\t\f]/,e=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(A,M){A.innerHTML=M};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(A,M){MSApp.execUnsafeLocalFunction(function(){A.innerHTML=M})}),I.canUseDOM){var T=document.createElement("div");T.innerHTML=" ",""===T.innerHTML&&(i=function(A,M){if(A.parentNode&&A.parentNode.replaceChild(A,A),g.test(M)||"<"===M[0]&&e.test(M)){A.innerHTML=String.fromCharCode(65279)+M;var t=A.firstChild;1===t.data.length?A.removeChild(t):t.deleteData(0,1)}else A.innerHTML=M})}A.exports=i},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=function(A){var M=A.label,t=A.id,I=A.name,g=A.value,i=A.onChange,T=A.type,E=A.spellCheck,N=A.required,o=A.readonly,n=A.autoComplete,C=A.align,c=A.className,D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n});return o&&(D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n,disabled:!0})),e.default.createElement("div",{className:"input-group "+C+" "+c},D,e.default.createElement("i",{className:"ig-helpers"}),e.default.createElement("label",{className:"ig-label"},M))};M.default=i},function(A,M,t){A.exports={default:t(259),__esModule:!0}},function(A,M,t){var I=t(265),g=t(49),e=t(134),i="prototype",T=function(A,M,t){var E,N,o,n=A&T.F,C=A&T.G,c=A&T.S,D=A&T.P,a=A&T.B,B=A&T.W,Q=C?g:g[M]||(g[M]={}),r=C?I:c?I[M]:(I[M]||{})[i];C&&(t=M);for(E in t)N=!n&&r&&E in r,N&&E in Q||(o=N?r[E]:t[E],Q[E]=C&&"function"!=typeof r[E]?t[E]:a&&N?e(o,I):B&&r[E]==o?function(A){var M=function(M){return this instanceof A?new A(M):A(M)};return M[i]=A[i],M}(o):D&&"function"==typeof o?e(Function.call,o):o,D&&((Q[i]||(Q[i]={}))[E]=o))};T.F=1,T.G=2,T.S=4,T.P=8,T.B=16,T.W=32,A.exports=T},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M,t){"use strict";var I=t(32),g=function(){};I&&(g=function(){return document.addEventListener?function(A,M,t,I){return A.addEventListener(M,t,I||!1)}:document.attachEvent?function(A,M,t){return A.attachEvent("on"+M,t)}:void 0}()),A.exports=g},function(A,M,t){"use strict";var I=t(145),g=t(295),e=t(290),i=t(291),T=Object.prototype.hasOwnProperty;A.exports=function(A,M,t){var E="",N=M;if("string"==typeof M){if(void 0===t)return A.style[I(M)]||e(A).getPropertyValue(g(M));(N={})[M]=t}for(var o in N)T.call(N,o)&&(N[o]||0===N[o]?E+=g(o)+":"+N[o]+";":i(A,g(o)));A.style.cssText+=";"+E}},function(A,M,t){(function(){var t=this,I=t.humanize,g={};"undefined"!=typeof A&&A.exports&&(M=A.exports=g),M.humanize=g,g.noConflict=function(){return t.humanize=I,this},g.pad=function(A,M,t,I){if(A+="",t?t.length>1&&(t=t.charAt(0)):t=" ",I=void 0===I?"left":"right","right"===I)for(;A.length4&&A<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th"},w:function(){return t.getDay()},z:function(){return(o.L()?i[o.n()]:e[o.n()])+o.j()-1},W:function(){var A=o.z()-o.N()+1.5;return g.pad(1+Math.floor(Math.abs(A)/7)+(A%7>3.5?1:0),2,"0")},F:function(){return N[t.getMonth()]},m:function(){return g.pad(o.n(),2,"0")},M:function(){return o.F().slice(0,3)},n:function(){return t.getMonth()+1},t:function(){return new Date(o.Y(),o.n(),0).getDate()},L:function(){return 1===new Date(o.Y(),1,29).getMonth()?1:0},o:function(){var A=o.n(),M=o.W();return o.Y()+(12===A&&M<9?-1:1===A&&M>9)},Y:function(){return t.getFullYear()},y:function(){return String(o.Y()).slice(-2)},a:function(){return t.getHours()>11?"pm":"am"},A:function(){return o.a().toUpperCase()},B:function(){var A=t.getTime()/1e3,M=A%86400+3600;M<0&&(M+=86400);var I=M/86.4%1e3;return A<0?Math.ceil(I):Math.floor(I)},g:function(){return o.G()%12||12},G:function(){return t.getHours()},h:function(){return g.pad(o.g(),2,"0")},H:function(){return g.pad(o.G(),2,"0")},i:function(){return g.pad(t.getMinutes(),2,"0")},s:function(){return g.pad(t.getSeconds(),2,"0")},u:function(){return g.pad(1e3*t.getMilliseconds(),6,"0")},O:function(){var A=t.getTimezoneOffset(),M=Math.abs(A);return(A>0?"-":"+")+g.pad(100*Math.floor(M/60)+M%60,4,"0")},P:function(){var A=o.O();return A.substr(0,3)+":"+A.substr(3,2)},Z:function(){return 60*-t.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(I,T)},r:function(){return"D, d M Y H:i:s O".replace(I,T)},U:function(){return t.getTime()/1e3||0}};return A.replace(I,T)},g.numberFormat=function(A,M,t,I){M=isNaN(M)?2:Math.abs(M),t=void 0===t?".":t,I=void 0===I?",":I;var g=A<0?"-":"";A=Math.abs(+A||0);var e=parseInt(A.toFixed(M),10)+"",i=e.length>3?e.length%3:0;return g+(i?e.substr(0,i)+I:"")+e.substr(i).replace(/(\d{3})(?=\d)/g,"$1"+I)+(M?t+Math.abs(A-e).toFixed(M).slice(2):"")},g.naturalDay=function(A,M){A=void 0===A?g.time():A,M=void 0===M?"Y-m-d":M;var t=86400,I=new Date,e=new Date(I.getFullYear(),I.getMonth(),I.getDate()).getTime()/1e3;return A=e-t?"yesterday":A>=e&&A=e+t&&A-2)return(t>=0?"just ":"")+"now";if(t<60&&t>-60)return t>=0?Math.floor(t)+" seconds ago":"in "+Math.floor(-t)+" seconds";if(t<120&&t>-120)return t>=0?"about a minute ago":"in about a minute";if(t<3600&&t>-3600)return t>=0?Math.floor(t/60)+" minutes ago":"in "+Math.floor(-t/60)+" minutes";if(t<7200&&t>-7200)return t>=0?"about an hour ago":"in about an hour";if(t<86400&&t>-86400)return t>=0?Math.floor(t/3600)+" hours ago":"in "+Math.floor(-t/3600)+" hours";var I=172800;if(t-I)return t>=0?"1 day ago":"in 1 day";var e=2505600;if(t-e)return t>=0?Math.floor(t/86400)+" days ago":"in "+Math.floor(-t/86400)+" days";var i=5184e3;if(t-i)return t>=0?"about a month ago":"in about a month";var T=parseInt(g.date("Y",M),10),E=parseInt(g.date("Y",A),10),N=12*T+parseInt(g.date("n",M),10),o=12*E+parseInt(g.date("n",A),10),n=N-o;if(n<12&&n>-12)return n>=0?n+" months ago":"in "+-n+" months";var C=T-E;return C<2&&C>-2?C>=0?"a year ago":"in a year":C>=0?C+" years ago":"in "+-C+" years"},g.ordinal=function(A){A=parseInt(A,10),A=isNaN(A)?0:A;var M=A<0?"-":"";A=Math.abs(A);var t=A%100;return M+A+(t>4&&t<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th")},g.filesize=function(A,M,t,I,e,i){return M=void 0===M?1024:M,A<=0?"0 bytes":(A

    "),A=A.replace(/\n/g,"
    "),"

    "+A+"

    "},g.nl2br=function(A){return A.replace(/(\r\n|\n|\r)/g,"
    ")},g.truncatechars=function(A,M){return A.length<=M?A:A.substr(0,M)+"…"},g.truncatewords=function(A,M){var t=A.split(" ");return t.length0,Q=C.enumErrorProps&&(A===u||A instanceof Error),r=C.enumPrototypes&&T(A);++IM.documentElement.clientHeight;return{modalStyles:{paddingRight:I&&!g?Q.default():void 0,paddingLeft:!I&&g?Q.default():void 0}}}});X.Body=z.default,X.Header=U.default,X.Title=m.default,X.Footer=f.default,X.Dialog=h.default,X.TRANSITION_DURATION=300,X.BACKDROP_TRANSITION_DURATION=150,M.default=c.bsSizes([a.Sizes.LARGE,a.Sizes.SMALL],c.bsClass("modal",X)),A.exports=M.default},function(A,M,t){"use strict";var I=t(15).default,g=t(14).default,e=t(38).default,i=t(7).default,T=t(6).default;M.__esModule=!0;var E=t(1),N=T(E),o=t(5),n=T(o),C=t(11),c=T(C),D=t(44),a=T(D),B=function(A){function M(){g(this,M),A.apply(this,arguments)}return I(M,A),M.prototype.render=function(){var A=this.props,M=A["aria-label"],t=e(A,["aria-label"]),I=a.default(this.context.$bs_onModalHide,this.props.onHide);return N.default.createElement("div",i({},t,{className:n.default(this.props.className,c.default.prefix(this.props,"header"))}),this.props.closeButton&&N.default.createElement("button",{type:"button",className:"close","aria-label":M,onClick:I},N.default.createElement("span",{"aria-hidden":"true" -},"×")),this.props.children)},M}(N.default.Component);B.propTypes={"aria-label":N.default.PropTypes.string,bsClass:N.default.PropTypes.string,closeButton:N.default.PropTypes.bool,onHide:N.default.PropTypes.func},B.contextTypes={$bs_onModalHide:N.default.PropTypes.func},B.defaultProps={"aria-label":"Close",closeButton:!1},M.default=C.bsClass("modal",B),A.exports=M.default},function(A,M,t){"use strict";function I(A,M){return Array.isArray(M)?M.indexOf(A)>=0:A===M}var g=t(7).default,e=t(78).default,i=t(6).default;M.__esModule=!0;var T=t(40),E=i(T),N=t(170),o=i(N),n=t(1),C=i(n),c=t(16),D=i(c),a=t(127),B=(i(a),t(370)),Q=i(B),r=t(44),s=i(r),x=C.default.createClass({displayName:"OverlayTrigger",propTypes:g({},Q.default.propTypes,{trigger:C.default.PropTypes.oneOfType([C.default.PropTypes.oneOf(["click","hover","focus"]),C.default.PropTypes.arrayOf(C.default.PropTypes.oneOf(["click","hover","focus"]))]),delay:C.default.PropTypes.number,delayShow:C.default.PropTypes.number,delayHide:C.default.PropTypes.number,defaultOverlayShown:C.default.PropTypes.bool,overlay:C.default.PropTypes.node.isRequired,onBlur:C.default.PropTypes.func,onClick:C.default.PropTypes.func,onFocus:C.default.PropTypes.func,onMouseEnter:C.default.PropTypes.func,onMouseLeave:C.default.PropTypes.func,target:function(){},onHide:function(){},show:function(){}}),getDefaultProps:function(){return{defaultOverlayShown:!1,trigger:["hover","focus"]}},getInitialState:function(){return{isOverlayShown:this.props.defaultOverlayShown}},show:function(){this.setState({isOverlayShown:!0})},hide:function(){this.setState({isOverlayShown:!1})},toggle:function(){this.state.isOverlayShown?this.hide():this.show()},componentWillMount:function(){this.handleMouseOver=this.handleMouseOverOut.bind(null,this.handleDelayedShow),this.handleMouseOut=this.handleMouseOverOut.bind(null,this.handleDelayedHide)},componentDidMount:function(){this._mountNode=document.createElement("div"),this.renderOverlay()},renderOverlay:function(){D.default.unstable_renderSubtreeIntoContainer(this,this._overlay,this._mountNode)},componentWillUnmount:function(){D.default.unmountComponentAtNode(this._mountNode),this._mountNode=null,clearTimeout(this._hoverShowDelay),clearTimeout(this._hoverHideDelay)},componentDidUpdate:function(){this._mountNode&&this.renderOverlay()},getOverlayTarget:function(){return D.default.findDOMNode(this)},getOverlay:function(){var A=g({},o.default(this.props,e(Q.default.propTypes)),{show:this.state.isOverlayShown,onHide:this.hide,target:this.getOverlayTarget,onExit:this.props.onExit,onExiting:this.props.onExiting,onExited:this.props.onExited,onEnter:this.props.onEnter,onEntering:this.props.onEntering,onEntered:this.props.onEntered}),M=n.cloneElement(this.props.overlay,{placement:A.placement,container:A.container});return C.default.createElement(Q.default,A,M)},render:function(){var A=C.default.Children.only(this.props.children),M=A.props,t={"aria-describedby":this.props.overlay.props.id};return this._overlay=this.getOverlay(),t.onClick=s.default(M.onClick,this.props.onClick),I("click",this.props.trigger)&&(t.onClick=s.default(this.toggle,t.onClick)),I("hover",this.props.trigger)&&(t.onMouseOver=s.default(this.handleMouseOver,this.props.onMouseOver,M.onMouseOver),t.onMouseOut=s.default(this.handleMouseOut,this.props.onMouseOut,M.onMouseOut)),I("focus",this.props.trigger)&&(t.onFocus=s.default(this.handleDelayedShow,this.props.onFocus,M.onFocus),t.onBlur=s.default(this.handleDelayedHide,this.props.onBlur,M.onBlur)),n.cloneElement(A,t)},handleDelayedShow:function(){var A=this;if(null!=this._hoverHideDelay)return clearTimeout(this._hoverHideDelay),void(this._hoverHideDelay=null);if(!this.state.isOverlayShown&&null==this._hoverShowDelay){var M=null!=this.props.delayShow?this.props.delayShow:this.props.delay;return M?void(this._hoverShowDelay=setTimeout(function(){A._hoverShowDelay=null,A.show()},M)):void this.show()}},handleDelayedHide:function(){var A=this;if(null!=this._hoverShowDelay)return clearTimeout(this._hoverShowDelay),void(this._hoverShowDelay=null);if(this.state.isOverlayShown&&null==this._hoverHideDelay){var M=null!=this.props.delayHide?this.props.delayHide:this.props.delay;return M?void(this._hoverHideDelay=setTimeout(function(){A._hoverHideDelay=null,A.hide()},M)):void this.hide()}},handleMouseOverOut:function(A,M){var t=M.currentTarget,I=M.relatedTarget||M.nativeEvent.toElement;I&&(I===t||E.default(t,I))||A(M)}});M.default=x,A.exports=M.default},function(A,M,t){"use strict";var I=t(7).default,g=t(6).default;M.__esModule=!0;var e=t(1),i=g(e),T=t(5),E=g(T),N=t(11),o=g(N),n=t(183),C=g(n),c=i.default.createClass({displayName:"Tooltip",propTypes:{id:C.default(i.default.PropTypes.oneOfType([i.default.PropTypes.string,i.default.PropTypes.number])),placement:i.default.PropTypes.oneOf(["top","right","bottom","left"]),positionLeft:i.default.PropTypes.number,positionTop:i.default.PropTypes.number,arrowOffsetLeft:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),arrowOffsetTop:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),title:i.default.PropTypes.node},getDefaultProps:function(){return{bsClass:"tooltip",placement:"right"}},render:function(){var A,M=(A={},A[o.default.prefix(this.props)]=!0,A[this.props.placement]=!0,A),t=I({left:this.props.positionLeft,top:this.props.positionTop},this.props.style),g={left:this.props.arrowOffsetLeft,top:this.props.arrowOffsetTop};return i.default.createElement("div",I({role:"tooltip"},this.props,{className:E.default(this.props.className,M),style:t}),i.default.createElement("div",{className:o.default.prefix(this.props,"arrow"),style:g}),i.default.createElement("div",{className:o.default.prefix(this.props,"inner")},this.props.children))}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return A="function"==typeof A?A():A,i.default.findDOMNode(A)||M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=g;var e=t(16),i=I(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement. You can usually obtain a ReactComponent or DOMElement from a ReactElement by attaching a ref to it."):"object"===E&&"function"==typeof i.render||1===i.nodeType?null:new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement.")}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M,t){"use strict";function I(){function A(A,M,I){for(var g=0;g>",null!=t[I]?A(t,I,g):M?new Error("Required prop '"+I+"' was not specified in '"+g+"'."):void 0}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}M.__esModule=!0,M.errMsg=t,M.createChainableTypeChecker=I},function(A,M){"use strict";function t(A,M,t){function I(){return i=!0,T?void(N=[].concat(Array.prototype.slice.call(arguments))):void t.apply(this,arguments)}function g(){if(!i&&(E=!0,!T)){for(T=!0;!i&&e=A&&E&&(i=!0,t()))}}var e=0,i=!1,T=!1,E=!1,N=void 0;g()}function I(A,M,t){function I(A,M,I){i||(M?(i=!0,t(M)):(e[A]=I,i=++T===g,i&&t(null,e)))}var g=A.length,e=[];if(0===g)return t(null,e);var i=!1,T=0;A.forEach(function(A,t){M(A,t,function(A,M){I(t,A,M)})})}M.__esModule=!0,M.loopAsync=t,M.mapAsync=I},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0,M.router=M.routes=M.route=M.components=M.component=M.location=M.history=M.falsy=M.locationShape=M.routerShape=void 0;var e=t(1),i=t(66),T=(g(i),t(34)),E=I(T),N=t(9),o=(g(N),e.PropTypes.func),n=e.PropTypes.object,C=e.PropTypes.shape,c=e.PropTypes.string,D=M.routerShape=C({push:o.isRequired,replace:o.isRequired,go:o.isRequired,goBack:o.isRequired,goForward:o.isRequired,setRouteLeaveHook:o.isRequired,isActive:o.isRequired}),a=M.locationShape=C({pathname:c.isRequired,search:c.isRequired,state:n,action:c.isRequired,key:c}),B=M.falsy=E.falsy,Q=M.history=E.history,r=M.location=a,s=M.component=E.component,x=M.components=E.components,j=M.route=E.route,y=(M.routes=E.routes,M.router=D),u={falsy:B,history:Q,location:r,component:s,components:x,route:j,router:y};M.default=u},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!0;return!1}function e(A,M){function t(M){var t=!(arguments.length<=1||void 0===arguments[1])&&arguments[1],I=arguments.length<=2||void 0===arguments[2]?null:arguments[2],g=void 0;return t&&t!==!0||null!==I?(M={pathname:M,query:t},g=I||!1):(M=A.createLocation(M),g=t),(0,C.default)(M,g,s.location,s.routes,s.params)}function I(A,t){x&&x.location===A?e(x,t):(0,B.default)(M,A,function(M,I){M?t(M):I?e(i({},I,{location:A}),t):t()})}function e(A,M){function t(t,g){return t||g?I(t,g):void(0,D.default)(A,function(t,I){t?M(t):M(null,null,s=i({},A,{components:I}))})}function I(A,t){A?M(A):M(null,t)}var g=(0,N.default)(s,A),e=g.leaveRoutes,T=g.changeRoutes,E=g.enterRoutes;(0,o.runLeaveHooks)(e,s),e.filter(function(A){return E.indexOf(A)===-1}).forEach(a),(0,o.runChangeHooks)(T,s,A,function(M,g){return M||g?I(M,g):void(0,o.runEnterHooks)(E,A,t)})}function T(A){var M=arguments.length<=1||void 0===arguments[1]||arguments[1];return A.__id__||M&&(A.__id__=j++)}function E(A){return A.reduce(function(A,M){return A.push.apply(A,y[T(M)]),A},[])}function n(A,t){(0,B.default)(M,A,function(M,I){if(null==I)return void t();x=i({},I,{location:A});for(var g=E((0,N.default)(s,x).leaveRoutes),e=void 0,T=0,o=g.length;null==e&&T=32||13===M?M:0}A.exports=t},function(A,M){"use strict";function t(A){var M=this,t=M.nativeEvent;if(t.getModifierState)return t.getModifierState(A);var I=g[A];return!!I&&!!t[I]}function I(A){return t}var g={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};A.exports=I},function(A,M){"use strict";function t(A){var M=A.target||A.srcElement||window;return 3===M.nodeType?M.parentNode:M}A.exports=t},function(A,M){"use strict";function t(A){var M=A&&(I&&A[I]||A[g]);if("function"==typeof M)return M}var I="function"==typeof Symbol&&Symbol.iterator,g="@@iterator";A.exports=t},function(A,M,t){"use strict";function I(A){return"function"==typeof A&&"undefined"!=typeof A.prototype&&"function"==typeof A.prototype.mountComponent&&"function"==typeof A.prototype.receiveComponent}function g(A){var M;if(null===A||A===!1)M=new i(g);else if("object"==typeof A){var t=A;!t||"function"!=typeof t.type&&"string"!=typeof t.type?N(!1):void 0,M="string"==typeof t.type?T.createInternalComponent(t):I(t.type)?new t.type(t):new o}else"string"==typeof A||"number"==typeof A?M=T.createInstanceForText(A):N(!1);return M.construct(A),M._mountIndex=0,M._mountImage=null,M}var e=t(443),i=t(215),T=t(221),E=t(4),N=t(2),o=(t(3),function(){});E(o.prototype,e.Mixin,{_instantiateReactComponent:g}),A.exports=g},function(A,M,t){"use strict";/** +!function(){"use strict";function t(){for(var A=[],M=0;M2?t-2:0),g=2;g1){for(var c=Array(C),D=0;D1){for(var a=Array(D),B=0;B3&&void 0!==arguments[3]?arguments[3]:{},N=Boolean(A),C=A||w,D=void 0;D="function"==typeof M?M:M?(0,Q.default)(M):l;var B=t||L,r=I.pure,s=void 0===r||r,x=I.withRef,y=void 0!==x&&x,h=s&&B!==L,S=d++;return function(A){function M(A,M,t){var I=B(A,M,t);return I}var t="Connect("+T(A)+")",I=function(I){function T(A,M){g(this,T);var i=e(this,I.call(this,A,M));i.version=S,i.store=A.store||M.store,(0,u.default)(i.store,'Could not find "store" in either the context or '+('props of "'+t+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+t+'".'));var E=i.store.getState();return i.state={storeState:E},i.clearCache(),i}return i(T,I),T.prototype.shouldComponentUpdate=function(){return!s||this.haveOwnPropsChanged||this.hasStoreStateChanged},T.prototype.computeStateProps=function(A,M){if(!this.finalMapStateToProps)return this.configureFinalMapState(A,M);var t=A.getState(),I=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(t,M):this.finalMapStateToProps(t);return I},T.prototype.configureFinalMapState=function(A,M){var t=C(A.getState(),M),I="function"==typeof t;return this.finalMapStateToProps=I?t:C,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,I?this.computeStateProps(A,M):t},T.prototype.computeDispatchProps=function(A,M){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(A,M);var t=A.dispatch,I=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(t,M):this.finalMapDispatchToProps(t);return I},T.prototype.configureFinalMapDispatch=function(A,M){var t=D(A.dispatch,M),I="function"==typeof t;return this.finalMapDispatchToProps=I?t:D,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,I?this.computeDispatchProps(A,M):t},T.prototype.updateStatePropsIfNeeded=function(){var A=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,a.default)(A,this.stateProps))&&(this.stateProps=A,!0)},T.prototype.updateDispatchPropsIfNeeded=function(){var A=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,a.default)(A,this.dispatchProps))&&(this.dispatchProps=A,!0)},T.prototype.updateMergedPropsIfNeeded=function(){var A=M(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&h&&(0,a.default)(A,this.mergedProps))&&(this.mergedProps=A,!0)},T.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},T.prototype.trySubscribe=function(){N&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},T.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},T.prototype.componentDidMount=function(){this.trySubscribe()},T.prototype.componentWillReceiveProps=function(A){s&&(0,a.default)(A,this.props)||(this.haveOwnPropsChanged=!0)},T.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},T.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},T.prototype.handleChange=function(){if(this.unsubscribe){var A=this.store.getState(),M=this.state.storeState;if(!s||M!==A){if(s&&!this.doStatePropsDependOnOwnProps){var t=E(this.updateStatePropsIfNeeded,this);if(!t)return;t===Y&&(this.statePropsPrecalculationError=Y.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:A})}}},T.prototype.getWrappedInstance=function(){return(0,u.default)(y,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},T.prototype.render=function(){var M=this.haveOwnPropsChanged,t=this.hasStoreStateChanged,I=this.haveStatePropsBeenPrecalculated,g=this.statePropsPrecalculationError,e=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,g)throw g;var i=!0,T=!0;s&&e&&(i=t||M&&this.doStatePropsDependOnOwnProps,T=M&&this.doDispatchPropsDependOnOwnProps);var E=!1,N=!1;I?E=!0:i&&(E=this.updateStatePropsIfNeeded()),T&&(N=this.updateDispatchPropsIfNeeded());var C=!0;return C=!!(E||N||M)&&this.updateMergedPropsIfNeeded(),!C&&e?e:(y?this.renderedElement=(0,n.createElement)(A,o({},this.mergedProps,{ref:"wrappedInstance"})):this.renderedElement=(0,n.createElement)(A,this.mergedProps),this.renderedElement)},T}(n.Component);return I.displayName=t,I.WrappedComponent=A,I.contextTypes={store:c.default},I.propTypes={store:c.default},(0,j.default)(I,A)}}M.__esModule=!0;var o=Object.assign||function(A){for(var M=1;M should not have a "'+M+'" prop')}M.__esModule=!0,M.routes=M.route=M.components=M.component=M.history=void 0,M.falsy=I;var g=t(1),e=g.PropTypes.func,i=g.PropTypes.object,T=g.PropTypes.arrayOf,E=g.PropTypes.oneOfType,N=g.PropTypes.element,o=g.PropTypes.shape,n=g.PropTypes.string,C=(M.history=o({listen:e.isRequired,push:e.isRequired,replace:e.isRequired,go:e.isRequired,goBack:e.isRequired,goForward:e.isRequired}),M.component=E([e,n])),c=(M.components=E([C,i]),M.route=E([i,N]));M.routes=E([c,T(c)])},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){var M=A.match(/^https?:\/\/[^\/]*/);return null==M?A:A.substring(M[0].length)}function e(A){var M=g(A),t="",I="",e=M.indexOf("#");e!==-1&&(I=M.substring(e),M=M.substring(0,e));var i=M.indexOf("?");return i!==-1&&(t=M.substring(i),M=M.substring(0,i)),""===M&&(M="/"),{pathname:M,search:t,hash:I}}M.__esModule=!0,M.extractPath=g,M.parsePath=e;var i=t(23);I(i)},function(A,M,t){"use strict";function I(){g.attachRefs(this,this._currentElement)}var g=t(459),e={mountComponent:function(A,M,t,g){var e=A.mountComponent(M,t,g);return A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A),e},unmountComponent:function(A){g.detachRefs(A,A._currentElement),A.unmountComponent()},receiveComponent:function(A,M,t,e){var i=A._currentElement;if(M!==i||e!==A._context){var T=g.shouldUpdateRefs(i,M);T&&g.detachRefs(A,i),A.receiveComponent(M,t,e),T&&A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A)}},performUpdateIfNecessary:function(A,M){A.performUpdateIfNecessary(M)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t,I){this.dispatchConfig=A,this.dispatchMarker=M,this.nativeEvent=t;var g=this.constructor.Interface;for(var e in g)if(g.hasOwnProperty(e)){var T=g[e];T?this[e]=T(t):"target"===e?this.target=I:this[e]=t[e]}var E=null!=t.defaultPrevented?t.defaultPrevented:t.returnValue===!1;E?this.isDefaultPrevented=i.thatReturnsTrue:this.isDefaultPrevented=i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse}var g=t(31),e=t(4),i=t(20),T=(t(3),{type:null,target:null,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(A){return A.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null});e(I.prototype,{preventDefault:function(){this.defaultPrevented=!0;var A=this.nativeEvent;A&&(A.preventDefault?A.preventDefault():A.returnValue=!1,this.isDefaultPrevented=i.thatReturnsTrue)},stopPropagation:function(){var A=this.nativeEvent;A&&(A.stopPropagation?A.stopPropagation():A.cancelBubble=!0,this.isPropagationStopped=i.thatReturnsTrue)},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var A=this.constructor.Interface;for(var M in A)this[M]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),I.Interface=T,I.augmentClass=function(A,M){var t=this,I=Object.create(t.prototype);e(I,A.prototype),A.prototype=I,A.prototype.constructor=A,A.Interface=e({},t.Interface,M),A.augmentClass=t.augmentClass,g.addPoolingTo(A,g.fourArgumentPooler)},g.addPoolingTo(I,g.fourArgumentPooler),A.exports=I},function(A,M){"use strict";M.default=function(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t},M.__esModule=!0},function(A,M){"use strict";function t(A){return A&&A.ownerDocument||document}M.__esModule=!0,M.default=t,A.exports=M.default},function(A,M,t){"use strict";var I=t(32),g=function(){var A=I&&document.documentElement;return A&&A.contains?function(A,M){return A.contains(M)}:A&&A.compareDocumentPosition?function(A,M){return A===M||!!(16&A.compareDocumentPosition(M))}:function(A,M){if(M)do if(M===A)return!0;while(M=M.parentNode);return!1}}();A.exports=g},function(A,M){function t(A){return"number"==typeof A&&A>-1&&A%1==0&&A<=I}var I=9007199254740991;A.exports=t},function(A,M,t){(function(A){!function(M,t){A.exports=t()}(this,function(){"use strict";function M(){return aI.apply(null,arguments)}function t(A){aI=A}function I(A){return A instanceof Array||"[object Array]"===Object.prototype.toString.call(A)}function g(A){return null!=A&&"[object Object]"===Object.prototype.toString.call(A)}function e(A){var M;for(M in A)return!1;return!0}function i(A){return"number"==typeof A||"[object Number]"===Object.prototype.toString.call(A)}function T(A){return A instanceof Date||"[object Date]"===Object.prototype.toString.call(A)}function E(A,M){var t,I=[];for(t=0;t0)for(t in rI)I=rI[t],g=M[I],B(g)||(A[I]=g);return A}function r(A){Q(this,A),this._d=new Date(null!=A._d?A._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),sI===!1&&(sI=!0,M.updateOffset(this),sI=!1)}function s(A){return A instanceof r||null!=A&&null!=A._isAMomentObject}function x(A){return A<0?Math.ceil(A)||0:Math.floor(A)}function j(A){var M=+A,t=0;return 0!==M&&isFinite(M)&&(t=x(M)),t}function y(A,M,t){var I,g=Math.min(A.length,M.length),e=Math.abs(A.length-M.length),i=0;for(I=0;I0?"future":"past"];return L(t)?t(M):t.replace(/%s/i,M)}function F(A,M){var t=A.toLowerCase();SI[t]=SI[t+"s"]=SI[M]=A}function f(A){return"string"==typeof A?SI[A]||SI[A.toLowerCase()]:void 0}function k(A){var M,t,I={};for(t in A)N(A,t)&&(M=f(t),M&&(I[M]=A[t]));return I}function R(A,M){zI[A]=M}function J(A){var M=[];for(var t in A)M.push({unit:t,priority:zI[t]});return M.sort(function(A,M){return A.priority-M.priority}),M}function G(A,t){return function(I){return null!=I?(b(this,A,I),M.updateOffset(this,t),this):H(this,A)}}function H(A,M){return A.isValid()?A._d["get"+(A._isUTC?"UTC":"")+M]():NaN}function b(A,M,t){A.isValid()&&A._d["set"+(A._isUTC?"UTC":"")+M](t)}function v(A){return A=f(A),L(this[A])?this[A]():this}function X(A,M){if("object"==typeof A){A=k(A);for(var t=J(A),I=0;I=0;return(e?t?"+":"":"-")+Math.pow(10,Math.max(0,g)).toString().substr(1)+I}function V(A,M,t,I){var g=I;"string"==typeof I&&(g=function(){return this[I]()}),A&&(mI[A]=g),M&&(mI[M[0]]=function(){return W(g.apply(this,arguments),M[1],M[2])}),t&&(mI[t]=function(){return this.localeData().ordinal(g.apply(this,arguments),A)})}function P(A){return A.match(/\[[\s\S]/)?A.replace(/^\[|\]$/g,""):A.replace(/\\/g,"")}function Z(A){var M,t,I=A.match(pI);for(M=0,t=I.length;M=0&&UI.test(A);)A=A.replace(UI,t),UI.lastIndex=0,I-=1;return A}function _(A,M,t){$I[A]=L(M)?M:function(A,I){return A&&t?t:M}}function $(A,M){return N($I,A)?$I[A](M._strict,M._locale):new RegExp(AA(A))}function AA(A){return MA(A.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(A,M,t,I,g){return M||t||I||g}))}function MA(A){return A.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tA(A,M){var t,I=M;for("string"==typeof A&&(A=[A]),i(M)&&(I=function(A,t){t[M]=j(A)}),t=0;t=0&&isFinite(T.getFullYear())&&T.setFullYear(A),T}function xA(A){var M=new Date(Date.UTC.apply(null,arguments));return A<100&&A>=0&&isFinite(M.getUTCFullYear())&&M.setUTCFullYear(A),M}function jA(A,M,t){var I=7+M-t,g=(7+xA(A,0,I).getUTCDay()-M)%7;return-g+I-1}function yA(A,M,t,I,g){var e,i,T=(7+t-I)%7,E=jA(A,I,g),N=1+7*(M-1)+T+E;return N<=0?(e=A-1,i=BA(e)+N):N>BA(A)?(e=A+1,i=N-BA(A)):(e=A,i=N),{year:e,dayOfYear:i}}function uA(A,M,t){var I,g,e=jA(A.year(),M,t),i=Math.floor((A.dayOfYear()-e-1)/7)+1;return i<1?(g=A.year()-1,I=i+wA(g,M,t)):i>wA(A.year(),M,t)?(I=i-wA(A.year(),M,t),g=A.year()+1):(g=A.year(),I=i),{week:I,year:g}}function wA(A,M,t){var I=jA(A,M,t),g=jA(A+1,M,t);return(BA(A)-I+g)/7}function lA(A){return uA(A,this._week.dow,this._week.doy).week}function LA(){return this._week.dow}function YA(){return this._week.doy}function dA(A){var M=this.localeData().week(this);return null==A?M:this.add(7*(A-M),"d")}function hA(A){var M=uA(this,1,4).week;return null==A?M:this.add(7*(A-M),"d")}function SA(A,M){return"string"!=typeof A?A:isNaN(A)?(A=M.weekdaysParse(A),"number"==typeof A?A:null):parseInt(A,10)}function zA(A,M){return"string"==typeof A?M.weekdaysParse(A)%7||7:isNaN(A)?null:A}function pA(A,M){return A?I(this._weekdays)?this._weekdays[A.day()]:this._weekdays[this._weekdays.isFormat.test(M)?"format":"standalone"][A.day()]:this._weekdays}function UA(A){return A?this._weekdaysShort[A.day()]:this._weekdaysShort}function OA(A){return A?this._weekdaysMin[A.day()]:this._weekdaysMin}function mA(A,M,t){var I,g,e,i=A.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],I=0;I<7;++I)e=n([2e3,1]).day(I),this._minWeekdaysParse[I]=this.weekdaysMin(e,"").toLocaleLowerCase(),this._shortWeekdaysParse[I]=this.weekdaysShort(e,"").toLocaleLowerCase(),this._weekdaysParse[I]=this.weekdays(e,"").toLocaleLowerCase();return t?"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:null):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null):"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null)))}function FA(A,M,t){var I,g,e;if(this._weekdaysParseExact)return mA.call(this,A,M,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),I=0;I<7;I++){if(g=n([2e3,1]).day(I),t&&!this._fullWeekdaysParse[I]&&(this._fullWeekdaysParse[I]=new RegExp("^"+this.weekdays(g,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[I]=new RegExp("^"+this.weekdaysShort(g,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[I]=new RegExp("^"+this.weekdaysMin(g,"").replace(".",".?")+"$","i")),this._weekdaysParse[I]||(e="^"+this.weekdays(g,"")+"|^"+this.weekdaysShort(g,"")+"|^"+this.weekdaysMin(g,""),this._weekdaysParse[I]=new RegExp(e.replace(".",""),"i")),t&&"dddd"===M&&this._fullWeekdaysParse[I].test(A))return I;if(t&&"ddd"===M&&this._shortWeekdaysParse[I].test(A))return I;if(t&&"dd"===M&&this._minWeekdaysParse[I].test(A))return I;if(!t&&this._weekdaysParse[I].test(A))return I}}function fA(A){if(!this.isValid())return null!=A?this:NaN;var M=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=A?(A=SA(A,this.localeData()),this.add(A-M,"d")):M}function kA(A){if(!this.isValid())return null!=A?this:NaN;var M=(this.day()+7-this.localeData()._week.dow)%7;return null==A?M:this.add(A-M,"d")}function RA(A){if(!this.isValid())return null!=A?this:NaN;if(null!=A){var M=zA(A,this.localeData());return this.day(this.day()%7?M:M-7)}return this.day()||7}function JA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysStrictRegex:this._weekdaysRegex):(N(this,"_weekdaysRegex")||(this._weekdaysRegex=jg),this._weekdaysStrictRegex&&A?this._weekdaysStrictRegex:this._weekdaysRegex)}function GA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(N(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=yg),this._weekdaysShortStrictRegex&&A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function HA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(N(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ug),this._weekdaysMinStrictRegex&&A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function bA(){function A(A,M){return M.length-A.length}var M,t,I,g,e,i=[],T=[],E=[],N=[];for(M=0;M<7;M++)t=n([2e3,1]).day(M),I=this.weekdaysMin(t,""),g=this.weekdaysShort(t,""),e=this.weekdays(t,""),i.push(I),T.push(g),E.push(e),N.push(I),N.push(g),N.push(e);for(i.sort(A),T.sort(A),E.sort(A),N.sort(A),M=0;M<7;M++)T[M]=MA(T[M]),E[M]=MA(E[M]),N[M]=MA(N[M]);this._weekdaysRegex=new RegExp("^("+N.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+E.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+T.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function vA(){return this.hours()%12||12}function XA(){return this.hours()||24}function WA(A,M){V(A,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),M)})}function VA(A,M){return M._meridiemParse}function PA(A){return"p"===(A+"").toLowerCase().charAt(0)}function ZA(A,M,t){return A>11?t?"pm":"PM":t?"am":"AM"}function KA(A){return A?A.toLowerCase().replace("_","-"):A}function qA(A){for(var M,t,I,g,e=0;e0;){if(I=_A(g.slice(0,M).join("-")))return I;if(t&&t.length>=M&&y(g,t,!0)>=M-1)break;M--}e++}return null}function _A(M){var t=null;if(!dg[M]&&"undefined"!=typeof A&&A&&A.exports)try{t=wg._abbr,!function(){var A=new Error('Cannot find module "./locale"');throw A.code="MODULE_NOT_FOUND",A}(),$A(t)}catch(A){}return dg[M]}function $A(A,M){var t;return A&&(t=B(M)?tM(A):AM(A,M),t&&(wg=t)),wg._abbr}function AM(A,M){if(null!==M){var t=Yg;if(M.abbr=A,null!=dg[A])l("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),t=dg[A]._config;else if(null!=M.parentLocale){if(null==dg[M.parentLocale])return hg[M.parentLocale]||(hg[M.parentLocale]=[]),hg[M.parentLocale].push({name:A,config:M}),null;t=dg[M.parentLocale]._config}return dg[A]=new h(d(t,M)),hg[A]&&hg[A].forEach(function(A){AM(A.name,A.config)}),$A(A),dg[A]}return delete dg[A],null}function MM(A,M){if(null!=M){var t,I=Yg;null!=dg[A]&&(I=dg[A]._config),M=d(I,M),t=new h(M),t.parentLocale=dg[A],dg[A]=t,$A(A)}else null!=dg[A]&&(null!=dg[A].parentLocale?dg[A]=dg[A].parentLocale:null!=dg[A]&&delete dg[A]);return dg[A]}function tM(A){var M;if(A&&A._locale&&A._locale._abbr&&(A=A._locale._abbr),!A)return wg;if(!I(A)){if(M=_A(A))return M;A=[A]}return qA(A)}function IM(){return uI(dg)}function gM(A){var M,t=A._a;return t&&c(A).overflow===-2&&(M=t[tg]<0||t[tg]>11?tg:t[Ig]<1||t[Ig]>eA(t[Mg],t[tg])?Ig:t[gg]<0||t[gg]>24||24===t[gg]&&(0!==t[eg]||0!==t[ig]||0!==t[Tg])?gg:t[eg]<0||t[eg]>59?eg:t[ig]<0||t[ig]>59?ig:t[Tg]<0||t[Tg]>999?Tg:-1,c(A)._overflowDayOfYear&&(MIg)&&(M=Ig),c(A)._overflowWeeks&&M===-1&&(M=Eg),c(A)._overflowWeekday&&M===-1&&(M=Ng),c(A).overflow=M),A}function eM(A){var M,t,I,g,e,i,T=A._i,E=Sg.exec(T)||zg.exec(T);if(E){for(c(A).iso=!0,M=0,t=Ug.length;MBA(g)&&(c(A)._overflowDayOfYear=!0),t=xA(g,0,A._dayOfYear),A._a[tg]=t.getUTCMonth(),A._a[Ig]=t.getUTCDate()),M=0;M<3&&null==A._a[M];++M)A._a[M]=e[M]=I[M];for(;M<7;M++)A._a[M]=e[M]=null==A._a[M]?2===M?1:0:A._a[M];24===A._a[gg]&&0===A._a[eg]&&0===A._a[ig]&&0===A._a[Tg]&&(A._nextDay=!0,A._a[gg]=0),A._d=(A._useUTC?xA:sA).apply(null,e),null!=A._tzm&&A._d.setUTCMinutes(A._d.getUTCMinutes()-A._tzm),A._nextDay&&(A._a[gg]=24)}}function oM(A){var M,t,I,g,e,i,T,E;if(M=A._w,null!=M.GG||null!=M.W||null!=M.E)e=1,i=4,t=TM(M.GG,A._a[Mg],uA(sM(),1,4).year),I=TM(M.W,1),g=TM(M.E,1),(g<1||g>7)&&(E=!0);else{e=A._locale._week.dow,i=A._locale._week.doy;var N=uA(sM(),e,i);t=TM(M.gg,A._a[Mg],N.year),I=TM(M.w,N.week),null!=M.d?(g=M.d,(g<0||g>6)&&(E=!0)):null!=M.e?(g=M.e+e,(M.e<0||M.e>6)&&(E=!0)):g=e}I<1||I>wA(t,e,i)?c(A)._overflowWeeks=!0:null!=E?c(A)._overflowWeekday=!0:(T=yA(t,I,g,e,i),A._a[Mg]=T.year,A._dayOfYear=T.dayOfYear)}function nM(A){if(A._f===M.ISO_8601)return void eM(A);A._a=[],c(A).empty=!0;var t,I,g,e,i,T=""+A._i,E=T.length,N=0;for(g=q(A._f,A._locale).match(pI)||[],t=0;t0&&c(A).unusedInput.push(i),T=T.slice(T.indexOf(I)+I.length),N+=I.length),mI[e]?(I?c(A).empty=!1:c(A).unusedTokens.push(e),gA(e,I,A)):A._strict&&!I&&c(A).unusedTokens.push(e);c(A).charsLeftOver=E-N,T.length>0&&c(A).unusedInput.push(T),A._a[gg]<=12&&c(A).bigHour===!0&&A._a[gg]>0&&(c(A).bigHour=void 0),c(A).parsedDateParts=A._a.slice(0),c(A).meridiem=A._meridiem,A._a[gg]=CM(A._locale,A._a[gg],A._meridiem),NM(A),gM(A)}function CM(A,M,t){var I;return null==t?M:null!=A.meridiemHour?A.meridiemHour(M,t):null!=A.isPM?(I=A.isPM(t),I&&M<12&&(M+=12),I||12!==M||(M=0),M):M}function cM(A){var M,t,I,g,e;if(0===A._f.length)return c(A).invalidFormat=!0,void(A._d=new Date(NaN));for(g=0;gthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function fM(){if(!B(this._isDSTShifted))return this._isDSTShifted;var A={};if(Q(A,this),A=BM(A),A._a){var M=A._isUTC?n(A._a):sM(A._a);this._isDSTShifted=this.isValid()&&y(A._a,M.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function kM(){return!!this.isValid()&&!this._isUTC}function RM(){return!!this.isValid()&&this._isUTC}function JM(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function GM(A,M){var t,I,g,e=A,T=null;return wM(A)?e={ms:A._milliseconds,d:A._days,M:A._months}:i(A)?(e={},M?e[M]=A:e.milliseconds=A):(T=Jg.exec(A))?(t="-"===T[1]?-1:1,e={y:0,d:j(T[Ig])*t,h:j(T[gg])*t,m:j(T[eg])*t,s:j(T[ig])*t,ms:j(lM(1e3*T[Tg]))*t}):(T=Gg.exec(A))?(t="-"===T[1]?-1:1,e={y:HM(T[2],t),M:HM(T[3],t),w:HM(T[4],t),d:HM(T[5],t),h:HM(T[6],t),m:HM(T[7],t),s:HM(T[8],t)}):null==e?e={}:"object"==typeof e&&("from"in e||"to"in e)&&(g=vM(sM(e.from),sM(e.to)),e={},e.ms=g.milliseconds,e.M=g.months),I=new uM(e),wM(A)&&N(A,"_locale")&&(I._locale=A._locale),I}function HM(A,M){var t=A&&parseFloat(A.replace(",","."));return(isNaN(t)?0:t)*M}function bM(A,M){var t={milliseconds:0,months:0};return t.months=M.month()-A.month()+12*(M.year()-A.year()),A.clone().add(t.months,"M").isAfter(M)&&--t.months,t.milliseconds=+M-+A.clone().add(t.months,"M"),t}function vM(A,M){var t;return A.isValid()&&M.isValid()?(M=dM(M,A),A.isBefore(M)?t=bM(A,M):(t=bM(M,A),t.milliseconds=-t.milliseconds,t.months=-t.months),t):{milliseconds:0,months:0}}function XM(A,M){return function(t,I){var g,e;return null===I||isNaN(+I)||(l(M,"moment()."+M+"(period, number) is deprecated. Please use moment()."+M+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),e=t,t=I,I=e),t="string"==typeof t?+t:t,g=GM(t,I),WM(this,g,A),this}}function WM(A,t,I,g){var e=t._milliseconds,i=lM(t._days),T=lM(t._months);A.isValid()&&(g=null==g||g,e&&A._d.setTime(A._d.valueOf()+e*I),i&&b(A,"Date",H(A,"Date")+i*I),T&&oA(A,H(A,"Month")+T*I),g&&M.updateOffset(A,i||T))}function VM(A,M){var t=A.diff(M,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"}function PM(A,t){var I=A||sM(),g=dM(I,this).startOf("day"),e=M.calendarFormat(this,g)||"sameElse",i=t&&(L(t[e])?t[e].call(this,I):t[e]);return this.format(i||this.localeData().calendar(e,this,sM(I)))}function ZM(){return new r(this)}function KM(A,M){var t=s(A)?A:sM(A);return!(!this.isValid()||!t.isValid())&&(M=f(B(M)?"millisecond":M),"millisecond"===M?this.valueOf()>t.valueOf():t.valueOf()e&&(M=e),pt.call(this,A,M,t,I,g))}function pt(A,M,t,I,g){var e=yA(A,M,t,I,g),i=xA(e.year,0,e.dayOfYear);return this.year(i.getUTCFullYear()),this.month(i.getUTCMonth()),this.date(i.getUTCDate()),this}function Ut(A){return null==A?Math.ceil((this.month()+1)/3):this.month(3*(A-1)+this.month()%3)}function Ot(A){var M=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==A?M:this.add(A-M,"d")}function mt(A,M){M[Tg]=j(1e3*("0."+A))}function Ft(){return this._isUTC?"UTC":""}function ft(){return this._isUTC?"Coordinated Universal Time":""}function kt(A){return sM(1e3*A)}function Rt(){return sM.apply(null,arguments).parseZone()}function Jt(A){return A}function Gt(A,M,t,I){var g=tM(),e=n().set(I,M);return g[t](e,A)}function Ht(A,M,t){if(i(A)&&(M=A,A=void 0),A=A||"",null!=M)return Gt(A,M,t,"month");var I,g=[];for(I=0;I<12;I++)g[I]=Gt(A,I,t,"month");return g}function bt(A,M,t,I){"boolean"==typeof A?(i(M)&&(t=M,M=void 0),M=M||""):(M=A,t=M,A=!1,i(M)&&(t=M,M=void 0),M=M||"");var g=tM(),e=A?g._week.dow:0;if(null!=t)return Gt(M,(t+e)%7,I,"day");var T,E=[];for(T=0;T<7;T++)E[T]=Gt(M,(T+e)%7,I,"day");return E}function vt(A,M){return Ht(A,M,"months")}function Xt(A,M){return Ht(A,M,"monthsShort")}function Wt(A,M,t){return bt(A,M,t,"weekdays")}function Vt(A,M,t){return bt(A,M,t,"weekdaysShort")}function Pt(A,M,t){return bt(A,M,t,"weekdaysMin")}function Zt(){var A=this._data;return this._milliseconds=_g(this._milliseconds),this._days=_g(this._days),this._months=_g(this._months),A.milliseconds=_g(A.milliseconds),A.seconds=_g(A.seconds),A.minutes=_g(A.minutes),A.hours=_g(A.hours),A.months=_g(A.months),A.years=_g(A.years),this}function Kt(A,M,t,I){var g=GM(M,t);return A._milliseconds+=I*g._milliseconds,A._days+=I*g._days,A._months+=I*g._months,A._bubble()}function qt(A,M){return Kt(this,A,M,1)}function _t(A,M){return Kt(this,A,M,-1)}function $t(A){return A<0?Math.floor(A):Math.ceil(A)}function AI(){var A,M,t,I,g,e=this._milliseconds,i=this._days,T=this._months,E=this._data;return e>=0&&i>=0&&T>=0||e<=0&&i<=0&&T<=0||(e+=864e5*$t(tI(T)+i),i=0,T=0),E.milliseconds=e%1e3,A=x(e/1e3),E.seconds=A%60,M=x(A/60),E.minutes=M%60,t=x(M/60),E.hours=t%24,i+=x(t/24),g=x(MI(i)),T+=g,i-=$t(tI(g)),I=x(T/12),T%=12,E.days=i,E.months=T,E.years=I,this}function MI(A){return 4800*A/146097}function tI(A){return 146097*A/4800}function II(A){var M,t,I=this._milliseconds;if(A=f(A),"month"===A||"year"===A)return M=this._days+I/864e5,t=this._months+MI(M),"month"===A?t:t/12;switch(M=this._days+Math.round(tI(this._months)),A){case"week":return M/7+I/6048e5;case"day":return M+I/864e5;case"hour":return 24*M+I/36e5;case"minute":return 1440*M+I/6e4;case"second":return 86400*M+I/1e3;case"millisecond":return Math.floor(864e5*M)+I;default:throw new Error("Unknown unit "+A)}}function gI(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*j(this._months/12)}function eI(A){return function(){return this.as(A)}}function iI(A){return A=f(A),this[A+"s"]()}function TI(A){return function(){return this._data[A]}}function EI(){return x(this.days()/7)}function NI(A,M,t,I,g){return g.relativeTime(M||1,!!t,A,I)}function oI(A,M,t){var I=GM(A).abs(),g=De(I.as("s")),e=De(I.as("m")),i=De(I.as("h")),T=De(I.as("d")),E=De(I.as("M")),N=De(I.as("y")),o=g0,o[4]=t,NI.apply(null,o)}function nI(A){return void 0===A?De:"function"==typeof A&&(De=A,!0)}function CI(A,M){return void 0!==ae[A]&&(void 0===M?ae[A]:(ae[A]=M,!0))}function cI(A){var M=this.localeData(),t=oI(this,!A,M);return A&&(t=M.pastFuture(+this,t)),M.postformat(t)}function DI(){var A,M,t,I=Be(this._milliseconds)/1e3,g=Be(this._days),e=Be(this._months);A=x(I/60),M=x(A/60),I%=60,A%=60,t=x(e/12),e%=12;var i=t,T=e,E=g,N=M,o=A,n=I,C=this.asSeconds();return C?(C<0?"-":"")+"P"+(i?i+"Y":"")+(T?T+"M":"")+(E?E+"D":"")+(N||o||n?"T":"")+(N?N+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"}var aI,BI;BI=Array.prototype.some?Array.prototype.some:function(A){for(var M=Object(this),t=M.length>>>0,I=0;I68?1900:2e3)};var Bg=G("FullYear",!0);V("w",["ww",2],"wo","week"),V("W",["WW",2],"Wo","isoWeek"),F("week","w"),F("isoWeek","W"),R("week",5),R("isoWeek",5),_("w",GI),_("ww",GI,fI),_("W",GI),_("WW",GI,fI),IA(["w","ww","W","WW"],function(A,M,t,I){M[I.substr(0,1)]=j(A)});var Qg={dow:0,doy:6};V("d",0,"do","day"),V("dd",0,0,function(A){return this.localeData().weekdaysMin(this,A)}),V("ddd",0,0,function(A){return this.localeData().weekdaysShort(this,A)}),V("dddd",0,0,function(A){return this.localeData().weekdays(this,A)}),V("e",0,0,"weekday"),V("E",0,0,"isoWeekday"),F("day","d"),F("weekday","e"),F("isoWeekday","E"),R("day",11),R("weekday",11),R("isoWeekday",11),_("d",GI),_("e",GI),_("E",GI),_("dd",function(A,M){return M.weekdaysMinRegex(A)}),_("ddd",function(A,M){return M.weekdaysShortRegex(A)}),_("dddd",function(A,M){return M.weekdaysRegex(A)}),IA(["dd","ddd","dddd"],function(A,M,t,I){var g=t._locale.weekdaysParse(A,I,t._strict);null!=g?M.d=g:c(t).invalidWeekday=A}),IA(["d","e","E"],function(A,M,t,I){M[I]=j(A)});var rg="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),sg="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xg="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),jg=_I,yg=_I,ug=_I;V("H",["HH",2],0,"hour"),V("h",["hh",2],0,vA),V("k",["kk",2],0,XA),V("hmm",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)}),V("hmmss",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)+W(this.seconds(),2)}),V("Hmm",0,0,function(){return""+this.hours()+W(this.minutes(),2)}),V("Hmmss",0,0,function(){return""+this.hours()+W(this.minutes(),2)+W(this.seconds(),2)}),WA("a",!0),WA("A",!1),F("hour","h"),R("hour",13),_("a",VA),_("A",VA),_("H",GI),_("h",GI),_("HH",GI,fI),_("hh",GI,fI),_("hmm",HI),_("hmmss",bI),_("Hmm",HI),_("Hmmss",bI),tA(["H","HH"],gg),tA(["a","A"],function(A,M,t){t._isPm=t._locale.isPM(A),t._meridiem=A}),tA(["h","hh"],function(A,M,t){M[gg]=j(A),c(t).bigHour=!0}),tA("hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I)),c(t).bigHour=!0}),tA("hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g)),c(t).bigHour=!0}),tA("Hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I))}),tA("Hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g))});var wg,lg=/[ap]\.?m?\.?/i,Lg=G("Hours",!0),Yg={calendar:wI,longDateFormat:lI,invalidDate:LI,ordinal:YI,ordinalParse:dI,relativeTime:hI,months:Cg,monthsShort:cg,week:Qg,weekdays:rg,weekdaysMin:xg,weekdaysShort:sg,meridiemParse:lg},dg={},hg={},Sg=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,zg=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pg=/Z|[+-]\d\d(?::?\d\d)?/,Ug=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Og=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mg=/^\/?Date\((\-?\d+)/i;M.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(A){A._d=new Date(A._i+(A._useUTC?" UTC":""))}),M.ISO_8601=function(){};var Fg=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var A=sM.apply(null,arguments);return this.isValid()&&A.isValid()?Athis?this:A:a()}),kg=function(){return Date.now?Date.now():+new Date};LM("Z",":"),LM("ZZ",""),_("Z",KI),_("ZZ",KI),tA(["Z","ZZ"],function(A,M,t){t._useUTC=!0,t._tzm=YM(KI,A)});var Rg=/([\+\-]|\d\d)/gi;M.updateOffset=function(){};var Jg=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Gg=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;GM.fn=uM.prototype;var Hg=XM(1,"add"),bg=XM(-1,"subtract");M.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",M.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var vg=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(A){return void 0===A?this.localeData():this.locale(A)});V(0,["gg",2],0,function(){return this.weekYear()%100}),V(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Lt("gggg","weekYear"),Lt("ggggg","weekYear"),Lt("GGGG","isoWeekYear"),Lt("GGGGG","isoWeekYear"),F("weekYear","gg"),F("isoWeekYear","GG"),R("weekYear",1),R("isoWeekYear",1),_("G",PI),_("g",PI),_("GG",GI,fI),_("gg",GI,fI),_("GGGG",XI,RI),_("gggg",XI,RI),_("GGGGG",WI,JI),_("ggggg",WI,JI),IA(["gggg","ggggg","GGGG","GGGGG"],function(A,M,t,I){M[I.substr(0,2)]=j(A)}),IA(["gg","GG"],function(A,t,I,g){t[g]=M.parseTwoDigitYear(A)}),V("Q",0,"Qo","quarter"),F("quarter","Q"),R("quarter",7),_("Q",FI),tA("Q",function(A,M){M[tg]=3*(j(A)-1)}),V("D",["DD",2],"Do","date"),F("date","D"),R("date",9),_("D",GI),_("DD",GI,fI),_("Do",function(A,M){return A?M._ordinalParse:M._ordinalParseLenient}),tA(["D","DD"],Ig),tA("Do",function(A,M){M[Ig]=j(A.match(GI)[0],10)});var Xg=G("Date",!0);V("DDD",["DDDD",3],"DDDo","dayOfYear"),F("dayOfYear","DDD"),R("dayOfYear",4),_("DDD",vI),_("DDDD",kI),tA(["DDD","DDDD"],function(A,M,t){t._dayOfYear=j(A)}),V("m",["mm",2],0,"minute"),F("minute","m"),R("minute",14),_("m",GI),_("mm",GI,fI),tA(["m","mm"],eg);var Wg=G("Minutes",!1);V("s",["ss",2],0,"second"),F("second","s"),R("second",15),_("s",GI),_("ss",GI,fI),tA(["s","ss"],ig);var Vg=G("Seconds",!1);V("S",0,0,function(){return~~(this.millisecond()/100)}),V(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),V(0,["SSS",3],0,"millisecond"),V(0,["SSSS",4],0,function(){return 10*this.millisecond()}),V(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),V(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),V(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),V(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),V(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),F("millisecond","ms"),R("millisecond",16),_("S",vI,FI),_("SS",vI,fI),_("SSS",vI,kI);var Pg;for(Pg="SSSS";Pg.length<=9;Pg+="S")_(Pg,VI);for(Pg="S";Pg.length<=9;Pg+="S")tA(Pg,mt);var Zg=G("Milliseconds",!1);V("z",0,0,"zoneAbbr"),V("zz",0,0,"zoneName");var Kg=r.prototype;Kg.add=Hg,Kg.calendar=PM,Kg.clone=ZM,Kg.diff=tt,Kg.endOf=at,Kg.format=Tt,Kg.from=Et,Kg.fromNow=Nt,Kg.to=ot,Kg.toNow=nt,Kg.get=v,Kg.invalidAt=wt,Kg.isAfter=KM,Kg.isBefore=qM,Kg.isBetween=_M,Kg.isSame=$M,Kg.isSameOrAfter=At,Kg.isSameOrBefore=Mt,Kg.isValid=yt,Kg.lang=vg,Kg.locale=Ct,Kg.localeData=ct,Kg.max=fg,Kg.min=Fg,Kg.parsingFlags=ut,Kg.set=X,Kg.startOf=Dt,Kg.subtract=bg,Kg.toArray=st,Kg.toObject=xt,Kg.toDate=rt,Kg.toISOString=et,Kg.inspect=it,Kg.toJSON=jt,Kg.toString=gt,Kg.unix=Qt,Kg.valueOf=Bt,Kg.creationData=lt,Kg.year=Bg,Kg.isLeapYear=rA,Kg.weekYear=Yt,Kg.isoWeekYear=dt,Kg.quarter=Kg.quarters=Ut,Kg.month=nA,Kg.daysInMonth=CA,Kg.week=Kg.weeks=dA,Kg.isoWeek=Kg.isoWeeks=hA,Kg.weeksInYear=St,Kg.isoWeeksInYear=ht,Kg.date=Xg,Kg.day=Kg.days=fA,Kg.weekday=kA,Kg.isoWeekday=RA,Kg.dayOfYear=Ot,Kg.hour=Kg.hours=Lg,Kg.minute=Kg.minutes=Wg,Kg.second=Kg.seconds=Vg,Kg.millisecond=Kg.milliseconds=Zg,Kg.utcOffset=SM,Kg.utc=pM,Kg.local=UM,Kg.parseZone=OM,Kg.hasAlignedHourOffset=mM,Kg.isDST=FM,Kg.isLocal=kM,Kg.isUtcOffset=RM,Kg.isUtc=JM,Kg.isUTC=JM,Kg.zoneAbbr=Ft,Kg.zoneName=ft,Kg.dates=w("dates accessor is deprecated. Use date instead.",Xg),Kg.months=w("months accessor is deprecated. Use month instead",nA),Kg.years=w("years accessor is deprecated. Use year instead",Bg),Kg.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",zM),Kg.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",fM);var qg=h.prototype;qg.calendar=S,qg.longDateFormat=z,qg.invalidDate=p,qg.ordinal=U,qg.preparse=Jt,qg.postformat=Jt,qg.relativeTime=O,qg.pastFuture=m,qg.set=Y,qg.months=iA,qg.monthsShort=TA,qg.monthsParse=NA,qg.monthsRegex=DA,qg.monthsShortRegex=cA,qg.week=lA,qg.firstDayOfYear=YA,qg.firstDayOfWeek=LA,qg.weekdays=pA,qg.weekdaysMin=OA,qg.weekdaysShort=UA,qg.weekdaysParse=FA,qg.weekdaysRegex=JA,qg.weekdaysShortRegex=GA,qg.weekdaysMinRegex=HA,qg.isPM=PA,qg.meridiem=ZA,$A("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(A){var M=A%10,t=1===j(A%100/10)?"th":1===M?"st":2===M?"nd":3===M?"rd":"th";return A+t}}),M.lang=w("moment.lang is deprecated. Use moment.locale instead.",$A),M.langData=w("moment.langData is deprecated. Use moment.localeData instead.",tM);var _g=Math.abs,$g=eI("ms"),Ae=eI("s"),Me=eI("m"),te=eI("h"),Ie=eI("d"),ge=eI("w"),ee=eI("M"),ie=eI("y"),Te=TI("milliseconds"),Ee=TI("seconds"),Ne=TI("minutes"),oe=TI("hours"),ne=TI("days"),Ce=TI("months"),ce=TI("years"),De=Math.round,ae={s:45,m:45,h:22,d:26,M:11},Be=Math.abs,Qe=uM.prototype;return Qe.abs=Zt,Qe.add=qt,Qe.subtract=_t,Qe.as=II,Qe.asMilliseconds=$g,Qe.asSeconds=Ae,Qe.asMinutes=Me,Qe.asHours=te,Qe.asDays=Ie,Qe.asWeeks=ge,Qe.asMonths=ee,Qe.asYears=ie,Qe.valueOf=gI,Qe._bubble=AI,Qe.get=iI,Qe.milliseconds=Te,Qe.seconds=Ee,Qe.minutes=Ne,Qe.hours=oe,Qe.days=ne,Qe.weeks=EI,Qe.months=Ce,Qe.years=ce,Qe.humanize=cI,Qe.toISOString=DI,Qe.toString=DI,Qe.toJSON=DI,Qe.locale=Ct,Qe.localeData=ct,Qe.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",DI),Qe.lang=vg,V("X",0,0,"unix"),V("x",0,0,"valueOf"),_("x",PI),_("X",qI),tA("X",function(A,M,t){t._d=new Date(1e3*parseFloat(A,10))}),tA("x",function(A,M,t){t._d=new Date(j(A))}),M.version="2.17.1",t(sM),M.fn=Kg,M.min=jM,M.max=yM,M.now=kg,M.utc=n,M.unix=kt,M.months=vt,M.isDate=T,M.locale=$A,M.invalid=a,M.duration=GM,M.isMoment=s,M.weekdays=Wt,M.parseZone=Rt,M.localeData=tM,M.isDuration=wM,M.monthsShort=Xt,M.weekdaysMin=Pt,M.defineLocale=AM,M.updateLocale=MM,M.locales=IM,M.weekdaysShort=Vt,M.normalizeUnits=f,M.relativeTimeRounding=nI,M.relativeTimeThreshold=CI,M.calendarFormat=VM,M.prototype=Kg,M})}).call(M,t(128)(A))},function(A,M,t){"use strict";var I=t(132).default,g=t(133).default,e=t(78).default;M.__esModule=!0;var i=function(A){return I(g({values:function(){var A=this;return e(this).map(function(M){return A[M]})}}),A)},T={SIZES:{large:"lg",medium:"md",small:"sm",xsmall:"xs",lg:"lg",md:"md",sm:"sm",xs:"xs"},GRID_COLUMNS:12},E=i({LARGE:"large",MEDIUM:"medium",SMALL:"small",XSMALL:"xsmall"});M.Sizes=E;var N=i({SUCCESS:"success",WARNING:"warning",DANGER:"danger",INFO:"info"});M.State=N;var o="default";M.DEFAULT=o;var n="primary";M.PRIMARY=n;var C="link";M.LINK=C;var c="inverse";M.INVERSE=c,M.default=T},function(A,M){"use strict";function t(){for(var A=arguments.length,M=Array(A),t=0;t0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURI(o))):"("===E?g+=1:")"===E?g-=1:":"===E.charAt(0)?(N=E.substring(1),o=M[N],null!=o||g>0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURIComponent(o))):e+=E;return e.replace(/\/+/g,"/")}M.__esModule=!0,M.compilePattern=i,M.matchPattern=T,M.getParamNames=E,M.getParams=N,M.formatPattern=o;var n=t(8),C=I(n),c=Object.create(null)},function(A,M){"use strict";M.__esModule=!0;var t="PUSH";M.PUSH=t;var I="REPLACE";M.REPLACE=I;var g="POP";M.POP=g,M.default={PUSH:t,REPLACE:I,POP:g}},function(A,M,t){"use strict";function I(A,M){return(A&M)===M}var g=t(2),e={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(A){var M=e,t=A.Properties||{},i=A.DOMAttributeNamespaces||{},E=A.DOMAttributeNames||{},N=A.DOMPropertyNames||{},o=A.DOMMutationMethods||{};A.isCustomAttribute&&T._isCustomAttributeFunctions.push(A.isCustomAttribute);for(var n in t){T.properties.hasOwnProperty(n)?g(!1):void 0;var C=n.toLowerCase(),c=t[n],D={attributeName:C,attributeNamespace:null,propertyName:n,mutationMethod:null,mustUseAttribute:I(c,M.MUST_USE_ATTRIBUTE),mustUseProperty:I(c,M.MUST_USE_PROPERTY),hasSideEffects:I(c,M.HAS_SIDE_EFFECTS),hasBooleanValue:I(c,M.HAS_BOOLEAN_VALUE),hasNumericValue:I(c,M.HAS_NUMERIC_VALUE),hasPositiveNumericValue:I(c,M.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:I(c,M.HAS_OVERLOADED_BOOLEAN_VALUE)};if(D.mustUseAttribute&&D.mustUseProperty?g(!1):void 0,!D.mustUseProperty&&D.hasSideEffects?g(!1):void 0,D.hasBooleanValue+D.hasNumericValue+D.hasOverloadedBooleanValue<=1?void 0:g(!1),E.hasOwnProperty(n)){var a=E[n];D.attributeName=a}i.hasOwnProperty(n)&&(D.attributeNamespace=i[n]),N.hasOwnProperty(n)&&(D.propertyName=N[n]),o.hasOwnProperty(n)&&(D.mutationMethod=o[n]),T.properties[n]=D}}},i={},T={ID_ATTRIBUTE_NAME:"data-reactid",properties:{},getPossibleStandardName:null,_isCustomAttributeFunctions:[],isCustomAttribute:function(A){for(var M=0;M1){var M=A.indexOf(c,1);return M>-1?A.substr(0,M):A}return null},traverseEnterLeave:function(A,M,t,I,g){var e=N(A,M);e!==A&&o(A,e,t,I,!1,!0),e!==M&&o(e,M,t,g,!0,!1)},traverseTwoPhase:function(A,M,t){A&&(o("",A,M,t,!0,!1),o(A,"",M,t,!1,!0))},traverseTwoPhaseSkipTarget:function(A,M,t){A&&(o("",A,M,t,!0,!0),o(A,"",M,t,!0,!0))},traverseAncestors:function(A,M,t){o("",A,M,t,!0,!1)},getFirstCommonAncestorID:N,_getNextDescendantID:E,isAncestorIDOf:i,SEPARATOR:c};A.exports=B},function(A,M){var t=A.exports={version:"1.2.6"};"number"==typeof __e&&(__e=t)},function(A,M,t){"use strict";var I={};A.exports=I},function(A,M,t){"use strict";function I(A,M,t){var I=0;return n.default.Children.map(A,function(A){if(n.default.isValidElement(A)){var g=I;return I++,M.call(t,A,g)}return A})}function g(A,M,t){var I=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I),I++)})}function e(A){var M=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&M++}),M}function i(A){var M=!1;return n.default.Children.forEach(A,function(A){!M&&n.default.isValidElement(A)&&(M=!0)}),M}function T(A,M){var t=void 0;return g(A,function(I,g){!t&&M(I,g,A)&&(t=I)}),t}function E(A,M,t){var I=0,g=[];return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I)&&g.push(A),I++)}),g}var N=t(6).default;M.__esModule=!0;var o=t(1),n=N(o);M.default={map:I,forEach:g,numberOf:e,find:T,findValidComponents:E,hasValidComponent:i},A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=function(A){return(0,T.default)(e.default.findDOMNode(A))};var g=t(16),e=I(g),i=t(39),T=I(i);A.exports=M.default},function(A,M,t){"use strict";var I=t(204),g=t(437),e=t(217),i=t(226),T=t(227),E=t(2),N=(t(3),{}),o=null,n=function(A,M){A&&(g.executeDispatchesInOrder(A,M),A.isPersistent()||A.constructor.release(A))},C=function(A){return n(A,!0)},c=function(A){return n(A,!1)},D=null,a={injection:{injectMount:g.injection.injectMount,injectInstanceHandle:function(A){D=A},getInstanceHandle:function(){return D},injectEventPluginOrder:I.injectEventPluginOrder,injectEventPluginsByName:I.injectEventPluginsByName},eventNameDispatchConfigs:I.eventNameDispatchConfigs,registrationNameModules:I.registrationNameModules,putListener:function(A,M,t){"function"!=typeof t?E(!1):void 0;var g=N[M]||(N[M]={});g[A]=t;var e=I.registrationNameModules[M];e&&e.didPutListener&&e.didPutListener(A,M,t)},getListener:function(A,M){var t=N[M];return t&&t[A]},deleteListener:function(A,M){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M);var g=N[M];g&&delete g[A]},deleteAllListeners:function(A){for(var M in N)if(N[M][A]){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M),delete N[M][A]}},extractEvents:function(A,M,t,g,e){for(var T,E=I.plugins,N=0;N1?I-1:0),e=1;e":">","<":"<",'"':""","'":"'"},e=/[&><"']/g;A.exports=I},function(A,M,t){"use strict";var I=t(10),g=/^[ \r\n\t\f]/,e=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(A,M){A.innerHTML=M};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(A,M){MSApp.execUnsafeLocalFunction(function(){A.innerHTML=M})}),I.canUseDOM){var T=document.createElement("div");T.innerHTML=" ",""===T.innerHTML&&(i=function(A,M){if(A.parentNode&&A.parentNode.replaceChild(A,A),g.test(M)||"<"===M[0]&&e.test(M)){A.innerHTML=String.fromCharCode(65279)+M;var t=A.firstChild;1===t.data.length?A.removeChild(t):t.deleteData(0,1)}else A.innerHTML=M})}A.exports=i},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=function(A){var M=A.label,t=A.id,I=A.name,g=A.value,i=A.onChange,T=A.type,E=A.spellCheck,N=A.required,o=A.readonly,n=A.autoComplete,C=A.align,c=A.className,D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n});return o&&(D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n,disabled:!0})),e.default.createElement("div",{className:"input-group "+C+" "+c},D,e.default.createElement("i",{className:"ig-helpers"}),e.default.createElement("label",{className:"ig-label"},M))};M.default=i},function(A,M,t){A.exports={default:t(259),__esModule:!0}},function(A,M,t){var I=t(265),g=t(49),e=t(134),i="prototype",T=function(A,M,t){var E,N,o,n=A&T.F,C=A&T.G,c=A&T.S,D=A&T.P,a=A&T.B,B=A&T.W,Q=C?g:g[M]||(g[M]={}),r=C?I:c?I[M]:(I[M]||{})[i];C&&(t=M);for(E in t)N=!n&&r&&E in r,N&&E in Q||(o=N?r[E]:t[E],Q[E]=C&&"function"!=typeof r[E]?t[E]:a&&N?e(o,I):B&&r[E]==o?function(A){var M=function(M){return this instanceof A?new A(M):A(M)};return M[i]=A[i],M}(o):D&&"function"==typeof o?e(Function.call,o):o,D&&((Q[i]||(Q[i]={}))[E]=o))};T.F=1,T.G=2,T.S=4,T.P=8,T.B=16,T.W=32,A.exports=T},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M,t){"use strict";var I=t(32),g=function(){};I&&(g=function(){return document.addEventListener?function(A,M,t,I){return A.addEventListener(M,t,I||!1)}:document.attachEvent?function(A,M,t){return A.attachEvent("on"+M,t)}:void 0}()),A.exports=g},function(A,M,t){"use strict";var I=t(145),g=t(295),e=t(290),i=t(291),T=Object.prototype.hasOwnProperty;A.exports=function(A,M,t){var E="",N=M;if("string"==typeof M){if(void 0===t)return A.style[I(M)]||e(A).getPropertyValue(g(M));(N={})[M]=t}for(var o in N)T.call(N,o)&&(N[o]||0===N[o]?E+=g(o)+":"+N[o]+";":i(A,g(o)));A.style.cssText+=";"+E}},function(A,M,t){(function(){var t=this,I=t.humanize,g={};"undefined"!=typeof A&&A.exports&&(M=A.exports=g),M.humanize=g,g.noConflict=function(){return t.humanize=I,this},g.pad=function(A,M,t,I){if(A+="",t?t.length>1&&(t=t.charAt(0)):t=" ",I=void 0===I?"left":"right","right"===I)for(;A.length4&&A<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th"},w:function(){return t.getDay()},z:function(){return(o.L()?i[o.n()]:e[o.n()])+o.j()-1},W:function(){var A=o.z()-o.N()+1.5;return g.pad(1+Math.floor(Math.abs(A)/7)+(A%7>3.5?1:0),2,"0")},F:function(){return N[t.getMonth()]},m:function(){return g.pad(o.n(),2,"0")},M:function(){return o.F().slice(0,3)},n:function(){return t.getMonth()+1},t:function(){return new Date(o.Y(),o.n(),0).getDate()},L:function(){return 1===new Date(o.Y(),1,29).getMonth()?1:0},o:function(){var A=o.n(),M=o.W();return o.Y()+(12===A&&M<9?-1:1===A&&M>9)},Y:function(){return t.getFullYear()},y:function(){return String(o.Y()).slice(-2)},a:function(){return t.getHours()>11?"pm":"am"},A:function(){return o.a().toUpperCase()},B:function(){var A=t.getTime()/1e3,M=A%86400+3600;M<0&&(M+=86400);var I=M/86.4%1e3;return A<0?Math.ceil(I):Math.floor(I)},g:function(){return o.G()%12||12},G:function(){return t.getHours()},h:function(){return g.pad(o.g(),2,"0")},H:function(){return g.pad(o.G(),2,"0")},i:function(){return g.pad(t.getMinutes(),2,"0")},s:function(){return g.pad(t.getSeconds(),2,"0")},u:function(){return g.pad(1e3*t.getMilliseconds(),6,"0")},O:function(){var A=t.getTimezoneOffset(),M=Math.abs(A);return(A>0?"-":"+")+g.pad(100*Math.floor(M/60)+M%60,4,"0")},P:function(){var A=o.O();return A.substr(0,3)+":"+A.substr(3,2)},Z:function(){return 60*-t.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(I,T)},r:function(){return"D, d M Y H:i:s O".replace(I,T)},U:function(){return t.getTime()/1e3||0}};return A.replace(I,T)},g.numberFormat=function(A,M,t,I){M=isNaN(M)?2:Math.abs(M),t=void 0===t?".":t,I=void 0===I?",":I;var g=A<0?"-":"";A=Math.abs(+A||0);var e=parseInt(A.toFixed(M),10)+"",i=e.length>3?e.length%3:0;return g+(i?e.substr(0,i)+I:"")+e.substr(i).replace(/(\d{3})(?=\d)/g,"$1"+I)+(M?t+Math.abs(A-e).toFixed(M).slice(2):"")},g.naturalDay=function(A,M){A=void 0===A?g.time():A,M=void 0===M?"Y-m-d":M;var t=86400,I=new Date,e=new Date(I.getFullYear(),I.getMonth(),I.getDate()).getTime()/1e3;return A=e-t?"yesterday":A>=e&&A=e+t&&A-2)return(t>=0?"just ":"")+"now";if(t<60&&t>-60)return t>=0?Math.floor(t)+" seconds ago":"in "+Math.floor(-t)+" seconds";if(t<120&&t>-120)return t>=0?"about a minute ago":"in about a minute";if(t<3600&&t>-3600)return t>=0?Math.floor(t/60)+" minutes ago":"in "+Math.floor(-t/60)+" minutes";if(t<7200&&t>-7200)return t>=0?"about an hour ago":"in about an hour";if(t<86400&&t>-86400)return t>=0?Math.floor(t/3600)+" hours ago":"in "+Math.floor(-t/3600)+" hours";var I=172800;if(t-I)return t>=0?"1 day ago":"in 1 day";var e=2505600;if(t-e)return t>=0?Math.floor(t/86400)+" days ago":"in "+Math.floor(-t/86400)+" days";var i=5184e3;if(t-i)return t>=0?"about a month ago":"in about a month";var T=parseInt(g.date("Y",M),10),E=parseInt(g.date("Y",A),10),N=12*T+parseInt(g.date("n",M),10),o=12*E+parseInt(g.date("n",A),10),n=N-o;if(n<12&&n>-12)return n>=0?n+" months ago":"in "+-n+" months";var C=T-E;return C<2&&C>-2?C>=0?"a year ago":"in a year":C>=0?C+" years ago":"in "+-C+" years"},g.ordinal=function(A){A=parseInt(A,10),A=isNaN(A)?0:A;var M=A<0?"-":"";A=Math.abs(A);var t=A%100;return M+A+(t>4&&t<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th")},g.filesize=function(A,M,t,I,e,i){return M=void 0===M?1024:M,A<=0?"0 bytes":(A

    "),A=A.replace(/\n/g,"
    "),"

    "+A+"

    "},g.nl2br=function(A){return A.replace(/(\r\n|\n|\r)/g,"
    ")},g.truncatechars=function(A,M){return A.length<=M?A:A.substr(0,M)+"…"},g.truncatewords=function(A,M){var t=A.split(" ");return t.length0,Q=C.enumErrorProps&&(A===u||A instanceof Error),r=C.enumPrototypes&&T(A);++IM.documentElement.clientHeight;return{modalStyles:{paddingRight:I&&!g?Q.default():void 0,paddingLeft:!I&&g?Q.default():void 0}}}});v.Body=z.default,v.Header=U.default,v.Title=m.default,v.Footer=f.default,v.Dialog=h.default,v.TRANSITION_DURATION=300,v.BACKDROP_TRANSITION_DURATION=150,M.default=c.bsSizes([a.Sizes.LARGE,a.Sizes.SMALL],c.bsClass("modal",v)), +A.exports=M.default},function(A,M,t){"use strict";var I=t(15).default,g=t(14).default,e=t(38).default,i=t(7).default,T=t(6).default;M.__esModule=!0;var E=t(1),N=T(E),o=t(5),n=T(o),C=t(11),c=T(C),D=t(44),a=T(D),B=function(A){function M(){g(this,M),A.apply(this,arguments)}return I(M,A),M.prototype.render=function(){var A=this.props,M=A["aria-label"],t=e(A,["aria-label"]),I=a.default(this.context.$bs_onModalHide,this.props.onHide);return N.default.createElement("div",i({},t,{className:n.default(this.props.className,c.default.prefix(this.props,"header"))}),this.props.closeButton&&N.default.createElement("button",{type:"button",className:"close","aria-label":M,onClick:I},N.default.createElement("span",{"aria-hidden":"true"},"×")),this.props.children)},M}(N.default.Component);B.propTypes={"aria-label":N.default.PropTypes.string,bsClass:N.default.PropTypes.string,closeButton:N.default.PropTypes.bool,onHide:N.default.PropTypes.func},B.contextTypes={$bs_onModalHide:N.default.PropTypes.func},B.defaultProps={"aria-label":"Close",closeButton:!1},M.default=C.bsClass("modal",B),A.exports=M.default},function(A,M,t){"use strict";function I(A,M){return Array.isArray(M)?M.indexOf(A)>=0:A===M}var g=t(7).default,e=t(78).default,i=t(6).default;M.__esModule=!0;var T=t(40),E=i(T),N=t(170),o=i(N),n=t(1),C=i(n),c=t(16),D=i(c),a=t(127),B=(i(a),t(370)),Q=i(B),r=t(44),s=i(r),x=C.default.createClass({displayName:"OverlayTrigger",propTypes:g({},Q.default.propTypes,{trigger:C.default.PropTypes.oneOfType([C.default.PropTypes.oneOf(["click","hover","focus"]),C.default.PropTypes.arrayOf(C.default.PropTypes.oneOf(["click","hover","focus"]))]),delay:C.default.PropTypes.number,delayShow:C.default.PropTypes.number,delayHide:C.default.PropTypes.number,defaultOverlayShown:C.default.PropTypes.bool,overlay:C.default.PropTypes.node.isRequired,onBlur:C.default.PropTypes.func,onClick:C.default.PropTypes.func,onFocus:C.default.PropTypes.func,onMouseEnter:C.default.PropTypes.func,onMouseLeave:C.default.PropTypes.func,target:function(){},onHide:function(){},show:function(){}}),getDefaultProps:function(){return{defaultOverlayShown:!1,trigger:["hover","focus"]}},getInitialState:function(){return{isOverlayShown:this.props.defaultOverlayShown}},show:function(){this.setState({isOverlayShown:!0})},hide:function(){this.setState({isOverlayShown:!1})},toggle:function(){this.state.isOverlayShown?this.hide():this.show()},componentWillMount:function(){this.handleMouseOver=this.handleMouseOverOut.bind(null,this.handleDelayedShow),this.handleMouseOut=this.handleMouseOverOut.bind(null,this.handleDelayedHide)},componentDidMount:function(){this._mountNode=document.createElement("div"),this.renderOverlay()},renderOverlay:function(){D.default.unstable_renderSubtreeIntoContainer(this,this._overlay,this._mountNode)},componentWillUnmount:function(){D.default.unmountComponentAtNode(this._mountNode),this._mountNode=null,clearTimeout(this._hoverShowDelay),clearTimeout(this._hoverHideDelay)},componentDidUpdate:function(){this._mountNode&&this.renderOverlay()},getOverlayTarget:function(){return D.default.findDOMNode(this)},getOverlay:function(){var A=g({},o.default(this.props,e(Q.default.propTypes)),{show:this.state.isOverlayShown,onHide:this.hide,target:this.getOverlayTarget,onExit:this.props.onExit,onExiting:this.props.onExiting,onExited:this.props.onExited,onEnter:this.props.onEnter,onEntering:this.props.onEntering,onEntered:this.props.onEntered}),M=n.cloneElement(this.props.overlay,{placement:A.placement,container:A.container});return C.default.createElement(Q.default,A,M)},render:function(){var A=C.default.Children.only(this.props.children),M=A.props,t={"aria-describedby":this.props.overlay.props.id};return this._overlay=this.getOverlay(),t.onClick=s.default(M.onClick,this.props.onClick),I("click",this.props.trigger)&&(t.onClick=s.default(this.toggle,t.onClick)),I("hover",this.props.trigger)&&(t.onMouseOver=s.default(this.handleMouseOver,this.props.onMouseOver,M.onMouseOver),t.onMouseOut=s.default(this.handleMouseOut,this.props.onMouseOut,M.onMouseOut)),I("focus",this.props.trigger)&&(t.onFocus=s.default(this.handleDelayedShow,this.props.onFocus,M.onFocus),t.onBlur=s.default(this.handleDelayedHide,this.props.onBlur,M.onBlur)),n.cloneElement(A,t)},handleDelayedShow:function(){var A=this;if(null!=this._hoverHideDelay)return clearTimeout(this._hoverHideDelay),void(this._hoverHideDelay=null);if(!this.state.isOverlayShown&&null==this._hoverShowDelay){var M=null!=this.props.delayShow?this.props.delayShow:this.props.delay;return M?void(this._hoverShowDelay=setTimeout(function(){A._hoverShowDelay=null,A.show()},M)):void this.show()}},handleDelayedHide:function(){var A=this;if(null!=this._hoverShowDelay)return clearTimeout(this._hoverShowDelay),void(this._hoverShowDelay=null);if(this.state.isOverlayShown&&null==this._hoverHideDelay){var M=null!=this.props.delayHide?this.props.delayHide:this.props.delay;return M?void(this._hoverHideDelay=setTimeout(function(){A._hoverHideDelay=null,A.hide()},M)):void this.hide()}},handleMouseOverOut:function(A,M){var t=M.currentTarget,I=M.relatedTarget||M.nativeEvent.toElement;I&&(I===t||E.default(t,I))||A(M)}});M.default=x,A.exports=M.default},function(A,M,t){"use strict";var I=t(7).default,g=t(6).default;M.__esModule=!0;var e=t(1),i=g(e),T=t(5),E=g(T),N=t(11),o=g(N),n=t(183),C=g(n),c=i.default.createClass({displayName:"Tooltip",propTypes:{id:C.default(i.default.PropTypes.oneOfType([i.default.PropTypes.string,i.default.PropTypes.number])),placement:i.default.PropTypes.oneOf(["top","right","bottom","left"]),positionLeft:i.default.PropTypes.number,positionTop:i.default.PropTypes.number,arrowOffsetLeft:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),arrowOffsetTop:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),title:i.default.PropTypes.node},getDefaultProps:function(){return{bsClass:"tooltip",placement:"right"}},render:function(){var A,M=(A={},A[o.default.prefix(this.props)]=!0,A[this.props.placement]=!0,A),t=I({left:this.props.positionLeft,top:this.props.positionTop},this.props.style),g={left:this.props.arrowOffsetLeft,top:this.props.arrowOffsetTop};return i.default.createElement("div",I({role:"tooltip"},this.props,{className:E.default(this.props.className,M),style:t}),i.default.createElement("div",{className:o.default.prefix(this.props,"arrow"),style:g}),i.default.createElement("div",{className:o.default.prefix(this.props,"inner")},this.props.children))}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return A="function"==typeof A?A():A,i.default.findDOMNode(A)||M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=g;var e=t(16),i=I(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement. You can usually obtain a ReactComponent or DOMElement from a ReactElement by attaching a ref to it."):"object"===E&&"function"==typeof i.render||1===i.nodeType?null:new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement.")}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M,t){"use strict";function I(){function A(A,M,I){for(var g=0;g>",null!=t[I]?A(t,I,g):M?new Error("Required prop '"+I+"' was not specified in '"+g+"'."):void 0}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}M.__esModule=!0,M.errMsg=t,M.createChainableTypeChecker=I},function(A,M){"use strict";function t(A,M,t){function I(){return i=!0,T?void(N=[].concat(Array.prototype.slice.call(arguments))):void t.apply(this,arguments)}function g(){if(!i&&(E=!0,!T)){for(T=!0;!i&&e=A&&E&&(i=!0,t()))}}var e=0,i=!1,T=!1,E=!1,N=void 0;g()}function I(A,M,t){function I(A,M,I){i||(M?(i=!0,t(M)):(e[A]=I,i=++T===g,i&&t(null,e)))}var g=A.length,e=[];if(0===g)return t(null,e);var i=!1,T=0;A.forEach(function(A,t){M(A,t,function(A,M){I(t,A,M)})})}M.__esModule=!0,M.loopAsync=t,M.mapAsync=I},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0,M.router=M.routes=M.route=M.components=M.component=M.location=M.history=M.falsy=M.locationShape=M.routerShape=void 0;var e=t(1),i=t(66),T=(g(i),t(34)),E=I(T),N=t(9),o=(g(N),e.PropTypes.func),n=e.PropTypes.object,C=e.PropTypes.shape,c=e.PropTypes.string,D=M.routerShape=C({push:o.isRequired,replace:o.isRequired,go:o.isRequired,goBack:o.isRequired,goForward:o.isRequired,setRouteLeaveHook:o.isRequired,isActive:o.isRequired}),a=M.locationShape=C({pathname:c.isRequired,search:c.isRequired,state:n,action:c.isRequired,key:c}),B=M.falsy=E.falsy,Q=M.history=E.history,r=M.location=a,s=M.component=E.component,x=M.components=E.components,j=M.route=E.route,y=(M.routes=E.routes,M.router=D),u={falsy:B,history:Q,location:r,component:s,components:x,route:j,router:y};M.default=u},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!0;return!1}function e(A,M){function t(M){var t=!(arguments.length<=1||void 0===arguments[1])&&arguments[1],I=arguments.length<=2||void 0===arguments[2]?null:arguments[2],g=void 0;return t&&t!==!0||null!==I?(M={pathname:M,query:t},g=I||!1):(M=A.createLocation(M),g=t),(0,C.default)(M,g,s.location,s.routes,s.params)}function I(A,t){x&&x.location===A?e(x,t):(0,B.default)(M,A,function(M,I){M?t(M):I?e(i({},I,{location:A}),t):t()})}function e(A,M){function t(t,g){return t||g?I(t,g):void(0,D.default)(A,function(t,I){t?M(t):M(null,null,s=i({},A,{components:I}))})}function I(A,t){A?M(A):M(null,t)}var g=(0,N.default)(s,A),e=g.leaveRoutes,T=g.changeRoutes,E=g.enterRoutes;(0,o.runLeaveHooks)(e,s),e.filter(function(A){return E.indexOf(A)===-1}).forEach(a),(0,o.runChangeHooks)(T,s,A,function(M,g){return M||g?I(M,g):void(0,o.runEnterHooks)(E,A,t)})}function T(A){var M=arguments.length<=1||void 0===arguments[1]||arguments[1];return A.__id__||M&&(A.__id__=j++)}function E(A){return A.reduce(function(A,M){return A.push.apply(A,y[T(M)]),A},[])}function n(A,t){(0,B.default)(M,A,function(M,I){if(null==I)return void t();x=i({},I,{location:A});for(var g=E((0,N.default)(s,x).leaveRoutes),e=void 0,T=0,o=g.length;null==e&&T=32||13===M?M:0}A.exports=t},function(A,M){"use strict";function t(A){var M=this,t=M.nativeEvent;if(t.getModifierState)return t.getModifierState(A);var I=g[A];return!!I&&!!t[I]}function I(A){return t}var g={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};A.exports=I},function(A,M){"use strict";function t(A){var M=A.target||A.srcElement||window;return 3===M.nodeType?M.parentNode:M}A.exports=t},function(A,M){"use strict";function t(A){var M=A&&(I&&A[I]||A[g]);if("function"==typeof M)return M}var I="function"==typeof Symbol&&Symbol.iterator,g="@@iterator";A.exports=t},function(A,M,t){"use strict";function I(A){return"function"==typeof A&&"undefined"!=typeof A.prototype&&"function"==typeof A.prototype.mountComponent&&"function"==typeof A.prototype.receiveComponent}function g(A){var M;if(null===A||A===!1)M=new i(g);else if("object"==typeof A){var t=A;!t||"function"!=typeof t.type&&"string"!=typeof t.type?N(!1):void 0,M="string"==typeof t.type?T.createInternalComponent(t):I(t.type)?new t.type(t):new o}else"string"==typeof A||"number"==typeof A?M=T.createInstanceForText(A):N(!1);return M.construct(A),M._mountIndex=0,M._mountImage=null,M}var e=t(443),i=t(215),T=t(221),E=t(4),N=t(2),o=(t(3),function(){});E(o.prototype,e.Mixin,{_instantiateReactComponent:g}),A.exports=g},function(A,M,t){"use strict";/** * Checks if an event is supported in the current execution environment. * * NOTE: This will not work correctly for non-generic events such as ` + "`" + `change` + "`" + `, @@ -200,25 +200,25 @@ A.exports=function(A){return A===A.window?A:9===A.nodeType&&(A.defaultView||A.pa * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */ -function I(A,M){if(!e.canUseDOM||M&&!("addEventListener"in document))return!1;var t="on"+A,I=t in document;if(!I){var i=document.createElement("div");i.setAttribute(t,"return;"),I="function"==typeof i[t]}return!I&&g&&"wheel"===A&&(I=document.implementation.hasFeature("Events.wheel","3.0")),I}var g,e=t(10);e.canUseDOM&&(g=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),A.exports=I},function(A,M,t){"use strict";var I=t(10),g=t(75),e=t(76),i=function(A,M){A.textContent=M};I.canUseDOM&&("textContent"in document.documentElement||(i=function(A,M){e(A,g(M))})),A.exports=i},function(A,M){"use strict";function t(A,M){var t=null===A||A===!1,I=null===M||M===!1;if(t||I)return t===I;var g=typeof A,e=typeof M;return"string"===g||"number"===g?"string"===e||"number"===e:"object"===e&&A.type===M.type&&A.key===M.key}A.exports=t},function(A,M,t){"use strict";function I(A){return a[A]}function g(A,M){return A&&null!=A.key?i(A.key):M.toString(36)}function e(A){return(""+A).replace(B,I)}function i(A){return"$"+e(A)}function T(A,M,t,I){var e=typeof A;if("undefined"!==e&&"boolean"!==e||(A=null),null===A||"string"===e||"number"===e||N.isValidElement(A))return t(I,A,""===M?c+g(A,0):M),1;var E,o,a=0,B=""===M?c:M+D;if(Array.isArray(A))for(var Q=0;QM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;t":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;iM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;t":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;i-1&&A%1==0&&A1)for(var t=1;tA.clientHeight}Object.defineProperty(M,"__esModule",{value:!0}),M.default=i;var T=t(57),E=I(T),N=t(39),o=I(N);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):"function"!==E&&"string"!==E?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):null}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M){"use strict";function t(A){function M(M,t,I,g,e,i){var T=g||"<>",E=i||I;if(null==t[I])return M?new Error("Required "+e+" ` + "`" + `"+E+"` + "`" + ` was not specified "+("in ` + "`" + `"+T+"` + "`" + `.")):null;for(var N=arguments.length,o=Array(N>6?N-6:0),n=6;n=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return 0===A.button}function i(A){return!!(A.metaKey||A.altKey||A.ctrlKey||A.shiftKey)}function T(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!1;return!0}function E(A,M){var t=M.query,I=M.hash,g=M.state;return t||I||g?{pathname:A,query:t,hash:I,state:g}:A}M.__esModule=!0;var N=Object.assign||function(A){for(var M=1;M=0;I--){var g=A[I],e=g.path||"";if(t=e.replace(/\/*$/,"/")+t,0===e.indexOf("/"))break}return"/"+t}},propTypes:{path:C,from:C,to:C.isRequired,query:c,state:c,onEnter:o.falsy,children:o.falsy},render:function(){(0,T.default)(!1)}});M.default=D,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0;var g=t(1),e=I(g),i=t(8),T=I(i),E=t(30),N=t(34),o=e.default.PropTypes,n=o.string,C=o.func,c=e.default.createClass({displayName:"Route",statics:{createRouteFromReactElement:E.createRouteFromReactElement},propTypes:{path:n,component:N.component,components:N.components,getComponent:C,getComponents:C},render:function(){(0,T.default)(!1)}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return!A||!A.__v2_compatible__}function i(A){return A&&A.getCurrentLocation}M.__esModule=!0;var T=Object.assign||function(A){for(var M=1;M=0&&0===window.sessionStorage.length)return;throw A}}function i(A){var M=void 0;try{M=window.sessionStorage.getItem(g(A))}catch(A){if(A.name===o)return null}if(M)try{return JSON.parse(M)}catch(A){}return null}M.__esModule=!0,M.saveState=e,M.readState=i;var T=t(23),E=(I(T),"@@History/"),N=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],o="SecurityError"},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){function M(A){return E.canUseDOM?void 0:T.default(!1),t.listen(A)}var t=n.default(e({getUserConfirmation:N.getUserConfirmation},A,{go:N.go}));return e({},t,{listen:M})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M1?M-1:0),e=1;e=A.childNodes.length?null:A.childNodes.item(t);A.insertBefore(M,I)}var g=t(434),e=t(220),i=t(17),T=t(76),E=t(121),N=t(2),o={dangerouslyReplaceNodeWithMarkup:g.dangerouslyReplaceNodeWithMarkup,updateTextContent:E,processUpdates:function(A,M){for(var t,i=null,o=null,n=0;n-1?void 0:i(!1),!N.plugins[t]){M.extractEvents?void 0:i(!1),N.plugins[t]=M;var I=M.eventTypes;for(var e in I)g(I[e],M,e)?void 0:i(!1)}}}function g(A,M,t){N.eventNameDispatchConfigs.hasOwnProperty(t)?i(!1):void 0,N.eventNameDispatchConfigs[t]=A;var I=A.phasedRegistrationNames;if(I){for(var g in I)if(I.hasOwnProperty(g)){var T=I[g];e(T,M,t)}return!0}return!!A.registrationName&&(e(A.registrationName,M,t),!0)}function e(A,M,t){N.registrationNameModules[A]?i(!1):void 0,N.registrationNameModules[A]=M,N.registrationNameDependencies[A]=M.eventTypes[t].dependencies}var i=t(2),T=null,E={},N={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(A){T?i(!1):void 0,T=Array.prototype.slice.call(A),I()},injectEventPluginsByName:function(A){var M=!1;for(var t in A)if(A.hasOwnProperty(t)){var g=A[t];E.hasOwnProperty(t)&&E[t]===g||(E[t]?i(!1):void 0,E[t]=g,M=!0)}M&&I()},getPluginModuleForEvent:function(A){var M=A.dispatchConfig;if(M.registrationName)return N.registrationNameModules[M.registrationName]||null;for(var t in M.phasedRegistrationNames)if(M.phasedRegistrationNames.hasOwnProperty(t)){var I=N.registrationNameModules[M.phasedRegistrationNames[t]];if(I)return I}return null},_resetEventPlugins:function(){T=null;for(var A in E)E.hasOwnProperty(A)&&delete E[A];N.plugins.length=0;var M=N.eventNameDispatchConfigs;for(var t in M)M.hasOwnProperty(t)&&delete M[t];var I=N.registrationNameModules;for(var g in I)I.hasOwnProperty(g)&&delete I[g]}};A.exports=N},function(A,M,t){"use strict";function I(A){return(""+A).replace(x,"//")}function g(A,M){this.func=A,this.context=M,this.count=0}function e(A,M,t){var I=A.func,g=A.context;I.call(g,M,A.count++)}function i(A,M,t){if(null==A)return A;var I=g.getPooled(M,t);Q(A,e,I),g.release(I)}function T(A,M,t,I){this.result=A,this.keyPrefix=M,this.func=t,this.context=I,this.count=0}function E(A,M,t){var g=A.result,e=A.keyPrefix,i=A.func,T=A.context,E=i.call(T,M,A.count++);Array.isArray(E)?N(E,g,t,B.thatReturnsArgument):null!=E&&(a.isValidElement(E)&&(E=a.cloneAndReplaceKey(E,e+(E!==M?I(E.key||"")+"/":"")+t)),g.push(E))}function N(A,M,t,g,e){var i="";null!=t&&(i=I(t)+"/");var N=T.getPooled(M,i,g,e);Q(A,E,N),T.release(N)}function o(A,M,t){if(null==A)return A;var I=[];return N(A,I,null,M,t),I}function n(A,M,t){return null}function C(A,M){return Q(A,n,null)}function c(A){var M=[];return N(A,M,null,B.thatReturnsArgument),M}var D=t(31),a=t(13),B=t(20),Q=t(123),r=D.twoArgumentPooler,s=D.fourArgumentPooler,x=/\/(?!\/)/g;g.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},D.addPoolingTo(g,r),T.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},D.addPoolingTo(T,s);var j={forEach:i,map:o,mapIntoWithKeyPrefixInternal:N,count:C,toArray:c};A.exports=j},function(A,M,t){"use strict";function I(A,M){var t=y.hasOwnProperty(M)?y[M]:null;w.hasOwnProperty(M)&&(t!==x.OVERRIDE_BASE?B(!1):void 0),A.hasOwnProperty(M)&&(t!==x.DEFINE_MANY&&t!==x.DEFINE_MANY_MERGED?B(!1):void 0)}function g(A,M){if(M){"function"==typeof M?B(!1):void 0,C.isValidElement(M)?B(!1):void 0;var t=A.prototype;M.hasOwnProperty(s)&&u.mixins(A,M.mixins);for(var g in M)if(M.hasOwnProperty(g)&&g!==s){var e=M[g];if(I(t,g),u.hasOwnProperty(g))u[g](A,e);else{var i=y.hasOwnProperty(g),N=t.hasOwnProperty(g),o="function"==typeof e,n=o&&!i&&!N&&M.autobind!==!1;if(n)t.__reactAutoBindMap||(t.__reactAutoBindMap={}),t.__reactAutoBindMap[g]=e,t[g]=e;else if(N){var c=y[g];!i||c!==x.DEFINE_MANY_MERGED&&c!==x.DEFINE_MANY?B(!1):void 0,c===x.DEFINE_MANY_MERGED?t[g]=T(t[g],e):c===x.DEFINE_MANY&&(t[g]=E(t[g],e))}else t[g]=e}}}}function e(A,M){if(M)for(var t in M){var I=M[t];if(M.hasOwnProperty(t)){var g=t in u;g?B(!1):void 0;var e=t in A;e?B(!1):void 0,A[t]=I}}}function i(A,M){A&&M&&"object"==typeof A&&"object"==typeof M?void 0:B(!1);for(var t in M)M.hasOwnProperty(t)&&(void 0!==A[t]?B(!1):void 0,A[t]=M[t]);return A}function T(A,M){return function(){var t=A.apply(this,arguments),I=M.apply(this,arguments);if(null==t)return I;if(null==I)return t;var g={};return i(g,t),i(g,I),g}}function E(A,M){return function(){A.apply(this,arguments),M.apply(this,arguments)}}function N(A,M){var t=M.bind(A);return t}function o(A){for(var M in A.__reactAutoBindMap)if(A.__reactAutoBindMap.hasOwnProperty(M)){var t=A.__reactAutoBindMap[M];A[M]=N(A,t)}}var n=t(207),C=t(13),c=(t(71),t(70),t(222)),D=t(4),a=t(50),B=t(2),Q=t(59),r=t(27),s=(t(3),r({mixins:null})),x=Q({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),j=[],y={mixins:x.DEFINE_MANY,statics:x.DEFINE_MANY,propTypes:x.DEFINE_MANY,contextTypes:x.DEFINE_MANY,childContextTypes:x.DEFINE_MANY,getDefaultProps:x.DEFINE_MANY_MERGED,getInitialState:x.DEFINE_MANY_MERGED,getChildContext:x.DEFINE_MANY_MERGED,render:x.DEFINE_ONCE,componentWillMount:x.DEFINE_MANY,componentDidMount:x.DEFINE_MANY,componentWillReceiveProps:x.DEFINE_MANY,shouldComponentUpdate:x.DEFINE_ONCE,componentWillUpdate:x.DEFINE_MANY,componentDidUpdate:x.DEFINE_MANY,componentWillUnmount:x.DEFINE_MANY,updateComponent:x.OVERRIDE_BASE},u={displayName:function(A,M){A.displayName=M},mixins:function(A,M){if(M)for(var t=0;t"+T+""},receiveComponent:function(A,M){if(A!==this._currentElement){this._currentElement=A;var t=""+A;if(t!==this._stringText){this._stringText=t;var g=i.getNode(this._rootNodeID);I.updateTextContent(g,t)}}},unmountComponent:function(){e.unmountIDFromEnvironment(this._rootNodeID)}}),A.exports=o},function(A,M,t){"use strict";function I(){this.reinitializeTransaction()}var g=t(18),e=t(73),i=t(4),T=t(20),E={initialize:T,close:function(){C.isBatchingUpdates=!1}},N={initialize:T,close:g.flushBatchedUpdates.bind(g)},o=[N,E];i(I.prototype,e.Mixin,{getTransactionWrappers:function(){return o}});var n=new I,C={isBatchingUpdates:!1,batchedUpdates:function(A,M,t,I,g,e){var i=C.isBatchingUpdates;C.isBatchingUpdates=!0,i?A(M,t,I,g,e):n.perform(A,null,M,t,I,g,e)}};A.exports=C},function(A,M,t){"use strict";function I(){if(!L){L=!0,Q.EventEmitter.injectReactEventListener(B),Q.EventPluginHub.injectEventPluginOrder(T),Q.EventPluginHub.injectInstanceHandle(r),Q.EventPluginHub.injectMount(s),Q.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:u,EnterLeaveEventPlugin:E,ChangeEventPlugin:e,SelectEventPlugin:j,BeforeInputEventPlugin:g}),Q.NativeComponent.injectGenericComponentClass(D),Q.NativeComponent.injectTextComponentClass(a),Q.Class.injectMixin(n),Q.DOMProperty.injectDOMPropertyConfig(o),Q.DOMProperty.injectDOMPropertyConfig(w),Q.EmptyComponent.injectEmptyComponent("noscript"),Q.Updates.injectReconcileTransaction(x),Q.Updates.injectBatchingStrategy(c),Q.RootIndex.injectCreateReactRootIndex(N.canUseDOM?i.createReactRootIndex:y.createReactRootIndex),Q.Component.injectEnvironment(C)}}var g=t(430),e=t(432),i=t(433),T=t(435),E=t(436),N=t(10),o=t(439),n=t(441),C=t(109),c=t(212),D=t(445),a=t(211),B=t(453),Q=t(454),r=t(48),s=t(12),x=t(458),j=t(464),y=t(465),u=t(466),w=t(463),L=!1;A.exports={inject:I}},function(A,M,t){"use strict";function I(){if(n.current){var A=n.current.getName();if(A)return" Check the render method of ` + "`" + `"+A+"` + "`" + `."}return""}function g(A,M){if(A._store&&!A._store.validated&&null==A.key){A._store.validated=!0;e("uniqueKey",A,M)}}function e(A,M,t){var g=I();if(!g){var e="string"==typeof t?t:t.displayName||t.name;e&&(g=" Check the top-level render call using <"+e+">.")}var i=D[A]||(D[A]={});if(i[g])return null;i[g]=!0;var T={parentOrOwner:g,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return M&&M._owner&&M._owner!==n.current&&(T.childOwner=" It was passed a child from "+M._owner.getName()+"."),T}function i(A,M){if("object"==typeof A)if(Array.isArray(A))for(var t=0;t/,e={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(A){var M=I(A);return A.replace(g," "+e.CHECKSUM_ATTR_NAME+'="'+M+'"$&')},canReuseMarkup:function(A,M){var t=M.getAttribute(e.CHECKSUM_ATTR_NAME);t=t&&parseInt(t,10);var g=I(A);return g===t}};A.exports=e},function(A,M,t){"use strict";var I=t(59),g=I({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,SET_MARKUP:null,TEXT_CONTENT:null});A.exports=g},function(A,M,t){"use strict";function I(A){if("function"==typeof A.type)return A.type;var M=A.type,t=n[M];return null==t&&(n[M]=t=N(M)),t}function g(A){return o?void 0:E(!1),new o(A.type,A.props)}function e(A){return new C(A)}function i(A){return A instanceof C}var T=t(4),E=t(2),N=null,o=null,n={},C=null,c={injectGenericComponentClass:function(A){o=A},injectTextComponentClass:function(A){C=A},injectComponentClasses:function(A){T(n,A)}},D={getComponentClassForElement:I,createInternalComponent:g,createInstanceForText:e,isTextComponent:i,injection:c};A.exports=D},function(A,M,t){"use strict";function I(A,M){}var g=(t(3),{isMounted:function(A){return!1},enqueueCallback:function(A,M){},enqueueForceUpdate:function(A){I(A,"forceUpdate")},enqueueReplaceState:function(A,M){I(A,"replaceState")},enqueueSetState:function(A,M){I(A,"setState")},enqueueSetProps:function(A,M){I(A,"setProps")},enqueueReplaceProps:function(A,M){I(A,"replaceProps")}});A.exports=g},function(A,M,t){"use strict";function I(A){function M(M,t,I,g,e,i){if(g=g||y,i=i||I,null==t[I]){var T=s[e];return M?new Error("Required "+T+" ` + "`" + `"+i+"` + "`" + ` was not specified in "+("` + "`" + `"+g+"` + "`" + `.")):null}return A(t,I,g,e,i)}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}function g(A){function M(M,t,I,g,e){var i=M[t],T=a(i);if(T!==A){var E=s[g],N=B(i);return new Error("Invalid "+E+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+N+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected ")+("` + "`" + `"+A+"` + "`" + `."))}return null}return I(M)}function e(){return I(x.thatReturns(null))}function i(A){function M(M,t,I,g,e){var i=M[t];if(!Array.isArray(i)){var T=s[g],E=a(i);return new Error("Invalid "+T+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+E+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected an array."))}for(var N=0;N>"}var r=t(13),s=t(70),x=t(20),j=t(118),y="<>",u={array:g("array"),bool:g("boolean"),func:g("function"),number:g("number"),object:g("object"),string:g("string"),any:e(),arrayOf:i,element:T(),instanceOf:E,node:C(),objectOf:o,oneOf:N,oneOfType:n,shape:c};A.exports=u},function(A,M){"use strict";var t={injectCreateReactRootIndex:function(A){I.createReactRootIndex=A}},I={createReactRootIndex:null,injection:t};A.exports=I},function(A,M){"use strict";var t={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(A){t.currentScrollLeft=A.x,t.currentScrollTop=A.y}};A.exports=t},function(A,M,t){"use strict";function I(A,M){if(null==M?g(!1):void 0,null==A)return M;var t=Array.isArray(A),I=Array.isArray(M);return t&&I?(A.push.apply(A,M),A):t?(A.push(M),A):I?[A].concat(M):[A,M]}var g=t(2);A.exports=I},function(A,M){"use strict";var t=function(A,M,t){Array.isArray(A)?A.forEach(M,t):A&&M.call(t,A)};A.exports=t},function(A,M,t){"use strict";function I(){return!e&&g.canUseDOM&&(e="textContent"in document.documentElement?"textContent":"innerText"),e}var g=t(10),e=null;A.exports=I},function(A,M){"use strict";function t(A){var M=A&&A.nodeName&&A.nodeName.toLowerCase();return M&&("input"===M&&I[A.type]||"textarea"===M)}var I={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};A.exports=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){for(var A=arguments.length,M=Array(A),t=0;t=0&&s.splice(M,1)}function T(A){var M=document.createElement("style");return M.type="text/css",e(A,M),M}function E(A){var M=document.createElement("link");return M.rel="stylesheet",e(A,M),M}function N(A,M){var t,I,g;if(M.singleton){var e=r++;t=Q||(Q=T(M)),I=o.bind(null,t,e,!1),g=o.bind(null,t,e,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=E(M),I=C.bind(null,t),g=function(){i(t),t.href&&URL.revokeObjectURL(t.href)}):(t=T(M),I=n.bind(null,t),g=function(){i(t)});return I(A),function(M){if(M){if(M.css===A.css&&M.media===A.media&&M.sourceMap===A.sourceMap)return;I(A=M)}else g()}}function o(A,M,t,I){var g=t?"":I.css;if(A.styleSheet)A.styleSheet.cssText=x(M,g);else{var e=document.createTextNode(g),i=A.childNodes;i[M]&&A.removeChild(i[M]),i.length?A.insertBefore(e,i[M]):A.appendChild(e)}}function n(A,M){var t=M.css,I=M.media;if(I&&A.setAttribute("media",I),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function C(A,M){var t=M.css,I=M.sourceMap;I&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(I))))+" */");var g=new Blob([t],{type:"text/css"}),e=A.href;A.href=URL.createObjectURL(g),e&&URL.revokeObjectURL(e)}var c={},D=function(A){var M;return function(){return"undefined"==typeof M&&(M=A.apply(this,arguments)),M}},a=D(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),B=D(function(){return document.head||document.getElementsByTagName("head")[0]}),Q=null,r=0,s=[];A.exports=function(A,M){M=M||{},"undefined"==typeof M.singleton&&(M.singleton=a()),"undefined"==typeof M.insertAt&&(M.insertAt="bottom");var t=g(A);return I(t,M),function(A){for(var e=[],i=0;i",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(360);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");L&&(t.auth=L.shift(),t.host=t.hostname=L.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var l=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===l||".."===l)||""===l,d=0,h=j.length;h>=0;h--)l=j[h],"."===l?j.splice(h,1):".."===l?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var L=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");L&&(t.auth=L.shift(),t.host=t.hostname=L.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){var t={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,stopOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};A.exports=function(A,M){return"number"!=typeof M||t[A]?M:M+"px"}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M,t){return P.LoggedIn()?t():(location.pathname!==z.minioBrowserPrefix&&location.pathname!==z.minioBrowserPrefix+"/"||M(z.minioBrowserPrefix+"/login"),t())}function i(A,M){P.LoggedIn()&&M(""+z.minioBrowserPrefix)}function T(){q<2&&setTimeout(function(){document.querySelector(".page-load").classList.add("pl-"+q),q++,T()},K[q])}t(499);var E=t(1),N=g(E),o=t(16),n=g(o),C=t(485),c=g(C),D=t(125),a=g(D),B=t(230),Q=g(B),r=t(190),s=g(r),x=t(191),j=g(x),y=t(65),u=g(y),w=t(187),L=g(w),l=t(394),Y=g(l),d=t(22),h=g(d),S=t(42),z=(g(S),t(26)),p=t(19),U=I(p),O=t(255),m=g(O),F=t(245),f=g(F),k=t(241),R=g(k),J=t(498),G=(g(J),t(131)),H=g(G),b=t(60),X=g(b);window.Web=H.default;var v=(0,Q.default)(c.default)(a.default)(m.default),W=(0,h.default)(function(A){return A})(R.default),V=(0,h.default)(function(A){return A})(f.default),P=new H.default(window.location.protocol+"//"+window.location.host+z.minioBrowserPrefix+"/webrpc",v.dispatch);window.web=P,v.dispatch(U.setWeb(P));var Z=function(A){return N.default.createElement("div",null,A.children)};n.default.render(N.default.createElement(Y.default,{store:v,web:P},N.default.createElement(j.default,{history:u.default},N.default.createElement(s.default,{path:"/",component:Z},N.default.createElement(s.default,{path:"minio",component:Z},N.default.createElement(L.default,{component:W,onEnter:e}),N.default.createElement(s.default,{path:"login",component:V,onEnter:i}),N.default.createElement(s.default,{path:":bucket",component:W,onEnter:e}),N.default.createElement(s.default,{path:":bucket/*",component:W,onEnter:e}))))),document.getElementById("root"));var K=[0,400],q=0;T(),X.default.getItem("newlyUpdated")&&(v.dispatch(U.showAlert({type:"success",message:"Updated to the latest UI Version."})),X.default.removeItem("newlyUpdated"))},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=(M.currentPath,M.currentBucket),e=M.deleteConfirmation;t.RemoveObject({bucketName:g,objectName:e.object}).then(function(){A.hideDeleteConfirmation(),I(eA.removeObject(e.object))}).catch(function(A){return I(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideAlert",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAlert())}},{key:"showDeleteConfirmation",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.showDeleteConfirmation(M))}},{key:"hideDeleteConfirmation",value:function(){var A=this.props.dispatch;A(eA.hideDeleteConfirmation())}},{key:"shareObject",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.shareObject(M))}},{key:"hideShareObjectModal",value:function(){var A=this.props.dispatch;A(eA.hideShareObject())}},{key:"dataType",value:function(A,M){return NA.getDataType(A,M)}},{key:"sortObjectsByName",value:function(A){var M=this.props,t=M.dispatch,I=M.objects,g=M.sortNameOrder;t(eA.setObjects(TA.sortObjectsByName(I,!g))),t(eA.setSortNameOrder(!g))}},{key:"sortObjectsBySize",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortSizeOrder;M(eA.setObjects(TA.sortObjectsBySize(t,!I))),M(eA.setSortSizeOrder(!I))}},{key:"sortObjectsByDate",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortDateOrder;M(eA.setObjects(TA.sortObjectsByDate(t,!I))),M(eA.setSortDateOrder(!I))}},{key:"logout",value:function(A){var M=this.props.web;A.preventDefault(),M.Logout(),D.default.push(oA.minioBrowserPrefix+"/login")}},{key:"fullScreen",value:function(A){A.preventDefault();var M=document.documentElement;M.requestFullscreen&&M.requestFullscreen(),M.mozRequestFullScreen&&M.mozRequestFullScreen(),M.webkitRequestFullscreen&&M.webkitRequestFullscreen(),M.msRequestFullscreen&&M.msRequestFullscreen()}},{key:"toggleSidebar",value:function(A){this.props.dispatch(eA.setSidebarStatus(A))}},{key:"hideSidebar",value:function(A){var M=A||window.event,t=M.srcElement||M.target;3===t.nodeType&&(t=t.parentNode);var I=t.id;"feh-trigger"!==I&&this.props.dispatch(eA.setSidebarStatus(!1))}},{key:"showSettings",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showSettings())}},{key:"showMessage",value:function(){var A=this.props.dispatch;A(eA.showAlert({type:"success",message:"Link copied to clipboard!"})),this.hideShareObjectModal()}},{key:"selectTexts",value:function(){this.refs.copyTextInput.select()}},{key:"handleExpireValue",value:function(A,M){M===-1?this.refs[A].stepDown(1):this.refs[A].stepUp(1),7==this.refs.expireDays.value&&(this.refs.expireHours.value=0,this.refs.expireMins.value=0)}},{key:"render",value:function(){var A=this.props.storageInfo,M=A.total,t=A.free,I=this.props,g=I.showMakeBucketModal,e=I.alert,i=I.sortNameOrder,T=I.sortSizeOrder,E=I.sortDateOrder,N=I.showAbout,n=I.showBucketPolicy,c=this.props.serverInfo,D=c.version,a=c.memory,Q=c.platform,r=c.runtime,x=this.props.sidebarStatus,y=this.props.showSettings,w=this.props,l=w.policies,d=w.currentBucket,S=(w.currentPath,this.props.deleteConfirmation),p=this.props.shareObject,U=this.props,O=U.web,F=U.prefixWritable,k=U.istruncated,J=y?o.default.createElement(V.default,null):o.default.createElement("noscript",null),H=o.default.createElement(L.default,{className:(0,C.default)({alert:!0,animated:!0,fadeInDown:e.show,fadeOutUp:!e.show}),bsStyle:e.type,onDismiss:this.hideAlert.bind(this)},o.default.createElement("div",{className:"text-center"},e.message));e.message||(H="");var X=(o.default.createElement(h.default,{id:"tt-sign-out"},"Sign out"),o.default.createElement(h.default,{id:"tt-upload-file"},"Upload file")),W=o.default.createElement(h.default,{id:"tt-create-bucket"},"Create bucket"),P="",K="",_="",AA=M-t,tA=AA/M*100+"%";O.LoggedIn()?K=o.default.createElement($.default,{fullScreenFunc:this.fullScreen.bind(this),aboutFunc:this.showAbout.bind(this),settingsFunc:this.showSettings.bind(this),logoutFunc:this.logout.bind(this)}):P=o.default.createElement("a",{className:"btn btn-danger",href:"/minio/login"},"Login"),O.LoggedIn()&&(_=o.default.createElement("div",{className:"feh-usage"},o.default.createElement("div",{className:"fehu-chart"},o.default.createElement("div",{style:{width:tA}})),o.default.createElement("ul",null,o.default.createElement("li",null,"Used:",B.default.filesize(M-t)),o.default.createElement("li",{className:"pull-right"},"Free:",B.default.filesize(M-AA)))));var gA="";return O.LoggedIn()?gA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:X},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," "))),o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-bucket",onClick:this.showMakeBucketModal.bind(this)},o.default.createElement("i",{className:"fa fa-hdd-o"}))))):F&&(gA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:X},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," ")))))),o.default.createElement("div",{className:(0,C.default)({"file-explorer":!0,toggled:x})},o.default.createElement(R.default,{searchBuckets:this.searchBuckets.bind(this),selectBucket:this.selectBucket.bind(this),clickOutside:this.hideSidebar.bind(this),showPolicy:this.showBucketPolicy.bind(this)}),o.default.createElement("div",{className:"fe-body"},o.default.createElement(m.default,null,H,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":x}),onClick:this.toggleSidebar.bind(this,!x)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),_,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),P,K)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fi-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fi-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fi-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fi-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:k,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this)})),o.default.createElement("div",{className:"text-center",style:{display:k?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(v.default,null),gA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,D)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,r)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",d,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:d}),l.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:S.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:p.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+p.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:O.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:24,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:1,max:60,defaultValue:45})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:p.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),J)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/miniobrowser"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){ -return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",expiry:604800},prefixWritable:!1},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(t.objects),e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)))}return t}},function(A,M,t){A.exports={default:t(260),__esModule:!0}},function(A,M,t){t(270),A.exports=t(49).Object.assign},function(A,M,t){var I=t(80);A.exports=function(A,M){return I.create(A,M)}},function(A,M,t){t(271),A.exports=t(49).Object.keys},function(A,M,t){t(272),A.exports=t(49).Object.setPrototypeOf},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M,t){var I=t(136);A.exports=function(A){if(!I(A))throw TypeError(A+" is not an object!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(263);A.exports=Object("z").propertyIsEnumerable(0)?Object:function(A){return"String"==I(A)?A.split(""):Object(A)}},function(A,M,t){var I=t(80),g=t(137),e=t(266);A.exports=t(135)(function(){var A=Object.assign,M={},t={},I=Symbol(),g="abcdefghijklmnopqrst";return M[I]=7,g.split("").forEach(function(A){t[A]=A}),7!=A({},M)[I]||Object.keys(A({},t)).join("")!=g})?function(A,M){for(var t=g(A),i=arguments,T=i.length,E=1,N=I.getKeys,o=I.getSymbols,n=I.isEnum;T>E;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(135);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(136),e=t(262),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(134)(Function.call,I(Object.prototype,"__proto__").set,2), -g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(267)})},function(A,M,t){var I=t(137);t(268)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(269).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;g-1&&A%1==0&&A1)for(var t=1;tA.clientHeight}Object.defineProperty(M,"__esModule",{value:!0}),M.default=i;var T=t(57),E=I(T),N=t(39),o=I(N);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):"function"!==E&&"string"!==E?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):null}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M){"use strict";function t(A){function M(M,t,I,g,e,i){var T=g||"<>",E=i||I;if(null==t[I])return M?new Error("Required "+e+" ` + "`" + `"+E+"` + "`" + ` was not specified "+("in ` + "`" + `"+T+"` + "`" + `.")):null;for(var N=arguments.length,o=Array(N>6?N-6:0),n=6;n=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return 0===A.button}function i(A){return!!(A.metaKey||A.altKey||A.ctrlKey||A.shiftKey)}function T(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!1;return!0}function E(A,M){var t=M.query,I=M.hash,g=M.state;return t||I||g?{pathname:A,query:t,hash:I,state:g}:A}M.__esModule=!0;var N=Object.assign||function(A){for(var M=1;M=0;I--){var g=A[I],e=g.path||"";if(t=e.replace(/\/*$/,"/")+t,0===e.indexOf("/"))break}return"/"+t}},propTypes:{path:C,from:C,to:C.isRequired,query:c,state:c,onEnter:o.falsy,children:o.falsy},render:function(){(0,T.default)(!1)}});M.default=D,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0;var g=t(1),e=I(g),i=t(8),T=I(i),E=t(30),N=t(34),o=e.default.PropTypes,n=o.string,C=o.func,c=e.default.createClass({displayName:"Route",statics:{createRouteFromReactElement:E.createRouteFromReactElement},propTypes:{path:n,component:N.component,components:N.components,getComponent:C,getComponents:C},render:function(){(0,T.default)(!1)}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return!A||!A.__v2_compatible__}function i(A){return A&&A.getCurrentLocation}M.__esModule=!0;var T=Object.assign||function(A){for(var M=1;M=0&&0===window.sessionStorage.length)return;throw A}}function i(A){var M=void 0;try{M=window.sessionStorage.getItem(g(A))}catch(A){if(A.name===o)return null}if(M)try{return JSON.parse(M)}catch(A){}return null}M.__esModule=!0,M.saveState=e,M.readState=i;var T=t(23),E=(I(T),"@@History/"),N=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],o="SecurityError"},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){function M(A){return E.canUseDOM?void 0:T.default(!1),t.listen(A)}var t=n.default(e({getUserConfirmation:N.getUserConfirmation},A,{go:N.go}));return e({},t,{listen:M})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M1?M-1:0),e=1;e=A.childNodes.length?null:A.childNodes.item(t);A.insertBefore(M,I)}var g=t(434),e=t(220),i=t(17),T=t(76),E=t(121),N=t(2),o={dangerouslyReplaceNodeWithMarkup:g.dangerouslyReplaceNodeWithMarkup,updateTextContent:E,processUpdates:function(A,M){for(var t,i=null,o=null,n=0;n-1?void 0:i(!1),!N.plugins[t]){M.extractEvents?void 0:i(!1),N.plugins[t]=M;var I=M.eventTypes;for(var e in I)g(I[e],M,e)?void 0:i(!1)}}}function g(A,M,t){N.eventNameDispatchConfigs.hasOwnProperty(t)?i(!1):void 0,N.eventNameDispatchConfigs[t]=A;var I=A.phasedRegistrationNames;if(I){for(var g in I)if(I.hasOwnProperty(g)){var T=I[g];e(T,M,t)}return!0}return!!A.registrationName&&(e(A.registrationName,M,t),!0)}function e(A,M,t){N.registrationNameModules[A]?i(!1):void 0,N.registrationNameModules[A]=M,N.registrationNameDependencies[A]=M.eventTypes[t].dependencies}var i=t(2),T=null,E={},N={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(A){T?i(!1):void 0,T=Array.prototype.slice.call(A),I()},injectEventPluginsByName:function(A){var M=!1;for(var t in A)if(A.hasOwnProperty(t)){var g=A[t];E.hasOwnProperty(t)&&E[t]===g||(E[t]?i(!1):void 0,E[t]=g,M=!0)}M&&I()},getPluginModuleForEvent:function(A){var M=A.dispatchConfig;if(M.registrationName)return N.registrationNameModules[M.registrationName]||null;for(var t in M.phasedRegistrationNames)if(M.phasedRegistrationNames.hasOwnProperty(t)){var I=N.registrationNameModules[M.phasedRegistrationNames[t]];if(I)return I}return null},_resetEventPlugins:function(){T=null;for(var A in E)E.hasOwnProperty(A)&&delete E[A];N.plugins.length=0;var M=N.eventNameDispatchConfigs;for(var t in M)M.hasOwnProperty(t)&&delete M[t];var I=N.registrationNameModules;for(var g in I)I.hasOwnProperty(g)&&delete I[g]}};A.exports=N},function(A,M,t){"use strict";function I(A){return(""+A).replace(x,"//")}function g(A,M){this.func=A,this.context=M,this.count=0}function e(A,M,t){var I=A.func,g=A.context;I.call(g,M,A.count++)}function i(A,M,t){if(null==A)return A;var I=g.getPooled(M,t);Q(A,e,I),g.release(I)}function T(A,M,t,I){this.result=A,this.keyPrefix=M,this.func=t,this.context=I,this.count=0}function E(A,M,t){var g=A.result,e=A.keyPrefix,i=A.func,T=A.context,E=i.call(T,M,A.count++);Array.isArray(E)?N(E,g,t,B.thatReturnsArgument):null!=E&&(a.isValidElement(E)&&(E=a.cloneAndReplaceKey(E,e+(E!==M?I(E.key||"")+"/":"")+t)),g.push(E))}function N(A,M,t,g,e){var i="";null!=t&&(i=I(t)+"/");var N=T.getPooled(M,i,g,e);Q(A,E,N),T.release(N)}function o(A,M,t){if(null==A)return A;var I=[];return N(A,I,null,M,t),I}function n(A,M,t){return null}function C(A,M){return Q(A,n,null)}function c(A){var M=[];return N(A,M,null,B.thatReturnsArgument),M}var D=t(31),a=t(13),B=t(20),Q=t(123),r=D.twoArgumentPooler,s=D.fourArgumentPooler,x=/\/(?!\/)/g;g.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},D.addPoolingTo(g,r),T.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},D.addPoolingTo(T,s);var j={forEach:i,map:o,mapIntoWithKeyPrefixInternal:N,count:C,toArray:c};A.exports=j},function(A,M,t){"use strict";function I(A,M){var t=y.hasOwnProperty(M)?y[M]:null;w.hasOwnProperty(M)&&(t!==x.OVERRIDE_BASE?B(!1):void 0),A.hasOwnProperty(M)&&(t!==x.DEFINE_MANY&&t!==x.DEFINE_MANY_MERGED?B(!1):void 0)}function g(A,M){if(M){"function"==typeof M?B(!1):void 0,C.isValidElement(M)?B(!1):void 0;var t=A.prototype;M.hasOwnProperty(s)&&u.mixins(A,M.mixins);for(var g in M)if(M.hasOwnProperty(g)&&g!==s){var e=M[g];if(I(t,g),u.hasOwnProperty(g))u[g](A,e);else{var i=y.hasOwnProperty(g),N=t.hasOwnProperty(g),o="function"==typeof e,n=o&&!i&&!N&&M.autobind!==!1;if(n)t.__reactAutoBindMap||(t.__reactAutoBindMap={}),t.__reactAutoBindMap[g]=e,t[g]=e;else if(N){var c=y[g];!i||c!==x.DEFINE_MANY_MERGED&&c!==x.DEFINE_MANY?B(!1):void 0,c===x.DEFINE_MANY_MERGED?t[g]=T(t[g],e):c===x.DEFINE_MANY&&(t[g]=E(t[g],e))}else t[g]=e}}}}function e(A,M){if(M)for(var t in M){var I=M[t];if(M.hasOwnProperty(t)){var g=t in u;g?B(!1):void 0;var e=t in A;e?B(!1):void 0,A[t]=I}}}function i(A,M){A&&M&&"object"==typeof A&&"object"==typeof M?void 0:B(!1);for(var t in M)M.hasOwnProperty(t)&&(void 0!==A[t]?B(!1):void 0,A[t]=M[t]);return A}function T(A,M){return function(){var t=A.apply(this,arguments),I=M.apply(this,arguments);if(null==t)return I;if(null==I)return t;var g={};return i(g,t),i(g,I),g}}function E(A,M){return function(){A.apply(this,arguments),M.apply(this,arguments)}}function N(A,M){var t=M.bind(A);return t}function o(A){for(var M in A.__reactAutoBindMap)if(A.__reactAutoBindMap.hasOwnProperty(M)){var t=A.__reactAutoBindMap[M];A[M]=N(A,t)}}var n=t(207),C=t(13),c=(t(71),t(70),t(222)),D=t(4),a=t(50),B=t(2),Q=t(59),r=t(27),s=(t(3),r({mixins:null})),x=Q({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),j=[],y={mixins:x.DEFINE_MANY,statics:x.DEFINE_MANY,propTypes:x.DEFINE_MANY,contextTypes:x.DEFINE_MANY,childContextTypes:x.DEFINE_MANY,getDefaultProps:x.DEFINE_MANY_MERGED,getInitialState:x.DEFINE_MANY_MERGED,getChildContext:x.DEFINE_MANY_MERGED,render:x.DEFINE_ONCE,componentWillMount:x.DEFINE_MANY,componentDidMount:x.DEFINE_MANY,componentWillReceiveProps:x.DEFINE_MANY,shouldComponentUpdate:x.DEFINE_ONCE,componentWillUpdate:x.DEFINE_MANY,componentDidUpdate:x.DEFINE_MANY,componentWillUnmount:x.DEFINE_MANY,updateComponent:x.OVERRIDE_BASE},u={displayName:function(A,M){A.displayName=M},mixins:function(A,M){if(M)for(var t=0;t"+T+""},receiveComponent:function(A,M){if(A!==this._currentElement){this._currentElement=A;var t=""+A;if(t!==this._stringText){this._stringText=t;var g=i.getNode(this._rootNodeID);I.updateTextContent(g,t)}}},unmountComponent:function(){e.unmountIDFromEnvironment(this._rootNodeID)}}),A.exports=o},function(A,M,t){"use strict";function I(){this.reinitializeTransaction()}var g=t(18),e=t(73),i=t(4),T=t(20),E={initialize:T,close:function(){C.isBatchingUpdates=!1}},N={initialize:T,close:g.flushBatchedUpdates.bind(g)},o=[N,E];i(I.prototype,e.Mixin,{getTransactionWrappers:function(){return o}});var n=new I,C={isBatchingUpdates:!1,batchedUpdates:function(A,M,t,I,g,e){var i=C.isBatchingUpdates;C.isBatchingUpdates=!0,i?A(M,t,I,g,e):n.perform(A,null,M,t,I,g,e)}};A.exports=C},function(A,M,t){"use strict";function I(){if(!l){l=!0,Q.EventEmitter.injectReactEventListener(B),Q.EventPluginHub.injectEventPluginOrder(T),Q.EventPluginHub.injectInstanceHandle(r),Q.EventPluginHub.injectMount(s),Q.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:u,EnterLeaveEventPlugin:E,ChangeEventPlugin:e,SelectEventPlugin:j,BeforeInputEventPlugin:g}),Q.NativeComponent.injectGenericComponentClass(D),Q.NativeComponent.injectTextComponentClass(a),Q.Class.injectMixin(n),Q.DOMProperty.injectDOMPropertyConfig(o),Q.DOMProperty.injectDOMPropertyConfig(w),Q.EmptyComponent.injectEmptyComponent("noscript"),Q.Updates.injectReconcileTransaction(x),Q.Updates.injectBatchingStrategy(c),Q.RootIndex.injectCreateReactRootIndex(N.canUseDOM?i.createReactRootIndex:y.createReactRootIndex),Q.Component.injectEnvironment(C)}}var g=t(430),e=t(432),i=t(433),T=t(435),E=t(436),N=t(10),o=t(439),n=t(441),C=t(109),c=t(212),D=t(445),a=t(211),B=t(453),Q=t(454),r=t(48),s=t(12),x=t(458),j=t(464),y=t(465),u=t(466),w=t(463),l=!1;A.exports={inject:I}},function(A,M,t){"use strict";function I(){if(n.current){var A=n.current.getName();if(A)return" Check the render method of ` + "`" + `"+A+"` + "`" + `."}return""}function g(A,M){if(A._store&&!A._store.validated&&null==A.key){A._store.validated=!0;e("uniqueKey",A,M)}}function e(A,M,t){var g=I();if(!g){var e="string"==typeof t?t:t.displayName||t.name;e&&(g=" Check the top-level render call using <"+e+">.")}var i=D[A]||(D[A]={});if(i[g])return null;i[g]=!0;var T={parentOrOwner:g,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return M&&M._owner&&M._owner!==n.current&&(T.childOwner=" It was passed a child from "+M._owner.getName()+"."),T}function i(A,M){if("object"==typeof A)if(Array.isArray(A))for(var t=0;t/,e={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(A){var M=I(A);return A.replace(g," "+e.CHECKSUM_ATTR_NAME+'="'+M+'"$&')},canReuseMarkup:function(A,M){var t=M.getAttribute(e.CHECKSUM_ATTR_NAME);t=t&&parseInt(t,10);var g=I(A);return g===t}};A.exports=e},function(A,M,t){"use strict";var I=t(59),g=I({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,SET_MARKUP:null,TEXT_CONTENT:null});A.exports=g},function(A,M,t){"use strict";function I(A){if("function"==typeof A.type)return A.type;var M=A.type,t=n[M];return null==t&&(n[M]=t=N(M)),t}function g(A){return o?void 0:E(!1),new o(A.type,A.props)}function e(A){return new C(A)}function i(A){return A instanceof C}var T=t(4),E=t(2),N=null,o=null,n={},C=null,c={injectGenericComponentClass:function(A){o=A},injectTextComponentClass:function(A){C=A},injectComponentClasses:function(A){T(n,A)}},D={getComponentClassForElement:I,createInternalComponent:g,createInstanceForText:e,isTextComponent:i,injection:c};A.exports=D},function(A,M,t){"use strict";function I(A,M){}var g=(t(3),{isMounted:function(A){return!1},enqueueCallback:function(A,M){},enqueueForceUpdate:function(A){I(A,"forceUpdate")},enqueueReplaceState:function(A,M){I(A,"replaceState")},enqueueSetState:function(A,M){I(A,"setState")},enqueueSetProps:function(A,M){I(A,"setProps")},enqueueReplaceProps:function(A,M){I(A,"replaceProps")}});A.exports=g},function(A,M,t){"use strict";function I(A){function M(M,t,I,g,e,i){if(g=g||y,i=i||I,null==t[I]){var T=s[e];return M?new Error("Required "+T+" ` + "`" + `"+i+"` + "`" + ` was not specified in "+("` + "`" + `"+g+"` + "`" + `.")):null}return A(t,I,g,e,i)}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}function g(A){function M(M,t,I,g,e){var i=M[t],T=a(i);if(T!==A){var E=s[g],N=B(i);return new Error("Invalid "+E+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+N+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected ")+("` + "`" + `"+A+"` + "`" + `."))}return null}return I(M)}function e(){return I(x.thatReturns(null))}function i(A){function M(M,t,I,g,e){var i=M[t];if(!Array.isArray(i)){var T=s[g],E=a(i);return new Error("Invalid "+T+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+E+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected an array."))}for(var N=0;N>"}var r=t(13),s=t(70),x=t(20),j=t(118),y="<>",u={array:g("array"),bool:g("boolean"),func:g("function"),number:g("number"),object:g("object"),string:g("string"),any:e(),arrayOf:i,element:T(),instanceOf:E,node:C(),objectOf:o,oneOf:N,oneOfType:n,shape:c};A.exports=u},function(A,M){"use strict";var t={injectCreateReactRootIndex:function(A){I.createReactRootIndex=A}},I={createReactRootIndex:null,injection:t};A.exports=I},function(A,M){"use strict";var t={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(A){t.currentScrollLeft=A.x,t.currentScrollTop=A.y}};A.exports=t},function(A,M,t){"use strict";function I(A,M){if(null==M?g(!1):void 0,null==A)return M;var t=Array.isArray(A),I=Array.isArray(M);return t&&I?(A.push.apply(A,M),A):t?(A.push(M),A):I?[A].concat(M):[A,M]}var g=t(2);A.exports=I},function(A,M){"use strict";var t=function(A,M,t){Array.isArray(A)?A.forEach(M,t):A&&M.call(t,A)};A.exports=t},function(A,M,t){"use strict";function I(){return!e&&g.canUseDOM&&(e="textContent"in document.documentElement?"textContent":"innerText"),e}var g=t(10),e=null;A.exports=I},function(A,M){"use strict";function t(A){var M=A&&A.nodeName&&A.nodeName.toLowerCase();return M&&("input"===M&&I[A.type]||"textarea"===M)}var I={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};A.exports=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){for(var A=arguments.length,M=Array(A),t=0;t=0&&s.splice(M,1)}function T(A){var M=document.createElement("style");return M.type="text/css",e(A,M),M}function E(A){var M=document.createElement("link");return M.rel="stylesheet",e(A,M),M}function N(A,M){var t,I,g;if(M.singleton){var e=r++;t=Q||(Q=T(M)),I=o.bind(null,t,e,!1),g=o.bind(null,t,e,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=E(M),I=C.bind(null,t),g=function(){i(t),t.href&&URL.revokeObjectURL(t.href)}):(t=T(M),I=n.bind(null,t),g=function(){i(t)});return I(A),function(M){if(M){if(M.css===A.css&&M.media===A.media&&M.sourceMap===A.sourceMap)return;I(A=M)}else g()}}function o(A,M,t,I){var g=t?"":I.css;if(A.styleSheet)A.styleSheet.cssText=x(M,g);else{var e=document.createTextNode(g),i=A.childNodes;i[M]&&A.removeChild(i[M]),i.length?A.insertBefore(e,i[M]):A.appendChild(e)}}function n(A,M){var t=M.css,I=M.media;if(I&&A.setAttribute("media",I),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function C(A,M){var t=M.css,I=M.sourceMap;I&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(I))))+" */");var g=new Blob([t],{type:"text/css"}),e=A.href;A.href=URL.createObjectURL(g),e&&URL.revokeObjectURL(e)}var c={},D=function(A){var M;return function(){return"undefined"==typeof M&&(M=A.apply(this,arguments)),M}},a=D(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),B=D(function(){return document.head||document.getElementsByTagName("head")[0]}),Q=null,r=0,s=[];A.exports=function(A,M){M=M||{},"undefined"==typeof M.singleton&&(M.singleton=a()),"undefined"==typeof M.insertAt&&(M.insertAt="bottom");var t=g(A);return I(t,M),function(A){for(var e=[],i=0;i",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(360);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){var t={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,stopOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};A.exports=function(A,M){return"number"!=typeof M||t[A]?M:M+"px"}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M,t){return P.LoggedIn()?t():(location.pathname!==z.minioBrowserPrefix&&location.pathname!==z.minioBrowserPrefix+"/"||M(z.minioBrowserPrefix+"/login"),t())}function i(A,M){P.LoggedIn()&&M(""+z.minioBrowserPrefix)}function T(){q<2&&setTimeout(function(){document.querySelector(".page-load").classList.add("pl-"+q),q++,T()},K[q])}t(499);var E=t(1),N=g(E),o=t(16),n=g(o),C=t(485),c=g(C),D=t(125),a=g(D),B=t(230),Q=g(B),r=t(190),s=g(r),x=t(191),j=g(x),y=t(65),u=g(y),w=t(187),l=g(w),L=t(394),Y=g(L),d=t(22),h=g(d),S=t(42),z=(g(S),t(26)),p=t(19),U=I(p),O=t(255),m=g(O),F=t(245),f=g(F),k=t(241),R=g(k),J=t(498),G=(g(J),t(131)),H=g(G),b=t(60),v=g(b);window.Web=H.default;var X=(0,Q.default)(c.default)(a.default)(m.default),W=(0,h.default)(function(A){return A})(R.default),V=(0,h.default)(function(A){return A})(f.default),P=new H.default(window.location.protocol+"//"+window.location.host+z.minioBrowserPrefix+"/webrpc",X.dispatch);window.web=P,X.dispatch(U.setWeb(P));var Z=function(A){return N.default.createElement("div",null,A.children)};n.default.render(N.default.createElement(Y.default,{store:X,web:P},N.default.createElement(j.default,{history:u.default},N.default.createElement(s.default,{path:"/",component:Z},N.default.createElement(s.default,{path:"minio",component:Z},N.default.createElement(l.default,{component:W,onEnter:e}),N.default.createElement(s.default,{path:"login",component:V,onEnter:i}),N.default.createElement(s.default,{path:":bucket",component:W,onEnter:e}),N.default.createElement(s.default,{path:":bucket/*",component:W,onEnter:e}))))),document.getElementById("root"));var K=[0,400],q=0;T(),v.default.getItem("newlyUpdated")&&(X.dispatch(U.showAlert({type:"success",message:"Updated to the latest UI Version."})),v.default.removeItem("newlyUpdated"))},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=(M.currentPath,M.currentBucket),e=M.deleteConfirmation;t.RemoveObject({bucketName:g,objectName:e.object}).then(function(){A.hideDeleteConfirmation(),I(eA.removeObject(e.object))}).catch(function(A){return I(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideAlert",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAlert())}},{key:"showDeleteConfirmation",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.showDeleteConfirmation(M))}},{key:"hideDeleteConfirmation",value:function(){var A=this.props.dispatch;A(eA.hideDeleteConfirmation())}},{key:"shareObject",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.shareObject(M))}},{key:"hideShareObjectModal",value:function(){var A=this.props.dispatch;A(eA.hideShareObject())}},{key:"dataType",value:function(A,M){return NA.getDataType(A,M)}},{key:"sortObjectsByName",value:function(A){var M=this.props,t=M.dispatch,I=M.objects,g=M.sortNameOrder;t(eA.setObjects(TA.sortObjectsByName(I,!g))),t(eA.setSortNameOrder(!g))}},{key:"sortObjectsBySize",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortSizeOrder;M(eA.setObjects(TA.sortObjectsBySize(t,!I))),M(eA.setSortSizeOrder(!I))}},{key:"sortObjectsByDate",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortDateOrder;M(eA.setObjects(TA.sortObjectsByDate(t,!I))),M(eA.setSortDateOrder(!I))}},{key:"logout",value:function(A){var M=this.props.web;A.preventDefault(),M.Logout(),D.default.push(oA.minioBrowserPrefix+"/login")}},{key:"fullScreen",value:function(A){A.preventDefault();var M=document.documentElement;M.requestFullscreen&&M.requestFullscreen(),M.mozRequestFullScreen&&M.mozRequestFullScreen(),M.webkitRequestFullscreen&&M.webkitRequestFullscreen(),M.msRequestFullscreen&&M.msRequestFullscreen()}},{key:"toggleSidebar",value:function(A){this.props.dispatch(eA.setSidebarStatus(A))}},{key:"hideSidebar",value:function(A){var M=A||window.event,t=M.srcElement||M.target;3===t.nodeType&&(t=t.parentNode);var I=t.id;"feh-trigger"!==I&&this.props.dispatch(eA.setSidebarStatus(!1))}},{key:"showSettings",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showSettings())}},{key:"showMessage",value:function(){var A=this.props.dispatch;A(eA.showAlert({type:"success",message:"Link copied to clipboard!"})),this.hideShareObjectModal()}},{key:"selectTexts",value:function(){this.refs.copyTextInput.select()}},{key:"handleExpireValue",value:function(A,M){M===-1?this.refs[A].stepDown(1):this.refs[A].stepUp(1),7==this.refs.expireDays.value&&(this.refs.expireHours.value=0,this.refs.expireMins.value=0)}},{key:"checkObject",value:function(A,M){var t=this.props.dispatch;t(A.target.checked?eA.checkedObjectsAdd(M):eA.checkedObjectsRemove(M))}},{key:"downloadAll",value:function(){var A=this.props.dispatch,M={bucketName:this.props.currentBucket,objects:this.props.checkedObjects,prefix:this.props.currentPath},t=location.origin+"/minio/zip?token="+localStorage.token;this.xhr=new XMLHttpRequest,A(eA.downloadAllasZip(t,M,this.xhr))}},{key:"render",value:function(){var A=this.props.storageInfo,M=A.total,t=A.free,I=this.props,g=I.showMakeBucketModal,e=I.alert,i=I.sortNameOrder,T=I.sortSizeOrder,E=I.sortDateOrder,N=I.showAbout,n=I.showBucketPolicy,c=I.checkedObjects,D=this.props.serverInfo,a=D.version,Q=D.memory,r=D.platform,x=D.runtime,y=this.props.sidebarStatus,w=this.props.showSettings,L=this.props,d=L.policies,S=L.currentBucket,p=(L.currentPath,this.props.deleteConfirmation),U=this.props.shareObject,O=this.props,F=O.web,k=O.prefixWritable,J=O.istruncated,H=w?o.default.createElement(V.default,null):o.default.createElement("noscript",null),v=o.default.createElement(l.default,{className:(0,C.default)({alert:!0,animated:!0,fadeInDown:e.show,fadeOutUp:!e.show}),bsStyle:e.type,onDismiss:this.hideAlert.bind(this)},o.default.createElement("div",{className:"text-center"},e.message));e.message||(v="");var W=(o.default.createElement(h.default,{id:"tt-sign-out"},"Sign out"),o.default.createElement(h.default,{id:"tt-upload-file"},"Upload file")),P=o.default.createElement(h.default,{id:"tt-create-bucket"},"Create bucket"),K="",_="",AA="",tA=M-t,gA=tA/M*100+"%";F.LoggedIn()?_=o.default.createElement($.default,{fullScreenFunc:this.fullScreen.bind(this),aboutFunc:this.showAbout.bind(this),settingsFunc:this.showSettings.bind(this),logoutFunc:this.logout.bind(this)}):K=o.default.createElement("a",{className:"btn btn-danger",href:"/minio/login"},"Login"),F.LoggedIn()&&(AA=o.default.createElement("div",{className:"feh-usage"},o.default.createElement("div",{className:"fehu-chart"},o.default.createElement("div",{style:{width:gA}})),o.default.createElement("ul",null,o.default.createElement("li",null,"Used:",B.default.filesize(M-t)),o.default.createElement("li",{className:"pull-right"},"Free:",B.default.filesize(M-tA)))));var eA="";return F.LoggedIn()?eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," "))),o.default.createElement(Y.default,{placement:"left",overlay:P},o.default.createElement("a",{href:"#",className:"feba-btn feba-bucket",onClick:this.showMakeBucketModal.bind(this)},o.default.createElement("i",{className:"fa fa-hdd-o"}))))):k&&(eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," ")))))),o.default.createElement("div",{className:(0,C.default)({"file-explorer":!0,toggled:y})},o.default.createElement(R.default,{searchBuckets:this.searchBuckets.bind(this),selectBucket:this.selectBucket.bind(this),clickOutside:this.hideSidebar.bind(this),showPolicy:this.showBucketPolicy.bind(this)}),o.default.createElement("div",{className:"fe-body"},o.default.createElement("div",{className:"list-actions"+(0,C.default)({" list-actions-toggled":c.length>0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadAll.bind(this)}," Download all as zip "))),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:24,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:1,max:60,defaultValue:45})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{ +className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1?" fesl-row-selected":"";return e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",expiry:604800},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(t.objects),e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return console.log(t.checkedObjects),t}},function(A,M,t){A.exports={default:t(260),__esModule:!0}},function(A,M,t){t(270),A.exports=t(49).Object.assign; +},function(A,M,t){var I=t(80);A.exports=function(A,M){return I.create(A,M)}},function(A,M,t){t(271),A.exports=t(49).Object.keys},function(A,M,t){t(272),A.exports=t(49).Object.setPrototypeOf},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M,t){var I=t(136);A.exports=function(A){if(!I(A))throw TypeError(A+" is not an object!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(263);A.exports=Object("z").propertyIsEnumerable(0)?Object:function(A){return"String"==I(A)?A.split(""):Object(A)}},function(A,M,t){var I=t(80),g=t(137),e=t(266);A.exports=t(135)(function(){var A=Object.assign,M={},t={},I=Symbol(),g="abcdefghijklmnopqrst";return M[I]=7,g.split("").forEach(function(A){t[A]=A}),7!=A({},M)[I]||Object.keys(A({},t)).join("")!=g})?function(A,M){for(var t=g(A),i=arguments,T=i.length,E=1,N=I.getKeys,o=I.getSymbols,n=I.isEnum;T>E;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(135);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(136),e=t(262),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(134)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(267)})},function(A,M,t){var I=t(137);t(268)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(269).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;gli{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\\F000"}.fa-music:before{content:"\\F001"}.fa-search:before{content:"\\F002"}.fa-envelope-o:before{content:"\\F003"}.fa-heart:before{content:"\\F004"}.fa-star:before{content:"\\F005"}.fa-star-o:before{content:"\\F006"}.fa-user:before{content:"\\F007"}.fa-film:before{content:"\\F008"}.fa-th-large:before{content:"\\F009"}.fa-th:before{content:"\\F00A"}.fa-th-list:before{content:"\\F00B"}.fa-check:before{content:"\\F00C"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\\F00D"}.fa-search-plus:before{content:"\\F00E"}.fa-search-minus:before{content:"\\F010"}.fa-power-off:before{content:"\\F011"}.fa-signal:before{content:"\\F012"}.fa-cog:before,.fa-gear:before{content:"\\F013"}.fa-trash-o:before{content:"\\F014"}.fa-home:before{content:"\\F015"}.fa-file-o:before{content:"\\F016"}.fa-clock-o:before{content:"\\F017"}.fa-road:before{content:"\\F018"}.fa-download:before{content:"\\F019"}.fa-arrow-circle-o-down:before{content:"\\F01A"}.fa-arrow-circle-o-up:before{content:"\\F01B"}.fa-inbox:before{content:"\\F01C"}.fa-play-circle-o:before{content:"\\F01D"}.fa-repeat:before,.fa-rotate-right:before{content:"\\F01E"}.fa-refresh:before{content:"\\F021"}.fa-list-alt:before{content:"\\F022"}.fa-lock:before{content:"\\F023"}.fa-flag:before{content:"\\F024"}.fa-headphones:before{content:"\\F025"}.fa-volume-off:before{content:"\\F026"}.fa-volume-down:before{content:"\\F027"}.fa-volume-up:before{content:"\\F028"}.fa-qrcode:before{content:"\\F029"}.fa-barcode:before{content:"\\F02A"}.fa-tag:before{content:"\\F02B"}.fa-tags:before{content:"\\F02C"}.fa-book:before{content:"\\F02D"}.fa-bookmark:before{content:"\\F02E"}.fa-print:before{content:"\\F02F"}.fa-camera:before{content:"\\F030"}.fa-font:before{content:"\\F031"}.fa-bold:before{content:"\\F032"}.fa-italic:before{content:"\\F033"}.fa-text-height:before{content:"\\F034"}.fa-text-width:before{content:"\\F035"}.fa-align-left:before{content:"\\F036"}.fa-align-center:before{content:"\\F037"}.fa-align-right:before{content:"\\F038"}.fa-align-justify:before{content:"\\F039"}.fa-list:before{content:"\\F03A"}.fa-dedent:before,.fa-outdent:before{content:"\\F03B"}.fa-indent:before{content:"\\F03C"}.fa-video-camera:before{content:"\\F03D"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\\F03E"}.fa-pencil:before{content:"\\F040"}.fa-map-marker:before{content:"\\F041"}.fa-adjust:before{content:"\\F042"}.fa-tint:before{content:"\\F043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\\F044"}.fa-share-square-o:before{content:"\\F045"}.fa-check-square-o:before{content:"\\F046"}.fa-arrows:before{content:"\\F047"}.fa-step-backward:before{content:"\\F048"}.fa-fast-backward:before{content:"\\F049"}.fa-backward:before{content:"\\F04A"}.fa-play:before{content:"\\F04B"}.fa-pause:before{content:"\\F04C"}.fa-stop:before{content:"\\F04D"}.fa-forward:before{content:"\\F04E"}.fa-fast-forward:before{content:"\\F050"}.fa-step-forward:before{content:"\\F051"}.fa-eject:before{content:"\\F052"}.fa-chevron-left:before{content:"\\F053"}.fa-chevron-right:before{content:"\\F054"}.fa-plus-circle:before{content:"\\F055"}.fa-minus-circle:before{content:"\\F056"}.fa-times-circle:before{content:"\\F057"}.fa-check-circle:before{content:"\\F058"}.fa-question-circle:before{content:"\\F059"}.fa-info-circle:before{content:"\\F05A"}.fa-crosshairs:before{content:"\\F05B"}.fa-times-circle-o:before{content:"\\F05C"}.fa-check-circle-o:before{content:"\\F05D"}.fa-ban:before{content:"\\F05E"}.fa-arrow-left:before{content:"\\F060"}.fa-arrow-right:before{content:"\\F061"}.fa-arrow-up:before{content:"\\F062"}.fa-arrow-down:before{content:"\\F063"}.fa-mail-forward:before,.fa-share:before{content:"\\F064"}.fa-expand:before{content:"\\F065"}.fa-compress:before{content:"\\F066"}.fa-plus:before{content:"\\F067"}.fa-minus:before{content:"\\F068"}.fa-asterisk:before{content:"\\F069"}.fa-exclamation-circle:before{content:"\\F06A"}.fa-gift:before{content:"\\F06B"}.fa-leaf:before{content:"\\F06C"}.fa-fire:before{content:"\\F06D"}.fa-eye:before{content:"\\F06E"}.fa-eye-slash:before{content:"\\F070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\\F071"}.fa-plane:before{content:"\\F072"}.fa-calendar:before{content:"\\F073"}.fa-random:before{content:"\\F074"}.fa-comment:before{content:"\\F075"}.fa-magnet:before{content:"\\F076"}.fa-chevron-up:before{content:"\\F077"}.fa-chevron-down:before{content:"\\F078"}.fa-retweet:before{content:"\\F079"}.fa-shopping-cart:before{content:"\\F07A"}.fa-folder:before{content:"\\F07B"}.fa-folder-open:before{content:"\\F07C"}.fa-arrows-v:before{content:"\\F07D"}.fa-arrows-h:before{content:"\\F07E"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\\F080"}.fa-twitter-square:before{content:"\\F081"}.fa-facebook-square:before{content:"\\F082"}.fa-camera-retro:before{content:"\\F083"}.fa-key:before{content:"\\F084"}.fa-cogs:before,.fa-gears:before{content:"\\F085"}.fa-comments:before{content:"\\F086"}.fa-thumbs-o-up:before{content:"\\F087"}.fa-thumbs-o-down:before{content:"\\F088"}.fa-star-half:before{content:"\\F089"}.fa-heart-o:before{content:"\\F08A"}.fa-sign-out:before{content:"\\F08B"}.fa-linkedin-square:before{content:"\\F08C"}.fa-thumb-tack:before{content:"\\F08D"}.fa-external-link:before{content:"\\F08E"}.fa-sign-in:before{content:"\\F090"}.fa-trophy:before{content:"\\F091"}.fa-github-square:before{content:"\\F092"}.fa-upload:before{content:"\\F093"}.fa-lemon-o:before{content:"\\F094"}.fa-phone:before{content:"\\F095"}.fa-square-o:before{content:"\\F096"}.fa-bookmark-o:before{content:"\\F097"}.fa-phone-square:before{content:"\\F098"}.fa-twitter:before{content:"\\F099"}.fa-facebook-f:before,.fa-facebook:before{content:"\\F09A"}.fa-github:before{content:"\\F09B"}.fa-unlock:before{content:"\\F09C"}.fa-credit-card:before{content:"\\F09D"}.fa-feed:before,.fa-rss:before{content:"\\F09E"}.fa-hdd-o:before{content:"\\F0A0"}.fa-bullhorn:before{content:"\\F0A1"}.fa-bell:before{content:"\\F0F3"}.fa-certificate:before{content:"\\F0A3"}.fa-hand-o-right:before{content:"\\F0A4"}.fa-hand-o-left:before{content:"\\F0A5"}.fa-hand-o-up:before{content:"\\F0A6"}.fa-hand-o-down:before{content:"\\F0A7"}.fa-arrow-circle-left:before{content:"\\F0A8"}.fa-arrow-circle-right:before{content:"\\F0A9"}.fa-arrow-circle-up:before{content:"\\F0AA"}.fa-arrow-circle-down:before{content:"\\F0AB"}.fa-globe:before{content:"\\F0AC"}.fa-wrench:before{content:"\\F0AD"}.fa-tasks:before{content:"\\F0AE"}.fa-filter:before{content:"\\F0B0"}.fa-briefcase:before{content:"\\F0B1"}.fa-arrows-alt:before{content:"\\F0B2"}.fa-group:before,.fa-users:before{content:"\\F0C0"}.fa-chain:before,.fa-link:before{content:"\\F0C1"}.fa-cloud:before{content:"\\F0C2"}.fa-flask:before{content:"\\F0C3"}.fa-cut:before,.fa-scissors:before{content:"\\F0C4"}.fa-copy:before,.fa-files-o:before{content:"\\F0C5"}.fa-paperclip:before{content:"\\F0C6"}.fa-floppy-o:before,.fa-save:before{content:"\\F0C7"}.fa-square:before{content:"\\F0C8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\\F0C9"}.fa-list-ul:before{content:"\\F0CA"}.fa-list-ol:before{content:"\\F0CB"}.fa-strikethrough:before{content:"\\F0CC"}.fa-underline:before{content:"\\F0CD"}.fa-table:before{content:"\\F0CE"}.fa-magic:before{content:"\\F0D0"}.fa-truck:before{content:"\\F0D1"}.fa-pinterest:before{content:"\\F0D2"}.fa-pinterest-square:before{content:"\\F0D3"}.fa-google-plus-square:before{content:"\\F0D4"}.fa-google-plus:before{content:"\\F0D5"}.fa-money:before{content:"\\F0D6"}.fa-caret-down:before{content:"\\F0D7"}.fa-caret-up:before{content:"\\F0D8"}.fa-caret-left:before{content:"\\F0D9"}.fa-caret-right:before{content:"\\F0DA"}.fa-columns:before{content:"\\F0DB"}.fa-sort:before,.fa-unsorted:before{content:"\\F0DC"}.fa-sort-desc:before,.fa-sort-down:before{content:"\\F0DD"}.fa-sort-asc:before,.fa-sort-up:before{content:"\\F0DE"}.fa-envelope:before{content:"\\F0E0"}.fa-linkedin:before{content:"\\F0E1"}.fa-rotate-left:before,.fa-undo:before{content:"\\F0E2"}.fa-gavel:before,.fa-legal:before{content:"\\F0E3"}.fa-dashboard:before,.fa-tachometer:before{content:"\\F0E4"}.fa-comment-o:before{content:"\\F0E5"}.fa-comments-o:before{content:"\\F0E6"}.fa-bolt:before,.fa-flash:before{content:"\\F0E7"}.fa-sitemap:before{content:"\\F0E8"}.fa-umbrella:before{content:"\\F0E9"}.fa-clipboard:before,.fa-paste:before{content:"\\F0EA"}.fa-lightbulb-o:before{content:"\\F0EB"}.fa-exchange:before{content:"\\F0EC"}.fa-cloud-download:before{content:"\\F0ED"}.fa-cloud-upload:before{content:"\\F0EE"}.fa-user-md:before{content:"\\F0F0"}.fa-stethoscope:before{content:"\\F0F1"}.fa-suitcase:before{content:"\\F0F2"}.fa-bell-o:before{content:"\\F0A2"}.fa-coffee:before{content:"\\F0F4"}.fa-cutlery:before{content:"\\F0F5"}.fa-file-text-o:before{content:"\\F0F6"}.fa-building-o:before{content:"\\F0F7"}.fa-hospital-o:before{content:"\\F0F8"}.fa-ambulance:before{content:"\\F0F9"}.fa-medkit:before{content:"\\F0FA"}.fa-fighter-jet:before{content:"\\F0FB"}.fa-beer:before{content:"\\F0FC"}.fa-h-square:before{content:"\\F0FD"}.fa-plus-square:before{content:"\\F0FE"}.fa-angle-double-left:before{content:"\\F100"}.fa-angle-double-right:before{content:"\\F101"}.fa-angle-double-up:before{content:"\\F102"}.fa-angle-double-down:before{content:"\\F103"}.fa-angle-left:before{content:"\\F104"}.fa-angle-right:before{content:"\\F105"}.fa-angle-up:before{content:"\\F106"}.fa-angle-down:before{content:"\\F107"}.fa-desktop:before{content:"\\F108"}.fa-laptop:before{content:"\\F109"}.fa-tablet:before{content:"\\F10A"}.fa-mobile-phone:before,.fa-mobile:before{content:"\\F10B"}.fa-circle-o:before{content:"\\F10C"}.fa-quote-left:before{content:"\\F10D"}.fa-quote-right:before{content:"\\F10E"}.fa-spinner:before{content:"\\F110"}.fa-circle:before{content:"\\F111"}.fa-mail-reply:before,.fa-reply:before{content:"\\F112"}.fa-github-alt:before{content:"\\F113"}.fa-folder-o:before{content:"\\F114"}.fa-folder-open-o:before{content:"\\F115"}.fa-smile-o:before{content:"\\F118"}.fa-frown-o:before{content:"\\F119"}.fa-meh-o:before{content:"\\F11A"}.fa-gamepad:before{content:"\\F11B"}.fa-keyboard-o:before{content:"\\F11C"}.fa-flag-o:before{content:"\\F11D"}.fa-flag-checkered:before{content:"\\F11E"}.fa-terminal:before{content:"\\F120"}.fa-code:before{content:"\\F121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\\F122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\\F123"}.fa-location-arrow:before{content:"\\F124"}.fa-crop:before{content:"\\F125"}.fa-code-fork:before{content:"\\F126"}.fa-chain-broken:before,.fa-unlink:before{content:"\\F127"}.fa-question:before{content:"\\F128"}.fa-info:before{content:"\\F129"}.fa-exclamation:before{content:"\\F12A"}.fa-superscript:before{content:"\\F12B"}.fa-subscript:before{content:"\\F12C"}.fa-eraser:before{content:"\\F12D"}.fa-puzzle-piece:before{content:"\\F12E"}.fa-microphone:before{content:"\\F130"}.fa-microphone-slash:before{content:"\\F131"}.fa-shield:before{content:"\\F132"}.fa-calendar-o:before{content:"\\F133"}.fa-fire-extinguisher:before{content:"\\F134"}.fa-rocket:before{content:"\\F135"}.fa-maxcdn:before{content:"\\F136"}.fa-chevron-circle-left:before{content:"\\F137"}.fa-chevron-circle-right:before{content:"\\F138"}.fa-chevron-circle-up:before{content:"\\F139"}.fa-chevron-circle-down:before{content:"\\F13A"}.fa-html5:before{content:"\\F13B"}.fa-css3:before{content:"\\F13C"}.fa-anchor:before{content:"\\F13D"}.fa-unlock-alt:before{content:"\\F13E"}.fa-bullseye:before{content:"\\F140"}.fa-ellipsis-h:before{content:"\\F141"}.fa-ellipsis-v:before{content:"\\F142"}.fa-rss-square:before{content:"\\F143"}.fa-play-circle:before{content:"\\F144"}.fa-ticket:before{content:"\\F145"}.fa-minus-square:before{content:"\\F146"}.fa-minus-square-o:before{content:"\\F147"}.fa-level-up:before{content:"\\F148"}.fa-level-down:before{content:"\\F149"}.fa-check-square:before{content:"\\F14A"}.fa-pencil-square:before{content:"\\F14B"}.fa-external-link-square:before{content:"\\F14C"}.fa-share-square:before{content:"\\F14D"}.fa-compass:before{content:"\\F14E"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\\F150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\\F151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\\F152"}.fa-eur:before,.fa-euro:before{content:"\\F153"}.fa-gbp:before{content:"\\F154"}.fa-dollar:before,.fa-usd:before{content:"\\F155"}.fa-inr:before,.fa-rupee:before{content:"\\F156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\\F157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\\F158"}.fa-krw:before,.fa-won:before{content:"\\F159"}.fa-bitcoin:before,.fa-btc:before{content:"\\F15A"}.fa-file:before{content:"\\F15B"}.fa-file-text:before{content:"\\F15C"}.fa-sort-alpha-asc:before{content:"\\F15D"}.fa-sort-alpha-desc:before{content:"\\F15E"}.fa-sort-amount-asc:before{content:"\\F160"}.fa-sort-amount-desc:before{content:"\\F161"}.fa-sort-numeric-asc:before{content:"\\F162"}.fa-sort-numeric-desc:before{content:"\\F163"}.fa-thumbs-up:before{content:"\\F164"}.fa-thumbs-down:before{content:"\\F165"}.fa-youtube-square:before{content:"\\F166"}.fa-youtube:before{content:"\\F167"}.fa-xing:before{content:"\\F168"}.fa-xing-square:before{content:"\\F169"}.fa-youtube-play:before{content:"\\F16A"}.fa-dropbox:before{content:"\\F16B"}.fa-stack-overflow:before{content:"\\F16C"}.fa-instagram:before{content:"\\F16D"}.fa-flickr:before{content:"\\F16E"}.fa-adn:before{content:"\\F170"}.fa-bitbucket:before{content:"\\F171"}.fa-bitbucket-square:before{content:"\\F172"}.fa-tumblr:before{content:"\\F173"}.fa-tumblr-square:before{content:"\\F174"}.fa-long-arrow-down:before{content:"\\F175"}.fa-long-arrow-up:before{content:"\\F176"}.fa-long-arrow-left:before{content:"\\F177"}.fa-long-arrow-right:before{content:"\\F178"}.fa-apple:before{content:"\\F179"}.fa-windows:before{content:"\\F17A"}.fa-android:before{content:"\\F17B"}.fa-linux:before{content:"\\F17C"}.fa-dribbble:before{content:"\\F17D"}.fa-skype:before{content:"\\F17E"}.fa-foursquare:before{content:"\\F180"}.fa-trello:before{content:"\\F181"}.fa-female:before{content:"\\F182"}.fa-male:before{content:"\\F183"}.fa-gittip:before,.fa-gratipay:before{content:"\\F184"}.fa-sun-o:before{content:"\\F185"}.fa-moon-o:before{content:"\\F186"}.fa-archive:before{content:"\\F187"}.fa-bug:before{content:"\\F188"}.fa-vk:before{content:"\\F189"}.fa-weibo:before{content:"\\F18A"}.fa-renren:before{content:"\\F18B"}.fa-pagelines:before{content:"\\F18C"}.fa-stack-exchange:before{content:"\\F18D"}.fa-arrow-circle-o-right:before{content:"\\F18E"}.fa-arrow-circle-o-left:before{content:"\\F190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\\F191"}.fa-dot-circle-o:before{content:"\\F192"}.fa-wheelchair:before{content:"\\F193"}.fa-vimeo-square:before{content:"\\F194"}.fa-try:before,.fa-turkish-lira:before{content:"\\F195"}.fa-plus-square-o:before{content:"\\F196"}.fa-space-shuttle:before{content:"\\F197"}.fa-slack:before{content:"\\F198"}.fa-envelope-square:before{content:"\\F199"}.fa-wordpress:before{content:"\\F19A"}.fa-openid:before{content:"\\F19B"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\\F19C"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\\F19D"}.fa-yahoo:before{content:"\\F19E"}.fa-google:before{content:"\\F1A0"}.fa-reddit:before{content:"\\F1A1"}.fa-reddit-square:before{content:"\\F1A2"}.fa-stumbleupon-circle:before{content:"\\F1A3"}.fa-stumbleupon:before{content:"\\F1A4"}.fa-delicious:before{content:"\\F1A5"}.fa-digg:before{content:"\\F1A6"}.fa-pied-piper-pp:before{content:"\\F1A7"}.fa-pied-piper-alt:before{content:"\\F1A8"}.fa-drupal:before{content:"\\F1A9"}.fa-joomla:before{content:"\\F1AA"}.fa-language:before{content:"\\F1AB"}.fa-fax:before{content:"\\F1AC"}.fa-building:before{content:"\\F1AD"}.fa-child:before{content:"\\F1AE"}.fa-paw:before{content:"\\F1B0"}.fa-spoon:before{content:"\\F1B1"}.fa-cube:before{content:"\\F1B2"}.fa-cubes:before{content:"\\F1B3"}.fa-behance:before{content:"\\F1B4"}.fa-behance-square:before{content:"\\F1B5"}.fa-steam:before{content:"\\F1B6"}.fa-steam-square:before{content:"\\F1B7"}.fa-recycle:before{content:"\\F1B8"}.fa-automobile:before,.fa-car:before{content:"\\F1B9"}.fa-cab:before,.fa-taxi:before{content:"\\F1BA"}.fa-tree:before{content:"\\F1BB"}.fa-spotify:before{content:"\\F1BC"}.fa-deviantart:before{content:"\\F1BD"}.fa-soundcloud:before{content:"\\F1BE"}.fa-database:before{content:"\\F1C0"}.fa-file-pdf-o:before{content:"\\F1C1"}.fa-file-word-o:before{content:"\\F1C2"}.fa-file-excel-o:before{content:"\\F1C3"}.fa-file-powerpoint-o:before{content:"\\F1C4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\\F1C5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\\F1C6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\\F1C7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\\F1C8"}.fa-file-code-o:before{content:"\\F1C9"}.fa-vine:before{content:"\\F1CA"}.fa-codepen:before{content:"\\F1CB"}.fa-jsfiddle:before{content:"\\F1CC"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\\F1CD"}.fa-circle-o-notch:before{content:"\\F1CE"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\\F1D0"}.fa-empire:before,.fa-ge:before{content:"\\F1D1"}.fa-git-square:before{content:"\\F1D2"}.fa-git:before{content:"\\F1D3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\\F1D4"}.fa-tencent-weibo:before{content:"\\F1D5"}.fa-qq:before{content:"\\F1D6"}.fa-wechat:before,.fa-weixin:before{content:"\\F1D7"}.fa-paper-plane:before,.fa-send:before{content:"\\F1D8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\\F1D9"}.fa-history:before{content:"\\F1DA"}.fa-circle-thin:before{content:"\\F1DB"}.fa-header:before{content:"\\F1DC"}.fa-paragraph:before{content:"\\F1DD"}.fa-sliders:before{content:"\\F1DE"}.fa-share-alt:before{content:"\\F1E0"}.fa-share-alt-square:before{content:"\\F1E1"}.fa-bomb:before{content:"\\F1E2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\\F1E3"}.fa-tty:before{content:"\\F1E4"}.fa-binoculars:before{content:"\\F1E5"}.fa-plug:before{content:"\\F1E6"}.fa-slideshare:before{content:"\\F1E7"}.fa-twitch:before{content:"\\F1E8"}.fa-yelp:before{content:"\\F1E9"}.fa-newspaper-o:before{content:"\\F1EA"}.fa-wifi:before{content:"\\F1EB"}.fa-calculator:before{content:"\\F1EC"}.fa-paypal:before{content:"\\F1ED"}.fa-google-wallet:before{content:"\\F1EE"}.fa-cc-visa:before{content:"\\F1F0"}.fa-cc-mastercard:before{content:"\\F1F1"}.fa-cc-discover:before{content:"\\F1F2"}.fa-cc-amex:before{content:"\\F1F3"}.fa-cc-paypal:before{content:"\\F1F4"}.fa-cc-stripe:before{content:"\\F1F5"}.fa-bell-slash:before{content:"\\F1F6"}.fa-bell-slash-o:before{content:"\\F1F7"}.fa-trash:before{content:"\\F1F8"}.fa-copyright:before{content:"\\F1F9"}.fa-at:before{content:"\\F1FA"}.fa-eyedropper:before{content:"\\F1FB"}.fa-paint-brush:before{content:"\\F1FC"}.fa-birthday-cake:before{content:"\\F1FD"}.fa-area-chart:before{content:"\\F1FE"}.fa-pie-chart:before{content:"\\F200"}.fa-line-chart:before{content:"\\F201"}.fa-lastfm:before{content:"\\F202"}.fa-lastfm-square:before{content:"\\F203"}.fa-toggle-off:before{content:"\\F204"}.fa-toggle-on:before{content:"\\F205"}.fa-bicycle:before{content:"\\F206"}.fa-bus:before{content:"\\F207"}.fa-ioxhost:before{content:"\\F208"}.fa-angellist:before{content:"\\F209"}.fa-cc:before{content:"\\F20A"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\\F20B"}.fa-meanpath:before{content:"\\F20C"}.fa-buysellads:before{content:"\\F20D"}.fa-connectdevelop:before{content:"\\F20E"}.fa-dashcube:before{content:"\\F210"}.fa-forumbee:before{content:"\\F211"}.fa-leanpub:before{content:"\\F212"}.fa-sellsy:before{content:"\\F213"}.fa-shirtsinbulk:before{content:"\\F214"}.fa-simplybuilt:before{content:"\\F215"}.fa-skyatlas:before{content:"\\F216"}.fa-cart-plus:before{content:"\\F217"}.fa-cart-arrow-down:before{content:"\\F218"}.fa-diamond:before{content:"\\F219"}.fa-ship:before{content:"\\F21A"}.fa-user-secret:before{content:"\\F21B"}.fa-motorcycle:before{content:"\\F21C"}.fa-street-view:before{content:"\\F21D"}.fa-heartbeat:before{content:"\\F21E"}.fa-venus:before{content:"\\F221"}.fa-mars:before{content:"\\F222"}.fa-mercury:before{content:"\\F223"}.fa-intersex:before,.fa-transgender:before{content:"\\F224"}.fa-transgender-alt:before{content:"\\F225"}.fa-venus-double:before{content:"\\F226"}.fa-mars-double:before{content:"\\F227"}.fa-venus-mars:before{content:"\\F228"}.fa-mars-stroke:before{content:"\\F229"}.fa-mars-stroke-v:before{content:"\\F22A"}.fa-mars-stroke-h:before{content:"\\F22B"}.fa-neuter:before{content:"\\F22C"}.fa-genderless:before{content:"\\F22D"}.fa-facebook-official:before{content:"\\F230"}.fa-pinterest-p:before{content:"\\F231"}.fa-whatsapp:before{content:"\\F232"}.fa-server:before{content:"\\F233"}.fa-user-plus:before{content:"\\F234"}.fa-user-times:before{content:"\\F235"}.fa-bed:before,.fa-hotel:before{content:"\\F236"}.fa-viacoin:before{content:"\\F237"}.fa-train:before{content:"\\F238"}.fa-subway:before{content:"\\F239"}.fa-medium:before{content:"\\F23A"}.fa-y-combinator:before,.fa-yc:before{content:"\\F23B"}.fa-optin-monster:before{content:"\\F23C"}.fa-opencart:before{content:"\\F23D"}.fa-expeditedssl:before{content:"\\F23E"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:"\\F240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\\F241"}.fa-battery-2:before,.fa-battery-half:before{content:"\\F242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\\F243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\\F244"}.fa-mouse-pointer:before{content:"\\F245"}.fa-i-cursor:before{content:"\\F246"}.fa-object-group:before{content:"\\F247"}.fa-object-ungroup:before{content:"\\F248"}.fa-sticky-note:before{content:"\\F249"}.fa-sticky-note-o:before{content:"\\F24A"}.fa-cc-jcb:before{content:"\\F24B"}.fa-cc-diners-club:before{content:"\\F24C"}.fa-clone:before{content:"\\F24D"}.fa-balance-scale:before{content:"\\F24E"}.fa-hourglass-o:before{content:"\\F250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\\F251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\\F252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\\F253"}.fa-hourglass:before{content:"\\F254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\\F255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\\F256"}.fa-hand-scissors-o:before{content:"\\F257"}.fa-hand-lizard-o:before{content:"\\F258"}.fa-hand-spock-o:before{content:"\\F259"}.fa-hand-pointer-o:before{content:"\\F25A"}.fa-hand-peace-o:before{content:"\\F25B"}.fa-trademark:before{content:"\\F25C"}.fa-registered:before{content:"\\F25D"}.fa-creative-commons:before{content:"\\F25E"}.fa-gg:before{content:"\\F260"}.fa-gg-circle:before{content:"\\F261"}.fa-tripadvisor:before{content:"\\F262"}.fa-odnoklassniki:before{content:"\\F263"}.fa-odnoklassniki-square:before{content:"\\F264"}.fa-get-pocket:before{content:"\\F265"}.fa-wikipedia-w:before{content:"\\F266"}.fa-safari:before{content:"\\F267"}.fa-chrome:before{content:"\\F268"}.fa-firefox:before{content:"\\F269"}.fa-opera:before{content:"\\F26A"}.fa-internet-explorer:before{content:"\\F26B"}.fa-television:before,.fa-tv:before{content:"\\F26C"}.fa-contao:before{content:"\\F26D"}.fa-500px:before{content:"\\F26E"}.fa-amazon:before{content:"\\F270"}.fa-calendar-plus-o:before{content:"\\F271"}.fa-calendar-minus-o:before{content:"\\F272"}.fa-calendar-times-o:before{content:"\\F273"}.fa-calendar-check-o:before{content:"\\F274"}.fa-industry:before{content:"\\F275"}.fa-map-pin:before{content:"\\F276"}.fa-map-signs:before{content:"\\F277"}.fa-map-o:before{content:"\\F278"}.fa-map:before{content:"\\F279"}.fa-commenting:before{content:"\\F27A"}.fa-commenting-o:before{content:"\\F27B"}.fa-houzz:before{content:"\\F27C"}.fa-vimeo:before{content:"\\F27D"}.fa-black-tie:before{content:"\\F27E"}.fa-fonticons:before{content:"\\F280"}.fa-reddit-alien:before{content:"\\F281"}.fa-edge:before{content:"\\F282"}.fa-credit-card-alt:before{content:"\\F283"}.fa-codiepie:before{content:"\\F284"}.fa-modx:before{content:"\\F285"}.fa-fort-awesome:before{content:"\\F286"}.fa-usb:before{content:"\\F287"}.fa-product-hunt:before{content:"\\F288"}.fa-mixcloud:before{content:"\\F289"}.fa-scribd:before{content:"\\F28A"}.fa-pause-circle:before{content:"\\F28B"}.fa-pause-circle-o:before{content:"\\F28C"}.fa-stop-circle:before{content:"\\F28D"}.fa-stop-circle-o:before{content:"\\F28E"}.fa-shopping-bag:before{content:"\\F290"}.fa-shopping-basket:before{content:"\\F291"}.fa-hashtag:before{content:"\\F292"}.fa-bluetooth:before{content:"\\F293"}.fa-bluetooth-b:before{content:"\\F294"}.fa-percent:before{content:"\\F295"}.fa-gitlab:before{content:"\\F296"}.fa-wpbeginner:before{content:"\\F297"}.fa-wpforms:before{content:"\\F298"}.fa-envira:before{content:"\\F299"}.fa-universal-access:before{content:"\\F29A"}.fa-wheelchair-alt:before{content:"\\F29B"}.fa-question-circle-o:before{content:"\\F29C"}.fa-blind:before{content:"\\F29D"}.fa-audio-description:before{content:"\\F29E"}.fa-volume-control-phone:before{content:"\\F2A0"}.fa-braille:before{content:"\\F2A1"}.fa-assistive-listening-systems:before{content:"\\F2A2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\\F2A3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\\F2A4"}.fa-glide:before{content:"\\F2A5"}.fa-glide-g:before{content:"\\F2A6"}.fa-sign-language:before,.fa-signing:before{content:"\\F2A7"}.fa-low-vision:before{content:"\\F2A8"}.fa-viadeo:before{content:"\\F2A9"}.fa-viadeo-square:before{content:"\\F2AA"}.fa-snapchat:before{content:"\\F2AB"}.fa-snapchat-ghost:before{content:"\\F2AC"}.fa-snapchat-square:before{content:"\\F2AD"}.fa-pied-piper:before{content:"\\F2AE"}.fa-first-order:before{content:"\\F2B0"}.fa-yoast:before{content:"\\F2B1"}.fa-themeisle:before{content:"\\F2B2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\\F2B3"}.fa-fa:before,.fa-font-awesome:before{content:"\\F2B4"}.fa-handshake-o:before{content:"\\F2B5"}.fa-envelope-open:before{content:"\\F2B6"}.fa-envelope-open-o:before{content:"\\F2B7"}.fa-linode:before{content:"\\F2B8"}.fa-address-book:before{content:"\\F2B9"}.fa-address-book-o:before{content:"\\F2BA"}.fa-address-card:before,.fa-vcard:before{content:"\\F2BB"}.fa-address-card-o:before,.fa-vcard-o:before{content:"\\F2BC"}.fa-user-circle:before{content:"\\F2BD"}.fa-user-circle-o:before{content:"\\F2BE"}.fa-user-o:before{content:"\\F2C0"}.fa-id-badge:before{content:"\\F2C1"}.fa-drivers-license:before,.fa-id-card:before{content:"\\F2C2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\\F2C3"}.fa-quora:before{content:"\\F2C4"}.fa-free-code-camp:before{content:"\\F2C5"}.fa-telegram:before{content:"\\F2C6"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:"\\F2C7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\\F2C8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\\F2C9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\\F2CA"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\\F2CB"}.fa-shower:before{content:"\\F2CC"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:"\\F2CD"}.fa-podcast:before{content:"\\F2CE"}.fa-window-maximize:before{content:"\\F2D0"}.fa-window-minimize:before{content:"\\F2D1"}.fa-window-restore:before{content:"\\F2D2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\\F2D3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\\F2D4"}.fa-bandcamp:before{content:"\\F2D5"}.fa-grav:before{content:"\\F2D6"}.fa-etsy:before{content:"\\F2D7"}.fa-imdb:before{content:"\\F2D8"}.fa-ravelry:before{content:"\\F2D9"}.fa-eercast:before{content:"\\F2DA"}.fa-microchip:before{content:"\\F2DB"}.fa-snowflake-o:before{content:"\\F2DC"}.fa-superpowers:before{content:"\\F2DD"}.fa-wpexplorer:before{content:"\\F2DE"}.fa-meetup:before{content:"\\F2E0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}',""]); -},function(A,M,t){M=A.exports=t(138)(),M.push([A.id,'*,:after,:before{box-sizing:border-box}body{font-family:Lato,sans-serif;font-size:15px;line-height:1.42857143;color:#8e8e8e;background-color:#edecec}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#46a5e0}a,a:focus,a:hover{text-decoration:none}a:focus,a:hover{color:#1f7fba}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#edecec;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,.08)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#8e8e8e;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#333;background-color:rgba(0,0,0,.05)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#333;text-decoration:none;outline:0;background-color:rgba(0,0,0,.075)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#e4e4e4}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:13px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu>li>a{text-align:right}.navbar-right .dropdown-menu-left{left:0;right:auto}}.modal,.modal-open{overflow:hidden}.modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid transparent;border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:rgba(0,0,0,.1)}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:30px 35px 0;border-bottom:1px solid transparent}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:transparent}.modal-body{position:relative;padding:30px 35px}.modal-footer{padding:30px 35px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:400px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Lato,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:13px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:active,:focus{outline:0}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{min-height:100%}a{-webkit-transition:color;transition:color;-webkit-transition-duration:.3s;transition-duration:.3s}button{border:0}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.text-center{text-align:center!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.modal-footer:after,.modal-header:after,.row:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.p-relative{position:relative}.m-0{margin:0!important}.m-t-0{margin-top:0!important}.m-b-0{margin-bottom:0!important}.m-l-0{margin-left:0!important}.m-r-0{margin-right:0!important}.m-5{margin:5px!important}.m-t-5{margin-top:5px!important}.m-b-5{margin-bottom:5px!important}.m-l-5{margin-left:5px!important}.m-r-5{margin-right:5px!important}.m-10{margin:10px!important}.m-t-10{margin-top:10px!important}.m-b-10{margin-bottom:10px!important}.m-l-10{margin-left:10px!important}.m-r-10{margin-right:10px!important}.m-15{margin:15px!important}.m-t-15{margin-top:15px!important}.m-b-15{margin-bottom:15px!important}.m-l-15{margin-left:15px!important}.m-r-15{margin-right:15px!important}.m-20{margin:20px!important}.m-t-20{margin-top:20px!important}.m-b-20{margin-bottom:20px!important}.m-l-20{margin-left:20px!important}.m-r-20{margin-right:20px!important}.m-25{margin:25px!important}.m-t-25{margin-top:25px!important}.m-b-25{margin-bottom:25px!important}.m-l-25{margin-left:25px!important}.m-r-25{margin-right:25px!important}.m-30{margin:30px!important}.m-t-30{margin-top:30px!important}.m-b-30{margin-bottom:30px!important}.m-l-30{margin-left:30px!important}.m-r-30{margin-right:30px!important}.p-0{padding:0!important}.p-t-0{padding-top:0!important}.p-b-0{padding-bottom:0!important}.p-l-0{padding-left:0!important}.p-r-0{padding-right:0!important}.p-5{padding:5px!important}.p-t-5{padding-top:5px!important}.p-b-5{padding-bottom:5px!important}.p-l-5{padding-left:5px!important}.p-r-5{padding-right:5px!important}.p-10{padding:10px!important}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.p-l-10{padding-left:10px!important}.p-r-10{padding-right:10px!important}.p-15{padding:15px!important}.p-t-15{padding-top:15px!important}.p-b-15{padding-bottom:15px!important}.p-l-15{padding-left:15px!important}.p-r-15{padding-right:15px!important}.p-20{padding:20px!important}.p-t-20{padding-top:20px!important}.p-b-20{padding-bottom:20px!important}.p-l-20{padding-left:20px!important}.p-r-20{padding-right:20px!important}.p-25{padding:25px!important}.p-t-25{padding-top:25px!important}.p-b-25{padding-bottom:25px!important}.p-l-25{padding-left:25px!important}.p-r-25{padding-right:25px!important}.p-30{padding:30px!important}.p-t-30{padding-top:30px!important}.p-b-30{padding-bottom:30px!important}.p-l-30{padding-left:30px!important}.p-r-30{padding-right:30px!important}@font-face{font-family:Lato;src:url('+t(515)+') format("woff2"),url('+t(514)+') format("woff");font-weight:400;font-style:normal}.form-control{border:0;border-bottom:1px solid #eee;color:#32393f;padding:5px;width:100%;font-size:13px;background-color:transparent}select.form-control{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background:url('+t(518)+') no-repeat bottom 7px right}.input-group{position:relative}.input-group:not(:last-child){margin-bottom:25px}.input-group label:not(.ig-label){font-size:13px;display:block;margin-bottom:10px}.ig-label{position:absolute;text-align:center;bottom:7px;left:0;width:100%;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;padding:2px 0 3px;border-radius:2px;font-weight:400}.ig-helpers{z-index:1;width:100%;left:0}.ig-helpers,.ig-helpers:after,.ig-helpers:before{position:absolute;height:2px;bottom:0}.ig-helpers:after,.ig-helpers:before{content:"";width:0;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;background-color:#03a9f4}.ig-helpers:before{left:50%}.ig-helpers:after{right:50%}.ig-text{width:100%;height:40px;border:0;background:transparent;text-align:center;position:relative;z-index:1;border-bottom:1px solid #eee;color:#32393f;font-size:13px}.ig-text:focus+.ig-helpers:after,.ig-text:focus+.ig-helpers:before{width:50%}.ig-text:disabled~.ig-label,.ig-text:focus~.ig-label,.ig-text:valid~.ig-label{bottom:35px;font-size:13px;z-index:1}.ig-text:disabled{opacity:.5;filter:alpha(opacity=50)}.ig-dark .ig-text{color:#fff;border-color:hsla(0,0%,100%,.1)}.ig-dark .ig-helpers:after,.ig-dark .ig-helpers:before{background-color:#dfdfdf;height:1px}.ig-left .ig-label,.ig-left .ig-text{text-align:left}.ig-error .ig-label{color:#e23f3f}.ig-error .ig-helpers i:first-child,.ig-error .ig-helpers i:first-child:after,.ig-error .ig-helpers i:first-child:before{background:rgba(226,63,63,.43)}.ig-error .ig-helpers i:last-child,.ig-error .ig-helpers i:last-child:after,.ig-error .ig-helpers i:last-child:before{background:#e23f3f!important}.ig-error:after{content:"\\F05A";font-family:FontAwesome;position:absolute;top:17px;right:9px;font-size:20px;color:#d33d3e}.ig-search:before{font-family:fontAwesome;content:"\\F002";font-size:15px;position:absolute;left:2px;top:8px}.ig-search .ig-text{padding-left:25px}.set-expire{border:1px solid #eee;margin:35px 0 30px}.set-expire-item{padding:9px 5px 3px;position:relative;display:table-cell;width:1%;text-align:center}.set-expire-item:not(:last-child){border-right:1px solid #eee}.set-expire-title{font-size:10px;text-transform:uppercase}.set-expire-value{display:inline-block;overflow:hidden;position:relative;left:-8px}.set-expire-value input{font-size:20px;text-align:center;position:relative;right:-15px;border:0;color:#333;padding:0;height:25px;width:100%;font-weight:400}.set-expire-decrease,.set-expire-increase{position:absolute;width:20px;height:20px;background:url('+t(516)+') no-repeat 50%;background-size:85%;left:50%;margin-left:-10px;opacity:.2;filter:alpha(opacity=20);cursor:pointer}.set-expire-decrease:hover,.set-expire-increase:hover{opacity:.5;filter:alpha(opacity=50)}.set-expire-increase{top:-25px}.set-expire-decrease{bottom:-27px;-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.btn{border:0;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:2px;text-align:center;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.btn:focus,.btn:hover{opacity:.9;filter:alpha(opacity=90)}.btn-block{display:block;width:100%}.btn-link{color:#545454;background-color:#eee}.btn-link:focus,.btn-link:hover{color:#545454;background-color:#dfdfdf}.btn-danger{color:#fff;background-color:#ff726f}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff5450}.btn-primary{color:#fff;background-color:#50b2ff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#31a5ff}.btn-success{color:#fff;background-color:#33d46f}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#28c061}.close{right:15px;font-weight:400;opacity:1;font-size:18px;position:absolute;text-align:center;top:16px;z-index:1;padding:0;border:0;background-color:transparent}.close span{width:25px;height:25px;display:block;border-radius:50%;line-height:24px;text-shadow:none}.close:not(.close-alt) span{background-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.close:not(.close-alt):focus span,.close:not(.close-alt):hover span{background-color:hsla(0,0%,100%,.2);color:#fff}.close-alt span{background-color:#efefef;color:#989898}.close-alt:focus span,.close-alt:hover span{background-color:#e8e8e8;color:#7b7b7b}.hidden{display:none!important}.copy-text input{width:100%;border-radius:1px;border:1px solid #eee;padding:7px 12px;font-size:13px;line-height:100%;cursor:text;-webkit-transition:border-color;transition:border-color;-webkit-transition-duration:.3s;transition-duration:.3s}.copy-text input:hover{border-color:#e1e1e1}.share-availability{margin-bottom:40px}.share-availability:after,.share-availability:before{position:absolute;bottom:-30px;font-size:10px}.share-availability:before{content:"01 Sec";left:0}.share-availability:after{content:"7 days";right:0}.login{height:100vh;min-height:500px;background:#32393f;text-align:center}.login:before{height:calc(100% - 110px);width:1px;content:""}.l-wrap,.login:before{display:inline-block;vertical-align:middle}.l-wrap{width:80%;max-width:500px;margin-top:-50px}.l-wrap.toggled{display:inline-block}.l-wrap .input-group:not(:last-child){margin-bottom:40px}.l-footer{height:110px;padding:0 50px}.lf-logo{float:right}.lf-logo img{width:40px}.lf-server{float:left;color:hsla(0,0%,100%,.4);font-size:20px;font-weight:400;padding-top:40px}@media (max-width:768px){.lf-logo,.lf-server{float:none;display:block;text-align:center;width:100%}.lf-logo{margin-bottom:5px}.lf-server{font-size:15px}}.lw-btn{width:50px;height:50px;border:1px solid #fff;display:inline-block;border-radius:50%;font-size:22px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;opacity:.3;background-color:transparent;line-height:45px;padding:0}.lw-btn:hover{color:#fff;opacity:.8;border-color:#fff}.lw-btn i{display:block;width:100%;padding-left:3px}input:-webkit-autofill{-webkit-box-shadow:0 0 0 50px #32393f inset!important;-webkit-text-fill-color:#fff!important}.fe-header{padding:45px 55px 20px}@media (min-width:992px){.fe-header{position:relative}}@media (max-width:667px){.fe-header{padding:25px 25px 20px}}.fe-header h2{font-size:16px;font-weight:400;margin:0}.fe-header h2>span{margin-bottom:7px;display:inline-block}.fe-header h2>span:not(:first-child):before{content:"/";margin:0 4px;color:#8e8e8e}.fe-header p{margin-top:7px}.feh-usage{margin-top:12px;max-width:285px}@media (max-width:667px){.feh-usage{max-width:100%;font-size:12px}}.feh-usage>ul{margin-top:7px;list-style:none;padding:0}.feh-usage>ul>li{padding-right:0;display:inline-block}.fehu-chart{height:5px;background:#eee;position:relative;border-radius:2px;overflow:hidden}.fehu-chart>div{position:absolute;left:0;height:100%;background:#46a5e0}.feh-actions{list-style:none;padding:0;margin:0;position:absolute;right:35px;top:30px;z-index:11}@media (max-width:991px){.feh-actions{top:7px;right:10px;position:fixed}}.feh-actions>li{display:inline-block;text-align:right;vertical-align:top;line-height:100%}.feh-actions>li>.btn-group>button,.feh-actions>li>a{display:block;height:45px;min-width:45px;text-align:center;border-radius:50%;padding:0;border:0;background:none}@media (min-width:992px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{color:#7b7b7b;font-size:21px;line-height:45px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feh-actions>li>.btn-group>button:hover,.feh-actions>li>a:hover{background:rgba(0,0,0,.09)}}@media (max-width:991px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{background:url('+t(237)+') no-repeat 50%}.feh-actions>li>.btn-group>button .fa-reorder,.feh-actions>li>a .fa-reorder{display:none}}@media (max-width:991px){.fe-header-mobile{background-color:#32393f;padding:10px 50px 9px 12px;text-align:center;position:fixed;z-index:10;box-shadow:0 0 10px rgba(0,0,0,.3);left:0;top:0;width:100%}.fe-header-mobile .mh-logo{height:35px;position:relative;top:4px}.feh-trigger{width:41px;height:41px;cursor:pointer;float:left;position:relative;text-align:center}.feh-trigger:after,.feh-trigger:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.feh-trigger:after{z-index:1}.feh-trigger:before{background:hsla(0,0%,100%,.1);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:scale(0);transform:scale(0)}.feht-toggled:before{-webkit-transform:scale(1);transform:scale(1)}.feht-toggled .feht-lines{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.feht-toggled .feht-lines>div.top{width:12px;transform:translateX(8px) translateY(1px) rotate(45deg);-webkit-transform:translateX(8px) translateY(1px) rotate(45deg)}.feht-toggled .feht-lines>div.bottom{width:12px;transform:translateX(8px) translateY(-1px) rotate(-45deg);-webkit-transform:translateX(8px) translateY(-1px) rotate(-45deg)}.feht-lines,.feht-lines>div{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feht-lines{width:18px;height:12px;display:inline-block;margin-top:14px}.feht-lines>div{background-color:#eaeaea;width:18px;height:2px}.feht-lines>div.center{margin:3px 0}}.fe-sidebar{width:300px;background-color:#32393f;position:fixed;height:100%;overflow:hidden;padding:35px}@media (min-width:992px){.fe-sidebar{-webkit-transform:translateZ(0);transform:translateZ(0)}}@media (max-width:991px){.fe-sidebar{padding-top:85px;z-index:9;box-shadow:0 0 10px rgba(0,0,0,.65);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:translate3d(-315px,0,0);transform:translate3d(-315px,0,0)}.fe-sidebar.toggled{-webkit-transform:translateZ(0);transform:translateZ(0)}}.fe-sidebar a{color:hsla(0,0%,100%,.58)}.fe-sidebar a:hover{color:#fff}.fes-header{margin-bottom:40px}.fes-header h2,.fes-header img{float:left}.fes-header h2{margin:13px 0 0 10px;font-weight:400}.fes-header img{width:32px}.fesl-inner{height:calc(100vh - 260px);overflow:auto;padding:0;margin:0 -35px}.fesl-inner li{position:relative}.fesl-inner li>a{display:block;padding:10px 40px 12px 65px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fesl-inner li>a:before{font-family:FontAwesome;content:"\\F0A0";font-size:17px;position:absolute;top:10px;left:35px;opacity:.8;filter:alpha(opacity=80)}.fesl-inner li>a.fesli-loading:before{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.1);border-bottom-color:hsla(0,0%,100%,.5);position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:32px;top:0;bottom:0;margin:auto}.fesl-inner li.active{background-color:rgba(0,0,0,.2)}.fesl-inner li.active>a{color:#fff}.fesl-inner li:not(.active):hover{background-color:rgba(0,0,0,.1)}.fesl-inner li:not(.active):hover>a{color:#fff}.fesl-inner li:hover .fesli-trigger{opacity:.6;filter:alpha(opacity=60)}.fesl-inner li:hover .fesli-trigger:hover{opacity:1;filter:alpha(opacity=100)}.fesl-inner ul{list-style:none;padding:0;margin:0}.fesl-inner:hover .scrollbar-vertical{opacity:1}.fesli-trigger{filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;top:0;right:0;width:40px;cursor:pointer;background:url('+t(237)+') no-repeat 0}.fesli-trigger,.scrollbar-vertical{opacity:0;position:absolute;height:100%}.scrollbar-vertical{right:5px;width:4px;-webkit-transition:opacity;transition:opacity;-webkit-transition-duration:.3s;transition-duration:.3s}.scrollbar-vertical div{border-radius:1px!important;background-color:#6a6a6a!important}.fes-host{position:fixed;left:0;bottom:0;z-index:1;background:#32393f;color:hsla(0,0%,100%,.4);font-size:15px;font-weight:400;width:300px;padding:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fes-host>i{margin-right:10px}.fesl-row{padding-right:40px;padding-top:5px;padding-bottom:5px;position:relative}@media (min-width:668px){.fesl-row{display:flex;flex-flow:row nowrap;justify-content:space-between}}.fesl-row:after,.fesl-row:before{content:" ";display:table}.fesl-row:after{clear:both}@media (min-width:668px){header.fesl-row{margin-bottom:20px;border-bottom:1px solid #f0f0f0;padding-left:40px}header.fesl-row .fesl-item,header.fesl-row .fesli-sort{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}header.fesl-row .fesl-item{cursor:pointer;color:#8e8e8e;font-weight:500;margin-bottom:-5px}header.fesl-row .fesl-item>.fesli-sort{float:right;margin:4px 0 0;opacity:0;filter:alpha(opacity=0);color:#32393f;font-size:14px}header.fesl-row .fesl-item:hover:not(.fi-actions){background:#f5f5f5;color:#32393f}header.fesl-row .fesl-item:hover:not(.fi-actions)>.fesli-sort{opacity:.5;filter:alpha(opacity=50)}}@media (max-width:667px){header.fesl-row{display:none}}div.fesl-row{padding-left:85px;border-bottom:1px solid transparent;cursor:default}@media (max-width:667px){div.fesl-row{padding-left:70px;padding-right:45px}}div.fesl-row:nth-child(2n){background-color:#fafafa}div.fesl-row:hover{background-color:#fbf7dc}div.fesl-row[data-type]:before{font-family:fontAwesome;width:35px;height:35px;text-align:center;line-height:35px;position:absolute;border-radius:50%;font-size:16px;left:50px;top:9px;color:#fff}@media (max-width:667px){div.fesl-row[data-type]:before{left:20px}}@media (max-width:667px){div.fesl-row[data-type=folder] .fesl-item.fi-name{padding-top:10px;padding-bottom:7px}div.fesl-row[data-type=folder] .fesl-item.fi-modified,div.fesl-row[data-type=folder] .fesl-item.fi-size{display:none}}div.fesl-row[data-type=folder]:before{content:"\\F114";background-color:#a1d6dd}div.fesl-row[data-type=pdf]:before{content:"\\F1C1";background-color:#fa7775}div.fesl-row[data-type=zip]:before{content:"\\F1C6";background-color:#427089}div.fesl-row[data-type=audio]:before{content:"\\F1C7";background-color:#009688}div.fesl-row[data-type=code]:before{content:"\\F1C9";background-color:#997867}div.fesl-row[data-type=excel]:before{content:"\\F1C3";background-color:#64c866}div.fesl-row[data-type=image]:before{content:"\\F1C5";background-color:#f06292}div.fesl-row[data-type=video]:before{content:"\\F1C8";background-color:#f8c363}div.fesl-row[data-type=other]:before{content:"\\F016";background-color:#afafaf}div.fesl-row[data-type=text]:before{content:"\\F0F6";background-color:#8a8a8a}div.fesl-row[data-type=doc]:before{content:"\\F1C2";background-color:#2196f5}div.fesl-row[data-type=presentation]:before{content:"\\F1C4";background-color:#896ea6}div.fesl-row.fesl-loading:before{content:""}div.fesl-row.fesl-loading:after{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.5);border-bottom-color:#fff;position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:57px;top:17px}@media (max-width:667px){div.fesl-row.fesl-loading:after{left:27px}}.fesl-item{display:block}.fesl-item a{color:#818181}@media (min-width:668px){.fesl-item:not(.fi-actions){text-overflow:ellipsis;padding:10px 15px;white-space:nowrap;overflow:hidden}.fesl-item.fi-name{flex:3}.fesl-item.fi-size{width:140px}.fesl-item.fi-modified{width:190px}.fesl-item.fi-actions{width:40px}}@media (max-width:667px){.fesl-item{padding:0}.fesl-item.fi-name{width:100%;margin-bottom:3px}.fesl-item.fi-modified,.fesl-item.fi-size{font-size:12px;color:#b5b5b5;float:left}.fesl-item.fi-modified{max-width:72px;white-space:nowrap;overflow:hidden}.fesl-item.fi-size{margin-right:10px}.fesl-item.fi-actions{position:absolute;top:5px;right:10px}}.fia-toggle{height:36px;width:36px;background:transparent url('+t(517)+') no-repeat 50%;position:relative;top:3px;opacity:.4;filter:alpha(opacity=40)}.fia-toggle:hover{opacity:.7;filter:alpha(opacity=70)}.fi-actions .dropdown-menu{background-color:transparent;box-shadow:none;padding:0;right:38px;left:auto;margin:0;height:100%;text-align:right}.fi-actions .dropdown.open .dropdown-menu .fiad-action{right:0}.fiad-action{height:35px;width:35px;background:#ffc107;display:inline-block;border-radius:50%;text-align:center;line-height:35px;font-weight:400;position:relative;top:4px;margin-left:5px;-webkit-animation-name:fiad-action-anim;animation-name:fiad-action-anim;-webkit-transform-origin:center center;transform-origin:center center;-webkit-backface-visibility:none;backface-visibility:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.fiad-action:nth-child(2){-webkit-animation-duration:.1s;animation-duration:.1s}.fiad-action:first-child{-webkit-animation-duration:.25s;animation-duration:.25s}.fiad-action>i{font-size:14px;color:#fff}.fiad-action:hover{background-color:#f7b900}@-webkit-keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}@keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}.file-explorer{background-color:#fff;position:relative;height:100%}.file-explorer.toggled{height:100vh;overflow:hidden}.fe-body{min-height:100vh;overflow:auto}@media (min-width:992px){.fe-body{padding:0 0 40px 300px}}@media (max-width:991px){.fe-body{padding:75px 0 80px}}.feb-actions{position:fixed;bottom:30px;right:30px}.feb-actions .dropdown-menu{min-width:55px;width:55px;text-align:center;background:transparent;box-shadow:none;margin:0}.feb-actions.open .feba-btn{-webkit-transform:scale(1);transform:scale(1)}.feb-actions.open .feba-btn:first-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.3s;animation-duration:.3s}.feb-actions.open .feba-btn:last-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.1s;animation-duration:.1s}.feb-actions.open .feba-toggle{background:#ff403c}.feb-actions.open .feba-toggle>span{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.feba-toggle{width:55px;height:55px;line-height:55px;border-radius:50%;background:#ff726f;box-shadow:0 2px 3px rgba(0,0,0,.15);display:inline-block;text-align:center;border:0;padding:0}.feba-toggle span{display:inline-block;height:100%;width:100%}.feba-toggle i{color:#fff;font-size:17px;line-height:58px}.feba-toggle,.feba-toggle>span{-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;-webkit-backface-visibility:hidden;backface-visibility:hidden}.feba-btn{width:40px;margin-top:10px;height:40px;border-radius:50%;text-align:center;display:inline-block;line-height:40px;box-shadow:0 2px 3px rgba(0,0,0,.15);-webkit-transform:scale(0);transform:scale(0);position:relative}.feba-btn,.feba-btn:focus,.feba-btn:hover{color:#fff}.feba-btn label{width:100%;height:100%;position:absolute;left:0;top:0;cursor:pointer}.feba-bucket{background:#ffc155}.feba-upload{background:#ffc107}@-webkit-keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}@keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}.ie-warning{background-color:#ff5252;width:100%;height:100%;position:fixed;left:0;top:0;text-align:center}.ie-warning:before{width:1px;content:"";height:100%}.ie-warning .iw-inner,.ie-warning:before{display:inline-block;vertical-align:middle}.iw-inner{width:470px;height:300px;background-color:#fff;border-radius:5px;padding:40px;position:relative}.iw-inner ul{list-style:none;padding:0;margin:0;width:230px;margin-left:80px;margin-top:16px}.iw-inner ul>li{float:left}.iw-inner ul>li>a{display:block;padding:10px 15px 7px;font-size:14px;margin:0 1px;border-radius:3px}.iw-inner ul>li>a:hover{background:#eee}.iw-inner ul>li>a img{height:40px;margin-bottom:5px}.iwi-icon{color:#ff5252;font-size:40px;display:block;line-height:100%;margin-bottom:15px}.iwi-skip{position:absolute;left:0;bottom:-35px;width:100%;color:hsla(0,0%,100%,.6);cursor:pointer}.iwi-skip:hover{color:#fff}.dropdown-menu{padding:15px 0;top:0;margin-top:-1px}.dropdown-menu>li>a{padding:8px 20px;font-size:15px}.dropdown-menu>li>a>i{width:20px;position:relative;top:1px}.dropdown-menu-right>li>a{text-align:right}.alert{border:0;position:fixed;max-width:500px;margin:0;box-shadow:0 4px 5px rgba(0,0,0,.1);color:#fff;width:100%;right:20px;border-radius:3px;padding:17px 50px 17px 17px;z-index:10010;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.alert:not(.progress){top:20px}@media (min-width:768px){.alert:not(.progress){left:50%;margin-left:-250px}}.alert.progress{bottom:20px;right:20px}.alert.alert-danger{background:#ff726f}.alert.alert-success{background:#33d46f}.alert.alert-info{background:#50b2ff}@media (max-width:767px){.alert{left:20px;width:calc(100% - 40px);max-width:100%}}.alert .progress{margin:10px 10px 8px 0;height:5px;box-shadow:none;border-radius:1px;background-color:#50b2ff;border-radius:2px;overflow:hidden}.alert .progress-bar{box-shadow:none;background-color:#fff;height:100%}.alert .close{position:absolute;top:15px}@media (min-width:768px){.modal{text-align:center}.modal:before{content:"";height:100%;width:1px}.modal .modal-dialog,.modal:before{display:inline-block;vertical-align:middle}.modal .modal-dialog{text-align:left;margin:10px auto}}.modal-dark .modal-header{color:hsla(0,0%,100%,.4)}.modal-dark .modal-header small{color:hsla(0,0%,100%,.2)}.modal-dark .modal-content{background-color:#32393f}.modal-backdrop{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-backdrop,.modal-dialog{-webkit-animation-duration:.2s;animation-duration:.2s}.modal-dialog{-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-header{color:#333;position:relative}.modal-header small{display:block;text-transform:none;font-size:12px;margin-top:5px;color:#a8a8a8}.modal-content{border-radius:3px;box-shadow:none}.modal-footer{padding:0 30px 30px}.modal-confirm .modal-dialog,.modal-footer{text-align:center}.mc-icon{margin:0 0 10px}.mc-icon>i{font-size:60px}.mci-red{color:#ff8f8f}.mci-amber{color:#ffc107}.mci-green{color:#64e096}.mc-text{color:#333}.mc-sub{color:#bdbdbd;margin-top:5px;font-size:13px}@media (max-width:767px){.modal-about{text-align:center}.modal-about .modal-dialog{max-width:400px;width:90%;margin:20px auto 0}}.ma-inner{display:flex;flex-direction:row;align-items:center;min-height:350px;position:relative}@media (min-width:768px){.ma-inner:before{content:"";width:150px;height:100%;top:0;left:0;position:absolute;border-radius:3px 0 0 3px;background-color:#23282c}}.mai-item:first-child{width:150px;text-align:center}.mai-item:last-child{flex:4;padding:30px}.maii-logo{width:70px;position:relative}.maii-list{list-style:none;padding:0}.maii-list>li{margin-bottom:15px}.maii-list>li div{color:hsla(0,0%,100%,.8);text-transform:uppercase;font-size:14px}.maii-list>li small{font-size:13px;color:hsla(0,0%,100%,.4)}.toggle-password{position:absolute;bottom:30px;right:35px;width:30px;height:30px;border:1px solid #eee;border-radius:0;text-align:center;cursor:pointer;z-index:10;background-color:#fff;padding-top:5px}.toggle-password.toggled{background:#eee}.pm-body{padding-bottom:30px}.pmb-header{margin-bottom:35px}.pmb-list{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;padding:10px 35px}.pmb-list:nth-child(2n){background-color:#f7f7f7}.pmb-list .form-control{padding-left:0;padding-right:0}header.pmb-list{margin:20px 0 10px}.pmbl-item{display:block;font-size:13px}.pmbl-item:first-child{flex:2}.pmbl-item:nth-child(2){margin:0 25px;width:150px}.pmbl-item:nth-child(3){width:70px}div.pmb-list select{border:0}div.pmb-list .pml-item:not(:last-child){padding:0 5px}.modal-create-bucket .modal-dialog{position:fixed;right:25px;bottom:95px;margin:0;height:110px}.modal-create-bucket .modal-content{width:100%;height:100%}',""]); +},function(A,M,t){M=A.exports=t(138)(),M.push([A.id,'*,:after,:before{box-sizing:border-box}body{font-family:Lato,sans-serif;font-size:15px;line-height:1.42857143;color:#8e8e8e;background-color:#edecec}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#46a5e0}a,a:focus,a:hover{text-decoration:none}a:focus,a:hover{color:#1f7fba}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#edecec;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,.08)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#8e8e8e;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#333;background-color:rgba(0,0,0,.05)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#333;text-decoration:none;outline:0;background-color:rgba(0,0,0,.075)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#e4e4e4}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:13px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu>li>a{text-align:right}.navbar-right .dropdown-menu-left{left:0;right:auto}}.modal,.modal-open{overflow:hidden}.modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid transparent;border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:rgba(0,0,0,.1)}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:30px 35px 0;border-bottom:1px solid transparent}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:transparent}.modal-body{position:relative;padding:30px 35px}.modal-footer{padding:30px 35px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:400px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Lato,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:13px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:active,:focus{outline:0}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{min-height:100%}a{-webkit-transition:color;transition:color;-webkit-transition-duration:.3s;transition-duration:.3s}button{border:0}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.text-center{text-align:center!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.modal-footer:after,.modal-header:after,.row:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.p-relative{position:relative}.m-0{margin:0!important}.m-t-0{margin-top:0!important}.m-b-0{margin-bottom:0!important}.m-l-0{margin-left:0!important}.m-r-0{margin-right:0!important}.m-5{margin:5px!important}.m-t-5{margin-top:5px!important}.m-b-5{margin-bottom:5px!important}.m-l-5{margin-left:5px!important}.m-r-5{margin-right:5px!important}.m-10{margin:10px!important}.m-t-10{margin-top:10px!important}.m-b-10{margin-bottom:10px!important}.m-l-10{margin-left:10px!important}.m-r-10{margin-right:10px!important}.m-15{margin:15px!important}.m-t-15{margin-top:15px!important}.m-b-15{margin-bottom:15px!important}.m-l-15{margin-left:15px!important}.m-r-15{margin-right:15px!important}.m-20{margin:20px!important}.m-t-20{margin-top:20px!important}.m-b-20{margin-bottom:20px!important}.m-l-20{margin-left:20px!important}.m-r-20{margin-right:20px!important}.m-25{margin:25px!important}.m-t-25{margin-top:25px!important}.m-b-25{margin-bottom:25px!important}.m-l-25{margin-left:25px!important}.m-r-25{margin-right:25px!important}.m-30{margin:30px!important}.m-t-30{margin-top:30px!important}.m-b-30{margin-bottom:30px!important}.m-l-30{margin-left:30px!important}.m-r-30{margin-right:30px!important}.p-0{padding:0!important}.p-t-0{padding-top:0!important}.p-b-0{padding-bottom:0!important}.p-l-0{padding-left:0!important}.p-r-0{padding-right:0!important}.p-5{padding:5px!important}.p-t-5{padding-top:5px!important}.p-b-5{padding-bottom:5px!important}.p-l-5{padding-left:5px!important}.p-r-5{padding-right:5px!important}.p-10{padding:10px!important}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.p-l-10{padding-left:10px!important}.p-r-10{padding-right:10px!important}.p-15{padding:15px!important}.p-t-15{padding-top:15px!important}.p-b-15{padding-bottom:15px!important}.p-l-15{padding-left:15px!important}.p-r-15{padding-right:15px!important}.p-20{padding:20px!important}.p-t-20{padding-top:20px!important}.p-b-20{padding-bottom:20px!important}.p-l-20{padding-left:20px!important}.p-r-20{padding-right:20px!important}.p-25{padding:25px!important}.p-t-25{padding-top:25px!important}.p-b-25{padding-bottom:25px!important}.p-l-25{padding-left:25px!important}.p-r-25{padding-right:25px!important}.p-30{padding:30px!important}.p-t-30{padding-top:30px!important}.p-b-30{padding-bottom:30px!important}.p-l-30{padding-left:30px!important}.p-r-30{padding-right:30px!important}@font-face{font-family:Lato;src:url('+t(515)+') format("woff2"),url('+t(514)+') format("woff");font-weight:400;font-style:normal}.form-control{border:0;border-bottom:1px solid #eee;color:#32393f;padding:5px;width:100%;font-size:13px;background-color:transparent}select.form-control{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background:url('+t(518)+') no-repeat bottom 7px right}.input-group{position:relative}.input-group:not(:last-child){margin-bottom:25px}.input-group label:not(.ig-label){font-size:13px;display:block;margin-bottom:10px}.ig-label{position:absolute;text-align:center;bottom:7px;left:0;width:100%;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;padding:2px 0 3px;border-radius:2px;font-weight:400}.ig-helpers{z-index:1;width:100%;left:0}.ig-helpers,.ig-helpers:after,.ig-helpers:before{position:absolute;height:2px;bottom:0}.ig-helpers:after,.ig-helpers:before{content:"";width:0;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;background-color:#03a9f4}.ig-helpers:before{left:50%}.ig-helpers:after{right:50%}.ig-text{width:100%;height:40px;border:0;background:transparent;text-align:center;position:relative;z-index:1;border-bottom:1px solid #eee;color:#32393f;font-size:13px}.ig-text:focus+.ig-helpers:after,.ig-text:focus+.ig-helpers:before{width:50%}.ig-text:disabled~.ig-label,.ig-text:focus~.ig-label,.ig-text:valid~.ig-label{bottom:35px;font-size:13px;z-index:1}.ig-text:disabled{opacity:.5;filter:alpha(opacity=50)}.ig-dark .ig-text{color:#fff;border-color:hsla(0,0%,100%,.1)}.ig-dark .ig-helpers:after,.ig-dark .ig-helpers:before{background-color:#dfdfdf;height:1px}.ig-left .ig-label,.ig-left .ig-text{text-align:left}.ig-error .ig-label{color:#e23f3f}.ig-error .ig-helpers i:first-child,.ig-error .ig-helpers i:first-child:after,.ig-error .ig-helpers i:first-child:before{background:rgba(226,63,63,.43)}.ig-error .ig-helpers i:last-child,.ig-error .ig-helpers i:last-child:after,.ig-error .ig-helpers i:last-child:before{background:#e23f3f!important}.ig-error:after{content:"\\F05A";font-family:FontAwesome;position:absolute;top:17px;right:9px;font-size:20px;color:#d33d3e}.ig-search:before{font-family:fontAwesome;content:"\\F002";font-size:15px;position:absolute;left:2px;top:8px}.ig-search .ig-text{padding-left:25px}.set-expire{border:1px solid #eee;margin:35px 0 30px}.set-expire-item{padding:9px 5px 3px;position:relative;display:table-cell;width:1%;text-align:center}.set-expire-item:not(:last-child){border-right:1px solid #eee}.set-expire-title{font-size:10px;text-transform:uppercase}.set-expire-value{display:inline-block;overflow:hidden;position:relative;left:-8px}.set-expire-value input{font-size:20px;text-align:center;position:relative;right:-15px;border:0;color:#333;padding:0;height:25px;width:100%;font-weight:400}.set-expire-decrease,.set-expire-increase{position:absolute;width:20px;height:20px;background:url('+t(516)+') no-repeat 50%;background-size:85%;left:50%;margin-left:-10px;opacity:.2;filter:alpha(opacity=20);cursor:pointer}.set-expire-decrease:hover,.set-expire-increase:hover{opacity:.5;filter:alpha(opacity=50)}.set-expire-increase{top:-25px}.set-expire-decrease{bottom:-27px;-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.btn{border:0;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:2px;text-align:center;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.btn:focus,.btn:hover{opacity:.9;filter:alpha(opacity=90)}.btn-block{display:block;width:100%}.btn-white{color:#5b5b5b;background-color:#fff}.btn-white:focus,.btn-white:hover{color:#5b5b5b;background-color:#f0f0f0}.btn-link{color:#545454;background-color:#eee}.btn-link:focus,.btn-link:hover{color:#545454;background-color:#dfdfdf}.btn-danger{color:#fff;background-color:#ff726f}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff5450}.btn-primary{color:#fff;background-color:#50b2ff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#31a5ff}.btn-success{color:#fff;background-color:#33d46f}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#28c061}.close{right:15px;font-weight:400;opacity:1;font-size:18px;position:absolute;text-align:center;top:16px;z-index:1;padding:0;border:0;background-color:transparent}.close span{width:25px;height:25px;display:block;border-radius:50%;line-height:24px;text-shadow:none}.close:not(.close-alt) span{background-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.close:not(.close-alt):focus span,.close:not(.close-alt):hover span{background-color:hsla(0,0%,100%,.2);color:#fff}.close-alt span{background-color:#efefef;color:#989898}.close-alt:focus span,.close-alt:hover span{background-color:#e8e8e8;color:#7b7b7b}.hidden{display:none!important}.copy-text input{width:100%;border-radius:1px;border:1px solid #eee;padding:7px 12px;font-size:13px;line-height:100%;cursor:text;-webkit-transition:border-color;transition:border-color;-webkit-transition-duration:.3s;transition-duration:.3s}.copy-text input:hover{border-color:#e1e1e1}.share-availability{margin-bottom:40px}.share-availability:after,.share-availability:before{position:absolute;bottom:-30px;font-size:10px}.share-availability:before{content:"01 Sec";left:0}.share-availability:after{content:"7 days";right:0}.modal-aheader{height:100px}.modal-aheader:before{height:0!important}.modal-aheader .modal-dialog{margin:0;vertical-align:top}.login{height:100vh;min-height:500px;background:#32393f;text-align:center}.login:before{height:calc(100% - 110px);width:1px;content:""}.l-wrap,.login:before{display:inline-block;vertical-align:middle}.l-wrap{width:80%;max-width:500px;margin-top:-50px}.l-wrap.toggled{display:inline-block}.l-wrap .input-group:not(:last-child){margin-bottom:40px}.l-footer{height:110px;padding:0 50px}.lf-logo{float:right}.lf-logo img{width:40px}.lf-server{float:left;color:hsla(0,0%,100%,.4);font-size:20px;font-weight:400;padding-top:40px}@media (max-width:768px){.lf-logo,.lf-server{float:none;display:block;text-align:center;width:100%}.lf-logo{margin-bottom:5px}.lf-server{font-size:15px}}.lw-btn{width:50px;height:50px;border:1px solid #fff;display:inline-block;border-radius:50%;font-size:22px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;opacity:.3;background-color:transparent;line-height:45px;padding:0}.lw-btn:hover{color:#fff;opacity:.8;border-color:#fff}.lw-btn i{display:block;width:100%;padding-left:3px}input:-webkit-autofill{-webkit-box-shadow:0 0 0 50px #32393f inset!important;-webkit-text-fill-color:#fff!important}@media (min-width:668px){.fe-header{position:relative;padding:40px 40px 20px 45px}}@media (max-width:667px){.fe-header{padding:20px}}.fe-header h2{font-size:16px;font-weight:400;margin:0}.fe-header h2>span{margin-bottom:7px;display:inline-block}.fe-header h2>span:not(:first-child):before{content:"/";margin:0 4px;color:#8e8e8e}.fe-header p{margin-top:7px}.feh-usage{margin-top:12px;max-width:285px}@media (max-width:667px){.feh-usage{max-width:100%;font-size:12px}}.feh-usage>ul{margin-top:7px;list-style:none;padding:0}.feh-usage>ul>li{padding-right:0;display:inline-block}.fehu-chart{height:5px;background:#eee;position:relative;border-radius:2px;overflow:hidden}.fehu-chart>div{position:absolute;left:0;height:100%;background:#46a5e0}.feh-actions{list-style:none;padding:0;margin:0;position:absolute;right:35px;top:30px;z-index:11}@media (max-width:991px){.feh-actions{top:7px;right:10px;position:fixed}}.feh-actions>li{display:inline-block;text-align:right;vertical-align:top;line-height:100%}.feh-actions>li>.btn-group>button,.feh-actions>li>a{display:block;height:45px;min-width:45px;text-align:center;border-radius:50%;padding:0;border:0;background:none}@media (min-width:992px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{color:#7b7b7b;font-size:21px;line-height:45px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feh-actions>li>.btn-group>button:hover,.feh-actions>li>a:hover{background:rgba(0,0,0,.09)}}@media (max-width:991px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{background:url('+t(237)+') no-repeat 50%}.feh-actions>li>.btn-group>button .fa-reorder,.feh-actions>li>a .fa-reorder{display:none}}@media (max-width:991px){.fe-header-mobile{background-color:#32393f;padding:10px 50px 9px 12px;text-align:center;position:fixed;z-index:10;box-shadow:0 0 10px rgba(0,0,0,.3);left:0;top:0;width:100%}.fe-header-mobile .mh-logo{height:35px;position:relative;top:4px}.feh-trigger{width:41px;height:41px;cursor:pointer;float:left;position:relative;text-align:center}.feh-trigger:after,.feh-trigger:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.feh-trigger:after{z-index:1}.feh-trigger:before{background:hsla(0,0%,100%,.1);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:scale(0);transform:scale(0)}.feht-toggled:before{-webkit-transform:scale(1);transform:scale(1)}.feht-toggled .feht-lines{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.feht-toggled .feht-lines>div.top{width:12px;transform:translateX(8px) translateY(1px) rotate(45deg);-webkit-transform:translateX(8px) translateY(1px) rotate(45deg)}.feht-toggled .feht-lines>div.bottom{width:12px;transform:translateX(8px) translateY(-1px) rotate(-45deg);-webkit-transform:translateX(8px) translateY(-1px) rotate(-45deg)}.feht-lines,.feht-lines>div{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feht-lines{width:18px;height:12px;display:inline-block;margin-top:14px}.feht-lines>div{background-color:#eaeaea;width:18px;height:2px}.feht-lines>div.center{margin:3px 0}}.fe-sidebar{width:300px;background-color:#32393f;position:fixed;height:100%;overflow:hidden;padding:35px}@media (min-width:992px){.fe-sidebar{-webkit-transform:translateZ(0);transform:translateZ(0)}}@media (max-width:991px){.fe-sidebar{padding-top:85px;z-index:9;box-shadow:0 0 10px rgba(0,0,0,.65);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:translate3d(-315px,0,0);transform:translate3d(-315px,0,0)}.fe-sidebar.toggled{-webkit-transform:translateZ(0);transform:translateZ(0)}}.fe-sidebar a{color:hsla(0,0%,100%,.58)}.fe-sidebar a:hover{color:#fff}.fes-header{margin-bottom:40px}.fes-header h2,.fes-header img{float:left}.fes-header h2{margin:13px 0 0 10px;font-weight:400}.fes-header img{width:32px}.fesl-inner{height:calc(100vh - 260px);overflow:auto;padding:0;margin:0 -35px}.fesl-inner li{position:relative}.fesl-inner li>a{display:block;padding:10px 40px 12px 65px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fesl-inner li>a:before{font-family:FontAwesome;content:"\\F0A0";font-size:17px;position:absolute;top:10px;left:35px;opacity:.8;filter:alpha(opacity=80)}.fesl-inner li>a.fesli-loading:before{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.1);border-bottom-color:hsla(0,0%,100%,.5);position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:32px;top:0;bottom:0;margin:auto}.fesl-inner li.active{background-color:rgba(0,0,0,.2)}.fesl-inner li.active>a{color:#fff}.fesl-inner li:not(.active):hover{background-color:rgba(0,0,0,.1)}.fesl-inner li:not(.active):hover>a{color:#fff}.fesl-inner li:hover .fesli-trigger{opacity:.6;filter:alpha(opacity=60)}.fesl-inner li:hover .fesli-trigger:hover{opacity:1;filter:alpha(opacity=100)}.fesl-inner ul{list-style:none;padding:0;margin:0}.fesl-inner:hover .scrollbar-vertical{opacity:1}.fesli-trigger{filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;top:0;right:0;width:40px;cursor:pointer;background:url('+t(237)+') no-repeat 0}.fesli-trigger,.scrollbar-vertical{opacity:0;position:absolute;height:100%}.scrollbar-vertical{right:5px;width:4px;-webkit-transition:opacity;transition:opacity;-webkit-transition-duration:.3s;transition-duration:.3s}.scrollbar-vertical div{border-radius:1px!important;background-color:#6a6a6a!important}.fes-host{position:fixed;left:0;bottom:0;z-index:1;background:#32393f;color:hsla(0,0%,100%,.4);font-size:15px;font-weight:400;width:300px;padding:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fes-host>i{margin-right:10px}.fesl-row{position:relative}@media (min-width:668px){.fesl-row{padding:5px 20px 5px 40px;display:flex;flex-flow:row nowrap;justify-content:space-between}}@media (max-width:667px){.fesl-row{padding:5px 20px}}.fesl-row:after,.fesl-row:before{content:" ";display:table}.fesl-row:after{clear:both}@media (min-width:668px){header.fesl-row{margin-bottom:20px;border-bottom:1px solid #f0f0f0;padding-left:30px}header.fesl-row .fesl-item,header.fesl-row .fesli-sort{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}header.fesl-row .fesl-item{cursor:pointer;color:#8e8e8e;font-weight:500;margin-bottom:-5px}header.fesl-row .fesl-item>.fesli-sort{float:right;margin:4px 0 0;opacity:0;filter:alpha(opacity=0);color:#32393f;font-size:14px}header.fesl-row .fesl-item:hover:not(.fesl-item-actions){background:#f5f5f5;color:#32393f}header.fesl-row .fesl-item:hover:not(.fesl-item-actions)>.fesli-sort{opacity:.5;filter:alpha(opacity=50)}}@media (max-width:667px){header.fesl-row{display:none}}div.fesl-row{border-bottom:1px solid transparent;cursor:default;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.5s;transition-duration:.5s}@media (max-width:667px){div.fesl-row{padding:5px 20px}}div.fesl-row:not(.fesl-row-selected):nth-child(2n){background-color:#fafafa}div.fesl-row:hover .fis-icon:before{opacity:0;filter:alpha(opacity=0)}div.fesl-row:hover .fis-helper:before{opacity:1;filter:alpha(opacity=100)}div.fesl-row[data-type=folder] .fis-icon{background-color:#a1d6dd}div.fesl-row[data-type=folder] .fis-icon:before{content:"\\F114"}div.fesl-row[data-type=pdf] .fis-icon{background-color:#fa7775}div.fesl-row[data-type=pdf] .fis-icon:before{content:"\\F1C1"}div.fesl-row[data-type=zip] .fis-icon{background-color:#427089}div.fesl-row[data-type=zip] .fis-icon:before{content:"\\F1C6"}div.fesl-row[data-type=audio] .fis-icon{background-color:#009688}div.fesl-row[data-type=audio] .fis-icon:before{content:"\\F1C7"}div.fesl-row[data-type=code] .fis-icon{background-color:#997867}div.fesl-row[data-type=code] .fis-icon:before{content:"\\F1C9"}div.fesl-row[data-type=excel] .fis-icon{background-color:#f1c3 3}div.fesl-row[data-type=excel] .fis-icon:before{content:"\\F1C3"}div.fesl-row[data-type=image] .fis-icon{background-color:#f06292}div.fesl-row[data-type=image] .fis-icon:before{content:"\\F1C5"}div.fesl-row[data-type=video] .fis-icon{background-color:#f8c363}div.fesl-row[data-type=video] .fis-icon:before{content:"\\F1C8"}div.fesl-row[data-type=other] .fis-icon{background-color:#afafaf}div.fesl-row[data-type=other] .fis-icon:before{content:"\\F016"}div.fesl-row[data-type=text] .fis-icon{background-color:#8a8a8a}div.fesl-row[data-type=text] .fis-icon:before{content:"\\F0F6"}div.fesl-row[data-type=doc] .fis-icon{background-color:#2196f5}div.fesl-row[data-type=doc] .fis-icon:before{content:"\\F1C2"}div.fesl-row[data-type=presentation] .fis-icon{background-color:#896ea6}div.fesl-row[data-type=presentation] .fis-icon:before{content:"\\F1C4"}div.fesl-row.fesl-loading:before{content:""}div.fesl-row.fesl-loading:after{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.5);border-bottom-color:#fff;position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:57px;top:17px}@media (max-width:667px){div.fesl-row.fesl-loading:after{left:27px}}.fesl-row-selected{background-color:#fbf2bf}.fesl-row-selected,.fesl-row-selected .fesl-item a{color:#757575}.fi-select{float:left;position:relative;width:35px;height:35px;margin:3px 0}@media (max-width:667px){.fi-select{margin-right:15px}}.fi-select input{position:absolute;left:0;top:0;width:35px;height:35px;z-index:20;opacity:0;cursor:pointer}.fi-select input:checked~.fis-icon{background-color:#32393f}.fi-select input:checked~.fis-icon:before{opacity:0}.fi-select input:checked~.fis-helper:before{-webkit-transform:scale(0);transform:scale(0)}.fi-select input:checked~.fis-helper:after{-webkit-transform:scale(1);transform:scale(1)}.fis-icon{display:inline-block;vertical-align:top;border-radius:50%;width:35px;height:35px;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-icon:before{width:100%;height:100%;text-align:center;position:absolute;border-radius:50%;font-family:fontAwesome;line-height:35px;font-size:16px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;font-style:normal}.fis-helper:after,.fis-helper:before{position:absolute;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-helper:before{content:"";width:15px;height:15px;border:2px solid #fff;z-index:10;border-radius:2px;top:10px;left:10px;opacity:0}.fis-helper:after{font-family:fontAwesome;content:"\\F00C";top:8px;left:9px;color:#fff;font-size:14px;-webkit-transform:scale(0);transform:scale(0)}.fesl-item{display:block}.fesl-item a{color:#818181}@media (min-width:668px){.fesl-item:not(.fesl-item-actions):not(.fesl-item-icon){text-overflow:ellipsis;padding:10px 15px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-name{flex:3}.fesl-item.fesl-item-size{width:140px}.fesl-item.fesl-item-modified{width:190px}.fesl-item.fesl-item-actions{width:40px}}@media (max-width:667px){.fesl-item{padding:0}.fesl-item.fesl-item-name{width:100%;margin-bottom:3px}.fesl-item.fesl-item-modified,.fesl-item.fesl-item-size{font-size:12px;color:#b5b5b5;float:left}.fesl-item.fesl-item-modified{max-width:72px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-size{margin-right:10px}.fesl-item.fesl-item-actions{position:absolute;top:5px;right:10px}}.fia-toggle{height:36px;width:36px;background:transparent url('+t(517)+') no-repeat 50%;position:relative;top:3px;opacity:.4;filter:alpha(opacity=40)}.fia-toggle:hover{opacity:.7;filter:alpha(opacity=70)}.fesl-item-actions .dropdown-menu{background-color:transparent;box-shadow:none;padding:0;right:38px;left:auto;margin:0;height:100%;text-align:right}.fesl-item-actions .dropdown.open .dropdown-menu .fiad-action{right:0}.fiad-action{height:35px;width:35px;background:#ffc107;display:inline-block;border-radius:50%;text-align:center;line-height:35px;font-weight:400;position:relative;top:4px;margin-left:5px;-webkit-animation-name:fiad-action-anim;animation-name:fiad-action-anim;-webkit-transform-origin:center center;transform-origin:center center;-webkit-backface-visibility:none;backface-visibility:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.fiad-action:nth-child(2){-webkit-animation-duration:.1s;animation-duration:.1s}.fiad-action:first-child{-webkit-animation-duration:.25s;animation-duration:.25s}.fiad-action>i{font-size:14px;color:#fff}.fiad-action:hover{background-color:#f7b900}.list-actions{position:fixed;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);opacity:0;filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;padding:20px 25px;top:0;left:0;width:100%;background-color:#2298f7;z-index:20;box-shadow:0 0 10px rgba(0,0,0,.3);text-align:center}.list-actions.list-actions-toggled{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1;filter:alpha(opacity=100)}.la-close{position:absolute;right:20px;top:0;color:#fff;width:30px;height:30px;border-radius:50%;text-align:center;line-height:30px!important;background:hsla(0,0%,100%,.1);font-weight:400;bottom:0;margin:auto;cursor:pointer}.la-close:hover{background-color:hsla(0,0%,100%,.2)}.la-label{color:#fff;float:left;padding:4px 0}.la-label .fa{font-size:22px;vertical-align:top;margin-right:10px;margin-top:-1px}.la-actions button{background-color:transparent;border:2px solid hsla(0,0%,100%,.9);color:#fff;border-radius:2px;padding:5px 10px;font-size:13px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.la-actions button:hover{background-color:#fff;color:#2298f7}@-webkit-keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}@keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}.file-explorer{background-color:#fff;position:relative;height:100%}.file-explorer.toggled{height:100vh;overflow:hidden}.fe-body{min-height:100vh;overflow:auto}@media (min-width:992px){.fe-body{padding:0 0 40px 300px}}@media (max-width:991px){.fe-body{padding:75px 0 80px}}.feb-actions{position:fixed;bottom:30px;right:30px}.feb-actions .dropdown-menu{min-width:55px;width:55px;text-align:center;background:transparent;box-shadow:none;margin:0}.feb-actions.open .feba-btn{-webkit-transform:scale(1);transform:scale(1)}.feb-actions.open .feba-btn:first-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.3s;animation-duration:.3s}.feb-actions.open .feba-btn:last-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.1s;animation-duration:.1s}.feb-actions.open .feba-toggle{background:#ff403c}.feb-actions.open .feba-toggle>span{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.feba-toggle{width:55px;height:55px;line-height:55px;border-radius:50%;background:#ff726f;box-shadow:0 2px 3px rgba(0,0,0,.15);display:inline-block;text-align:center;border:0;padding:0}.feba-toggle span{display:inline-block;height:100%;width:100%}.feba-toggle i{color:#fff;font-size:17px;line-height:58px}.feba-toggle,.feba-toggle>span{-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;-webkit-backface-visibility:hidden;backface-visibility:hidden}.feba-btn{width:40px;margin-top:10px;height:40px;border-radius:50%;text-align:center;display:inline-block;line-height:40px;box-shadow:0 2px 3px rgba(0,0,0,.15);-webkit-transform:scale(0);transform:scale(0);position:relative}.feba-btn,.feba-btn:focus,.feba-btn:hover{color:#fff}.feba-btn label{width:100%;height:100%;position:absolute;left:0;top:0;cursor:pointer}.feba-bucket{background:#ffc155}.feba-upload{background:#ffc107}@-webkit-keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}@keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}.ie-warning{background-color:#ff5252;width:100%;height:100%;position:fixed;left:0;top:0;text-align:center}.ie-warning:before{width:1px;content:"";height:100%}.ie-warning .iw-inner,.ie-warning:before{display:inline-block;vertical-align:middle}.iw-inner{width:470px;height:300px;background-color:#fff;border-radius:5px;padding:40px;position:relative}.iw-inner ul{list-style:none;padding:0;margin:0;width:230px;margin-left:80px;margin-top:16px}.iw-inner ul>li{float:left}.iw-inner ul>li>a{display:block;padding:10px 15px 7px;font-size:14px;margin:0 1px;border-radius:3px}.iw-inner ul>li>a:hover{background:#eee}.iw-inner ul>li>a img{height:40px;margin-bottom:5px}.iwi-icon{color:#ff5252;font-size:40px;display:block;line-height:100%;margin-bottom:15px}.iwi-skip{position:absolute;left:0;bottom:-35px;width:100%;color:hsla(0,0%,100%,.6);cursor:pointer}.iwi-skip:hover{color:#fff}.dropdown-menu{padding:15px 0;top:0;margin-top:-1px}.dropdown-menu>li>a{padding:8px 20px;font-size:15px}.dropdown-menu>li>a>i{width:20px;position:relative;top:1px}.dropdown-menu-right>li>a{text-align:right}.alert{border:0;position:fixed;max-width:500px;margin:0;box-shadow:0 4px 5px rgba(0,0,0,.1);color:#fff;width:100%;right:20px;border-radius:3px;padding:17px 50px 17px 17px;z-index:10010;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.alert:not(.progress){top:20px}@media (min-width:768px){.alert:not(.progress){left:50%;margin-left:-250px}}.alert.progress{bottom:20px;right:20px}.alert.alert-danger{background:#ff726f}.alert.alert-success{background:#33d46f}.alert.alert-info{background:#50b2ff}@media (max-width:767px){.alert{left:20px;width:calc(100% - 40px);max-width:100%}}.alert .progress{margin:10px 10px 8px 0;height:5px;box-shadow:none;border-radius:1px;background-color:#50b2ff;border-radius:2px;overflow:hidden}.alert .progress-bar{box-shadow:none;background-color:#fff;height:100%}.alert .close{position:absolute;top:15px}@media (min-width:768px){.modal{text-align:center}.modal:before{content:"";height:100%;width:1px}.modal .modal-dialog,.modal:before{display:inline-block;vertical-align:middle}.modal .modal-dialog{text-align:left;margin:10px auto}}.modal-dark .modal-header{color:hsla(0,0%,100%,.4)}.modal-dark .modal-header small{color:hsla(0,0%,100%,.2)}.modal-dark .modal-content{background-color:#32393f}.modal-backdrop{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-backdrop,.modal-dialog{-webkit-animation-duration:.2s;animation-duration:.2s}.modal-dialog{-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-header{color:#333;position:relative}.modal-header small{display:block;text-transform:none;font-size:12px;margin-top:5px;color:#a8a8a8}.modal-content{border-radius:3px;box-shadow:none}.modal-footer{padding:0 30px 30px}.modal-confirm .modal-dialog,.modal-footer{text-align:center}.mc-icon{margin:0 0 10px}.mc-icon>i{font-size:60px}.mci-red{color:#ff8f8f}.mci-amber{color:#ffc107}.mci-green{color:#64e096}.mc-text{color:#333}.mc-sub{color:#bdbdbd;margin-top:5px;font-size:13px}@media (max-width:767px){.modal-about{text-align:center}.modal-about .modal-dialog{max-width:400px;width:90%;margin:20px auto 0}}.ma-inner{display:flex;flex-direction:row;align-items:center;min-height:350px;position:relative}@media (min-width:768px){.ma-inner:before{content:"";width:150px;height:100%;top:0;left:0;position:absolute;border-radius:3px 0 0 3px;background-color:#23282c}}.mai-item:first-child{width:150px;text-align:center}.mai-item:last-child{flex:4;padding:30px}.maii-logo{width:70px;position:relative}.maii-list{list-style:none;padding:0}.maii-list>li{margin-bottom:15px}.maii-list>li div{color:hsla(0,0%,100%,.8);text-transform:uppercase;font-size:14px}.maii-list>li small{font-size:13px;color:hsla(0,0%,100%,.4)}.toggle-password{position:absolute;bottom:30px;right:35px;width:30px;height:30px;border:1px solid #eee;border-radius:0;text-align:center;cursor:pointer;z-index:10;background-color:#fff;padding-top:5px}.toggle-password.toggled{background:#eee}.pm-body{padding-bottom:30px}.pmb-header{margin-bottom:35px}.pmb-list{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;padding:10px 35px}.pmb-list:nth-child(2n){background-color:#f7f7f7}.pmb-list .form-control{padding-left:0;padding-right:0}header.pmb-list{margin:20px 0 10px}.pmbl-item{display:block;font-size:13px}.pmbl-item:first-child{flex:2}.pmbl-item:nth-child(2){margin:0 25px;width:150px}.pmbl-item:nth-child(3){width:70px}div.pmb-list select{border:0}div.pmb-list .pml-item:not(:last-child){padding:0 5px}.modal-create-bucket .modal-dialog{position:fixed;right:25px;bottom:95px;margin:0;height:110px}.modal-create-bucket .modal-content{width:100%;height:100%}',""]); },function(A,M,t){function I(A){return null===A||void 0===A}function g(A){return!(!A||"object"!=typeof A||"number"!=typeof A.length)&&("function"==typeof A.copy&&"function"==typeof A.slice&&!(A.length>0&&"number"!=typeof A[0]))}function e(A,M,t){var e,o;if(I(A)||I(M))return!1;if(A.prototype!==M.prototype)return!1;if(E(A))return!!E(M)&&(A=i.call(A),M=i.call(M),N(A,M,t));if(g(A)){if(!g(M))return!1;if(A.length!==M.length)return!1;for(e=0;e=0;e--)if(n[e]!=C[e])return!1;for(e=n.length-1;e>=0;e--)if(o=n[e],!N(A[o],M[o],t))return!1;return typeof A==typeof M}var i=Array.prototype.slice,T=t(280),E=t(279),N=A.exports=function(A,M,t){return t||(t={}),A===M||(A instanceof Date&&M instanceof Date?A.getTime()===M.getTime():!A||!M||"object"!=typeof A&&"object"!=typeof M?t.strict?A===M:A==M:e(A,M,t))}},function(A,M){function t(A){return"[object Arguments]"==Object.prototype.toString.call(A)}function I(A){return A&&"object"==typeof A&&"number"==typeof A.length&&Object.prototype.hasOwnProperty.call(A,"callee")&&!Object.prototype.propertyIsEnumerable.call(A,"callee")||!1}var g="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();M=A.exports=g?t:I,M.supported=t,M.unsupported=I},function(A,M){function t(A){var M=[];for(var t in A)M.push(t);return M}M=A.exports="function"==typeof Object.keys?Object.keys:t,M.shim=t},function(A,M,t){"use strict";var I=t(141);A.exports=function(A,M){A.classList?A.classList.add(M):I(A)||(A.className=A.className+" "+M)}},function(A,M,t){"use strict";A.exports={addClass:t(281),removeClass:t(283),hasClass:t(141)}},function(A,M){"use strict";A.exports=function(A,M){A.classList?A.classList.remove(M):A.className=A.className.replace(new RegExp("(^|\\s)"+M+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}},function(A,M,t){"use strict";var I=t(40),g=t(288);A.exports=function(A,M){return function(t){var e=t.currentTarget,i=t.target,T=g(e,A);T.some(function(A){return I(A,i)})&&M.call(this,t)}}},function(A,M,t){"use strict";var I=t(81),g=t(142),e=t(284);A.exports={on:I,off:g,filter:e}},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A){for(var M=(0,T.default)(A),t=A&&A.offsetParent;t&&"html"!==I(A)&&"static"===(0,N.default)(t,"position");)t=t.offsetParent;return t||M.documentElement}var e=t(58);M.__esModule=!0,M.default=g;var i=t(39),T=e.interopRequireDefault(i),E=t(82),N=e.interopRequireDefault(E);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A,M){var t,g={top:0,left:0};return"fixed"===(0,a.default)(A,"position")?t=A.getBoundingClientRect():(M=M||(0,N.default)(A),t=(0,T.default)(A),"html"!==I(M)&&(g=(0,T.default)(M)),g.top+=parseInt((0,a.default)(M,"borderTopWidth"),10)-(0,n.default)(M)||0,g.left+=parseInt((0,a.default)(M,"borderLeftWidth"),10)-(0,c.default)(M)||0),e._extends({},t,{top:t.top-g.top-(parseInt((0,a.default)(A,"marginTop"),10)||0),left:t.left-g.left-(parseInt((0,a.default)(A,"marginLeft"),10)||0)})}var e=t(58);M.__esModule=!0,M.default=g;var i=t(143),T=e.interopRequireDefault(i),E=t(286),N=e.interopRequireDefault(E),o=t(144),n=e.interopRequireDefault(o),C=t(289),c=e.interopRequireDefault(C),D=t(82),a=e.interopRequireDefault(D);A.exports=M.default},function(A,M){"use strict";var t=/^[\w-]*$/,I=Function.prototype.bind.call(Function.prototype.call,[].slice);A.exports=function(A,M){var g,e="#"===M[0],i="."===M[0],T=e||i?M.slice(1):M,E=t.test(T);return E?e?(A=A.getElementById?A:document,(g=A.getElementById(T))?[g]:[]):I(A.getElementsByClassName&&i?A.getElementsByClassName(T):A.getElementsByTagName(M)):I(A.querySelectorAll(M))}},function(A,M,t){"use strict";var I=t(57);A.exports=function(A,M){var t=I(A);return void 0===M?t?"pageXOffset"in t?t.pageXOffset:t.document.documentElement.scrollLeft:A.scrollLeft:void(t?t.scrollTo(M,"pageYOffset"in t?t.pageYOffset:t.document.documentElement.scrollTop):A.scrollLeft=M)}},function(A,M,t){"use strict";var I=t(58),g=t(145),e=I.interopRequireDefault(g),i=/^(top|right|bottom|left)$/,T=/^([+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/i;A.exports=function(A){if(!A)throw new TypeError("No Element passed to ` + "`" + `getComputedStyle()` + "`" + `");var M=A.ownerDocument;return"defaultView"in M?M.defaultView.opener?A.ownerDocument.defaultView.getComputedStyle(A,null):window.getComputedStyle(A,null):{getPropertyValue:function(M){var t=A.style;M=(0,e.default)(M),"float"==M&&(M="styleFloat");var I=A.currentStyle[M]||null;if(null==I&&t&&t[M]&&(I=t[M]),T.test(I)&&!i.test(M)){var g=t.left,E=A.runtimeStyle,N=E&&E.left;N&&(E.left=A.currentStyle.left),t.left="fontSize"===M?"1em":I,I=t.pixelLeft+"px",t.left=g,N&&(E.left=N)}return I}}}},function(A,M){"use strict";A.exports=function(A,M){return"removeProperty"in A.style?A.style.removeProperty(M):A.style.removeAttribute(M)}},function(A,M,t){"use strict";function I(){var A,M="",t={O:"otransitionend",Moz:"transitionend",Webkit:"webkitTransitionEnd",ms:"MSTransitionEnd"},I=document.createElement("div");for(var g in t)if(N.call(t,g)&&void 0!==I.style[g+"TransitionProperty"]){M="-"+g.toLowerCase()+"-",A=t[g];break}return A||void 0===I.style.transitionProperty||(A="transitionend"),{end:A,prefix:M}}var g,e,i,T,E=t(32),N=Object.prototype.hasOwnProperty,o="transform",n={};E&&(n=I(),o=n.prefix+o,i=n.prefix+"transition-property",e=n.prefix+"transition-duration",T=n.prefix+"transition-delay",g=n.prefix+"transition-timing-function"),A.exports={transform:o,end:n.end,property:i,timing:g,delay:T,duration:e}},function(A,M){"use strict";var t=/-(.)/g;A.exports=function(A){return A.replace(t,function(A,M){return M.toUpperCase()})}},function(A,M){"use strict";var t=/([A-Z])/g;A.exports=function(A){return A.replace(t,"-$1").toLowerCase()}},function(A,M,t){"use strict";var I=t(294),g=/^ms-/;A.exports=function(A){return I(A).replace(g,"-ms-")}},function(A,M){"use strict";function t(A){return A.replace(I,function(A,M){return M.toUpperCase()})}var I=/-(.)/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A.replace(e,"ms-"))}var g=t(296),e=/^-ms-/;A.exports=I},function(A,M,t){"use strict";function I(A){return!!A&&("object"==typeof A||"function"==typeof A)&&"length"in A&&!("setInterval"in A)&&"number"!=typeof A.nodeType&&(Array.isArray(A)||"callee"in A||"item"in A)}function g(A){return I(A)?Array.isArray(A)?A.slice():e(A):[A]}var e=t(307);A.exports=g},function(A,M,t){"use strict";function I(A){var M=A.match(o);return M&&M[1].toLowerCase()}function g(A,M){var t=N;N?void 0:E(!1);var g=I(A),e=g&&T(g);if(e){t.innerHTML=e[1]+A+e[2];for(var o=e[0];o--;)t=t.lastChild}else t.innerHTML=A;var n=t.getElementsByTagName("script");n.length&&(M?void 0:E(!1),i(n).forEach(M));for(var C=i(t.childNodes);t.lastChild;)t.removeChild(t.lastChild);return C}var e=t(10),i=t(298),T=t(151),E=t(2),N=e.canUseDOM?document.createElement("div"):null,o=/^\s*<(\w+)/;A.exports=g},function(A,M){"use strict";function t(A){return A===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:A.scrollLeft,y:A.scrollTop}}A.exports=t},function(A,M){"use strict";function t(A){return A.replace(I,"-$1").toLowerCase()}var I=/([A-Z])/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A).replace(e,"-ms-")}var g=t(301),e=/^ms-/;A.exports=I},function(A,M){"use strict";function t(A){return!(!A||!("function"==typeof Node?A instanceof Node:"object"==typeof A&&"number"==typeof A.nodeType&&"string"==typeof A.nodeName))}A.exports=t},function(A,M,t){"use strict";function I(A){return g(A)&&3==A.nodeType}var g=t(303);A.exports=I},function(A,M){"use strict";function t(A,M,t){if(!A)return null;var g={};for(var e in A)I.call(A,e)&&(g[e]=M.call(t,A[e],e,A));return g}var I=Object.prototype.hasOwnProperty;A.exports=t},function(A,M){"use strict";function t(A){var M={};return function(t){return M.hasOwnProperty(t)||(M[t]=A.call(this,t)),M[t]}}A.exports=t},function(A,M,t){"use strict";function I(A){var M=A.length;if(Array.isArray(A)||"object"!=typeof A&&"function"!=typeof A?g(!1):void 0,"number"!=typeof M?g(!1):void 0,0===M||M-1 in A?void 0:g(!1),A.hasOwnProperty)try{return Array.prototype.slice.call(A)}catch(A){}for(var t=Array(M),I=0;I=T?i(M):null,C=M.length;n&&(N=e,o=!1,M=n);A:for(;++Eg?0:g+M),t=void 0===t||t>g?g:+t||0,t<0&&(t+=g),g=M>t?0:t-M>>>0,M>>>=0;for(var e=Array(g);++I-1?t[N]:void 0}return e(t,I,A)}}var g=t(319),e=t(322),i=t(323),T=t(28);A.exports=I},function(A,M,t){function I(A,M,t,I,e,i,T){var E=-1,N=A.length,o=M.length;if(N!=o&&!(e&&o>N))return!1;for(;++E=T?i(M):null,C=M.length;n&&(N=e,o=!1,M=n);A:for(;++Eg?0:g+M),t=void 0===t||t>g?g:+t||0,t<0&&(t+=g),g=M>t?0:t-M>>>0,M>>>=0;for(var e=Array(g);++I-1?t[N]:void 0}return e(t,I,A)}}var g=t(319),e=t(322),i=t(323),T=t(28);A.exports=I},function(A,M,t){function I(A,M,t,I,e,i,T){var E=-1,N=A.length,o=M.length;if(N!=o&&!(e&&o>N))return!1;for(;++Eo||N===o&&"application/"===M[T].substr(0,12))continue}M[T]=I}}})}var E=t(351),N=t(354).extname,o=/^\s*([^;\s]*)(?:;|\s|$)/,n=/^text\//i;M.charset=I,M.charsets={lookup:I},M.contentType=g,M.extension=e,M.extensions=Object.create(null),M.lookup=i,M.types=Object.create(null),T(M.extensions,M.types)},function(A,M){function t(A){throw new Error("Cannot find module '"+A+"'.")}t.keys=function(){return[]},t.resolve=t,A.exports=t,t.id=353},function(A,M,t){(function(A){function t(A,M){for(var t=0,I=A.length-1;I>=0;I--){var g=A[I];"."===g?A.splice(I,1):".."===g?(A.splice(I,1),t++):t&&(A.splice(I,1),t--)}if(M)for(;t--;t)A.unshift("..");return A}function I(A,M){if(A.filter)return A.filter(M);for(var t=[],I=0;I=-1&&!g;e--){var i=e>=0?arguments[e]:A.cwd();if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(M=i+"/"+M,g="/"===i.charAt(0))}return M=t(I(M.split("/"),function(A){return!!A}),!g).join("/"),(g?"/":"")+M||"."},M.normalize=function(A){var g=M.isAbsolute(A),e="/"===i(A,-1);return A=t(I(A.split("/"),function(A){return!!A}),!g).join("/"),A||g||(A="."),A&&e&&(A+="/"),(g?"/":"")+A},M.isAbsolute=function(A){return"/"===A.charAt(0)},M.join=function(){var A=Array.prototype.slice.call(arguments,0);return M.normalize(I(A,function(A,M){if("string"!=typeof A)throw new TypeError("Arguments to path.join must be strings");return A}).join("/"))},M.relative=function(A,t){function I(A){for(var M=0;M=0&&""===A[t];t--);return M>t?[]:A.slice(M,t-M+1)}A=M.resolve(A).substr(1),t=M.resolve(t).substr(1);for(var g=I(A.split("/")),e=I(t.split("/")),i=Math.min(g.length,e.length),T=i,E=0;E=0;e--){var i=I[e]+g;if(i in M)return i}return!1}},function(A,M,t){"use strict";var I=t(497);M.extract=function(A){return A.split("?")[1]||""},M.parse=function(A){return"string"!=typeof A?{}:(A=A.trim().replace(/^(\?|#|&)/,""),A?A.split("&").reduce(function(A,M){var t=M.replace(/\+/g," ").split("="),I=t.shift(),g=t.length>0?t.join("="):void 0;return I=decodeURIComponent(I),g=void 0===g?null:decodeURIComponent(g),A.hasOwnProperty(I)?Array.isArray(A[I])?A[I].push(g):A[I]=[A[I],g]:A[I]=g,A},{}):{})},M.stringify=function(A){return A?Object.keys(A).sort().map(function(M){var t=A[M];return void 0===t?"":null===t?M:Array.isArray(t)?t.slice().sort().map(function(A){return I(M)+"="+I(A)}).join("&"):I(M)+"="+I(t)}).filter(function(A){return A.length>0}).join("&"):""}},function(A,M){"use strict";function t(A,M){return Object.prototype.hasOwnProperty.call(A,M)}A.exports=function(A,M,I,g){M=M||"&",I=I||"=";var e={};if("string"!=typeof A||0===A.length)return e;var i=/\+/g;A=A.split(M);var T=1e3;g&&"number"==typeof g.maxKeys&&(T=g.maxKeys);var E=A.length;T>0&&E>T&&(E=T);for(var N=0;N=0?(o=D.substr(0,a),n=D.substr(a+1)):(o=D,n=""),C=decodeURIComponent(o),c=decodeURIComponent(n),t(e,C)?Array.isArray(e[C])?e[C].push(c):e[C]=[e[C],c]:e[C]=c}return e}},function(A,M){"use strict";var t=function(A){switch(typeof A){case"string":return A;case"boolean":return A?"true":"false";case"number":return isFinite(A)?A:"";default:return""}};A.exports=function(A,M,I,g){return M=M||"&",I=I||"=",null===A&&(A=void 0),"object"==typeof A?Object.keys(A).map(function(g){var e=encodeURIComponent(t(g))+I;return Array.isArray(A[g])?A[g].map(function(A){return e+encodeURIComponent(t(A))}).join(M):e+encodeURIComponent(t(A[g]))}).join(M):g?encodeURIComponent(t(g))+I+encodeURIComponent(t(A)):""}},function(A,M,t){"use strict";M.decode=M.parse=t(358),M.encode=M.stringify=t(359)},function(A,M,t){(function(M){for(var I=t(355),g="undefined"==typeof window?M:window,e=["moz","webkit"],i="AnimationFrame",T=g["request"+i],E=g["cancel"+i]||g["cancelRequest"+i],N=0;!T&&N1)||(e=A,!1)}),e)return new Error("(children) "+I+" - Duplicate children detected of bsRole: "+e+". Only one child each allowed with the following bsRoles: "+M.join(", "))})}},A.exports=M.default},function(A,M,t){"use strict";function I(A){var M=[];return void 0===A?M:(i.default.forEach(A,function(A){M.push(A)}),M)}var g=t(6).default;M.__esModule=!0,M.default=I;var e=t(51),i=g(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}Object.defineProperty(M,"__esModule",{value:!0}),M.CopyToClipboard=void 0;var e=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){var M=A.style,t=g(A,["style"]),I=o({},M,{height:6,right:2,bottom:2,left:2,borderRadius:3});return C.default.createElement("div",o({style:I},t))}function i(A){var M=A.style,t=g(A,["style"]),I=o({},M,{width:6,right:2,bottom:2,top:2,borderRadius:3});return C.default.createElement("div",o({style:I},t))}function T(A){var M=A.style,t=g(A,["style"]),I=o({},M,{cursor:"pointer",borderRadius:"inherit",backgroundColor:"rgba(0,0,0,.2)"});return C.default.createElement("div",o({style:I},t))}function E(A){var M=A.style,t=g(A,["style"]),I=o({},M,{cursor:"pointer",borderRadius:"inherit",backgroundColor:"rgba(0,0,0,.2)"});return C.default.createElement("div",o({style:I},t))}function N(A){return C.default.createElement("div",A)}var o=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}var e=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M0||(this.setState({isDragActive:!1,isDragReject:!1}),this.props.onDragLeave&&this.props.onDragLeave.call(this,A))}},{key:"onDrop",value:function A(M){var t=this,I=this.props,A=I.onDrop,g=I.onDropAccepted,e=I.onDropRejected,i=I.multiple,T=I.disablePreview,E=(0,a.default)(M,i),N=[],o=[];M.preventDefault(),this.enterCounter=0,this.isFileDialogActive=!1,E.forEach(function(A){T||(A.preview=window.URL.createObjectURL(A)),t.fileAccepted(A)&&t.fileMatchSize(A)?N.push(A):o.push(A)}),A&&A.call(this,N,o,M),o.length>0&&e&&e.call(this,o,M),N.length>0&&g&&g.call(this,N,M),this.setState({isDragActive:!1,isDragReject:!1})}},{key:"onClick",value:function A(M){M.stopPropagation();var t=this.props,A=t.onClick,I=t.disableClick;I||(this.open(),A&&A.call(this,M))}},{key:"onFileDialogCancel",value:function A(){var A=this.props.onFileDialogCancel,M=this.fileInputEl,t=this.isFileDialogActive;A&&t&&setTimeout(function(){var I=M.files;I.length||(t=!1,A())},300)}},{key:"fileAccepted",value:function(A){return(0,c.default)(A,this.props.accept)}},{key:"fileMatchSize",value:function(A){return A.size<=this.props.maxSize&&A.size>=this.props.minSize}},{key:"allFilesAccepted",value:function(A){return A.every(this.fileAccepted)}},{key:"open",value:function(){this.isFileDialogActive=!0,this.fileInputEl.value=null,this.fileInputEl.click()}},{key:"render",value:function(){var A=this,M=this.props,t=M.accept,I=M.activeClassName,e=M.inputProps,i=M.multiple,T=M.name,N=M.rejectClassName,o=g(M,["accept","activeClassName","inputProps","multiple","name","rejectClassName"]),C=o.activeStyle,c=o.className,D=o.rejectStyle,a=o.style,Q=g(o,["activeStyle","className","rejectStyle","style"]),r=this.state,s=r.isDragActive,x=r.isDragReject;c=c||"",s&&I&&(c+=" "+I),x&&N&&(c+=" "+N),c||a||C||D||(a={width:200,height:200,borderWidth:2,borderColor:"#666",borderStyle:"dashed",borderRadius:5},C={borderStyle:"solid",backgroundColor:"#eee"},D={borderStyle:"solid",backgroundColor:"#ffdddd"});var j=void 0;j=C&&s?E({},a,C):D&&x?E({},a,D):E({},a);var y={accept:t,type:"file",style:{display:"none"},multiple:B&&i,ref:function(M){return A.fileInputEl=M},onChange:this.onDrop};T&&T.length&&(y.name=T);var u=["acceptedFiles","disablePreview","disableClick","onDropAccepted","onDropRejected","onFileDialogCancel","maxSize","minSize"],w=E({},Q);return u.forEach(function(A){return delete w[A]}),n.default.createElement("div",E({className:c,style:j},w,{onClick:this.onClick,onDragStart:this.onDragStart,onDragEnter:this.onDragEnter,onDragOver:this.onDragOver,onDragLeave:this.onDragLeave,onDrop:this.onDrop}),this.props.children,n.default.createElement("input",E({},e,y)))}}]),M}(n.default.Component);Q.defaultProps={disablePreview:!1,disableClick:!1,multiple:!0,maxSize:1/0,minSize:0},Q.propTypes={onClick:n.default.PropTypes.func,onDrop:n.default.PropTypes.func,onDropAccepted:n.default.PropTypes.func,onDropRejected:n.default.PropTypes.func,onDragStart:n.default.PropTypes.func,onDragEnter:n.default.PropTypes.func,onDragOver:n.default.PropTypes.func,onDragLeave:n.default.PropTypes.func,children:n.default.PropTypes.node,style:n.default.PropTypes.object,activeStyle:n.default.PropTypes.object,rejectStyle:n.default.PropTypes.object,className:n.default.PropTypes.string,activeClassName:n.default.PropTypes.string,rejectClassName:n.default.PropTypes.string,disablePreview:n.default.PropTypes.bool,disableClick:n.default.PropTypes.bool,onFileDialogCancel:n.default.PropTypes.func,inputProps:n.default.PropTypes.object,multiple:n.default.PropTypes.bool,accept:n.default.PropTypes.string,name:n.default.PropTypes.string,maxSize:n.default.PropTypes.number,minSize:n.default.PropTypes.number},M.default=Q,A.exports=M.default},function(M,t){M.exports=A},function(A,M){A.exports=function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){"use strict";M.__esModule=!0,t(8),t(9),M.default=function(A,M){if(A&&M){var t=function(){var t=Array.isArray(M)?M:M.split(","),I=A.name||"",g=A.type||"",e=g.replace(/\/.*$/,"");return{v:t.some(function(A){var M=A.trim();return"."===M.charAt(0)?I.toLowerCase().endsWith(M.toLowerCase()):/\/\*$/.test(M)?e===M.replace(/\/.*$/,""):g===M})}}();if("object"==typeof t)return t.v}return!0},A.exports=M.default},function(A,M){var t=A.exports={version:"1.2.2"};"number"==typeof __e&&(__e=t)},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(2),g=t(1),e=t(4),i=t(19),T="prototype",E=function(A,M){return function(){return A.apply(M,arguments)}},N=function(A,M,t){var o,n,C,c,D=A&N.G,a=A&N.P,B=D?I:A&N.S?I[M]||(I[M]={}):(I[M]||{})[T],Q=D?g:g[M]||(g[M]={});D&&(t=M);for(o in t)n=!(A&N.F)&&B&&o in B,C=(n?B:t)[o],c=A&N.B&&n?E(C,I):a&&"function"==typeof C?E(Function.call,C):C,B&&!n&&i(B,o,C),Q[o]!=C&&e(Q,o,c),a&&((Q[T]||(Q[T]={}))[o]=C)};I.core=g,N.F=1,N.G=2,N.S=4,N.P=8,N.B=16,N.W=32,A.exports=N},function(A,M,t){var I=t(5),g=t(18);A.exports=t(22)?function(A,M,t){return I.setDesc(A,M,g(1,t))}:function(A,M,t){return A[M]=t,A}},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M){var t=0,I=Math.random();A.exports=function(A){return"Symbol(".concat(void 0===A?"":A,")_",(++t+I).toString(36))}},function(A,M,t){var I=t(20)("wks"),g=t(2).Symbol;A.exports=function(A){return I[A]||(I[A]=g&&g[A]||(g||t(6))("Symbol."+A))}},function(A,M,t){t(26),A.exports=t(1).Array.some},function(A,M,t){t(25),A.exports=t(1).String.endsWith},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M,t){var I=t(10);A.exports=function(A,M,t){if(I(A),void 0===M)return A;switch(t){case 1:return function(t){return A.call(M,t)};case 2:return function(t,I){return A.call(M,t,I)};case 3:return function(t,I,g){return A.call(M,t,I,g)}}return function(){return A.apply(M,arguments)}}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M,t){A.exports=function(A){var M=/./;try{"/./"[A](M)}catch(I){try{return M[t(7)("match")]=!1,!"/./"[A](M)}catch(A){}}return!0}},function(A,M){A.exports=function(A){try{return!!A()}catch(A){return!0}}},function(A,M){A.exports=function(A){return"object"==typeof A?null!==A:"function"==typeof A}},function(A,M,t){var I=t(16),g=t(11),e=t(7)("match");A.exports=function(A){var M;return I(A)&&(void 0!==(M=A[e])?!!M:"RegExp"==g(A))}},function(A,M){A.exports=function(A,M){return{enumerable:!(1&A),configurable:!(2&A),writable:!(4&A),value:M}}},function(A,M,t){var I=t(2),g=t(4),e=t(6)("src"),i="toString",T=Function[i],E=(""+T).split(i);t(1).inspectSource=function(A){return T.call(A)},(A.exports=function(A,M,t,i){"function"==typeof t&&(g(t,e,A[M]?""+A[M]:E.join(String(M))),"name"in t||(t.name=M)),A===I?A[M]=t:(i||delete A[M],g(A,M,t))})(Function.prototype,i,function(){return"function"==typeof this&&this[e]||T.call(this)})},function(A,M,t){var I=t(2),g="__core-js_shared__",e=I[g]||(I[g]={});A.exports=function(A){return e[A]||(e[A]={})}},function(A,M,t){var I=t(17),g=t(13);A.exports=function(A,M,t){if(I(M))throw TypeError("String#"+t+" doesn't accept regex!");return String(g(A))}},function(A,M,t){A.exports=!t(15)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(A,M){var t=Math.ceil,I=Math.floor;A.exports=function(A){return isNaN(A=+A)?0:(A>0?I:t)(A)}},function(A,M,t){var I=t(23),g=Math.min;A.exports=function(A){return A>0?g(I(A),9007199254740991):0}},function(A,M,t){"use strict";var I=t(3),g=t(24),e=t(21),i="endsWith",T=""[i];I(I.P+I.F*t(14)(i),"String",{endsWith:function(A){var M=e(this,A,i),t=arguments,I=t.length>1?t[1]:void 0,E=g(M.length),N=void 0===I?E:Math.min(g(I),E),o=String(A);return T?T.call(M,o,N):M.slice(N-o.length,N)===o}})},function(A,M,t){var I=t(5),g=t(3),e=t(1).Array||Array,i={},T=function(A,M){I.each.call(A.split(","),function(A){void 0==M&&A in e?i[A]=e[A]:A in[]&&(i[A]=t(12)(Function.call,[][A],M))})};T("pop,reverse,shift,keys,values,entries",1),T("indexOf,every,some,forEach,map,filter,find,findIndex,includes",3),T("join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill"),g(g.S,"Array",i)}])},function(A,M){"use strict";function t(A){var M=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],t=[];if(A.dataTransfer){var I=A.dataTransfer;I.files&&I.files.length?t=I.files:I.items&&I.items.length&&(t=I.items)}else A.target&&A.target.files&&(t=A.target.files);return t.length>0&&(t=M?t:[t[0]]),Array.prototype.slice.call(t)}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t,A.exports=M.default}])})},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{},t=M.hideSiblingNodes,I=void 0===t||t,e=M.handleContainerOverflow,i=void 0===e||e;g(this,A),this.hideSiblingNodes=I,this.handleContainerOverflow=i,this.modals=[],this.containers=[],this.data=[]}return N(A,[{key:"add",value:function(A,M,t){var I=this.modals.indexOf(A),g=this.containers.indexOf(M);if(I!==-1)return I;if(I=this.modals.length,this.modals.push(A),this.hideSiblingNodes&&(0,r.hideSiblings)(M,A.mountNode),g!==-1)return this.data[g].modals.push(A),I;var e={modals:[A],classes:t?t.split(/\s+/):[],overflowing:(0,Q.default)(M)};return this.handleContainerOverflow&&T(e,M),e.classes.forEach(c.default.addClass.bind(null,M)),this.containers.push(M),this.data.push(e),I}},{key:"remove",value:function(A){var M=this.modals.indexOf(A);if(M!==-1){var t=i(this.data,A),I=this.data[t],g=this.containers[t];I.modals.splice(I.modals.indexOf(A),1),this.modals.splice(M,1),0===I.modals.length?(I.classes.forEach(c.default.removeClass.bind(null,g)),this.handleContainerOverflow&&E(I,g),this.hideSiblingNodes&&(0,r.showSiblings)(g,A.mountNode),this.containers.splice(t,1),this.data.splice(t,1)):this.hideSiblingNodes&&(0,r.ariaHidden)(!1,I.modals[I.modals.length-1].mountNode)}}},{key:"isTopModal",value:function(A){return!!this.modals.length&&this.modals[this.modals.length-1]===A}}]),A}();M.default=s,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M1?t-1:0),g=1;g=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}function E(){}Object.defineProperty(M,"__esModule",{value:!0}),M.EXITING=M.ENTERED=M.ENTERING=M.EXITED=M.UNMOUNTED=void 0;var N=Object.assign||function(A){for(var M=1;MT?T-N:0}function i(A,M,t,I){var e=g(t),i=e.width,T=A-I,E=A+I+M;return T<0?-T:E>i?i-E:0}function T(A,M,t,I,g){var T="BODY"===I.tagName?(0,N.default)(t):(0,n.default)(t,I),E=(0,N.default)(M),o=E.height,C=E.width,c=void 0,D=void 0,a=void 0,B=void 0;if("left"===A||"right"===A){D=T.top+(T.height-o)/2,c="left"===A?T.left-C:T.left+T.width;var Q=e(D,o,I,g);D+=Q,B=50*(1-2*Q/o)+"%",a=void 0}else{if("top"!==A&&"bottom"!==A)throw new Error('calcOverlayPosition(): No such placement of "'+A+'" found.');c=T.left+(T.width-C)/2,D="top"===A?T.top-o:T.top+T.height;var r=i(c,C,I,g);c+=r,a=50*(1-2*r/C)+"%",B=void 0}return{positionLeft:c,positionTop:D,arrowOffsetLeft:a,arrowOffsetTop:B}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=T;var E=t(143),N=I(E),o=t(287),n=I(o),C=t(144),c=I(C),D=t(52),a=I(D);A.exports=M.default},function(A,M){"use strict";function t(A,M){M&&(A?M.setAttribute("aria-hidden","true"):M.removeAttribute("aria-hidden"))}function I(A,M){T(A,M,function(A){return t(!0,A)})}function g(A,M){T(A,M,function(A){return t(!1,A)})}Object.defineProperty(M,"__esModule",{value:!0}),M.ariaHidden=t,M.hideSiblings=I,M.showSiblings=g;var e=["template","script","style"],i=function(A){var M=A.nodeType,t=A.tagName;return 1===M&&e.indexOf(t.toLowerCase())===-1},T=function(A,M,t){M=[].concat(M),[].forEach.call(A.children,function(A){M.indexOf(A)===-1&&i(A)&&t(A)})}},function(A,M,t){"use strict";var I=function(){};A.exports=I},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return function(t,I,g){if(null!=t[I]){var e='"'+I+'" property of "'+g+'" has been deprecated.\n'+M;E[e]||(T.default(!1,e),E[e]=!0)}return A(t,I,g)}}function e(){E={}}M.__esModule=!0,M.default=g;var i=t(127),T=I(i),E={};g._resetWarned=e,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function e(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function i(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}M.__esModule=!0,M.default=void 0;var T=t(1),E=t(184),N=I(E),o=t(185),n=(I(o),function(A){function M(t,I){g(this,M);var i=e(this,A.call(this,t,I));return i.store=t.store,i}return i(M,A),M.prototype.getChildContext=function(){return{store:this.store}},M.prototype.render=function(){return T.Children.only(this.props.children)},M}(T.Component));M.default=n,n.propTypes={store:N.default.isRequired,children:T.PropTypes.element.isRequired},n.childContextTypes={store:N.default.isRequired}},function(A,M){"use strict";function t(A,M){if(A===M)return!0;var t=Object.keys(A),I=Object.keys(M);if(t.length!==I.length)return!1;for(var g=Object.prototype.hasOwnProperty,e=0;e=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){var t=A.history,I=A.routes,e=A.location,E=g(A,["history","routes","location"]);t||e?void 0:(0,N.default)(!1),t=t?t:(0,n.default)(E);var o=(0,c.default)(t,(0,D.createRoutes)(I)),C=void 0;e?e=t.createLocation(e):C=t.listen(function(A){e=A});var B=(0,a.createRouterObject)(t,o);t=(0,a.createRoutingHistory)(t,o),o.match(e,function(A,I,g){M(A,I&&B.createLocation(I,T.REPLACE),g&&i({},g,{history:t,router:B,matchContext:{history:t,transitionManager:o,router:B}})),C&&C()})}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return function(){var M=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],t=M.routes,I=g(M,["routes"]),e=(0,E.default)(A)(I),T=(0,o.default)(e,t);return i({},e,T)}}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=A&&N&&(T=!0,t()))}}var i=0,T=!1,E=!1,N=!1,o=void 0;e()}M.__esModule=!0;var I=Array.prototype.slice;M.loopAsync=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){function A(A){try{A=A||window.history.state||{}}catch(M){A={}}var M=n.getWindowPath(),t=A,I=t.key,g=void 0;I?g=C.readState(I):(g=null,I=s.createKey(),Q&&window.history.replaceState(e({},A,{key:I}),null));var i=N.parsePath(M);return s.createLocation(e({},i,{state:g}),void 0,I)}function M(M){function t(M){void 0!==M.state&&I(A(M.state))}var I=M.transitionTo;return n.addEventListener(window,"popstate",t),function(){n.removeEventListener(window,"popstate",t)}}function t(A){var M=A.basename,t=A.pathname,I=A.search,g=A.hash,e=A.state,i=A.action,T=A.key;if(i!==E.POP){C.saveState(T,e);var N=(M||"")+t+I+g,o={key:T};if(i===E.PUSH){if(r)return window.location.href=N,!1;window.history.pushState(o,null,N)}else{if(r)return window.location.replace(N),!1;window.history.replaceState(o,null,N)}}}function I(A){1===++x&&(j=M(s));var t=s.listenBefore(A);return function(){t(),0===--x&&j()}}function g(A){1===++x&&(j=M(s));var t=s.listen(A);return function(){t(),0===--x&&j()}}function i(A){1===++x&&(j=M(s)),s.registerTransitionHook(A)}function c(A){s.unregisterTransitionHook(A),0===--x&&j()}var a=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];o.canUseDOM?void 0:T.default(!1);var B=a.forceRefresh,Q=n.supportsHistory(),r=!Q||B,s=D.default(e({},a,{getCurrentLocation:A,finishTransition:t,saveState:C.saveState})),x=0,j=void 0;return e({},s,{listenBefore:I,listen:g,registerTransitionHook:i,unregisterTransitionHook:c})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M=0&&M=0&&B8&&u<=11),l=32,Y=String.fromCharCode(l),d=c.topLevelTypes,h={beforeInput:{phasedRegistrationNames:{bubbled:s({onBeforeInput:null}),captured:s({onBeforeInputCapture:null})},dependencies:[d.topCompositionEnd,d.topKeyPress,d.topTextInput,d.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:s({onCompositionEnd:null}),captured:s({onCompositionEndCapture:null})},dependencies:[d.topBlur,d.topCompositionEnd,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:s({onCompositionStart:null}),captured:s({onCompositionStartCapture:null})},dependencies:[d.topBlur,d.topCompositionStart,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:s({onCompositionUpdate:null}),captured:s({onCompositionUpdateCapture:null})},dependencies:[d.topBlur,d.topCompositionUpdate,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]}},S=!1,z=null,p={eventTypes:h,extractEvents:function(A,M,t,I,g){return[N(A,M,t,I,g),C(A,M,t,I,g)]}};A.exports=p},function(A,M,t){"use strict";var I=t(202),g=t(10),e=t(17),i=(t(297),t(476)),T=t(302),E=t(306),N=(t(3),E(function(A){return T(A)})),o=!1,n="cssFloat";if(g.canUseDOM){var C=document.createElement("div").style;try{C.font=""}catch(A){o=!0}void 0===document.documentElement.style.cssFloat&&(n="styleFloat")}var c={createMarkupForStyles:function(A){var M="";for(var t in A)if(A.hasOwnProperty(t)){var I=A[t];null!=I&&(M+=N(t)+":",M+=i(t,I)+";")}return M||null},setValueForStyles:function(A,M){var t=A.style;for(var g in M)if(M.hasOwnProperty(g)){var e=i(g,M[g]);if("float"===g&&(g=n),e)t[g]=e;else{var T=o&&I.shorthandPropertyExpansions[g];if(T)for(var E in T)t[E]="";else t[g]=""}}}};e.measureMethods(c,"CSSPropertyOperations",{setValueForStyles:"setValueForStyles"}),A.exports=c},function(A,M,t){"use strict";function I(A){var M=A.nodeName&&A.nodeName.toLowerCase();return"select"===M||"input"===M&&"file"===A.type}function g(A){var M=u.getPooled(h.change,z,A,w(A));x.accumulateTwoPhaseDispatches(M),y.batchedUpdates(e,M)}function e(A){s.enqueueEvents(A),s.processEventQueue(!1)}function i(A,M){S=A,z=M,S.attachEvent("onchange",g)}function T(){S&&(S.detachEvent("onchange",g),S=null,z=null)}function E(A,M,t){if(A===d.topChange)return t}function N(A,M,t){A===d.topFocus?(T(),i(M,t)):A===d.topBlur&&T()}function o(A,M){S=A,z=M,p=A.value,U=Object.getOwnPropertyDescriptor(A.constructor.prototype,"value"),Object.defineProperty(S,"value",F),S.attachEvent("onpropertychange",C)}function n(){S&&(delete S.value,S.detachEvent("onpropertychange",C),S=null,z=null,p=null,U=null)}function C(A){if("value"===A.propertyName){var M=A.srcElement.value;M!==p&&(p=M,g(A))}}function c(A,M,t){if(A===d.topInput)return t}function D(A,M,t){A===d.topFocus?(n(),o(M,t)):A===d.topBlur&&n()}function a(A,M,t){if((A===d.topSelectionChange||A===d.topKeyUp||A===d.topKeyDown)&&S&&S.value!==p)return p=S.value,z}function B(A){return A.nodeName&&"input"===A.nodeName.toLowerCase()&&("checkbox"===A.type||"radio"===A.type)}function Q(A,M,t){if(A===d.topClick)return t}var r=t(24),s=t(53),x=t(54),j=t(10),y=t(18),u=t(37),w=t(117),L=t(120),l=t(229),Y=t(27),d=r.topLevelTypes,h={change:{phasedRegistrationNames:{bubbled:Y({onChange:null}),captured:Y({onChangeCapture:null})},dependencies:[d.topBlur,d.topChange,d.topClick,d.topFocus,d.topInput,d.topKeyDown,d.topKeyUp,d.topSelectionChange]}},S=null,z=null,p=null,U=null,O=!1;j.canUseDOM&&(O=L("change")&&(!("documentMode"in document)||document.documentMode>8));var m=!1;j.canUseDOM&&(m=L("input")&&(!("documentMode"in document)||document.documentMode>9));var F={get:function(){return U.get.call(this)},set:function(A){p=""+A,U.set.call(this,A)}},f={eventTypes:h,extractEvents:function(A,M,t,g,e){var i,T;if(I(M)?O?i=E:T=N:l(M)?m?i=c:(i=a,T=D):B(M)&&(i=Q),i){var o=i(A,M,t);if(o){var n=u.getPooled(h.change,o,g,e);return n.type="change",x.accumulateTwoPhaseDispatches(n),n}}T&&T(A,M,t)}};A.exports=f},function(A,M){"use strict";var t=0,I={createReactRootIndex:function(){return t++}};A.exports=I},function(A,M,t){"use strict";function I(A){return A.substring(1,A.indexOf(" "))}var g=t(10),e=t(299),i=t(20),T=t(151),E=t(2),N=/^(<[^ \/>]+)/,o="data-danger-index",n={dangerouslyRenderMarkup:function(A){g.canUseDOM?void 0:E(!1);for(var M,t={},n=0;n1?1-M:void 0;return this._fallbackText=g.slice(A,T),this._fallbackText}}),g.addPoolingTo(I),A.exports=I},function(A,M,t){"use strict";var I,g=t(47),e=t(10),i=g.injection.MUST_USE_ATTRIBUTE,T=g.injection.MUST_USE_PROPERTY,E=g.injection.HAS_BOOLEAN_VALUE,N=g.injection.HAS_SIDE_EFFECTS,o=g.injection.HAS_NUMERIC_VALUE,n=g.injection.HAS_POSITIVE_NUMERIC_VALUE,C=g.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(e.canUseDOM){var c=document.implementation;I=c&&c.hasFeature&&c.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var D={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:i|E,allowTransparency:i,alt:null,async:E,autoComplete:null,autoPlay:E,capture:i|E,cellPadding:null,cellSpacing:null,charSet:i,challenge:i,checked:T|E,classID:i,className:I?i:T,cols:i|n,colSpan:null,content:null,contentEditable:null,contextMenu:i,controls:T|E,coords:null,crossOrigin:null,data:null,dateTime:i,default:E,defer:E,dir:null,disabled:i|E,download:C,draggable:null,encType:null,form:i,formAction:i,formEncType:i,formMethod:i,formNoValidate:E,formTarget:i,frameBorder:i,headers:null,height:i,hidden:i|E,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:T,inputMode:i,integrity:null,is:i,keyParams:i,keyType:i,kind:null,label:null,lang:null,list:i,loop:T|E,low:null,manifest:i,marginHeight:null,marginWidth:null,max:null,maxLength:i,media:i,mediaGroup:null,method:null,min:null,minLength:i,multiple:T|E,muted:T|E,name:null,nonce:i,noValidate:E,open:E,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:T|E,rel:null,required:E,reversed:E,role:i,rows:i|n,rowSpan:null,sandbox:null,scope:null,scoped:E,scrolling:null,seamless:i|E,selected:T|E,shape:null,size:i|n,sizes:i,span:n,spellCheck:null,src:null,srcDoc:T,srcLang:null,srcSet:i,start:o,step:null,style:null,summary:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:T|N,width:i,wmode:i,wrap:null,about:i,datatype:i,inlist:i,prefix:i,property:i,resource:i,typeof:i,vocab:i,autoCapitalize:i,autoCorrect:i,autoSave:null,color:null,itemProp:i,itemScope:i|E,itemType:i,itemID:i,itemRef:i,results:null,security:i,unselectable:i},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",autoSave:"autosave",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};A.exports=D},function(A,M,t){"use strict";var I=t(208),g=t(450),e=t(455),i=t(4),T=t(477),E={};i(E,e),i(E,{findDOMNode:T("findDOMNode","ReactDOM","react-dom",I,I.findDOMNode),render:T("render","ReactDOM","react-dom",I,I.render),unmountComponentAtNode:T("unmountComponentAtNode","ReactDOM","react-dom",I,I.unmountComponentAtNode),renderToString:T("renderToString","ReactDOMServer","react-dom/server",g,g.renderToString),renderToStaticMarkup:T("renderToStaticMarkup","ReactDOMServer","react-dom/server",g,g.renderToStaticMarkup)}),E.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=I,E.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=g,A.exports=E},function(A,M,t){"use strict";var I=(t(55),t(114)),g=(t(3),"_getDOMNodeDidWarn"),e={getDOMNode:function(){return this.constructor[g]=!0,I(this)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t){var I=void 0===A[t];null!=M&&I&&(A[t]=e(M,null))}var g=t(36),e=t(119),i=t(122),T=t(123),E=(t(3),{instantiateChildren:function(A,M,t){if(null==A)return null;var g={};return T(A,I,g),g},updateChildren:function(A,M,t,I){if(!M&&!A)return null;var T;for(T in M)if(M.hasOwnProperty(T)){var E=A&&A[T],N=E&&E._currentElement,o=M[T];if(null!=E&&i(N,o))g.receiveComponent(E,o,t,I),M[T]=E;else{E&&g.unmountComponent(E,T);var n=e(o,null);M[T]=n}}for(T in A)!A.hasOwnProperty(T)||M&&M.hasOwnProperty(T)||g.unmountComponent(A[T]);return M},unmountChildren:function(A){for(var M in A)if(A.hasOwnProperty(M)){var t=A[M];g.unmountComponent(t)}}});A.exports=E},function(A,M,t){"use strict";function I(A){var M=A._currentElement._owner||null;if(M){var t=M.getName();if(t)return" Check the render method of ` + "`" + `"+t+"` + "`" + `."}return""}function g(A){}var e=t(110),i=t(25),T=t(13),E=t(55),N=t(17),o=t(71),n=(t(70),t(36)),C=t(112),c=t(4),D=t(50),a=t(2),B=t(122);t(3);g.prototype.render=function(){var A=E.get(this)._currentElement.type;return A(this.props,this.context,this.updater)};var Q=1,r={construct:function(A){this._currentElement=A,this._rootNodeID=null,this._instance=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._topLevelWrapper=null,this._pendingCallbacks=null},mountComponent:function(A,M,t){this._context=t,this._mountOrder=Q++,this._rootNodeID=A;var I,e,i=this._processProps(this._currentElement.props),N=this._processContext(t),o=this._currentElement.type,c="prototype"in o;c&&(I=new o(i,N,C)),c&&null!==I&&I!==!1&&!T.isValidElement(I)||(e=I,I=new g(o)),I.props=i,I.context=N,I.refs=D,I.updater=C,this._instance=I,E.set(I,this);var B=I.state;void 0===B&&(I.state=B=null),"object"!=typeof B||Array.isArray(B)?a(!1):void 0,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,I.componentWillMount&&(I.componentWillMount(),this._pendingStateQueue&&(I.state=this._processPendingState(I.props,I.context))),void 0===e&&(e=this._renderValidatedComponent()),this._renderedComponent=this._instantiateReactComponent(e);var r=n.mountComponent(this._renderedComponent,A,M,this._processChildContext(t));return I.componentDidMount&&M.getReactMountReady().enqueue(I.componentDidMount,I),r},unmountComponent:function(){var A=this._instance;A.componentWillUnmount&&A.componentWillUnmount(),n.unmountComponent(this._renderedComponent),this._renderedComponent=null,this._instance=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=null,this._topLevelWrapper=null,E.remove(A)},_maskContext:function(A){var M=null,t=this._currentElement.type,I=t.contextTypes;if(!I)return D;M={};for(var g in I)M[g]=A[g];return M},_processContext:function(A){var M=this._maskContext(A);return M},_processChildContext:function(A){var M=this._currentElement.type,t=this._instance,I=t.getChildContext&&t.getChildContext();if(I){"object"!=typeof M.childContextTypes?a(!1):void 0;for(var g in I)g in M.childContextTypes?void 0:a(!1);return c({},A,I)}return A},_processProps:function(A){return A},_checkPropTypes:function(A,M,t){var g=this.getName();for(var e in A)if(A.hasOwnProperty(e)){var i;try{"function"!=typeof A[e]?a(!1):void 0,i=A[e](M,e,g,t)}catch(A){i=A}if(i instanceof Error){I(this);t===o.prop}}},receiveComponent:function(A,M,t){var I=this._currentElement,g=this._context;this._pendingElement=null,this.updateComponent(M,I,A,g,t)},performUpdateIfNecessary:function(A){null!=this._pendingElement&&n.receiveComponent(this,this._pendingElement||this._currentElement,A,this._context),(null!==this._pendingStateQueue||this._pendingForceUpdate)&&this.updateComponent(A,this._currentElement,this._currentElement,this._context,this._context)},updateComponent:function(A,M,t,I,g){var e,i=this._instance,T=this._context===g?i.context:this._processContext(g);M===t?e=t.props:(e=this._processProps(t.props),i.componentWillReceiveProps&&i.componentWillReceiveProps(e,T));var E=this._processPendingState(e,T),N=this._pendingForceUpdate||!i.shouldComponentUpdate||i.shouldComponentUpdate(e,E,T);N?(this._pendingForceUpdate=!1,this._performComponentUpdate(t,e,E,T,A,g)):(this._currentElement=t,this._context=g,i.props=e,i.state=E,i.context=T)},_processPendingState:function(A,M){var t=this._instance,I=this._pendingStateQueue,g=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!I)return t.state;if(g&&1===I.length)return I[0];for(var e=c({},g?I[0]:t.state),i=g?1:0;i=0||null!=M.is}function B(A){D(A),this._tag=A.toLowerCase(),this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._rootNodeID=null,this._wrapperState=null,this._topLevelWrapper=null,this._nodeWithLegacyProperties=null}var Q=t(429),r=t(431),s=t(47),x=t(107),j=t(24),y=t(69),u=t(109),w=t(444),L=t(447),l=t(448),Y=t(210),d=t(451),h=t(12),S=t(456),z=t(17),p=t(112),U=t(4),O=t(74),m=t(75),F=t(2),f=(t(120),t(27)),k=t(76),R=t(121),J=(t(152),t(124),t(3),y.deleteListener),G=y.listenTo,H=y.registrationNameModules,b={string:!0,number:!0},X=f({children:null}),v=f({style:null}),W=f({__html:null}),V=1,P={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},Z={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},K={listing:!0,pre:!0,textarea:!0},q=(U({menuitem:!0},Z),/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/),_={},$={}.hasOwnProperty;B.displayName="ReactDOMComponent",B.Mixin={construct:function(A){this._currentElement=A},mountComponent:function(A,M,t){this._rootNodeID=A;var I=this._currentElement.props;switch(this._tag){case"iframe":case"img":case"form":case"video":case"audio":this._wrapperState={listeners:null},M.getReactMountReady().enqueue(n,this);break;case"button":I=w.getNativeProps(this,I,t);break;case"input":L.mountWrapper(this,I,t),I=L.getNativeProps(this,I,t);break;case"option":l.mountWrapper(this,I,t),I=l.getNativeProps(this,I,t);break;case"select":Y.mountWrapper(this,I,t),I=Y.getNativeProps(this,I,t),t=Y.processChildContext(this,I,t);break;case"textarea":d.mountWrapper(this,I,t),I=d.getNativeProps(this,I,t)}E(this,I);var g;if(M.useCreateElement){var e=t[h.ownerDocumentContextKey],i=e.createElement(this._currentElement.type);x.setAttributeForID(i,this._rootNodeID),h.getID(i),this._updateDOMProperties({},I,M,i),this._createInitialChildren(M,I,t,i),g=i}else{var T=this._createOpenTagMarkupAndPutListeners(M,I),N=this._createContentMarkup(M,I,t);g=!N&&Z[this._tag]?T+"/>":T+">"+N+""}switch(this._tag){case"input":M.getReactMountReady().enqueue(C,this);case"button":case"select":case"textarea":I.autoFocus&&M.getReactMountReady().enqueue(Q.focusDOMComponent,this)}return g},_createOpenTagMarkupAndPutListeners:function(A,M){var t="<"+this._currentElement.type;for(var I in M)if(M.hasOwnProperty(I)){var g=M[I];if(null!=g)if(H.hasOwnProperty(I))g&&N(this._rootNodeID,I,g,A);else{I===v&&(g&&(g=this._previousStyleCopy=U({},M.style)),g=r.createMarkupForStyles(g));var e=null;null!=this._tag&&a(this._tag,M)?I!==X&&(e=x.createMarkupForCustomAttribute(I,g)):e=x.createMarkupForProperty(I,g),e&&(t+=" "+e)}}if(A.renderToStaticMarkup)return t;var i=x.createMarkupForID(this._rootNodeID);return t+" "+i},_createContentMarkup:function(A,M,t){var I="",g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&(I=g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)I=m(e);else if(null!=i){var T=this.mountChildren(i,A,t);I=T.join("")}}return K[this._tag]&&"\n"===I.charAt(0)?"\n"+I:I},_createInitialChildren:function(A,M,t,I){var g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&k(I,g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)R(I,e);else if(null!=i)for(var T=this.mountChildren(i,A,t),E=0;EM.end?(t=M.end,I=M.start):(t=M.start,I=M.end),g.moveToElementText(A),g.moveStart("character",t),g.setEndPoint("EndToStart",g),g.moveEnd("character",I-t),g.select()}function T(A,M){if(window.getSelection){var t=window.getSelection(),I=A[o()].length,g=Math.min(M.start,I),e="undefined"==typeof M.end?g:Math.min(M.end,I);if(!t.extend&&g>e){var i=e;e=g,g=i}var T=N(A,g),E=N(A,e);if(T&&E){var n=document.createRange();n.setStart(T.node,T.offset),t.removeAllRanges(),g>e?(t.addRange(n),t.extend(E.node,E.offset)):(n.setEnd(E.node,E.offset),t.addRange(n))}}}var E=t(10),N=t(480),o=t(228),n=E.canUseDOM&&"selection"in document&&!("getSelection"in window),C={getOffsets:n?g:e,setOffsets:n?i:T};A.exports=C},function(A,M,t){"use strict";var I=t(213),g=t(461),e=t(113);I.inject();var i={renderToString:g.renderToString,renderToStaticMarkup:g.renderToStaticMarkup,version:e};A.exports=i},function(A,M,t){"use strict";function I(){this._rootNodeID&&o.updateWrapper(this)}function g(A){var M=this._currentElement.props,t=e.executeOnChange(M,A);return T.asap(I,this),t}var e=t(108),i=t(111),T=t(18),E=t(4),N=t(2),o=(t(3),{getNativeProps:function(A,M,t){null!=M.dangerouslySetInnerHTML?N(!1):void 0;var I=E({},M,{defaultValue:void 0,value:void 0,children:A._wrapperState.initialValue,onChange:A._wrapperState.onChange});return I},mountWrapper:function(A,M){var t=M.defaultValue,I=M.children;null!=I&&(null!=t?N(!1):void 0,Array.isArray(I)&&(I.length<=1?void 0:N(!1),I=I[0]),t=""+I),null==t&&(t="");var i=e.getValue(M);A._wrapperState={initialValue:""+(null!=i?i:t),onChange:g.bind(A)}},updateWrapper:function(A){var M=A._currentElement.props,t=e.getValue(M);null!=t&&i.updatePropertyByID(A._rootNodeID,"value",""+t)}});A.exports=o},function(A,M,t){"use strict";function I(A){g.enqueueEvents(A),g.processEventQueue(!1)}var g=t(53),e={handleTopLevel:function(A,M,t,e,i){var T=g.extractEvents(A,M,t,e,i);I(T)}};A.exports=e},function(A,M,t){"use strict";function I(A){var M=C.getID(A),t=n.getReactRootIDFromNodeID(M),I=C.findReactContainerForID(t),g=C.getFirstReactDOM(I);return g}function g(A,M){this.topLevelType=A,this.nativeEvent=M,this.ancestors=[]}function e(A){i(A)}function i(A){for(var M=C.getFirstReactDOM(a(A.nativeEvent))||window,t=M;t;)A.ancestors.push(t),t=I(t);for(var g=0;g=M)return{node:g,offset:M-e};e=i}g=t(I(g))}}A.exports=g},function(A,M,t){"use strict";function I(A){return g.isValidElement(A)?void 0:e(!1),A}var g=t(13),e=t(2);A.exports=I},function(A,M,t){"use strict";function I(A){return'"'+g(A)+'"'}var g=t(75);A.exports=I},function(A,M,t){"use strict";var I=t(12);A.exports=I.renderSubtreeIntoContainer},function(A,M){A.exports=function(A,M,t){for(var I=0,g=A.length,e=3==arguments.length?t:A[I++];I=400){ +"-webkit-touch-callout":"none","-webkit-user-select":"none","-khtml-user-select":"none","-moz-user-select":"none","-ms-user-select":"none","user-select":"none"},M.resetDisableSelectStyle={"-webkit-touch-callout":"","-webkit-user-select":"","-khtml-user-select":"","-moz-user-select":"","-ms-user-select":"","user-select":""}},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){if(T!==!1)return T;if("undefined"!=typeof document){var A=document.createElement("div");(0,i.default)(A,{width:100,height:100,position:"absolute",top:-9999,overflow:"scroll","-ms-overflow-style":"scrollbar"}),document.body.appendChild(A),T=A.offsetWidth-A.clientWidth,document.body.removeChild(A)}else T=0;return T}Object.defineProperty(M,"__esModule",{value:!0}),M.default=g;var e=t(139),i=I(e),T=!1},function(A,M){"use strict";function t(){return!1}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t},function(A,M,t){!function(M,I){A.exports=I(t(1))}(this,function(A){return function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M0||(this.setState({isDragActive:!1,isDragReject:!1}),this.props.onDragLeave&&this.props.onDragLeave.call(this,A))}},{key:"onDrop",value:function A(M){var t=this,I=this.props,A=I.onDrop,g=I.onDropAccepted,e=I.onDropRejected,i=I.multiple,T=I.disablePreview,E=(0,a.default)(M,i),N=[],o=[];M.preventDefault(),this.enterCounter=0,this.isFileDialogActive=!1,E.forEach(function(A){T||(A.preview=window.URL.createObjectURL(A)),t.fileAccepted(A)&&t.fileMatchSize(A)?N.push(A):o.push(A)}),A&&A.call(this,N,o,M),o.length>0&&e&&e.call(this,o,M),N.length>0&&g&&g.call(this,N,M),this.setState({isDragActive:!1,isDragReject:!1})}},{key:"onClick",value:function A(M){M.stopPropagation();var t=this.props,A=t.onClick,I=t.disableClick;I||(this.open(),A&&A.call(this,M))}},{key:"onFileDialogCancel",value:function A(){var A=this.props.onFileDialogCancel,M=this.fileInputEl,t=this.isFileDialogActive;A&&t&&setTimeout(function(){var I=M.files;I.length||(t=!1,A())},300)}},{key:"fileAccepted",value:function(A){return(0,c.default)(A,this.props.accept)}},{key:"fileMatchSize",value:function(A){return A.size<=this.props.maxSize&&A.size>=this.props.minSize}},{key:"allFilesAccepted",value:function(A){return A.every(this.fileAccepted)}},{key:"open",value:function(){this.isFileDialogActive=!0,this.fileInputEl.value=null,this.fileInputEl.click()}},{key:"render",value:function(){var A=this,M=this.props,t=M.accept,I=M.activeClassName,e=M.inputProps,i=M.multiple,T=M.name,N=M.rejectClassName,o=g(M,["accept","activeClassName","inputProps","multiple","name","rejectClassName"]),C=o.activeStyle,c=o.className,D=o.rejectStyle,a=o.style,Q=g(o,["activeStyle","className","rejectStyle","style"]),r=this.state,s=r.isDragActive,x=r.isDragReject;c=c||"",s&&I&&(c+=" "+I),x&&N&&(c+=" "+N),c||a||C||D||(a={width:200,height:200,borderWidth:2,borderColor:"#666",borderStyle:"dashed",borderRadius:5},C={borderStyle:"solid",backgroundColor:"#eee"},D={borderStyle:"solid",backgroundColor:"#ffdddd"});var j=void 0;j=C&&s?E({},a,C):D&&x?E({},a,D):E({},a);var y={accept:t,type:"file",style:{display:"none"},multiple:B&&i,ref:function(M){return A.fileInputEl=M},onChange:this.onDrop};T&&T.length&&(y.name=T);var u=["acceptedFiles","disablePreview","disableClick","onDropAccepted","onDropRejected","onFileDialogCancel","maxSize","minSize"],w=E({},Q);return u.forEach(function(A){return delete w[A]}),n.default.createElement("div",E({className:c,style:j},w,{onClick:this.onClick,onDragStart:this.onDragStart,onDragEnter:this.onDragEnter,onDragOver:this.onDragOver,onDragLeave:this.onDragLeave,onDrop:this.onDrop}),this.props.children,n.default.createElement("input",E({},e,y)))}}]),M}(n.default.Component);Q.defaultProps={disablePreview:!1,disableClick:!1,multiple:!0,maxSize:1/0,minSize:0},Q.propTypes={onClick:n.default.PropTypes.func,onDrop:n.default.PropTypes.func,onDropAccepted:n.default.PropTypes.func,onDropRejected:n.default.PropTypes.func,onDragStart:n.default.PropTypes.func,onDragEnter:n.default.PropTypes.func,onDragOver:n.default.PropTypes.func,onDragLeave:n.default.PropTypes.func,children:n.default.PropTypes.node,style:n.default.PropTypes.object,activeStyle:n.default.PropTypes.object,rejectStyle:n.default.PropTypes.object,className:n.default.PropTypes.string,activeClassName:n.default.PropTypes.string,rejectClassName:n.default.PropTypes.string,disablePreview:n.default.PropTypes.bool,disableClick:n.default.PropTypes.bool,onFileDialogCancel:n.default.PropTypes.func,inputProps:n.default.PropTypes.object,multiple:n.default.PropTypes.bool,accept:n.default.PropTypes.string,name:n.default.PropTypes.string,maxSize:n.default.PropTypes.number,minSize:n.default.PropTypes.number},M.default=Q,A.exports=M.default},function(M,t){M.exports=A},function(A,M){A.exports=function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){"use strict";M.__esModule=!0,t(8),t(9),M.default=function(A,M){if(A&&M){var t=function(){var t=Array.isArray(M)?M:M.split(","),I=A.name||"",g=A.type||"",e=g.replace(/\/.*$/,"");return{v:t.some(function(A){var M=A.trim();return"."===M.charAt(0)?I.toLowerCase().endsWith(M.toLowerCase()):/\/\*$/.test(M)?e===M.replace(/\/.*$/,""):g===M})}}();if("object"==typeof t)return t.v}return!0},A.exports=M.default},function(A,M){var t=A.exports={version:"1.2.2"};"number"==typeof __e&&(__e=t)},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(2),g=t(1),e=t(4),i=t(19),T="prototype",E=function(A,M){return function(){return A.apply(M,arguments)}},N=function(A,M,t){var o,n,C,c,D=A&N.G,a=A&N.P,B=D?I:A&N.S?I[M]||(I[M]={}):(I[M]||{})[T],Q=D?g:g[M]||(g[M]={});D&&(t=M);for(o in t)n=!(A&N.F)&&B&&o in B,C=(n?B:t)[o],c=A&N.B&&n?E(C,I):a&&"function"==typeof C?E(Function.call,C):C,B&&!n&&i(B,o,C),Q[o]!=C&&e(Q,o,c),a&&((Q[T]||(Q[T]={}))[o]=C)};I.core=g,N.F=1,N.G=2,N.S=4,N.P=8,N.B=16,N.W=32,A.exports=N},function(A,M,t){var I=t(5),g=t(18);A.exports=t(22)?function(A,M,t){return I.setDesc(A,M,g(1,t))}:function(A,M,t){return A[M]=t,A}},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M){var t=0,I=Math.random();A.exports=function(A){return"Symbol(".concat(void 0===A?"":A,")_",(++t+I).toString(36))}},function(A,M,t){var I=t(20)("wks"),g=t(2).Symbol;A.exports=function(A){return I[A]||(I[A]=g&&g[A]||(g||t(6))("Symbol."+A))}},function(A,M,t){t(26),A.exports=t(1).Array.some},function(A,M,t){t(25),A.exports=t(1).String.endsWith},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M,t){var I=t(10);A.exports=function(A,M,t){if(I(A),void 0===M)return A;switch(t){case 1:return function(t){return A.call(M,t)};case 2:return function(t,I){return A.call(M,t,I)};case 3:return function(t,I,g){return A.call(M,t,I,g)}}return function(){return A.apply(M,arguments)}}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M,t){A.exports=function(A){var M=/./;try{"/./"[A](M)}catch(I){try{return M[t(7)("match")]=!1,!"/./"[A](M)}catch(A){}}return!0}},function(A,M){A.exports=function(A){try{return!!A()}catch(A){return!0}}},function(A,M){A.exports=function(A){return"object"==typeof A?null!==A:"function"==typeof A}},function(A,M,t){var I=t(16),g=t(11),e=t(7)("match");A.exports=function(A){var M;return I(A)&&(void 0!==(M=A[e])?!!M:"RegExp"==g(A))}},function(A,M){A.exports=function(A,M){return{enumerable:!(1&A),configurable:!(2&A),writable:!(4&A),value:M}}},function(A,M,t){var I=t(2),g=t(4),e=t(6)("src"),i="toString",T=Function[i],E=(""+T).split(i);t(1).inspectSource=function(A){return T.call(A)},(A.exports=function(A,M,t,i){"function"==typeof t&&(g(t,e,A[M]?""+A[M]:E.join(String(M))),"name"in t||(t.name=M)),A===I?A[M]=t:(i||delete A[M],g(A,M,t))})(Function.prototype,i,function(){return"function"==typeof this&&this[e]||T.call(this)})},function(A,M,t){var I=t(2),g="__core-js_shared__",e=I[g]||(I[g]={});A.exports=function(A){return e[A]||(e[A]={})}},function(A,M,t){var I=t(17),g=t(13);A.exports=function(A,M,t){if(I(M))throw TypeError("String#"+t+" doesn't accept regex!");return String(g(A))}},function(A,M,t){A.exports=!t(15)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(A,M){var t=Math.ceil,I=Math.floor;A.exports=function(A){return isNaN(A=+A)?0:(A>0?I:t)(A)}},function(A,M,t){var I=t(23),g=Math.min;A.exports=function(A){return A>0?g(I(A),9007199254740991):0}},function(A,M,t){"use strict";var I=t(3),g=t(24),e=t(21),i="endsWith",T=""[i];I(I.P+I.F*t(14)(i),"String",{endsWith:function(A){var M=e(this,A,i),t=arguments,I=t.length>1?t[1]:void 0,E=g(M.length),N=void 0===I?E:Math.min(g(I),E),o=String(A);return T?T.call(M,o,N):M.slice(N-o.length,N)===o}})},function(A,M,t){var I=t(5),g=t(3),e=t(1).Array||Array,i={},T=function(A,M){I.each.call(A.split(","),function(A){void 0==M&&A in e?i[A]=e[A]:A in[]&&(i[A]=t(12)(Function.call,[][A],M))})};T("pop,reverse,shift,keys,values,entries",1),T("indexOf,every,some,forEach,map,filter,find,findIndex,includes",3),T("join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill"),g(g.S,"Array",i)}])},function(A,M){"use strict";function t(A){var M=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],t=[];if(A.dataTransfer){var I=A.dataTransfer;I.files&&I.files.length?t=I.files:I.items&&I.items.length&&(t=I.items)}else A.target&&A.target.files&&(t=A.target.files);return t.length>0&&(t=M?t:[t[0]]),Array.prototype.slice.call(t)}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t,A.exports=M.default}])})},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{},t=M.hideSiblingNodes,I=void 0===t||t,e=M.handleContainerOverflow,i=void 0===e||e;g(this,A),this.hideSiblingNodes=I,this.handleContainerOverflow=i,this.modals=[],this.containers=[],this.data=[]}return N(A,[{key:"add",value:function(A,M,t){var I=this.modals.indexOf(A),g=this.containers.indexOf(M);if(I!==-1)return I;if(I=this.modals.length,this.modals.push(A),this.hideSiblingNodes&&(0,r.hideSiblings)(M,A.mountNode),g!==-1)return this.data[g].modals.push(A),I;var e={modals:[A],classes:t?t.split(/\s+/):[],overflowing:(0,Q.default)(M)};return this.handleContainerOverflow&&T(e,M),e.classes.forEach(c.default.addClass.bind(null,M)),this.containers.push(M),this.data.push(e),I}},{key:"remove",value:function(A){var M=this.modals.indexOf(A);if(M!==-1){var t=i(this.data,A),I=this.data[t],g=this.containers[t];I.modals.splice(I.modals.indexOf(A),1),this.modals.splice(M,1),0===I.modals.length?(I.classes.forEach(c.default.removeClass.bind(null,g)),this.handleContainerOverflow&&E(I,g),this.hideSiblingNodes&&(0,r.showSiblings)(g,A.mountNode),this.containers.splice(t,1),this.data.splice(t,1)):this.hideSiblingNodes&&(0,r.ariaHidden)(!1,I.modals[I.modals.length-1].mountNode)}}},{key:"isTopModal",value:function(A){return!!this.modals.length&&this.modals[this.modals.length-1]===A}}]),A}();M.default=s,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M1?t-1:0),g=1;g=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}function E(){}Object.defineProperty(M,"__esModule",{value:!0}),M.EXITING=M.ENTERED=M.ENTERING=M.EXITED=M.UNMOUNTED=void 0;var N=Object.assign||function(A){for(var M=1;MT?T-N:0}function i(A,M,t,I){var e=g(t),i=e.width,T=A-I,E=A+I+M;return T<0?-T:E>i?i-E:0}function T(A,M,t,I,g){var T="BODY"===I.tagName?(0,N.default)(t):(0,n.default)(t,I),E=(0,N.default)(M),o=E.height,C=E.width,c=void 0,D=void 0,a=void 0,B=void 0;if("left"===A||"right"===A){D=T.top+(T.height-o)/2,c="left"===A?T.left-C:T.left+T.width;var Q=e(D,o,I,g);D+=Q,B=50*(1-2*Q/o)+"%",a=void 0}else{if("top"!==A&&"bottom"!==A)throw new Error('calcOverlayPosition(): No such placement of "'+A+'" found.');c=T.left+(T.width-C)/2,D="top"===A?T.top-o:T.top+T.height;var r=i(c,C,I,g);c+=r,a=50*(1-2*r/C)+"%",B=void 0}return{positionLeft:c,positionTop:D,arrowOffsetLeft:a,arrowOffsetTop:B}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=T;var E=t(143),N=I(E),o=t(287),n=I(o),C=t(144),c=I(C),D=t(52),a=I(D);A.exports=M.default},function(A,M){"use strict";function t(A,M){M&&(A?M.setAttribute("aria-hidden","true"):M.removeAttribute("aria-hidden"))}function I(A,M){T(A,M,function(A){return t(!0,A)})}function g(A,M){T(A,M,function(A){return t(!1,A)})}Object.defineProperty(M,"__esModule",{value:!0}),M.ariaHidden=t,M.hideSiblings=I,M.showSiblings=g;var e=["template","script","style"],i=function(A){var M=A.nodeType,t=A.tagName;return 1===M&&e.indexOf(t.toLowerCase())===-1},T=function(A,M,t){M=[].concat(M),[].forEach.call(A.children,function(A){M.indexOf(A)===-1&&i(A)&&t(A)})}},function(A,M,t){"use strict";var I=function(){};A.exports=I},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return function(t,I,g){if(null!=t[I]){var e='"'+I+'" property of "'+g+'" has been deprecated.\n'+M;E[e]||(T.default(!1,e),E[e]=!0)}return A(t,I,g)}}function e(){E={}}M.__esModule=!0,M.default=g;var i=t(127),T=I(i),E={};g._resetWarned=e,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function e(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function i(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}M.__esModule=!0,M.default=void 0;var T=t(1),E=t(184),N=I(E),o=t(185),n=(I(o),function(A){function M(t,I){g(this,M);var i=e(this,A.call(this,t,I));return i.store=t.store,i}return i(M,A),M.prototype.getChildContext=function(){return{store:this.store}},M.prototype.render=function(){return T.Children.only(this.props.children)},M}(T.Component));M.default=n,n.propTypes={store:N.default.isRequired,children:T.PropTypes.element.isRequired},n.childContextTypes={store:N.default.isRequired}},function(A,M){"use strict";function t(A,M){if(A===M)return!0;var t=Object.keys(A),I=Object.keys(M);if(t.length!==I.length)return!1;for(var g=Object.prototype.hasOwnProperty,e=0;e=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){var t=A.history,I=A.routes,e=A.location,E=g(A,["history","routes","location"]);t||e?void 0:(0,N.default)(!1),t=t?t:(0,n.default)(E);var o=(0,c.default)(t,(0,D.createRoutes)(I)),C=void 0;e?e=t.createLocation(e):C=t.listen(function(A){e=A});var B=(0,a.createRouterObject)(t,o);t=(0,a.createRoutingHistory)(t,o),o.match(e,function(A,I,g){M(A,I&&B.createLocation(I,T.REPLACE),g&&i({},g,{history:t,router:B,matchContext:{history:t,transitionManager:o,router:B}})),C&&C()})}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return function(){var M=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],t=M.routes,I=g(M,["routes"]),e=(0,E.default)(A)(I),T=(0,o.default)(e,t);return i({},e,T)}}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=A&&N&&(T=!0,t()))}}var i=0,T=!1,E=!1,N=!1,o=void 0;e()}M.__esModule=!0;var I=Array.prototype.slice;M.loopAsync=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){function A(A){try{A=A||window.history.state||{}}catch(M){A={}}var M=n.getWindowPath(),t=A,I=t.key,g=void 0;I?g=C.readState(I):(g=null,I=s.createKey(),Q&&window.history.replaceState(e({},A,{key:I}),null));var i=N.parsePath(M);return s.createLocation(e({},i,{state:g}),void 0,I)}function M(M){function t(M){void 0!==M.state&&I(A(M.state))}var I=M.transitionTo;return n.addEventListener(window,"popstate",t),function(){n.removeEventListener(window,"popstate",t)}}function t(A){var M=A.basename,t=A.pathname,I=A.search,g=A.hash,e=A.state,i=A.action,T=A.key;if(i!==E.POP){C.saveState(T,e);var N=(M||"")+t+I+g,o={key:T};if(i===E.PUSH){if(r)return window.location.href=N,!1;window.history.pushState(o,null,N)}else{if(r)return window.location.replace(N),!1;window.history.replaceState(o,null,N)}}}function I(A){1===++x&&(j=M(s));var t=s.listenBefore(A);return function(){t(),0===--x&&j()}}function g(A){1===++x&&(j=M(s));var t=s.listen(A);return function(){t(),0===--x&&j()}}function i(A){1===++x&&(j=M(s)),s.registerTransitionHook(A)}function c(A){s.unregisterTransitionHook(A),0===--x&&j()}var a=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];o.canUseDOM?void 0:T.default(!1);var B=a.forceRefresh,Q=n.supportsHistory(),r=!Q||B,s=D.default(e({},a,{getCurrentLocation:A,finishTransition:t,saveState:C.saveState})),x=0,j=void 0;return e({},s,{listenBefore:I,listen:g,registerTransitionHook:i,unregisterTransitionHook:c})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M=0&&M=0&&B8&&u<=11),L=32,Y=String.fromCharCode(L),d=c.topLevelTypes,h={beforeInput:{phasedRegistrationNames:{bubbled:s({onBeforeInput:null}),captured:s({onBeforeInputCapture:null})},dependencies:[d.topCompositionEnd,d.topKeyPress,d.topTextInput,d.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:s({onCompositionEnd:null}),captured:s({onCompositionEndCapture:null})},dependencies:[d.topBlur,d.topCompositionEnd,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:s({onCompositionStart:null}),captured:s({onCompositionStartCapture:null})},dependencies:[d.topBlur,d.topCompositionStart,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:s({onCompositionUpdate:null}),captured:s({onCompositionUpdateCapture:null})},dependencies:[d.topBlur,d.topCompositionUpdate,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]}},S=!1,z=null,p={eventTypes:h,extractEvents:function(A,M,t,I,g){return[N(A,M,t,I,g),C(A,M,t,I,g)]}};A.exports=p},function(A,M,t){"use strict";var I=t(202),g=t(10),e=t(17),i=(t(297),t(476)),T=t(302),E=t(306),N=(t(3),E(function(A){return T(A)})),o=!1,n="cssFloat";if(g.canUseDOM){var C=document.createElement("div").style;try{C.font=""}catch(A){o=!0}void 0===document.documentElement.style.cssFloat&&(n="styleFloat")}var c={createMarkupForStyles:function(A){var M="";for(var t in A)if(A.hasOwnProperty(t)){var I=A[t];null!=I&&(M+=N(t)+":",M+=i(t,I)+";")}return M||null},setValueForStyles:function(A,M){var t=A.style;for(var g in M)if(M.hasOwnProperty(g)){var e=i(g,M[g]);if("float"===g&&(g=n),e)t[g]=e;else{var T=o&&I.shorthandPropertyExpansions[g];if(T)for(var E in T)t[E]="";else t[g]=""}}}};e.measureMethods(c,"CSSPropertyOperations",{setValueForStyles:"setValueForStyles"}),A.exports=c},function(A,M,t){"use strict";function I(A){var M=A.nodeName&&A.nodeName.toLowerCase();return"select"===M||"input"===M&&"file"===A.type}function g(A){var M=u.getPooled(h.change,z,A,w(A));x.accumulateTwoPhaseDispatches(M),y.batchedUpdates(e,M)}function e(A){s.enqueueEvents(A),s.processEventQueue(!1)}function i(A,M){S=A,z=M,S.attachEvent("onchange",g)}function T(){S&&(S.detachEvent("onchange",g),S=null,z=null)}function E(A,M,t){if(A===d.topChange)return t}function N(A,M,t){A===d.topFocus?(T(),i(M,t)):A===d.topBlur&&T()}function o(A,M){S=A,z=M,p=A.value,U=Object.getOwnPropertyDescriptor(A.constructor.prototype,"value"),Object.defineProperty(S,"value",F),S.attachEvent("onpropertychange",C)}function n(){S&&(delete S.value,S.detachEvent("onpropertychange",C),S=null,z=null,p=null,U=null)}function C(A){if("value"===A.propertyName){var M=A.srcElement.value;M!==p&&(p=M,g(A))}}function c(A,M,t){if(A===d.topInput)return t}function D(A,M,t){A===d.topFocus?(n(),o(M,t)):A===d.topBlur&&n()}function a(A,M,t){if((A===d.topSelectionChange||A===d.topKeyUp||A===d.topKeyDown)&&S&&S.value!==p)return p=S.value,z}function B(A){return A.nodeName&&"input"===A.nodeName.toLowerCase()&&("checkbox"===A.type||"radio"===A.type)}function Q(A,M,t){if(A===d.topClick)return t}var r=t(24),s=t(53),x=t(54),j=t(10),y=t(18),u=t(37),w=t(117),l=t(120),L=t(229),Y=t(27),d=r.topLevelTypes,h={change:{phasedRegistrationNames:{bubbled:Y({onChange:null}),captured:Y({onChangeCapture:null})},dependencies:[d.topBlur,d.topChange,d.topClick,d.topFocus,d.topInput,d.topKeyDown,d.topKeyUp,d.topSelectionChange]}},S=null,z=null,p=null,U=null,O=!1;j.canUseDOM&&(O=l("change")&&(!("documentMode"in document)||document.documentMode>8));var m=!1;j.canUseDOM&&(m=l("input")&&(!("documentMode"in document)||document.documentMode>9));var F={get:function(){return U.get.call(this)},set:function(A){p=""+A,U.set.call(this,A)}},f={eventTypes:h,extractEvents:function(A,M,t,g,e){var i,T;if(I(M)?O?i=E:T=N:L(M)?m?i=c:(i=a,T=D):B(M)&&(i=Q),i){var o=i(A,M,t);if(o){var n=u.getPooled(h.change,o,g,e);return n.type="change",x.accumulateTwoPhaseDispatches(n),n}}T&&T(A,M,t)}};A.exports=f},function(A,M){"use strict";var t=0,I={createReactRootIndex:function(){return t++}};A.exports=I},function(A,M,t){"use strict";function I(A){return A.substring(1,A.indexOf(" "))}var g=t(10),e=t(299),i=t(20),T=t(151),E=t(2),N=/^(<[^ \/>]+)/,o="data-danger-index",n={dangerouslyRenderMarkup:function(A){g.canUseDOM?void 0:E(!1);for(var M,t={},n=0;n1?1-M:void 0;return this._fallbackText=g.slice(A,T),this._fallbackText}}),g.addPoolingTo(I),A.exports=I},function(A,M,t){"use strict";var I,g=t(47),e=t(10),i=g.injection.MUST_USE_ATTRIBUTE,T=g.injection.MUST_USE_PROPERTY,E=g.injection.HAS_BOOLEAN_VALUE,N=g.injection.HAS_SIDE_EFFECTS,o=g.injection.HAS_NUMERIC_VALUE,n=g.injection.HAS_POSITIVE_NUMERIC_VALUE,C=g.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(e.canUseDOM){var c=document.implementation;I=c&&c.hasFeature&&c.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var D={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:i|E,allowTransparency:i,alt:null,async:E,autoComplete:null,autoPlay:E,capture:i|E,cellPadding:null,cellSpacing:null,charSet:i,challenge:i,checked:T|E,classID:i,className:I?i:T,cols:i|n,colSpan:null,content:null,contentEditable:null,contextMenu:i,controls:T|E,coords:null,crossOrigin:null,data:null,dateTime:i,default:E,defer:E,dir:null,disabled:i|E,download:C,draggable:null,encType:null,form:i,formAction:i,formEncType:i,formMethod:i,formNoValidate:E,formTarget:i,frameBorder:i,headers:null,height:i,hidden:i|E,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:T,inputMode:i,integrity:null,is:i,keyParams:i,keyType:i,kind:null,label:null,lang:null,list:i,loop:T|E,low:null,manifest:i,marginHeight:null,marginWidth:null,max:null,maxLength:i,media:i,mediaGroup:null,method:null,min:null,minLength:i,multiple:T|E,muted:T|E,name:null,nonce:i,noValidate:E,open:E,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:T|E,rel:null,required:E,reversed:E,role:i,rows:i|n,rowSpan:null,sandbox:null,scope:null,scoped:E,scrolling:null,seamless:i|E,selected:T|E,shape:null,size:i|n,sizes:i,span:n,spellCheck:null,src:null,srcDoc:T,srcLang:null,srcSet:i,start:o,step:null,style:null,summary:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:T|N,width:i,wmode:i,wrap:null,about:i,datatype:i,inlist:i,prefix:i,property:i,resource:i,typeof:i,vocab:i,autoCapitalize:i,autoCorrect:i,autoSave:null,color:null,itemProp:i,itemScope:i|E,itemType:i,itemID:i,itemRef:i,results:null,security:i,unselectable:i},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",autoSave:"autosave",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};A.exports=D},function(A,M,t){"use strict";var I=t(208),g=t(450),e=t(455),i=t(4),T=t(477),E={};i(E,e),i(E,{findDOMNode:T("findDOMNode","ReactDOM","react-dom",I,I.findDOMNode),render:T("render","ReactDOM","react-dom",I,I.render),unmountComponentAtNode:T("unmountComponentAtNode","ReactDOM","react-dom",I,I.unmountComponentAtNode),renderToString:T("renderToString","ReactDOMServer","react-dom/server",g,g.renderToString),renderToStaticMarkup:T("renderToStaticMarkup","ReactDOMServer","react-dom/server",g,g.renderToStaticMarkup)}),E.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=I,E.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=g,A.exports=E},function(A,M,t){"use strict";var I=(t(55),t(114)),g=(t(3),"_getDOMNodeDidWarn"),e={getDOMNode:function(){return this.constructor[g]=!0,I(this)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t){var I=void 0===A[t];null!=M&&I&&(A[t]=e(M,null))}var g=t(36),e=t(119),i=t(122),T=t(123),E=(t(3),{instantiateChildren:function(A,M,t){if(null==A)return null;var g={};return T(A,I,g),g},updateChildren:function(A,M,t,I){if(!M&&!A)return null;var T;for(T in M)if(M.hasOwnProperty(T)){var E=A&&A[T],N=E&&E._currentElement,o=M[T];if(null!=E&&i(N,o))g.receiveComponent(E,o,t,I),M[T]=E;else{E&&g.unmountComponent(E,T);var n=e(o,null);M[T]=n}}for(T in A)!A.hasOwnProperty(T)||M&&M.hasOwnProperty(T)||g.unmountComponent(A[T]);return M},unmountChildren:function(A){for(var M in A)if(A.hasOwnProperty(M)){var t=A[M];g.unmountComponent(t)}}});A.exports=E},function(A,M,t){"use strict";function I(A){var M=A._currentElement._owner||null;if(M){var t=M.getName();if(t)return" Check the render method of ` + "`" + `"+t+"` + "`" + `."}return""}function g(A){}var e=t(110),i=t(25),T=t(13),E=t(55),N=t(17),o=t(71),n=(t(70),t(36)),C=t(112),c=t(4),D=t(50),a=t(2),B=t(122);t(3);g.prototype.render=function(){var A=E.get(this)._currentElement.type;return A(this.props,this.context,this.updater)};var Q=1,r={construct:function(A){this._currentElement=A,this._rootNodeID=null,this._instance=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._topLevelWrapper=null,this._pendingCallbacks=null},mountComponent:function(A,M,t){this._context=t,this._mountOrder=Q++,this._rootNodeID=A;var I,e,i=this._processProps(this._currentElement.props),N=this._processContext(t),o=this._currentElement.type,c="prototype"in o;c&&(I=new o(i,N,C)),c&&null!==I&&I!==!1&&!T.isValidElement(I)||(e=I,I=new g(o)),I.props=i,I.context=N,I.refs=D,I.updater=C,this._instance=I,E.set(I,this);var B=I.state;void 0===B&&(I.state=B=null),"object"!=typeof B||Array.isArray(B)?a(!1):void 0,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,I.componentWillMount&&(I.componentWillMount(),this._pendingStateQueue&&(I.state=this._processPendingState(I.props,I.context))),void 0===e&&(e=this._renderValidatedComponent()),this._renderedComponent=this._instantiateReactComponent(e);var r=n.mountComponent(this._renderedComponent,A,M,this._processChildContext(t));return I.componentDidMount&&M.getReactMountReady().enqueue(I.componentDidMount,I),r},unmountComponent:function(){var A=this._instance;A.componentWillUnmount&&A.componentWillUnmount(),n.unmountComponent(this._renderedComponent),this._renderedComponent=null,this._instance=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=null,this._topLevelWrapper=null,E.remove(A)},_maskContext:function(A){var M=null,t=this._currentElement.type,I=t.contextTypes;if(!I)return D;M={};for(var g in I)M[g]=A[g];return M},_processContext:function(A){var M=this._maskContext(A);return M},_processChildContext:function(A){var M=this._currentElement.type,t=this._instance,I=t.getChildContext&&t.getChildContext();if(I){"object"!=typeof M.childContextTypes?a(!1):void 0;for(var g in I)g in M.childContextTypes?void 0:a(!1);return c({},A,I)}return A},_processProps:function(A){return A},_checkPropTypes:function(A,M,t){var g=this.getName();for(var e in A)if(A.hasOwnProperty(e)){var i;try{"function"!=typeof A[e]?a(!1):void 0,i=A[e](M,e,g,t)}catch(A){i=A}if(i instanceof Error){I(this);t===o.prop}}},receiveComponent:function(A,M,t){var I=this._currentElement,g=this._context;this._pendingElement=null,this.updateComponent(M,I,A,g,t)},performUpdateIfNecessary:function(A){null!=this._pendingElement&&n.receiveComponent(this,this._pendingElement||this._currentElement,A,this._context),(null!==this._pendingStateQueue||this._pendingForceUpdate)&&this.updateComponent(A,this._currentElement,this._currentElement,this._context,this._context)},updateComponent:function(A,M,t,I,g){var e,i=this._instance,T=this._context===g?i.context:this._processContext(g);M===t?e=t.props:(e=this._processProps(t.props),i.componentWillReceiveProps&&i.componentWillReceiveProps(e,T));var E=this._processPendingState(e,T),N=this._pendingForceUpdate||!i.shouldComponentUpdate||i.shouldComponentUpdate(e,E,T);N?(this._pendingForceUpdate=!1,this._performComponentUpdate(t,e,E,T,A,g)):(this._currentElement=t,this._context=g,i.props=e,i.state=E,i.context=T)},_processPendingState:function(A,M){var t=this._instance,I=this._pendingStateQueue,g=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!I)return t.state;if(g&&1===I.length)return I[0];for(var e=c({},g?I[0]:t.state),i=g?1:0;i=0||null!=M.is}function B(A){D(A),this._tag=A.toLowerCase(),this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._rootNodeID=null,this._wrapperState=null,this._topLevelWrapper=null,this._nodeWithLegacyProperties=null}var Q=t(429),r=t(431),s=t(47),x=t(107),j=t(24),y=t(69),u=t(109),w=t(444),l=t(447),L=t(448),Y=t(210),d=t(451),h=t(12),S=t(456),z=t(17),p=t(112),U=t(4),O=t(74),m=t(75),F=t(2),f=(t(120),t(27)),k=t(76),R=t(121),J=(t(152),t(124),t(3),y.deleteListener),G=y.listenTo,H=y.registrationNameModules,b={string:!0,number:!0},v=f({children:null}),X=f({style:null}),W=f({__html:null}),V=1,P={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},Z={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},K={listing:!0,pre:!0,textarea:!0},q=(U({menuitem:!0},Z),/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/),_={},$={}.hasOwnProperty;B.displayName="ReactDOMComponent",B.Mixin={construct:function(A){this._currentElement=A},mountComponent:function(A,M,t){this._rootNodeID=A;var I=this._currentElement.props;switch(this._tag){case"iframe":case"img":case"form":case"video":case"audio":this._wrapperState={listeners:null},M.getReactMountReady().enqueue(n,this);break;case"button":I=w.getNativeProps(this,I,t);break;case"input":l.mountWrapper(this,I,t),I=l.getNativeProps(this,I,t);break;case"option":L.mountWrapper(this,I,t),I=L.getNativeProps(this,I,t);break;case"select":Y.mountWrapper(this,I,t),I=Y.getNativeProps(this,I,t),t=Y.processChildContext(this,I,t);break;case"textarea":d.mountWrapper(this,I,t),I=d.getNativeProps(this,I,t)}E(this,I);var g;if(M.useCreateElement){var e=t[h.ownerDocumentContextKey],i=e.createElement(this._currentElement.type);x.setAttributeForID(i,this._rootNodeID),h.getID(i),this._updateDOMProperties({},I,M,i),this._createInitialChildren(M,I,t,i),g=i}else{var T=this._createOpenTagMarkupAndPutListeners(M,I),N=this._createContentMarkup(M,I,t);g=!N&&Z[this._tag]?T+"/>":T+">"+N+""}switch(this._tag){case"input":M.getReactMountReady().enqueue(C,this);case"button":case"select":case"textarea":I.autoFocus&&M.getReactMountReady().enqueue(Q.focusDOMComponent,this)}return g},_createOpenTagMarkupAndPutListeners:function(A,M){var t="<"+this._currentElement.type;for(var I in M)if(M.hasOwnProperty(I)){var g=M[I];if(null!=g)if(H.hasOwnProperty(I))g&&N(this._rootNodeID,I,g,A);else{I===X&&(g&&(g=this._previousStyleCopy=U({},M.style)),g=r.createMarkupForStyles(g));var e=null;null!=this._tag&&a(this._tag,M)?I!==v&&(e=x.createMarkupForCustomAttribute(I,g)):e=x.createMarkupForProperty(I,g),e&&(t+=" "+e)}}if(A.renderToStaticMarkup)return t;var i=x.createMarkupForID(this._rootNodeID);return t+" "+i},_createContentMarkup:function(A,M,t){var I="",g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&(I=g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)I=m(e);else if(null!=i){var T=this.mountChildren(i,A,t);I=T.join("")}}return K[this._tag]&&"\n"===I.charAt(0)?"\n"+I:I},_createInitialChildren:function(A,M,t,I){var g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&k(I,g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)R(I,e);else if(null!=i)for(var T=this.mountChildren(i,A,t),E=0;EM.end?(t=M.end,I=M.start):(t=M.start,I=M.end),g.moveToElementText(A),g.moveStart("character",t),g.setEndPoint("EndToStart",g),g.moveEnd("character",I-t),g.select()}function T(A,M){if(window.getSelection){var t=window.getSelection(),I=A[o()].length,g=Math.min(M.start,I),e="undefined"==typeof M.end?g:Math.min(M.end,I);if(!t.extend&&g>e){var i=e;e=g,g=i}var T=N(A,g),E=N(A,e);if(T&&E){var n=document.createRange();n.setStart(T.node,T.offset),t.removeAllRanges(),g>e?(t.addRange(n),t.extend(E.node,E.offset)):(n.setEnd(E.node,E.offset),t.addRange(n))}}}var E=t(10),N=t(480),o=t(228),n=E.canUseDOM&&"selection"in document&&!("getSelection"in window),C={getOffsets:n?g:e,setOffsets:n?i:T};A.exports=C},function(A,M,t){"use strict";var I=t(213),g=t(461),e=t(113);I.inject();var i={renderToString:g.renderToString,renderToStaticMarkup:g.renderToStaticMarkup,version:e};A.exports=i},function(A,M,t){"use strict";function I(){this._rootNodeID&&o.updateWrapper(this)}function g(A){var M=this._currentElement.props,t=e.executeOnChange(M,A);return T.asap(I,this),t}var e=t(108),i=t(111),T=t(18),E=t(4),N=t(2),o=(t(3),{getNativeProps:function(A,M,t){null!=M.dangerouslySetInnerHTML?N(!1):void 0;var I=E({},M,{defaultValue:void 0,value:void 0,children:A._wrapperState.initialValue,onChange:A._wrapperState.onChange});return I},mountWrapper:function(A,M){var t=M.defaultValue,I=M.children;null!=I&&(null!=t?N(!1):void 0,Array.isArray(I)&&(I.length<=1?void 0:N(!1),I=I[0]),t=""+I),null==t&&(t="");var i=e.getValue(M);A._wrapperState={initialValue:""+(null!=i?i:t),onChange:g.bind(A)}},updateWrapper:function(A){var M=A._currentElement.props,t=e.getValue(M);null!=t&&i.updatePropertyByID(A._rootNodeID,"value",""+t)}});A.exports=o},function(A,M,t){"use strict";function I(A){g.enqueueEvents(A),g.processEventQueue(!1)}var g=t(53),e={handleTopLevel:function(A,M,t,e,i){var T=g.extractEvents(A,M,t,e,i);I(T)}};A.exports=e},function(A,M,t){"use strict";function I(A){var M=C.getID(A),t=n.getReactRootIDFromNodeID(M),I=C.findReactContainerForID(t),g=C.getFirstReactDOM(I);return g}function g(A,M){this.topLevelType=A,this.nativeEvent=M,this.ancestors=[]}function e(A){i(A)}function i(A){for(var M=C.getFirstReactDOM(a(A.nativeEvent))||window,t=M;t;)A.ancestors.push(t),t=I(t);for(var g=0;g=M)return{node:g,offset:M-e};e=i}g=t(I(g))}}A.exports=g},function(A,M,t){"use strict";function I(A){return g.isValidElement(A)?void 0:e(!1),A}var g=t(13),e=t(2);A.exports=I},function(A,M,t){"use strict";function I(A){return'"'+g(A)+'"'}var g=t(75);A.exports=I},function(A,M,t){"use strict";var I=t(12);A.exports=I.renderSubtreeIntoContainer},function(A,M){A.exports=function(A,M,t){for(var I=0,g=A.length,e=3==arguments.length?t:A[I++];I=400){ var T="cannot "+M.method+" "+M.url+" ("+i.status+")";A=new e(T),A.status=i.status,A.body=i.body,A.res=i,I(A)}else g?I(new e(g)):t(i)})})},g.prototype.then=function(){var A=this.promise();return A.then.apply(A,arguments)}},function(A,M,t){function I(){}function g(A){var M={}.toString.call(A);switch(M){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function e(A){if(!s(A))return A;var M=[];for(var t in A)null!=A[t]&&i(M,t,A[t]);return M.join("&")}function i(A,M,t){return Array.isArray(t)?t.forEach(function(t){i(A,M,t)}):void A.push(encodeURIComponent(M)+"="+encodeURIComponent(t))}function T(A){for(var M,t,I={},g=A.split("&"),e=0,i=g.length;e=200&&M.status<300)return t.callback(A,M);var I=new Error(M.statusText||"Unsuccessful HTTP response");I.original=A,I.response=M,I.status=M.status,t.callback(I,M)})}function D(A,M){var t=x("DELETE",A);return M&&t.end(M),t}var a,B=t(273),Q=t(484),r=t(502),s=t(236);a="undefined"!=typeof window?window:"undefined"!=typeof self?self:this;var x=A.exports=t(503).bind(null,c);x.getXHR=function(){if(!(!a.XMLHttpRequest||a.location&&"file:"==a.location.protocol&&a.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(A){}return!1};var j="".trim?function(A){return A.trim()}:function(A){return A.replace(/(^\s*|\s*$)/g,"")};x.serializeObject=e,x.parseString=T,x.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},x.serialize={"application/x-www-form-urlencoded":e,"application/json":JSON.stringify},x.parse={"application/x-www-form-urlencoded":T,"application/json":JSON.parse},C.prototype.get=function(A){return this.header[A.toLowerCase()]},C.prototype.setHeaderProperties=function(A){var M=this.header["content-type"]||"";this.type=o(M);var t=n(M);for(var I in t)this[I]=t[I]},C.prototype.parseBody=function(A){var M=x.parse[this.type];return!M&&N(this.type)&&(M=x.parse["application/json"]),M&&A&&(A.length||A instanceof Object)?M(A):null},C.prototype.setStatusProperties=function(A){1223===A&&(A=204);var M=A/100|0;this.status=this.statusCode=A,this.statusType=M,this.info=1==M,this.ok=2==M,this.clientError=4==M,this.serverError=5==M,this.error=(4==M||5==M)&&this.toError(),this.accepted=202==A,this.noContent=204==A,this.badRequest=400==A,this.unauthorized=401==A,this.notAcceptable=406==A,this.notFound=404==A,this.forbidden=403==A},C.prototype.toError=function(){var A=this.req,M=A.method,t=A.url,I="cannot "+M+" "+t+" ("+this.status+")",g=new Error(I);return g.status=this.status,g.method=M,g.url=t,g},x.Response=C,B(c.prototype);for(var y in r)c.prototype[y]=r[y];c.prototype.abort=function(){if(!this.aborted)return this.aborted=!0,this.xhr&&this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this},c.prototype.type=function(A){return this.set("Content-Type",x.types[A]||A),this},c.prototype.responseType=function(A){return this._responseType=A,this},c.prototype.accept=function(A){return this.set("Accept",x.types[A]||A),this},c.prototype.auth=function(A,M,t){switch(t||(t={type:"basic"}),t.type){case"basic":var I=btoa(A+":"+M);this.set("Authorization","Basic "+I);break;case"auto":this.username=A,this.password=M}return this},c.prototype.query=function(A){return"string"!=typeof A&&(A=e(A)),A&&this._query.push(A),this},c.prototype.attach=function(A,M,t){return this._getFormData().append(A,M,t||M.name),this},c.prototype._getFormData=function(){return this._formData||(this._formData=new a.FormData),this._formData},c.prototype.send=function(A){var M=s(A),t=this._header["content-type"];if(M&&s(this._data))for(var I in A)this._data[I]=A[I];else"string"==typeof A?(t||this.type("form"),t=this._header["content-type"],"application/x-www-form-urlencoded"==t?this._data=this._data?this._data+"&"+A:A:this._data=(this._data||"")+A):this._data=A;return!M||g(A)?this:(t||this.type("json"),this)},C.prototype.parse=function(A){return a.console&&console.warn("Client-side parse() method has been renamed to serialize(). This method is not compatible with superagent v2.0"),this.serialize(A),this},C.prototype.serialize=function(A){return this._parser=A,this},c.prototype.callback=function(A,M){var t=this._callback;this.clearTimeout(),t(A,M)},c.prototype.crossDomainError=function(){var A=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");A.crossDomain=!0,A.status=this.status,A.method=this.method,A.url=this.url,this.callback(A)},c.prototype.timeoutError=function(){var A=this._timeout,M=new Error("timeout of "+A+"ms exceeded");M.timeout=A,this.callback(M)},c.prototype.withCredentials=function(){return this._withCredentials=!0,this},c.prototype.end=function(A){var M=this,t=this.xhr=x.getXHR(),e=this._query.join("&"),i=this._timeout,T=this._formData||this._data;this._callback=A||I,t.onreadystatechange=function(){if(4==t.readyState){var A;try{A=t.status}catch(M){A=0}if(0==A){if(M.timedout)return M.timeoutError();if(M.aborted)return;return M.crossDomainError()}M.emit("end")}};var E=function(A){A.total>0&&(A.percent=A.loaded/A.total*100),A.direction="download",M.emit("progress",A)};this.hasListeners("progress")&&(t.onprogress=E);try{t.upload&&this.hasListeners("progress")&&(t.upload.onprogress=E)}catch(A){}if(i&&!this._timer&&(this._timer=setTimeout(function(){M.timedout=!0,M.abort()},i)),e&&(e=x.serializeObject(e),this.url+=~this.url.indexOf("?")?"&"+e:"?"+e),this.username&&this.password?t.open(this.method,this.url,!0,this.username,this.password):t.open(this.method,this.url,!0),this._withCredentials&&(t.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof T&&!g(T)){var o=this._header["content-type"],n=this._parser||x.serialize[o?o.split(";")[0]:""];!n&&N(o)&&(n=x.serialize["application/json"]),n&&(T=n(T))}for(var C in this.header)null!=this.header[C]&&t.setRequestHeader(C,this.header[C]);return this._responseType&&(t.responseType=this._responseType),this.emit("request",this),t.send("undefined"!=typeof T?T:null),this},x.Request=c,x.get=function(A,M,t){var I=x("GET",A);return"function"==typeof M&&(t=M,M=null),M&&I.query(M),t&&I.end(t),I},x.head=function(A,M,t){var I=x("HEAD",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.del=D,x.delete=D,x.patch=function(A,M,t){var I=x("PATCH",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.post=function(A,M,t){var I=x("POST",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.put=function(A,M,t){var I=x("PUT",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I}},function(A,M,t){var I=t(236);M.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},M.parse=function(A){return this._parser=A,this},M.timeout=function(A){return this._timeout=A,this},M.then=function(A,M){return this.end(function(t,I){t?M(t):A(I)})},M.use=function(A){return A(this),this},M.get=function(A){return this._header[A.toLowerCase()]},M.getHeader=M.get,M.set=function(A,M){if(I(A)){for(var t in A)this.set(t,A[t]);return this}return this._header[A.toLowerCase()]=M,this.header[A]=M,this},M.unset=function(A){return delete this._header[A.toLowerCase()],delete this.header[A],this},M.field=function(A,M){return this._getFormData().append(A,M),this}},function(A,M){function t(A,M,t){return"function"==typeof t?new A("GET",M).end(t):2==arguments.length?new A("GET",M):new A(M,t)}A.exports=t},function(A,M,t){A.exports=t(505)},function(A,M,t){(function(A,I){"use strict";function g(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var e,i=t(506),T=g(i);e="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof A?A:I;var E=(0,T.default)(e);M.default=E}).call(M,function(){return this}(),t(128)(A))},function(A,M){"use strict";function t(A){var M,t=A.Symbol;return"function"==typeof t?t.observable?M=t.observable:(M=t("observable"),t.observable=M):M="@@observable",M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t},function(A,M,t){function I(A){return g(A).replace(/\s(\w)/g,function(A,M){return M.toUpperCase()})}var g=t(509);A.exports=I},function(A,M){function t(A){return e.test(A)?A.toLowerCase():i.test(A)?(I(A)||A).toLowerCase():T.test(A)?g(A).toLowerCase():A.toLowerCase()}function I(A){return A.replace(E,function(A,M){return M?" "+M:""})}function g(A){return A.replace(N,function(A,M,t){return M+" "+t.toLowerCase().split("").join(" ")})}A.exports=t;var e=/\s/,i=/(_|-|\.|:)/,T=/([a-z][A-Z]|[A-Z][a-z])/,E=/[\W_]+(.|$)/g,N=/(.)([A-Z]+)/g},function(A,M,t){function I(A){return g(A).replace(/[\W_]+(.|$)/g,function(A,M){return M?" "+M:""}).trim()}var g=t(508);A.exports=I},function(A,M){A.exports=function(){var A=document.getSelection();if(!A.rangeCount)return function(){};for(var M=document.activeElement,t=[],I=0;I=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function i(A,M){function t(I,g){function i(A,t){var I=c.getLinkName(A),e=this.props[g[A]];I&&E(this.props,I)&&!e&&(e=this.props[I].requestChange);for(var i=arguments.length,T=Array(i>2?i-2:0),N=2;N=15||0===s[0]&&s[1]>=13?A:A.type}function T(A,M){var t=N(M);return t&&!E(A,M)&&E(A,t)?A[t].value:A[M]}function E(A,M){return void 0!==A[M]}function N(A){return"value"===A?"valueLink":"checked"===A?"checkedLink":null}function o(A){return"default"+A.charAt(0).toUpperCase()+A.substr(1)}function n(A,M,t){return function(){for(var I=arguments.length,g=Array(I),e=0;e1&&(I=t[0]+"@",A=t[1]),A=A.replace(z,".");var g=A.split("."),e=T(g,M).join(".");return I+e}function N(A){for(var M,t,I=[],g=0,e=A.length;g=55296&&M<=56319&&g65535&&(A-=65536,M+=m(A>>>10&1023|55296),A=56320|1023&A),M+=m(A)}).join("")}function n(A){return A-48<10?A-22:A-65<26?A-65:A-97<26?A-97:j}function C(A,M){return A+22+75*(A<26)-((0!=M)<<5)}function c(A,M,t){var I=0;for(A=t?O(A/L):A>>1,A+=O(A/M);A>U*u>>1;I+=j)A=O(A/U);return O(I+(U+1)*A/(A+w))}function D(A){var M,t,I,g,e,T,E,N,C,D,a=[],B=A.length,Q=0,r=Y,s=l;for(t=A.lastIndexOf(d),t<0&&(t=0),I=0;I=128&&i("not-basic"),a.push(A.charCodeAt(I));for(g=t>0?t+1:0;g=B&&i("invalid-input"),N=n(A.charCodeAt(g++)),(N>=j||N>O((x-Q)/T))&&i("overflow"),Q+=N*T,C=E<=s?y:E>=s+u?u:E-s,!(NO(x/D)&&i("overflow"),T*=D;M=a.length+1,s=c(Q-e,M,0==e),O(Q/M)>x-r&&i("overflow"),r+=O(Q/M),Q%=M,a.splice(Q++,0,r)}return o(a)}function a(A){var M,t,I,g,e,T,E,o,n,D,a,B,Q,r,s,w=[];for(A=N(A),B=A.length,M=Y,t=0,e=l,T=0;T=M&&aO((x-t)/Q)&&i("overflow"),t+=(E-M)*Q,M=E,T=0;Tx&&i("overflow"),a==M){for(o=t,n=j;D=n<=e?y:n>=e+u?u:n-e,!(o= 0x80 (not a basic code point)","invalid-input":"Invalid input"},U=j-y,O=Math.floor,m=String.fromCharCode;s={version:"1.3.2",ucs2:{decode:N,encode:o},decode:D,encode:a,toASCII:Q,toUnicode:B},I=function(){return s}.call(M,t,M,A),!(void 0!==I&&(A.exports=I))}(this)}).call(M,t(128)(A),function(){return this}())},function(A,M){"use strict";A.exports={isString:function(A){return"string"==typeof A},isObject:function(A){return"object"==typeof A&&null!==A},isNull:function(A){return null===A},isNullOrUndefined:function(A){return null==A}}}]);`) +},function(A,M,t){var I;(function(A,g){!function(e){function i(A){throw RangeError(p[A])}function T(A,M){for(var t=A.length,I=[];t--;)I[t]=M(A[t]);return I}function E(A,M){var t=A.split("@"),I="";t.length>1&&(I=t[0]+"@",A=t[1]),A=A.replace(z,".");var g=A.split("."),e=T(g,M).join(".");return I+e}function N(A){for(var M,t,I=[],g=0,e=A.length;g=55296&&M<=56319&&g65535&&(A-=65536,M+=m(A>>>10&1023|55296),A=56320|1023&A),M+=m(A)}).join("")}function n(A){return A-48<10?A-22:A-65<26?A-65:A-97<26?A-97:j}function C(A,M){return A+22+75*(A<26)-((0!=M)<<5)}function c(A,M,t){var I=0;for(A=t?O(A/l):A>>1,A+=O(A/M);A>U*u>>1;I+=j)A=O(A/U);return O(I+(U+1)*A/(A+w))}function D(A){var M,t,I,g,e,T,E,N,C,D,a=[],B=A.length,Q=0,r=Y,s=L;for(t=A.lastIndexOf(d),t<0&&(t=0),I=0;I=128&&i("not-basic"),a.push(A.charCodeAt(I));for(g=t>0?t+1:0;g=B&&i("invalid-input"),N=n(A.charCodeAt(g++)),(N>=j||N>O((x-Q)/T))&&i("overflow"),Q+=N*T,C=E<=s?y:E>=s+u?u:E-s,!(NO(x/D)&&i("overflow"),T*=D;M=a.length+1,s=c(Q-e,M,0==e),O(Q/M)>x-r&&i("overflow"),r+=O(Q/M),Q%=M,a.splice(Q++,0,r)}return o(a)}function a(A){var M,t,I,g,e,T,E,o,n,D,a,B,Q,r,s,w=[];for(A=N(A),B=A.length,M=Y,t=0,e=L,T=0;T=M&&aO((x-t)/Q)&&i("overflow"),t+=(E-M)*Q,M=E,T=0;Tx&&i("overflow"),a==M){for(o=t,n=j;D=n<=e?y:n>=e+u?u:n-e,!(o= 0x80 (not a basic code point)","invalid-input":"Invalid input"},U=j-y,O=Math.floor,m=String.fromCharCode;s={version:"1.3.2",ucs2:{decode:N,encode:o},decode:D,encode:a,toASCII:Q,toUnicode:B},I=function(){return s}.call(M,t,M,A),!(void 0!==I&&(A.exports=I))}(this)}).call(M,t(128)(A),function(){return this}())},function(A,M){"use strict";A.exports={isString:function(A){return"string"==typeof A},isObject:function(A){return"object"==typeof A&&null!==A},isNull:function(A){return null===A},isNullOrUndefined:function(A){return null==A}}}]);`) -func productionIndex_bundle20170215t224123zJsBytes() ([]byte, error) { - return _productionIndex_bundle20170215t224123zJs, nil +func productionIndex_bundle20170223t004442zJsBytes() ([]byte, error) { + return _productionIndex_bundle20170223t004442zJs, nil } -func productionIndex_bundle20170215t224123zJs() (*asset, error) { - bytes, err := productionIndex_bundle20170215t224123zJsBytes() +func productionIndex_bundle20170223t004442zJs() (*asset, error) { + bytes, err := productionIndex_bundle20170223t004442zJsBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "production/index_bundle-2017-02-15T22-41-23Z.js", size: 2276858, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/index_bundle-2017-02-23T00-44-42Z.js", size: 2282928, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -370,7 +370,7 @@ func productionLoaderCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -444,7 +444,7 @@ func productionLogoSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -461,7 +461,7 @@ func productionSafariPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1487198497, 0)} + info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -522,7 +522,7 @@ var _bindata = map[string]func() (*asset, error){ "production/favicon.ico": productionFaviconIco, "production/firefox.png": productionFirefoxPng, "production/index.html": productionIndexHTML, - "production/index_bundle-2017-02-15T22-41-23Z.js": productionIndex_bundle20170215t224123zJs, + "production/index_bundle-2017-02-23T00-44-42Z.js": productionIndex_bundle20170223t004442zJs, "production/loader.css": productionLoaderCss, "production/logo.svg": productionLogoSvg, "production/safari.png": productionSafariPng, @@ -574,7 +574,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "favicon.ico": {productionFaviconIco, map[string]*bintree{}}, "firefox.png": {productionFirefoxPng, map[string]*bintree{}}, "index.html": {productionIndexHTML, map[string]*bintree{}}, - "index_bundle-2017-02-15T22-41-23Z.js": {productionIndex_bundle20170215t224123zJs, map[string]*bintree{}}, + "index_bundle-2017-02-23T00-44-42Z.js": {productionIndex_bundle20170223t004442zJs, map[string]*bintree{}}, "loader.css": {productionLoaderCss, map[string]*bintree{}}, "logo.svg": {productionLogoSvg, map[string]*bintree{}}, "safari.png": {productionSafariPng, map[string]*bintree{}}, @@ -635,6 +635,6 @@ func assetFS() *assetfs.AssetFS { panic("unreachable") } -var UIReleaseTag = "RELEASE.2017-02-15T22-41-23Z" -var UICommitID = "b50e5164ba49acf3de57eb0dd5a45f1cd31b3411" -var UIVersion = "2017-02-15T22:41:23Z" +var UIReleaseTag = "RELEASE.2017-02-23T00-44-42Z" +var UICommitID = "52d6678bf0d1442d0ab9b7bc63b47ceda69d0e4a" +var UIVersion = "2017-02-23T00:44:42Z" diff --git a/browser/webpack.config.js b/browser/webpack.config.js index 3c84b329d..769b84c56 100644 --- a/browser/webpack.config.js +++ b/browser/webpack.config.js @@ -1,5 +1,5 @@ /* - * Minio Browser (C) 2016 Minio, Inc. + * Minio Cloud Storage (C) 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index 3f092c6d4..420338cb0 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -84,7 +84,7 @@ func (web *webAPIHandlers) ServerInfo(r *http.Request, args *WebGenericArgs, rep reply.MinioMemory = mem reply.MinioPlatform = platform reply.MinioRuntime = goruntime - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -104,7 +104,7 @@ func (web *webAPIHandlers) StorageInfo(r *http.Request, args *AuthRPCArgs, reply return toJSONError(errAuthentication) } reply.StorageInfo = objectAPI.StorageInfo() - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -128,7 +128,7 @@ func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, rep if err := objectAPI.MakeBucket(args.BucketName); err != nil { return toJSONError(err, args.BucketName) } - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -166,7 +166,7 @@ func (web *webAPIHandlers) ListBuckets(r *http.Request, args *WebGenericArgs, re CreationDate: bucket.Created, }) } - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -200,7 +200,7 @@ type WebObjectInfo struct { // ListObjects - list objects api. func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, reply *ListObjectsRep) error { - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion objectAPI := web.ObjectAPI() if objectAPI == nil { return toJSONError(errServerNotInitialized) @@ -272,7 +272,7 @@ func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs, if err := objectAPI.DeleteObject(args.BucketName, args.ObjectName); err != nil { if isErrObjectNotFound(err) { // Ignore object not found error. - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } return toJSONError(err, args.BucketName, args.ObjectName) @@ -290,7 +290,7 @@ func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs, }, }) - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -317,7 +317,7 @@ func (web *webAPIHandlers) Login(r *http.Request, args *LoginArgs, reply *LoginR } reply.Token = token - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -335,7 +335,7 @@ func (web webAPIHandlers) GenerateAuth(r *http.Request, args *WebGenericArgs, re cred := newCredential() reply.AccessKey = cred.AccessKey reply.SecretKey = cred.SecretKey - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -416,7 +416,7 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se } reply.Token = token - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -435,7 +435,7 @@ func (web *webAPIHandlers) GetAuth(r *http.Request, args *WebGenericArgs, reply creds := serverConfig.GetCredential() reply.AccessKey = creds.AccessKey reply.SecretKey = creds.SecretKey - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -663,7 +663,7 @@ func (web *webAPIHandlers) GetBucketPolicy(r *http.Request, args *GetBucketPolic return toJSONError(err, args.BucketName) } - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion reply.Policy = policy.GetPolicy(policyInfo.Statements, args.BucketName, args.Prefix) return nil @@ -702,7 +702,7 @@ func (web *webAPIHandlers) ListAllBucketPolicies(r *http.Request, args *ListAllB return toJSONError(err, args.BucketName) } - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion for prefix, policy := range policy.GetPolicies(policyInfo.Statements, args.BucketName) { reply.Policies = append(reply.Policies, bucketAccessPolicy{ Prefix: prefix, @@ -747,7 +747,7 @@ func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolic if err != nil { return toJSONError(err, args.BucketName) } - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } data, err := json.Marshal(policyInfo) @@ -766,7 +766,7 @@ func (web *webAPIHandlers) SetBucketPolicy(r *http.Request, args *SetBucketPolic } return toJSONError(err, args.BucketName) } - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion return nil } @@ -803,7 +803,7 @@ func (web *webAPIHandlers) PresignedGet(r *http.Request, args *PresignedGetArgs, Message: "Bucket and Object are mandatory arguments.", } } - reply.UIVersion = miniobrowser.UIVersion + reply.UIVersion = browser.UIVersion reply.URL = presignedGet(args.HostName, args.BucketName, args.ObjectName, args.Expiry) return nil } diff --git a/cmd/web-router.go b/cmd/web-router.go index 333e102ba..6f85156c3 100644 --- a/cmd/web-router.go +++ b/cmd/web-router.go @@ -47,9 +47,9 @@ const assetPrefix = "production" func assetFS() *assetfs.AssetFS { return &assetfs.AssetFS{ - Asset: miniobrowser.Asset, - AssetDir: miniobrowser.AssetDir, - AssetInfo: miniobrowser.AssetInfo, + Asset: browser.Asset, + AssetDir: browser.AssetDir, + AssetInfo: browser.AssetInfo, Prefix: assetPrefix, } } From bcc5b6e1efefd7fc023eee7e2e3b3d3fc72a41b4 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 24 Feb 2017 09:20:40 -0800 Subject: [PATCH 23/94] xl: Rename getOrderedDisks as shuffleDisks appropriately. (#3796) This PR is for readability cleanup - getOrderedDisks as shuffleDisks - getOrderedPartsMetadata as shufflePartsMetadata Distribution is now a second argument instead being the primary input argument for brevity. Also change the usage of type casted int64(0), instead rely on direct type reference as `var variable int64` everywhere. --- cmd/erasure-readfile.go | 4 +-- cmd/erasure-readfile_test.go | 32 +-------------------- cmd/erasure-utils.go | 4 +-- cmd/fs-v1-background-append.go | 2 +- cmd/fs-v1-multipart.go | 4 +-- cmd/fs-v1.go | 2 +- cmd/lock-instrument_test.go | 24 ++++++++-------- cmd/object-api-putobject_test.go | 2 +- cmd/object-handlers.go | 4 +-- cmd/server_utils_test.go | 2 +- cmd/xl-v1-healing.go | 6 ++-- cmd/xl-v1-multipart.go | 9 +++--- cmd/xl-v1-object.go | 19 +++++++------ cmd/xl-v1-utils.go | 32 +++++++++++++-------- cmd/xl-v1-utils_test.go | 48 ++++++++++++++++++++++++++++++++ 15 files changed, 110 insertions(+), 84 deletions(-) diff --git a/cmd/erasure-readfile.go b/cmd/erasure-readfile.go index 6d50d933a..682522c36 100644 --- a/cmd/erasure-readfile.go +++ b/cmd/erasure-readfile.go @@ -192,7 +192,7 @@ func erasureReadFile(writer io.Writer, disks []StorageAPI, volume string, path s }() // Total bytes written to writer - bytesWritten := int64(0) + var bytesWritten int64 startBlock := offset / blockSize endBlock := (offset + length) / blockSize @@ -263,7 +263,7 @@ func erasureReadFile(writer io.Writer, disks []StorageAPI, volume string, path s } // Offset in enBlocks from where data should be read from. - enBlocksOffset := int64(0) + var enBlocksOffset int64 // Total data to be read from enBlocks. enBlocksLength := curBlockSize diff --git a/cmd/erasure-readfile_test.go b/cmd/erasure-readfile_test.go index 51071952f..4fa3c43fa 100644 --- a/cmd/erasure-readfile_test.go +++ b/cmd/erasure-readfile_test.go @@ -121,35 +121,6 @@ func testGetReadDisks(t *testing.T, xl *xlObjects) { } } -// Test getOrderedDisks which returns ordered slice of disks from their -// actual distribution. -func testGetOrderedDisks(t *testing.T, xl *xlObjects) { - disks := xl.storageDisks - distribution := []int{16, 14, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7, 9, 11, 13, 15} - orderedDisks := getOrderedDisks(distribution, disks) - // From the "distribution" above you can notice that: - // 1st data block is in the 9th disk (i.e distribution index 8) - // 2nd data block is in the 8th disk (i.e distribution index 7) and so on. - if orderedDisks[0] != disks[8] || - orderedDisks[1] != disks[7] || - orderedDisks[2] != disks[9] || - orderedDisks[3] != disks[6] || - orderedDisks[4] != disks[10] || - orderedDisks[5] != disks[5] || - orderedDisks[6] != disks[11] || - orderedDisks[7] != disks[4] || - orderedDisks[8] != disks[12] || - orderedDisks[9] != disks[3] || - orderedDisks[10] != disks[13] || - orderedDisks[11] != disks[2] || - orderedDisks[12] != disks[14] || - orderedDisks[13] != disks[1] || - orderedDisks[14] != disks[15] || - orderedDisks[15] != disks[0] { - t.Errorf("getOrderedDisks returned incorrect order.") - } -} - // Test for isSuccessDataBlocks and isSuccessDecodeBlocks. func TestIsSuccessBlocks(t *testing.T) { dataBlocks := 8 @@ -217,7 +188,7 @@ func TestIsSuccessBlocks(t *testing.T) { } } -// Wrapper function for testGetReadDisks, testGetOrderedDisks. +// Wrapper function for testGetReadDisks, testShuffleDisks. func TestErasureReadUtils(t *testing.T) { nDisks := 16 disks, err := getRandomDisks(nDisks) @@ -236,7 +207,6 @@ func TestErasureReadUtils(t *testing.T) { defer removeRoots(disks) xl := objLayer.(*xlObjects) testGetReadDisks(t, xl) - testGetOrderedDisks(t, xl) } // Simulates a faulty disk for ReadFile() diff --git a/cmd/erasure-utils.go b/cmd/erasure-utils.go index 814df1c47..6fe01c499 100644 --- a/cmd/erasure-utils.go +++ b/cmd/erasure-utils.go @@ -116,7 +116,7 @@ func writeDataBlocks(dst io.Writer, enBlocks [][]byte, dataBlocks int, offset in write := length // Counter to increment total written. - totalWritten := int64(0) + var totalWritten int64 // Write all data blocks to dst. for _, block := range enBlocks[:dataBlocks] { @@ -180,7 +180,7 @@ func copyBuffer(writer io.Writer, disk StorageAPI, volume string, path string, b } // Starting offset for Reading the file. - startOffset := int64(0) + var startOffset int64 // Read until io.EOF. for { diff --git a/cmd/fs-v1-background-append.go b/cmd/fs-v1-background-append.go index 2e4362b4c..c3b7c868a 100644 --- a/cmd/fs-v1-background-append.go +++ b/cmd/fs-v1-background-append.go @@ -210,7 +210,7 @@ func (fs fsObjects) appendParts(bucket, object, uploadID string, info bgAppendPa func (fs fsObjects) appendPart(bucket, object, uploadID string, part objectPartInfo, buf []byte) error { partPath := pathJoin(fs.fsPath, minioMetaMultipartBucket, bucket, object, uploadID, part.Name) - offset := int64(0) + var offset int64 // Read each file part to start writing to the temporary concatenated object. file, size, err := fsOpenFile(partPath, offset) if err != nil { diff --git a/cmd/fs-v1-multipart.go b/cmd/fs-v1-multipart.go index b28eaf24a..edde3bfe8 100644 --- a/cmd/fs-v1-multipart.go +++ b/cmd/fs-v1-multipart.go @@ -463,7 +463,7 @@ func (fs fsObjects) CopyObjectPart(srcBucket, srcObject, dstBucket, dstObject, u pipeReader, pipeWriter := io.Pipe() go func() { - startOffset := int64(0) // Read the whole file. + var startOffset int64 // Read the whole file. if gerr := fs.GetObject(srcBucket, srcObject, startOffset, length, pipeWriter); gerr != nil { errorIf(gerr, "Unable to read %s/%s.", srcBucket, srcObject) pipeWriter.CloseWithError(gerr) @@ -864,7 +864,7 @@ func (fs fsObjects) CompleteMultipartUpload(bucket string, object string, upload multipartPartFile := pathJoin(fs.fsPath, minioMetaMultipartBucket, uploadIDPath, partSuffix) var reader io.ReadCloser - offset := int64(0) + var offset int64 reader, _, err = fsOpenFile(multipartPartFile, offset) if err != nil { fs.rwPool.Close(fsMetaPathMultipart) diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index 530a81c39..238720b14 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -395,7 +395,7 @@ func (fs fsObjects) CopyObject(srcBucket, srcObject, dstBucket, dstObject string pipeReader, pipeWriter := io.Pipe() go func() { - startOffset := int64(0) // Read the whole file. + var startOffset int64 // Read the whole file. if gerr := fs.GetObject(srcBucket, srcObject, startOffset, length, pipeWriter); gerr != nil { errorIf(gerr, "Unable to read %s/%s.", srcBucket, srcObject) pipeWriter.CloseWithError(gerr) diff --git a/cmd/lock-instrument_test.go b/cmd/lock-instrument_test.go index f06950c64..1b562b14b 100644 --- a/cmd/lock-instrument_test.go +++ b/cmd/lock-instrument_test.go @@ -653,14 +653,14 @@ func TestNsLockMapDeleteLockInfoEntryForOps(t *testing.T) { } else { t.Fatalf("Entry for %s, %s should have existed. ", param.volume, param.path) } - if globalNSMutex.counters.granted != int64(0) { - t.Errorf("Expected the count of total running locks to be %v, but got %v", int64(0), globalNSMutex.counters.granted) + if globalNSMutex.counters.granted != 0 { + t.Errorf("Expected the count of total running locks to be %v, but got %v", 0, globalNSMutex.counters.granted) } - if globalNSMutex.counters.blocked != int64(0) { - t.Errorf("Expected the count of total blocked locks to be %v, but got %v", int64(0), globalNSMutex.counters.blocked) + if globalNSMutex.counters.blocked != 0 { + t.Errorf("Expected the count of total blocked locks to be %v, but got %v", 0, globalNSMutex.counters.blocked) } - if globalNSMutex.counters.total != int64(0) { - t.Errorf("Expected the count of all locks to be %v, but got %v", int64(0), globalNSMutex.counters.total) + if globalNSMutex.counters.total != 0 { + t.Errorf("Expected the count of all locks to be %v, but got %v", 0, globalNSMutex.counters.total) } } @@ -723,13 +723,13 @@ func TestNsLockMapDeleteLockInfoEntryForVolumePath(t *testing.T) { t.Fatalf("Entry for %s, %s should have been deleted. ", param.volume, param.path) } // The lock count values should be 0. - if globalNSMutex.counters.granted != int64(0) { - t.Errorf("Expected the count of total running locks to be %v, but got %v", int64(0), globalNSMutex.counters.granted) + if globalNSMutex.counters.granted != 0 { + t.Errorf("Expected the count of total running locks to be %v, but got %v", 0, globalNSMutex.counters.granted) } - if globalNSMutex.counters.blocked != int64(0) { - t.Errorf("Expected the count of total blocked locks to be %v, but got %v", int64(0), globalNSMutex.counters.blocked) + if globalNSMutex.counters.blocked != 0 { + t.Errorf("Expected the count of total blocked locks to be %v, but got %v", 0, globalNSMutex.counters.blocked) } - if globalNSMutex.counters.total != int64(0) { - t.Errorf("Expected the count of all locks to be %v, but got %v", int64(0), globalNSMutex.counters.total) + if globalNSMutex.counters.total != 0 { + t.Errorf("Expected the count of all locks to be %v, but got %v", 0, globalNSMutex.counters.total) } } diff --git a/cmd/object-api-putobject_test.go b/cmd/object-api-putobject_test.go index 45c6fb516..3a7884e27 100644 --- a/cmd/object-api-putobject_test.go +++ b/cmd/object-api-putobject_test.go @@ -146,7 +146,7 @@ func testObjectAPIPutObject(obj ObjectLayer, instanceType string, t TestErrHandl // data with size different from the actual number of bytes available in the reader {bucket, object, data, nil, "", int64(len(data) - 1), getMD5Hash(data[:len(data)-1]), nil}, {bucket, object, nilBytes, nil, "", int64(len(nilBytes) + 1), getMD5Hash(nilBytes), IncompleteBody{}}, - {bucket, object, fiveMBBytes, nil, "", int64(0), getMD5Hash(fiveMBBytes), nil}, + {bucket, object, fiveMBBytes, nil, "", 0, getMD5Hash(fiveMBBytes), nil}, // Test case 30 // valid data with X-Amz-Meta- meta diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 06e385596..cb6d2b39c 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -133,7 +133,7 @@ func (api objectAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Req } // Get the object. - startOffset := int64(0) + var startOffset int64 length := objInfo.Size if hrange != nil { startOffset = hrange.offsetBegin @@ -620,7 +620,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt } // Get the object. - startOffset := int64(0) + var startOffset int64 length := objInfo.Size if hrange != nil { startOffset = hrange.offsetBegin diff --git a/cmd/server_utils_test.go b/cmd/server_utils_test.go index 7036cfd4d..a500ad772 100644 --- a/cmd/server_utils_test.go +++ b/cmd/server_utils_test.go @@ -91,7 +91,7 @@ func calculateStreamContentLength(dataLen, chunkSize int64) int64 { } chunksCount := int64(dataLen / chunkSize) remainingBytes := int64(dataLen % chunkSize) - streamLen := int64(0) + var streamLen int64 streamLen += chunksCount * calculateSignedChunkLength(chunkSize) if remainingBytes > 0 { streamLen += calculateSignedChunkLength(remainingBytes) diff --git a/cmd/xl-v1-healing.go b/cmd/xl-v1-healing.go index d0aaf56a7..db8ba2fdd 100644 --- a/cmd/xl-v1-healing.go +++ b/cmd/xl-v1-healing.go @@ -371,9 +371,9 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum } // Reorder so that we have data disks first and parity disks next. - latestDisks = getOrderedDisks(latestMeta.Erasure.Distribution, latestDisks) - outDatedDisks = getOrderedDisks(latestMeta.Erasure.Distribution, outDatedDisks) - partsMetadata = getOrderedPartsMetadata(latestMeta.Erasure.Distribution, partsMetadata) + latestDisks = shuffleDisks(latestDisks, latestMeta.Erasure.Distribution) + outDatedDisks = shuffleDisks(outDatedDisks, latestMeta.Erasure.Distribution) + partsMetadata = shufflePartsMetadata(partsMetadata, latestMeta.Erasure.Distribution) // We write at temporary location and then rename to fianal location. tmpID := mustGetUUID() diff --git a/cmd/xl-v1-multipart.go b/cmd/xl-v1-multipart.go index ff166e05d..c456fd22d 100644 --- a/cmd/xl-v1-multipart.go +++ b/cmd/xl-v1-multipart.go @@ -544,7 +544,7 @@ func (xl xlObjects) CopyObjectPart(srcBucket, srcObject, dstBucket, dstObject, u pipeReader, pipeWriter := io.Pipe() go func() { - startOffset := int64(0) // Read the whole file. + var startOffset int64 // Read the whole file. if gerr := xl.GetObject(srcBucket, srcObject, startOffset, length, pipeWriter); gerr != nil { errorIf(gerr, "Unable to read %s of the object `%s/%s`.", srcBucket, srcObject) pipeWriter.CloseWithError(toObjectErr(gerr, srcBucket, srcObject)) @@ -607,8 +607,7 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s return PartInfo{}, err } - onlineDisks = getOrderedDisks(xlMeta.Erasure.Distribution, onlineDisks) - _ = getOrderedPartsMetadata(xlMeta.Erasure.Distribution, partsMetadata) + onlineDisks = shuffleDisks(onlineDisks, xlMeta.Erasure.Distribution) // Need a unique name for the part being written in minioMetaBucket to // accommodate concurrent PutObjectPart requests @@ -919,10 +918,10 @@ func (xl xlObjects) CompleteMultipartUpload(bucket string, object string, upload } // Order online disks in accordance with distribution order. - onlineDisks = getOrderedDisks(xlMeta.Erasure.Distribution, onlineDisks) + onlineDisks = shuffleDisks(onlineDisks, xlMeta.Erasure.Distribution) // Order parts metadata in accordance with distribution order. - partsMetadata = getOrderedPartsMetadata(xlMeta.Erasure.Distribution, partsMetadata) + partsMetadata = shufflePartsMetadata(partsMetadata, xlMeta.Erasure.Distribution) // Save current xl meta for validation. var currentXLMeta = xlMeta diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index c544e93da..1316670e3 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -58,7 +58,7 @@ func (xl xlObjects) CopyObject(srcBucket, srcObject, dstBucket, dstObject string } // Reorder online disks based on erasure distribution order. - onlineDisks = getOrderedDisks(xlMeta.Erasure.Distribution, onlineDisks) + onlineDisks = shuffleDisks(onlineDisks, xlMeta.Erasure.Distribution) // Length of the file to read. length := xlMeta.Stat.Size @@ -106,7 +106,7 @@ func (xl xlObjects) CopyObject(srcBucket, srcObject, dstBucket, dstObject string pipeReader, pipeWriter := io.Pipe() go func() { - startOffset := int64(0) // Read the whole file. + var startOffset int64 // Read the whole file. if gerr := xl.GetObject(srcBucket, srcObject, startOffset, length, pipeWriter); gerr != nil { errorIf(gerr, "Unable to read %s of the object `%s/%s`.", srcBucket, srcObject) pipeWriter.CloseWithError(toObjectErr(gerr, srcBucket, srcObject)) @@ -163,10 +163,10 @@ func (xl xlObjects) GetObject(bucket, object string, startOffset int64, length i } // Reorder online disks based on erasure distribution order. - onlineDisks = getOrderedDisks(xlMeta.Erasure.Distribution, onlineDisks) + onlineDisks = shuffleDisks(onlineDisks, xlMeta.Erasure.Distribution) // Reorder parts metadata based on erasure distribution order. - metaArr = getOrderedPartsMetadata(xlMeta.Erasure.Distribution, metaArr) + metaArr = shufflePartsMetadata(metaArr, xlMeta.Erasure.Distribution) // For negative length read everything. if length < 0 { @@ -242,7 +242,7 @@ func (xl xlObjects) GetObject(bucket, object string, startOffset int64, length i } } - totalBytesRead := int64(0) + var totalBytesRead int64 chunkSize := getChunkSize(xlMeta.Erasure.BlockSize, xlMeta.Erasure.DataBlocks) pool := bpool.NewBytePool(chunkSize, len(onlineDisks)) @@ -525,7 +525,7 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io. } // Order disks according to erasure distribution - onlineDisks := getOrderedDisks(partsMetadata[0].Erasure.Distribution, xl.storageDisks) + onlineDisks := shuffleDisks(xl.storageDisks, partsMetadata[0].Erasure.Distribution) // Delete temporary object in the event of failure. // If PutObject succeeded there would be no temporary @@ -533,7 +533,7 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io. defer xl.deleteObject(minioMetaTmpBucket, tempObj) // Total size of the written object - sizeWritten := int64(0) + var sizeWritten int64 // Read data and split into parts - similar to multipart mechanism for partIdx := 1; ; partIdx++ { @@ -550,9 +550,10 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io. return ObjectInfo{}, toObjectErr(err, bucket, object) } - // Prepare file for eventual optimization in the disk + // Hint the filesystem to pre-allocate one continuous large block. + // This is only an optimization. if curPartSize > 0 { - // Calculate the real size of the part in the disk and prepare it for eventual optimization + // Calculate the real size of the part in the disk. actualSize := xl.sizeOnDisk(curPartSize, xlMeta.Erasure.BlockSize, xlMeta.Erasure.DataBlocks) for _, disk := range onlineDisks { if disk != nil { diff --git a/cmd/xl-v1-utils.go b/cmd/xl-v1-utils.go index ecedbad1e..4faf67d74 100644 --- a/cmd/xl-v1-utils.go +++ b/cmd/xl-v1-utils.go @@ -306,26 +306,34 @@ func readAllXLMetadata(disks []StorageAPI, bucket, object string) ([]xlMetaV1, [ return metadataArray, errs } -// Return ordered partsMetadata depending on distribution. -func getOrderedPartsMetadata(distribution []int, partsMetadata []xlMetaV1) (orderedPartsMetadata []xlMetaV1) { - orderedPartsMetadata = make([]xlMetaV1, len(partsMetadata)) +// Return shuffled partsMetadata depending on distribution. +func shufflePartsMetadata(partsMetadata []xlMetaV1, distribution []int) (shuffledPartsMetadata []xlMetaV1) { + if distribution == nil { + return partsMetadata + } + shuffledPartsMetadata = make([]xlMetaV1, len(partsMetadata)) + // Shuffle slice xl metadata for expected distribution. for index := range partsMetadata { blockIndex := distribution[index] - orderedPartsMetadata[blockIndex-1] = partsMetadata[index] + shuffledPartsMetadata[blockIndex-1] = partsMetadata[index] } - return orderedPartsMetadata + return shuffledPartsMetadata } -// getOrderedDisks - get ordered disks from erasure distribution. -// returns ordered slice of disks from their actual distribution. -func getOrderedDisks(distribution []int, disks []StorageAPI) (orderedDisks []StorageAPI) { - orderedDisks = make([]StorageAPI, len(disks)) - // From disks gets ordered disks. +// shuffleDisks - shuffle input disks slice depending on the +// erasure distribution. return shuffled slice of disks with +// their expected distribution. +func shuffleDisks(disks []StorageAPI, distribution []int) (shuffledDisks []StorageAPI) { + if distribution == nil { + return disks + } + shuffledDisks = make([]StorageAPI, len(disks)) + // Shuffle disks for expected distribution. for index := range disks { blockIndex := distribution[index] - orderedDisks[blockIndex-1] = disks[index] + shuffledDisks[blockIndex-1] = disks[index] } - return orderedDisks + return shuffledDisks } // Errors specifically generated by getPartSizeFromIdx function. diff --git a/cmd/xl-v1-utils_test.go b/cmd/xl-v1-utils_test.go index bf6f2205b..80901b703 100644 --- a/cmd/xl-v1-utils_test.go +++ b/cmd/xl-v1-utils_test.go @@ -383,3 +383,51 @@ func TestGetPartSizeFromIdx(t *testing.T) { } } } + +func TestShuffleDisks(t *testing.T) { + nDisks := 16 + disks, err := getRandomDisks(nDisks) + if err != nil { + t.Fatal(err) + } + endpoints, err := parseStorageEndpoints(disks) + if err != nil { + t.Fatal(err) + } + objLayer, _, err := initObjectLayer(endpoints) + if err != nil { + removeRoots(disks) + t.Fatal(err) + } + defer removeRoots(disks) + xl := objLayer.(*xlObjects) + testShuffleDisks(t, xl) +} + +// Test shuffleDisks which returns shuffled slice of disks for their actual distribution. +func testShuffleDisks(t *testing.T, xl *xlObjects) { + disks := xl.storageDisks + distribution := []int{16, 14, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7, 9, 11, 13, 15} + shuffledDisks := shuffleDisks(disks, distribution) + // From the "distribution" above you can notice that: + // 1st data block is in the 9th disk (i.e distribution index 8) + // 2nd data block is in the 8th disk (i.e distribution index 7) and so on. + if shuffledDisks[0] != disks[8] || + shuffledDisks[1] != disks[7] || + shuffledDisks[2] != disks[9] || + shuffledDisks[3] != disks[6] || + shuffledDisks[4] != disks[10] || + shuffledDisks[5] != disks[5] || + shuffledDisks[6] != disks[11] || + shuffledDisks[7] != disks[4] || + shuffledDisks[8] != disks[12] || + shuffledDisks[9] != disks[3] || + shuffledDisks[10] != disks[13] || + shuffledDisks[11] != disks[2] || + shuffledDisks[12] != disks[14] || + shuffledDisks[13] != disks[1] || + shuffledDisks[14] != disks[15] || + shuffledDisks[15] != disks[0] { + t.Errorf("shuffleDisks returned incorrect order.") + } +} From cff45db1b9a7e00f57ad15b45ad9ce296cad3d54 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 24 Feb 2017 14:19:20 -0800 Subject: [PATCH 24/94] cli: Use ADDRESS:PORT to clarify --address behavior (#3803) Currently we document as IP:PORT which doesn't provide if someone can use HOSTNAME:PORT. This is a change to clarify this by calling it as ADDRESS:PORT which encompasses both a HOSTNAME and an IP. Fixes #3799 --- cmd/server-main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/server-main.go b/cmd/server-main.go index d4b4a7852..3222c07ce 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -36,7 +36,7 @@ var serverFlags = []cli.Flag{ cli.StringFlag{ Name: "address", Value: ":9000", - Usage: `Bind to a specific IP:PORT. Defaults to ":9000".`, + Usage: "Bind to a specific ADDRESS:PORT, ADDRESS can be an IP or hostname.", }, } @@ -66,7 +66,7 @@ EXAMPLES: 1. Start minio server on "/home/shared" directory. $ {{.HelpName}} /home/shared - 2. Start minio server bound to a specific IP:PORT. + 2. Start minio server bound to a specific ADDRESS:PORT. $ {{.HelpName}} --address 192.168.1.101:9000 /home/shared 3. Start erasure coded minio server on a 12 disks server. From 70d2cb5f4d5d8453c01038ed086e7bb92353b21b Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 24 Feb 2017 18:26:56 -0800 Subject: [PATCH 25/94] rpc: Remove time check for each RPC calls. (#3804) This removal comes to avoid some redundant requirements which are adding more problems on a production setup. Here are the list of checks for time as they happen - Fresh connect (during server startup) - CORRECT - A reconnect after network disconnect - CORRECT - For each RPC call - INCORRECT. Verifying time for each RPC aggravates a situation where a RPC call is rejected in a sequence of events due to enough load on a production setup. 3 second might not be enough time window for the call to be initiated and received by the server. --- cmd/admin-rpc-server_test.go | 11 ++++------- cmd/auth-rpc-client.go | 3 --- cmd/lock-rpc-server_test.go | 21 --------------------- cmd/rpc-common.go | 14 -------------- cmd/s3-peer-rpc-handlers_test.go | 3 +-- cmd/storage-rpc-server_test.go | 13 ------------- 6 files changed, 5 insertions(+), 60 deletions(-) diff --git a/cmd/admin-rpc-server_test.go b/cmd/admin-rpc-server_test.go index dbc097a8d..44705a7a2 100644 --- a/cmd/admin-rpc-server_test.go +++ b/cmd/admin-rpc-server_test.go @@ -53,7 +53,7 @@ func testAdminCmd(cmd cmdType, t *testing.T) { <-globalServiceSignalCh }() - ga := AuthRPCArgs{AuthToken: reply.AuthToken, RequestTime: time.Now().UTC()} + ga := AuthRPCArgs{AuthToken: reply.AuthToken} genReply := AuthRPCReply{} switch cmd { case restartCmd: @@ -108,8 +108,7 @@ func TestReInitDisks(t *testing.T) { } authArgs := AuthRPCArgs{ - AuthToken: reply.AuthToken, - RequestTime: time.Now().UTC(), + AuthToken: reply.AuthToken, } authReply := AuthRPCReply{} @@ -134,8 +133,7 @@ func TestReInitDisks(t *testing.T) { } authArgs = AuthRPCArgs{ - AuthToken: fsReply.AuthToken, - RequestTime: time.Now().UTC(), + AuthToken: fsReply.AuthToken, } authReply = AuthRPCReply{} // Attempt ReInitDisks service on a FS backend. @@ -171,8 +169,7 @@ func TestGetConfig(t *testing.T) { } authArgs := AuthRPCArgs{ - AuthToken: reply.AuthToken, - RequestTime: time.Now().UTC(), + AuthToken: reply.AuthToken, } configReply := ConfigReply{} diff --git a/cmd/auth-rpc-client.go b/cmd/auth-rpc-client.go index f59fb8b5f..c8385badf 100644 --- a/cmd/auth-rpc-client.go +++ b/cmd/auth-rpc-client.go @@ -111,7 +111,6 @@ func (authClient *AuthRPCClient) Login() (err error) { // call makes a RPC call after logs into the server. func (authClient *AuthRPCClient) call(serviceMethod string, args interface { SetAuthToken(authToken string) - SetRequestTime(requestTime time.Time) }, reply interface{}) (err error) { // On successful login, execute RPC call. if err = authClient.Login(); err == nil { @@ -119,7 +118,6 @@ func (authClient *AuthRPCClient) call(serviceMethod string, args interface { // Set token and timestamp before the rpc call. args.SetAuthToken(authClient.authToken) authClient.Unlock() - args.SetRequestTime(time.Now().UTC()) // Do RPC call. err = authClient.rpcClient.Call(serviceMethod, args, reply) @@ -130,7 +128,6 @@ func (authClient *AuthRPCClient) call(serviceMethod string, args interface { // Call executes RPC call till success or globalAuthRPCRetryThreshold on ErrShutdown. func (authClient *AuthRPCClient) Call(serviceMethod string, args interface { SetAuthToken(authToken string) - SetRequestTime(requestTime time.Time) }, reply interface{}) (err error) { // Done channel is used to close any lingering retry routine, as soon diff --git a/cmd/lock-rpc-server_test.go b/cmd/lock-rpc-server_test.go index 3251a37bb..90661ca9b 100644 --- a/cmd/lock-rpc-server_test.go +++ b/cmd/lock-rpc-server_test.go @@ -85,7 +85,6 @@ func TestLockRpcServerLock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la.SetAuthToken(token) - la.SetRequestTime(time.Now().UTC()) // Claim a lock var result bool @@ -119,7 +118,6 @@ func TestLockRpcServerLock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la2.SetAuthToken(token) - la2.SetRequestTime(time.Now().UTC()) err = locker.Lock(&la2, &result) if err != nil { @@ -143,7 +141,6 @@ func TestLockRpcServerUnlock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la.SetAuthToken(token) - la.SetRequestTime(time.Now().UTC()) // First test return of error when attempting to unlock a lock that does not exist var result bool @@ -153,7 +150,6 @@ func TestLockRpcServerUnlock(t *testing.T) { } // Create lock (so that we can release) - la.SetRequestTime(time.Now().UTC()) err = locker.Lock(&la, &result) if err != nil { t.Errorf("Expected %#v, got %#v", nil, err) @@ -162,7 +158,6 @@ func TestLockRpcServerUnlock(t *testing.T) { } // Finally test successful release of lock - la.SetRequestTime(time.Now().UTC()) err = locker.Unlock(&la, &result) if err != nil { t.Errorf("Expected %#v, got %#v", nil, err) @@ -191,7 +186,6 @@ func TestLockRpcServerRLock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la.SetAuthToken(token) - la.SetRequestTime(time.Now().UTC()) // Claim a lock var result bool @@ -225,7 +219,6 @@ func TestLockRpcServerRLock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la2.SetAuthToken(token) - la2.SetRequestTime(time.Now().UTC()) err = locker.RLock(&la2, &result) if err != nil { @@ -249,7 +242,6 @@ func TestLockRpcServerRUnlock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la.SetAuthToken(token) - la.SetRequestTime(time.Now().UTC()) // First test return of error when attempting to unlock a read-lock that does not exist var result bool @@ -259,7 +251,6 @@ func TestLockRpcServerRUnlock(t *testing.T) { } // Create first lock ... (so that we can release) - la.SetRequestTime(time.Now().UTC()) err = locker.RLock(&la, &result) if err != nil { t.Errorf("Expected %#v, got %#v", nil, err) @@ -275,7 +266,6 @@ func TestLockRpcServerRUnlock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la2.SetAuthToken(token) - la2.SetRequestTime(time.Now().UTC()) // ... and create a second lock on same resource err = locker.RLock(&la2, &result) @@ -286,7 +276,6 @@ func TestLockRpcServerRUnlock(t *testing.T) { } // Test successful release of first read lock - la.SetRequestTime(time.Now().UTC()) err = locker.RUnlock(&la, &result) if err != nil { t.Errorf("Expected %#v, got %#v", nil, err) @@ -311,7 +300,6 @@ func TestLockRpcServerRUnlock(t *testing.T) { } // Finally test successful release of second (and last) read lock - la2.SetRequestTime(time.Now().UTC()) err = locker.RUnlock(&la2, &result) if err != nil { t.Errorf("Expected %#v, got %#v", nil, err) @@ -340,7 +328,6 @@ func TestLockRpcServerForceUnlock(t *testing.T) { ServiceEndpoint: "rpc-path", }) laForce.SetAuthToken(token) - laForce.SetRequestTime(time.Now().UTC()) // First test that UID should be empty var result bool @@ -351,7 +338,6 @@ func TestLockRpcServerForceUnlock(t *testing.T) { // Then test force unlock of a lock that does not exist (not returning an error) laForce.LockArgs.UID = "" - laForce.SetRequestTime(time.Now().UTC()) err = locker.ForceUnlock(&laForce, &result) if err != nil { t.Errorf("Expected no error, got %#v", err) @@ -364,7 +350,6 @@ func TestLockRpcServerForceUnlock(t *testing.T) { ServiceEndpoint: "rpc-path", }) la.SetAuthToken(token) - la.SetRequestTime(time.Now().UTC()) // Create lock ... (so that we can force unlock) err = locker.Lock(&la, &result) @@ -375,14 +360,12 @@ func TestLockRpcServerForceUnlock(t *testing.T) { } // Forcefully unlock the lock (not returning an error) - laForce.SetRequestTime(time.Now().UTC()) err = locker.ForceUnlock(&laForce, &result) if err != nil { t.Errorf("Expected no error, got %#v", err) } // Try to get lock again (should be granted) - la.SetRequestTime(time.Now().UTC()) err = locker.Lock(&la, &result) if err != nil { t.Errorf("Expected %#v, got %#v", nil, err) @@ -391,7 +374,6 @@ func TestLockRpcServerForceUnlock(t *testing.T) { } // Finally forcefully unlock the lock once again - laForce.SetRequestTime(time.Now().UTC()) err = locker.ForceUnlock(&laForce, &result) if err != nil { t.Errorf("Expected no error, got %#v", err) @@ -410,7 +392,6 @@ func TestLockRpcServerExpired(t *testing.T) { ServiceEndpoint: "rpc-path", }) la.SetAuthToken(token) - la.SetRequestTime(time.Now().UTC()) // Unknown lock at server will return expired = true var expired bool @@ -425,7 +406,6 @@ func TestLockRpcServerExpired(t *testing.T) { // Create lock (so that we can test that it is not expired) var result bool - la.SetRequestTime(time.Now().UTC()) err = locker.Lock(&la, &result) if err != nil { t.Errorf("Expected %#v, got %#v", nil, err) @@ -433,7 +413,6 @@ func TestLockRpcServerExpired(t *testing.T) { t.Errorf("Expected %#v, got %#v", true, result) } - la.SetRequestTime(time.Now().UTC()) err = locker.Expired(&la, &expired) if err != nil { t.Errorf("Expected no error, got %#v", err) diff --git a/cmd/rpc-common.go b/cmd/rpc-common.go index eeaa5e0c3..876f335d6 100644 --- a/cmd/rpc-common.go +++ b/cmd/rpc-common.go @@ -37,10 +37,6 @@ func isRequestTimeAllowed(requestTime time.Time) bool { type AuthRPCArgs struct { // Authentication token to be verified by the server for every RPC call. AuthToken string - - // Request time to be verified by the server for every RPC call. - // This is an addition check over Authentication token for time drifting. - RequestTime time.Time } // SetAuthToken - sets the token to the supplied value. @@ -48,11 +44,6 @@ func (args *AuthRPCArgs) SetAuthToken(authToken string) { args.AuthToken = authToken } -// SetRequestTime - sets the requestTime to the supplied value. -func (args *AuthRPCArgs) SetRequestTime(requestTime time.Time) { - args.RequestTime = requestTime -} - // IsAuthenticated - validated whether this auth RPC args are already authenticated or not. func (args AuthRPCArgs) IsAuthenticated() error { // Check whether the token is valid @@ -60,11 +51,6 @@ func (args AuthRPCArgs) IsAuthenticated() error { return errInvalidToken } - // Check if the request time is within the allowed skew limit. - if !isRequestTimeAllowed(args.RequestTime) { - return errServerTimeMismatch - } - // Good to go. return nil } diff --git a/cmd/s3-peer-rpc-handlers_test.go b/cmd/s3-peer-rpc-handlers_test.go index 4e7378cb9..825539940 100644 --- a/cmd/s3-peer-rpc-handlers_test.go +++ b/cmd/s3-peer-rpc-handlers_test.go @@ -20,7 +20,6 @@ import ( "encoding/json" "path" "testing" - "time" ) type TestRPCS3PeerSuite struct { @@ -62,7 +61,7 @@ func TestS3PeerRPC(t *testing.T) { // Test S3 RPC handlers func (s *TestRPCS3PeerSuite) testS3PeerRPC(t *testing.T) { // Validate for invalid token. - args := AuthRPCArgs{AuthToken: "garbage", RequestTime: time.Now().UTC()} + args := AuthRPCArgs{AuthToken: "garbage"} rclient := newRPCClient(s.testAuthConf.serverAddr, s.testAuthConf.serviceEndpoint, false) defer rclient.Close() err := rclient.Call("S3.SetBucketNotificationPeer", &args, &AuthRPCReply{}) diff --git a/cmd/storage-rpc-server_test.go b/cmd/storage-rpc-server_test.go index 48082e8ad..9b5e001fa 100644 --- a/cmd/storage-rpc-server_test.go +++ b/cmd/storage-rpc-server_test.go @@ -98,33 +98,28 @@ func TestStorageRPCInvalidToken(t *testing.T) { } // 1. DiskInfoHandler diskInfoReply := &disk.Info{} - badAuthRPCArgs.RequestTime = time.Now().UTC() err = storageRPC.DiskInfoHandler(&badAuthRPCArgs, diskInfoReply) errorIfInvalidToken(t, err) // 2. MakeVolHandler makeVolArgs := &badGenericVolArgs - makeVolArgs.AuthRPCArgs.RequestTime = time.Now().UTC() makeVolReply := &AuthRPCReply{} err = storageRPC.MakeVolHandler(makeVolArgs, makeVolReply) errorIfInvalidToken(t, err) // 3. ListVolsHandler listVolReply := &ListVolsReply{} - badAuthRPCArgs.RequestTime = time.Now().UTC() err = storageRPC.ListVolsHandler(&badAuthRPCArgs, listVolReply) errorIfInvalidToken(t, err) // 4. StatVolHandler statVolReply := &VolInfo{} statVolArgs := &badGenericVolArgs - statVolArgs.AuthRPCArgs.RequestTime = time.Now().UTC() err = storageRPC.StatVolHandler(statVolArgs, statVolReply) errorIfInvalidToken(t, err) // 5. DeleteVolHandler deleteVolArgs := &badGenericVolArgs - deleteVolArgs.AuthRPCArgs.RequestTime = time.Now().UTC() deleteVolReply := &AuthRPCReply{} err = storageRPC.DeleteVolHandler(deleteVolArgs, deleteVolReply) errorIfInvalidToken(t, err) @@ -133,7 +128,6 @@ func TestStorageRPCInvalidToken(t *testing.T) { statFileArgs := &StatFileArgs{ AuthRPCArgs: badAuthRPCArgs, } - statFileArgs.AuthRPCArgs.RequestTime = time.Now().UTC() statReply := &FileInfo{} err = storageRPC.StatFileHandler(statFileArgs, statReply) errorIfInvalidToken(t, err) @@ -142,7 +136,6 @@ func TestStorageRPCInvalidToken(t *testing.T) { listDirArgs := &ListDirArgs{ AuthRPCArgs: badAuthRPCArgs, } - listDirArgs.AuthRPCArgs.RequestTime = time.Now().UTC() listDirReply := &[]string{} err = storageRPC.ListDirHandler(listDirArgs, listDirReply) errorIfInvalidToken(t, err) @@ -151,13 +144,11 @@ func TestStorageRPCInvalidToken(t *testing.T) { readFileArgs := &ReadFileArgs{ AuthRPCArgs: badAuthRPCArgs, } - readFileArgs.AuthRPCArgs.RequestTime = time.Now().UTC() readFileReply := &[]byte{} err = storageRPC.ReadAllHandler(readFileArgs, readFileReply) errorIfInvalidToken(t, err) // 9. ReadFileHandler - readFileArgs.AuthRPCArgs.RequestTime = time.Now().UTC() err = storageRPC.ReadFileHandler(readFileArgs, readFileReply) errorIfInvalidToken(t, err) @@ -165,7 +156,6 @@ func TestStorageRPCInvalidToken(t *testing.T) { prepFileArgs := &PrepareFileArgs{ AuthRPCArgs: badAuthRPCArgs, } - prepFileArgs.AuthRPCArgs.RequestTime = time.Now().UTC() prepFileReply := &AuthRPCReply{} err = storageRPC.PrepareFileHandler(prepFileArgs, prepFileReply) errorIfInvalidToken(t, err) @@ -174,7 +164,6 @@ func TestStorageRPCInvalidToken(t *testing.T) { appendArgs := &AppendFileArgs{ AuthRPCArgs: badAuthRPCArgs, } - appendArgs.AuthRPCArgs.RequestTime = time.Now().UTC() appendReply := &AuthRPCReply{} err = storageRPC.AppendFileHandler(appendArgs, appendReply) errorIfInvalidToken(t, err) @@ -183,7 +172,6 @@ func TestStorageRPCInvalidToken(t *testing.T) { delFileArgs := &DeleteFileArgs{ AuthRPCArgs: badAuthRPCArgs, } - delFileArgs.AuthRPCArgs.RequestTime = time.Now().UTC() delFileRely := &AuthRPCReply{} err = storageRPC.DeleteFileHandler(delFileArgs, delFileRely) errorIfInvalidToken(t, err) @@ -192,7 +180,6 @@ func TestStorageRPCInvalidToken(t *testing.T) { renameArgs := &RenameFileArgs{ AuthRPCArgs: badAuthRPCArgs, } - renameArgs.AuthRPCArgs.RequestTime = time.Now().UTC() renameReply := &AuthRPCReply{} err = storageRPC.RenameFileHandler(renameArgs, renameReply) errorIfInvalidToken(t, err) From 69777b654e14665b2ff9312b2f9e5487ea347cff Mon Sep 17 00:00:00 2001 From: Bala FA Date: Sat, 25 Feb 2017 07:57:52 +0530 Subject: [PATCH 26/94] event: use common initialization logic (#3798) Previously creating and adding targets for each notification type was repeated. This patch fixes it. --- cmd/event-notifier.go | 144 ++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 89 deletions(-) diff --git a/cmd/event-notifier.go b/cmd/event-notifier.go index 9db12cccf..1aee1c626 100644 --- a/cmd/event-notifier.go +++ b/cmd/event-notifier.go @@ -537,6 +537,28 @@ func loadAllBucketNotifications(objAPI ObjectLayer) (map[string]*notificationCon return nConfigs, lConfigs, nil } +// addQueueTarget - calls newTargetFunc function and adds its returned value to queueTargets +func addQueueTarget(queueTargets map[string]*logrus.Logger, + accountID, queueType string, + newTargetFunc func(string) (*logrus.Logger, error)) (string, error) { + + // Construct the queue ARN for AMQP. + queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueType + + // Queue target if already initialized we move to the next ARN. + if _, ok := queueTargets[queueARN]; ok { + return queueARN, nil + } + + // Using accountID we can now initialize a new AMQP logrus instance. + logger, err := newTargetFunc(accountID) + if err == nil { + queueTargets[queueARN] = logger + } + + return queueARN, err +} + // Loads all queue targets, initializes each queueARNs depending on their config. // Each instance of queueARN registers its own logrus to communicate with the // queue service. QueueARN once initialized is not initialized again for the @@ -548,54 +570,37 @@ func loadAllQueueTargets() (map[string]*logrus.Logger, error) { if !amqpN.Enable { continue } - // Construct the queue ARN for AMQP. - queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueTypeAMQP - // Queue target if already initialized we move to the next ARN. - _, ok := queueTargets[queueARN] - if ok { - continue - } - // Using accountID we can now initialize a new AMQP logrus instance. - amqpLog, err := newAMQPNotify(accountID) - if err != nil { - // Encapsulate network error to be more informative. + + if queueARN, err := addQueueTarget(queueTargets, accountID, queueTypeAMQP, newAMQPNotify); err != nil { if _, ok := err.(net.Error); ok { - return nil, &net.OpError{ + err = &net.OpError{ Op: "Connecting to " + queueARN, Net: "tcp", Err: err, } } + return nil, err } - queueTargets[queueARN] = amqpLog } + // Load all nats targets, initialize their respective loggers. for accountID, natsN := range serverConfig.Notify.GetNATS() { if !natsN.Enable { continue } - // Construct the queue ARN for NATS. - queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueTypeNATS - // Queue target if already initialized we move to the next ARN. - _, ok := queueTargets[queueARN] - if ok { - continue - } - // Using accountID we can now initialize a new NATS logrus instance. - natsLog, err := newNATSNotify(accountID) - if err != nil { - // Encapsulate network error to be more informative. + + if queueARN, err := addQueueTarget(queueTargets, accountID, queueTypeNATS, newNATSNotify); err != nil { if _, ok := err.(net.Error); ok { - return nil, &net.OpError{ + err = &net.OpError{ Op: "Connecting to " + queueARN, Net: "tcp", Err: err, } } + return nil, err } - queueTargets[queueARN] = natsLog } // Load redis targets, initialize their respective loggers. @@ -603,27 +608,18 @@ func loadAllQueueTargets() (map[string]*logrus.Logger, error) { if !redisN.Enable { continue } - // Construct the queue ARN for Redis. - queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueTypeRedis - // Queue target if already initialized we move to the next ARN. - _, ok := queueTargets[queueARN] - if ok { - continue - } - // Using accountID we can now initialize a new Redis logrus instance. - redisLog, err := newRedisNotify(accountID) - if err != nil { - // Encapsulate network error to be more informative. + + if queueARN, err := addQueueTarget(queueTargets, accountID, queueTypeRedis, newRedisNotify); err != nil { if _, ok := err.(net.Error); ok { - return nil, &net.OpError{ + err = &net.OpError{ Op: "Connecting to " + queueARN, Net: "tcp", Err: err, } } + return nil, err } - queueTargets[queueARN] = redisLog } // Load Webhook targets, initialize their respective loggers. @@ -631,20 +627,10 @@ func loadAllQueueTargets() (map[string]*logrus.Logger, error) { if !webhookN.Enable { continue } - // Construct the queue ARN for Webhook. - queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueTypeWebhook - _, ok := queueTargets[queueARN] - if ok { - continue - } - - // Using accountID we can now initialize a new Webhook logrus instance. - webhookLog, err := newWebhookNotify(accountID) - if err != nil { + if _, err := addQueueTarget(queueTargets, accountID, queueTypeWebhook, newWebhookNotify); err != nil { return nil, err } - queueTargets[queueARN] = webhookLog } // Load elastic targets, initialize their respective loggers. @@ -652,25 +638,18 @@ func loadAllQueueTargets() (map[string]*logrus.Logger, error) { if !elasticN.Enable { continue } - // Construct the queue ARN for Elastic. - queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueTypeElastic - _, ok := queueTargets[queueARN] - if ok { - continue - } - // Using accountID we can now initialize a new ElasticSearch logrus instance. - elasticLog, err := newElasticNotify(accountID) - if err != nil { - // Encapsulate network error to be more informative. + + if queueARN, err := addQueueTarget(queueTargets, accountID, queueTypeElastic, newElasticNotify); err != nil { if _, ok := err.(net.Error); ok { - return nil, &net.OpError{ - Op: "Connecting to " + queueARN, Net: "tcp", + err = &net.OpError{ + Op: "Connecting to " + queueARN, + Net: "tcp", Err: err, } } + return nil, err } - queueTargets[queueARN] = elasticLog } // Load PostgreSQL targets, initialize their respective loggers. @@ -678,50 +657,37 @@ func loadAllQueueTargets() (map[string]*logrus.Logger, error) { if !pgN.Enable { continue } - // Construct the queue ARN for Postgres. - queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueTypePostgreSQL - _, ok := queueTargets[queueARN] - if ok { - continue - } - // Using accountID initialize a new Postgresql logrus instance. - pgLog, err := newPostgreSQLNotify(accountID) - if err != nil { - // Encapsulate network error to be more informative. + + if queueARN, err := addQueueTarget(queueTargets, accountID, queueTypePostgreSQL, newPostgreSQLNotify); err != nil { if _, ok := err.(net.Error); ok { - return nil, &net.OpError{ - Op: "Connecting to " + queueARN, Net: "tcp", + err = &net.OpError{ + Op: "Connecting to " + queueARN, + Net: "tcp", Err: err, } } + return nil, err } - queueTargets[queueARN] = pgLog } + // Load Kafka targets, initialize their respective loggers. for accountID, kafkaN := range serverConfig.Notify.GetKafka() { if !kafkaN.Enable { continue } - // Construct the queue ARN for Kafka. - queueARN := minioSqs + serverConfig.GetRegion() + ":" + accountID + ":" + queueTypeKafka - _, ok := queueTargets[queueARN] - if ok { - continue - } - // Using accountID initialize a new Kafka logrus instance. - kafkaLog, err := newKafkaNotify(accountID) - if err != nil { - // Encapsulate network error to be more informative. + + if queueARN, err := addQueueTarget(queueTargets, accountID, queueTypeKafka, newKafkaNotify); err != nil { if _, ok := err.(net.Error); ok { - return nil, &net.OpError{ - Op: "Connecting to " + queueARN, Net: "tcp", + err = &net.OpError{ + Op: "Connecting to " + queueARN, + Net: "tcp", Err: err, } } + return nil, err } - queueTargets[queueARN] = kafkaLog } // Successfully initialized queue targets. From 461b2bbd37c26869445ee86f160ae6cb72c31e26 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Sat, 25 Feb 2017 20:06:08 +0100 Subject: [PATCH 27/94] admin: Move SetCredentials from Service to Generic (#3805) Setting credentials doesn't belong to service management API anymore. --- pkg/madmin/API.md | 42 +++++++++-- ...-set-credentials.go => set-credentials.go} | 2 +- pkg/madmin/generic-commands.go | 72 +++++++++++++++++++ pkg/madmin/service-commands.go | 49 ------------- 4 files changed, 108 insertions(+), 57 deletions(-) rename pkg/madmin/examples/{service-set-credentials.go => set-credentials.go} (93%) create mode 100644 pkg/madmin/generic-commands.go diff --git a/pkg/madmin/API.md b/pkg/madmin/API.md index 84ba1e924..361034092 100644 --- a/pkg/madmin/API.md +++ b/pkg/madmin/API.md @@ -36,13 +36,13 @@ func main() { ``` -| Service operations|LockInfo operations|Healing operations|Config operations| -|:---|:---|:---|:---| -|[`ServiceStatus`](#ServiceStatus)| [`ListLocks`](#ListLocks)| [`ListObjectsHeal`](#ListObjectsHeal)|[`GetConfig`](#GetConfig)| -|[`ServiceRestart`](#ServiceRestart)| [`ClearLocks`](#ClearLocks)| [`ListBucketsHeal`](#ListBucketsHeal)|| -| | |[`HealBucket`](#HealBucket) || -| | |[`HealObject`](#HealObject)|| -| | |[`HealFormat`](#HealFormat)|| +| Service operations|LockInfo operations|Healing operations|Config operations| Misc | +|:---|:---|:---|:---|:---| +|[`ServiceStatus`](#ServiceStatus)| [`ListLocks`](#ListLocks)| [`ListObjectsHeal`](#ListObjectsHeal)|[`GetConfig`](#GetConfig)| [`SetCredentials`](#SetCredentials)| +|[`ServiceRestart`](#ServiceRestart)| [`ClearLocks`](#ClearLocks)| [`ListBucketsHeal`](#ListBucketsHeal)||| +| | |[`HealBucket`](#HealBucket) ||| +| | |[`HealObject`](#HealObject)||| +| | |[`HealFormat`](#HealFormat)||| ## 1. Constructor @@ -119,6 +119,9 @@ If successful restarts the running minio service, for distributed setup restarts log.Printf("Success") ``` + +## 3. Lock operations + ### ListLocks(bucket, prefix string, duration time.Duration) ([]VolumeLockInfo, error) If successful returns information on the list of locks held on ``bucket`` matching ``prefix`` for longer than ``duration`` seconds. @@ -149,6 +152,8 @@ __Example__ ``` +## 4. Heal operations + ### ListObjectsHeal(bucket, prefix string, recursive bool, doneCh <-chan struct{}) (<-chan ObjectInfo, error) If successful returns information on the list of objects that need healing in ``bucket`` matching ``prefix``. @@ -272,6 +277,9 @@ __Example__ log.Println("successfully healed storage format on available disks.") ``` + +## 5. Config operations + ### GetConfig() ([]byte, error) Get config.json of a minio setup. @@ -293,3 +301,23 @@ __Example__ log.Println("config received successfully: ", string(buf.Bytes())) ``` + +## 6. Misc operations + + + +### SetCredentials() error +Set new credentials of a Minio setup. + +__Example__ + +``` go + err = madmClnt.SetCredentials("YOUR-NEW-ACCESSKEY", "YOUR-NEW-SECRETKEY") + if err != nil { + log.Fatalln(err) + } + log.Println("New credentials successfully set.") + +``` + + diff --git a/pkg/madmin/examples/service-set-credentials.go b/pkg/madmin/examples/set-credentials.go similarity index 93% rename from pkg/madmin/examples/service-set-credentials.go rename to pkg/madmin/examples/set-credentials.go index 81f0dc203..35e81b958 100644 --- a/pkg/madmin/examples/service-set-credentials.go +++ b/pkg/madmin/examples/set-credentials.go @@ -36,7 +36,7 @@ func main() { log.Fatalln(err) } - err = madmClnt.ServiceSetCredentials("YOUR-NEW-ACCESSKEY", "YOUR-NEW-SECRETKEY") + err = madmClnt.SetCredentials("YOUR-NEW-ACCESSKEY", "YOUR-NEW-SECRETKEY") if err != nil { log.Fatalln(err) } diff --git a/pkg/madmin/generic-commands.go b/pkg/madmin/generic-commands.go new file mode 100644 index 000000000..9cef94275 --- /dev/null +++ b/pkg/madmin/generic-commands.go @@ -0,0 +1,72 @@ +/* + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package madmin + +import ( + "bytes" + "encoding/xml" + "errors" + "net/http" + "net/url" +) + +// setCredsReq - xml to send to the server to set new credentials +type setCredsReq struct { + Username string `xml:"username"` + Password string `xml:"password"` +} + +// SetCredentials - Call Set Credentials API to set new access and secret keys in the specified Minio server +func (adm *AdminClient) SetCredentials(access, secret string) error { + + // Disallow sending with the server if the connection is not secure + if !adm.secure { + return errors.New("setting new credentials requires HTTPS connection to the server") + } + + // Setup new request + reqData := requestData{} + reqData.queryValues = make(url.Values) + reqData.queryValues.Set("service", "") + reqData.customHeaders = make(http.Header) + reqData.customHeaders.Set(minioAdminOpHeader, "set-credentials") + + // Setup request's body + body, err := xml.Marshal(setCredsReq{Username: access, Password: secret}) + if err != nil { + return err + } + reqData.contentBody = bytes.NewReader(body) + reqData.contentLength = int64(len(body)) + reqData.contentMD5Bytes = sumMD5(body) + reqData.contentSHA256Bytes = sum256(body) + + // Execute GET on bucket to list objects. + resp, err := adm.executeMethod("POST", reqData) + + defer closeResponse(resp) + if err != nil { + return err + } + + // Return error to the caller if http response code is different from 200 + if resp.StatusCode != http.StatusOK { + return httpRespToErrorResponse(resp) + } + return nil +} diff --git a/pkg/madmin/service-commands.go b/pkg/madmin/service-commands.go index ee22a3feb..62bf8cb42 100644 --- a/pkg/madmin/service-commands.go +++ b/pkg/madmin/service-commands.go @@ -18,10 +18,7 @@ package madmin import ( - "bytes" "encoding/json" - "encoding/xml" - "errors" "io/ioutil" "net/http" "net/url" @@ -94,49 +91,3 @@ func (adm *AdminClient) ServiceRestart() error { } return nil } - -// setCredsReq - xml to send to the server to set new credentials -type setCredsReq struct { - Username string `xml:"username"` - Password string `xml:"password"` -} - -// ServiceSetCredentials - Call Service Set Credentials API to set new access and secret keys in the specified Minio server -func (adm *AdminClient) ServiceSetCredentials(access, secret string) error { - - // Disallow sending with the server if the connection is not secure - if !adm.secure { - return errors.New("setting new credentials requires HTTPS connection to the server") - } - - // Setup new request - reqData := requestData{} - reqData.queryValues = make(url.Values) - reqData.queryValues.Set("service", "") - reqData.customHeaders = make(http.Header) - reqData.customHeaders.Set(minioAdminOpHeader, "set-credentials") - - // Setup request's body - body, err := xml.Marshal(setCredsReq{Username: access, Password: secret}) - if err != nil { - return err - } - reqData.contentBody = bytes.NewReader(body) - reqData.contentLength = int64(len(body)) - reqData.contentMD5Bytes = sumMD5(body) - reqData.contentSHA256Bytes = sum256(body) - - // Execute GET on bucket to list objects. - resp, err := adm.executeMethod("POST", reqData) - - defer closeResponse(resp) - if err != nil { - return err - } - - // Return error to the caller if http response code is different from 200 - if resp.StatusCode != http.StatusOK { - return httpRespToErrorResponse(resp) - } - return nil -} From dce0345f8f8a4654d92dbb28d46a09f19db1d26d Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Sun, 26 Feb 2017 20:58:32 +0100 Subject: [PATCH 28/94] Set disk to nil after write which needs quorum (#3795) Ignore a disk which wasn't able to successfully perform an action to avoid eventual perturbations when the disk comes back in the middle of write change. --- cmd/erasure-createfile.go | 3 +++ cmd/xl-v1-metadata.go | 4 ++++ cmd/xl-v1-multipart.go | 2 ++ cmd/xl-v1-object.go | 2 ++ 4 files changed, 11 insertions(+) diff --git a/cmd/erasure-createfile.go b/cmd/erasure-createfile.go index f95c0c18c..807684210 100644 --- a/cmd/erasure-createfile.go +++ b/cmd/erasure-createfile.go @@ -114,6 +114,7 @@ func appendFile(disks []StorageAPI, volume, path string, enBlocks [][]byte, hash // Write encoded data to quorum disks in parallel. for index, disk := range disks { if disk == nil { + wErrs[index] = traceError(errDiskNotFound) continue } wg.Add(1) @@ -123,6 +124,8 @@ func appendFile(disks []StorageAPI, volume, path string, enBlocks [][]byte, hash wErr := disk.AppendFile(volume, path, enBlocks[index]) if wErr != nil { wErrs[index] = traceError(wErr) + // Ignore disk which returned an error. + disks[index] = nil return } diff --git a/cmd/xl-v1-metadata.go b/cmd/xl-v1-metadata.go index 243dab9fe..29613e480 100644 --- a/cmd/xl-v1-metadata.go +++ b/cmd/xl-v1-metadata.go @@ -361,6 +361,8 @@ func writeUniqueXLMetadata(disks []StorageAPI, bucket, prefix string, xlMetas [] err := writeXLMetadata(disk, bucket, prefix, xlMetas[index]) if err != nil { mErrs[index] = err + // Ignore disk which returned an error. + disks[index] = nil } }(index, disk) } @@ -399,6 +401,8 @@ func writeSameXLMetadata(disks []StorageAPI, bucket, prefix string, xlMeta xlMet err := writeXLMetadata(disk, bucket, prefix, metadata) if err != nil { mErrs[index] = err + // Ignore disk which returned an error. + disks[index] = nil } }(index, disk, xlMeta) } diff --git a/cmd/xl-v1-multipart.go b/cmd/xl-v1-multipart.go index c456fd22d..2fa73630c 100644 --- a/cmd/xl-v1-multipart.go +++ b/cmd/xl-v1-multipart.go @@ -254,6 +254,8 @@ func commitXLMetadata(disks []StorageAPI, srcBucket, srcPrefix, dstBucket, dstPr rErr := disk.RenameFile(srcBucket, srcJSONFile, dstBucket, dstJSONFile) if rErr != nil { mErrs[index] = traceError(rErr) + // Ignore disk which returned an error. + disks[index] = nil return } mErrs[index] = nil diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index 1316670e3..61d582330 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -395,6 +395,8 @@ func rename(disks []StorageAPI, srcBucket, srcEntry, dstBucket, dstEntry string, err := disk.RenameFile(srcBucket, srcEntry, dstBucket, dstEntry) if err != nil && err != errFileNotFound { errs[index] = traceError(err) + // Ignore disk which returned an error. + disks[index] = nil } }(index, disk) } From c9619673fb9ff0a387f0a9ad919752a0cb1a1b6a Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Tue, 28 Feb 2017 01:10:27 +0530 Subject: [PATCH 29/94] Implement SetConfig admin API handler. (#3792) --- cmd/admin-handlers.go | 124 ++++++++++++++- cmd/admin-handlers_test.go | 253 ++++++++++++++++++++++++++++++ cmd/admin-router.go | 2 + cmd/admin-rpc-client.go | 135 +++++++++++++++- cmd/admin-rpc-server.go | 72 +++++++++ cmd/admin-rpc-server_test.go | 61 +++++++ cmd/api-errors.go | 6 + cmd/generic-handlers.go | 2 +- pkg/madmin/API.md | 35 ++++- pkg/madmin/config-commands.go | 78 ++++++++- pkg/madmin/examples/set-config.go | 156 ++++++++++++++++++ 11 files changed, 912 insertions(+), 12 deletions(-) create mode 100644 pkg/madmin/examples/set-config.go diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index dce7d812d..4a21d2cee 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -17,8 +17,10 @@ package cmd import ( + "bytes" "encoding/json" "encoding/xml" + "fmt" "io/ioutil" "net/http" "net/url" @@ -27,7 +29,8 @@ import ( ) const ( - minioAdminOpHeader = "X-Minio-Operation" + minioAdminOpHeader = "X-Minio-Operation" + minioConfigTmpFormat = "config-%s.json" ) // Type-safe query params. @@ -694,10 +697,127 @@ func (adminAPI adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http // returns local config.json. configBytes, err := getPeerConfig(globalAdminPeers) if err != nil { - writeErrorResponse(w, toAPIErrorCode(err), r.URL) errorIf(err, "Failed to get config from peers") + writeErrorResponse(w, toAdminAPIErrCode(err), r.URL) return } writeSuccessResponseJSON(w, configBytes) } + +// toAdminAPIErrCode - converts errXLWriteQuorum error to admin API +// specific error. +func toAdminAPIErrCode(err error) APIErrorCode { + switch err { + case errXLWriteQuorum: + return ErrAdminConfigNoQuorum + } + return toAPIErrorCode(err) +} + +// SetConfigResult - represents detailed results of a set-config +// operation. +type nodeSummary struct { + Name string `json:"name"` + Err string `json:"err"` +} +type setConfigResult struct { + NodeResults []nodeSummary `json:"nodeResults"` + Status bool `json:"status"` +} + +// writeSetConfigResponse - writes setConfigResult value as json depending on the status. +func writeSetConfigResponse(w http.ResponseWriter, peers adminPeers, errs []error, status bool, reqURL *url.URL) { + var nodeResults []nodeSummary + // Build nodeResults based on error values received during + // set-config operation. + for i := range errs { + nodeResults = append(nodeResults, nodeSummary{ + Name: peers[i].addr, + Err: fmt.Sprintf("%v", errs[i]), + }) + + } + + result := setConfigResult{ + Status: status, + NodeResults: nodeResults, + } + + // The following elaborate json encoding is to avoid escaping + // '<', '>' in . Note: json.Encoder.Encode() adds a + // gratuitous "\n". + var resultBuf bytes.Buffer + enc := json.NewEncoder(&resultBuf) + enc.SetEscapeHTML(false) + jsonErr := enc.Encode(result) + if jsonErr != nil { + writeErrorResponse(w, toAPIErrorCode(jsonErr), reqURL) + return + } + + writeSuccessResponseJSON(w, resultBuf.Bytes()) + return +} + +// SetConfigHandler - PUT /?config +// - x-minio-operation = set +func (adminAPI adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Request) { + // Get current object layer instance. + objectAPI := newObjectLayerFn() + if objectAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + // Validate request signature. + adminAPIErr := checkRequestAuthType(r, "", "", "") + if adminAPIErr != ErrNone { + writeErrorResponse(w, adminAPIErr, r.URL) + return + } + + // Read configuration bytes from request body. + configBytes, err := ioutil.ReadAll(r.Body) + if err != nil { + errorIf(err, "Failed to read config from request body.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + // Write config received from request onto a temporary file on + // all nodes. + tmpFileName := fmt.Sprintf(minioConfigTmpFormat, mustGetUUID()) + errs := writeTmpConfigPeers(globalAdminPeers, tmpFileName, configBytes) + + // Check if the operation succeeded in quorum or more nodes. + rErr := reduceWriteQuorumErrs(errs, nil, len(globalAdminPeers)/2+1) + if rErr != nil { + writeSetConfigResponse(w, globalAdminPeers, errs, false, r.URL) + return + } + + // Take a lock on minio/config.json. NB minio is a reserved + // bucket name and wouldn't conflict with normal object + // operations. + configLock := globalNSMutex.NewNSLock(minioReservedBucket, globalMinioConfigFile) + configLock.Lock() + defer configLock.Unlock() + + // Rename the temporary config file to config.json + errs = commitConfigPeers(globalAdminPeers, tmpFileName) + rErr = reduceWriteQuorumErrs(errs, nil, len(globalAdminPeers)/2+1) + if rErr != nil { + writeSetConfigResponse(w, globalAdminPeers, errs, false, r.URL) + return + } + + // serverMux (cmd/server-mux.go) implements graceful shutdown, + // where all listeners are closed and process restart/shutdown + // happens after 5s or completion of all ongoing http + // requests, whichever is earlier. + writeSetConfigResponse(w, globalAdminPeers, errs, true, r.URL) + + // Restart all node for the modified config to take effect. + sendServiceCmd(globalAdminPeers, serviceRestart) +} diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index 7c7bb1b54..931c0c208 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/json" "encoding/xml" + "fmt" "io/ioutil" "net/http" "net/http/httptest" @@ -30,6 +31,102 @@ import ( router "github.com/gorilla/mux" ) +var configJSON = []byte(`{ + "version": "13", + "credential": { + "accessKey": "minio", + "secretKey": "minio123" + }, + "region": "us-west-1", + "logger": { + "console": { + "enable": true, + "level": "fatal" + }, + "file": { + "enable": false, + "fileName": "", + "level": "" + } + }, + "notify": { + "amqp": { + "1": { + "enable": false, + "url": "", + "exchange": "", + "routingKey": "", + "exchangeType": "", + "mandatory": false, + "immediate": false, + "durable": false, + "internal": false, + "noWait": false, + "autoDeleted": false + } + }, + "nats": { + "1": { + "enable": false, + "address": "", + "subject": "", + "username": "", + "password": "", + "token": "", + "secure": false, + "pingInterval": 0, + "streaming": { + "enable": false, + "clusterID": "", + "clientID": "", + "async": false, + "maxPubAcksInflight": 0 + } + } + }, + "elasticsearch": { + "1": { + "enable": false, + "url": "", + "index": "" + } + }, + "redis": { + "1": { + "enable": false, + "address": "", + "password": "", + "key": "" + } + }, + "postgresql": { + "1": { + "enable": false, + "connectionString": "", + "table": "", + "host": "", + "port": "", + "user": "", + "password": "", + "database": "" + } + }, + "kafka": { + "1": { + "enable": false, + "brokers": null, + "topic": "" + } + }, + "webhook": { + "1": { + "enable": false, + "endpoint": "" + } + } + } +}`) + // adminXLTestBed - encapsulates subsystems that need to be setup for // admin-handler unit tests. type adminXLTestBed struct { @@ -1033,3 +1130,159 @@ func TestGetConfigHandler(t *testing.T) { } } + +// TestSetConfigHandler - test for SetConfigHandler. +func TestSetConfigHandler(t *testing.T) { + adminTestBed, err := prepareAdminXLTestBed() + if err != nil { + t.Fatal("Failed to initialize a single node XL backend for admin handler tests.") + } + defer adminTestBed.TearDown() + + // Initialize admin peers to make admin RPC calls. + eps, err := parseStorageEndpoints([]string{"http://127.0.0.1"}) + if err != nil { + t.Fatalf("Failed to parse storage end point - %v", err) + } + + // Set globalMinioAddr to be able to distinguish local endpoints from remote. + globalMinioAddr = eps[0].Host + initGlobalAdminPeers(eps) + + // SetConfigHandler restarts minio setup - need to start a + // signal receiver to receive on globalServiceSignalCh. + go testServiceSignalReceiver(restartCmd, t) + + // Prepare query params for set-config mgmt REST API. + queryVal := url.Values{} + queryVal.Set("config", "") + + req, err := newTestRequest("PUT", "/?"+queryVal.Encode(), int64(len(configJSON)), bytes.NewReader(configJSON)) + if err != nil { + t.Fatalf("Failed to construct get-config object request - %v", err) + } + + // Set x-minio-operation header to set. + req.Header.Set(minioAdminOpHeader, "set") + + // Sign the request using signature v4. + cred := serverConfig.GetCredential() + err = signRequestV4(req, cred.AccessKey, cred.SecretKey) + if err != nil { + t.Fatalf("Failed to sign heal object request - %v", err) + } + + rec := httptest.NewRecorder() + adminTestBed.mux.ServeHTTP(rec, req) + if rec.Code != http.StatusOK { + t.Errorf("Expected to succeed but failed with %d", rec.Code) + } + + result := setConfigResult{} + err = json.NewDecoder(rec.Body).Decode(&result) + if err != nil { + t.Fatalf("Failed to decode set config result json %v", err) + } + + if result.Status != true { + t.Error("Expected set-config to succeed, but failed") + } +} + +// TestToAdminAPIErr - test for toAdminAPIErr helper function. +func TestToAdminAPIErr(t *testing.T) { + testCases := []struct { + err error + expectedAPIErr APIErrorCode + }{ + // 1. Server not in quorum. + { + err: errXLWriteQuorum, + expectedAPIErr: ErrAdminConfigNoQuorum, + }, + // 2. No error. + { + err: nil, + expectedAPIErr: ErrNone, + }, + // 3. Non-admin API specific error. + { + err: errDiskNotFound, + expectedAPIErr: toAPIErrorCode(errDiskNotFound), + }, + } + + for i, test := range testCases { + actualErr := toAdminAPIErrCode(test.err) + if actualErr != test.expectedAPIErr { + t.Errorf("Test %d: Expected %v but received %v", + i+1, test.expectedAPIErr, actualErr) + } + } +} + +func TestWriteSetConfigResponse(t *testing.T) { + testCases := []struct { + status bool + errs []error + }{ + // 1. all nodes returned success. + { + status: true, + errs: []error{nil, nil, nil, nil}, + }, + // 2. some nodes returned errors. + { + status: false, + errs: []error{errDiskNotFound, nil, errDiskAccessDenied, errFaultyDisk}, + }, + } + + testPeers := []adminPeer{ + adminPeer{ + addr: "localhost:9001", + }, + adminPeer{ + addr: "localhost:9002", + }, + adminPeer{ + addr: "localhost:9003", + }, + adminPeer{ + addr: "localhost:9004", + }, + } + + testURL, err := url.Parse("dummy.com") + if err != nil { + t.Fatalf("Failed to parse a place-holder url") + } + + var actualResult setConfigResult + for i, test := range testCases { + rec := httptest.NewRecorder() + writeSetConfigResponse(rec, testPeers, test.errs, test.status, testURL) + resp := rec.Result() + jsonBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatalf("Test %d: Failed to read response %v", i+1, err) + } + + err = json.Unmarshal(jsonBytes, &actualResult) + if err != nil { + t.Fatalf("Test %d: Failed to unmarshal json %v", i+1, err) + } + if actualResult.Status != test.status { + t.Errorf("Test %d: Expected status %v but received %v", i+1, test.status, actualResult.Status) + } + for p, res := range actualResult.NodeResults { + if res.Name != testPeers[p].addr { + t.Errorf("Test %d: Expected node name %s but received %s", i+1, testPeers[p].addr, res.Name) + } + expectedErrStr := fmt.Sprintf("%v", test.errs[p]) + if res.Err != expectedErrStr { + t.Errorf("Test %d: Expected error %s but received %s", i+1, expectedErrStr, res.Err) + } + } + } +} diff --git a/cmd/admin-router.go b/cmd/admin-router.go index 6bdcc8dc6..fa0b805b2 100644 --- a/cmd/admin-router.go +++ b/cmd/admin-router.go @@ -67,4 +67,6 @@ func registerAdminRouter(mux *router.Router) { // Get config adminRouter.Methods("GET").Queries("config", "").Headers(minioAdminOpHeader, "get").HandlerFunc(adminAPI.GetConfigHandler) + // Set Config + adminRouter.Methods("PUT").Queries("config", "").Headers(minioAdminOpHeader, "set").HandlerFunc(adminAPI.SetConfigHandler) } diff --git a/cmd/admin-rpc-client.go b/cmd/admin-rpc-client.go index 392f62c51..9241731e1 100644 --- a/cmd/admin-rpc-client.go +++ b/cmd/admin-rpc-client.go @@ -20,13 +20,26 @@ import ( "encoding/json" "errors" "net/url" + "os" "path" + "path/filepath" "reflect" "sort" "sync" "time" ) +const ( + // Admin service names + serviceRestartRPC = "Admin.Restart" + listLocksRPC = "Admin.ListLocks" + reInitDisksRPC = "Admin.ReInitDisks" + uptimeRPC = "Admin.Uptime" + getConfigRPC = "Admin.GetConfig" + writeTmpConfigRPC = "Admin.WriteTmpConfig" + commitConfigRPC = "Admin.CommitConfig" +) + // localAdminClient - represents admin operation to be executed locally. type localAdminClient struct { } @@ -45,6 +58,8 @@ type adminCmdRunner interface { ReInitDisks() error Uptime() (time.Duration, error) GetConfig() ([]byte, error) + WriteTmpConfig(tmpFileName string, configBytes []byte) error + CommitConfig(tmpFileName string) error } // Restart - Sends a message over channel to the go-routine @@ -63,7 +78,7 @@ func (lc localAdminClient) ListLocks(bucket, prefix string, duration time.Durati func (rc remoteAdminClient) Restart() error { args := AuthRPCArgs{} reply := AuthRPCReply{} - return rc.Call("Admin.Restart", &args, &reply) + return rc.Call(serviceRestartRPC, &args, &reply) } // ListLocks - Sends list locks command to remote server via RPC. @@ -74,7 +89,7 @@ func (rc remoteAdminClient) ListLocks(bucket, prefix string, duration time.Durat duration: duration, } var reply ListLocksReply - if err := rc.Call("Admin.ListLocks", &listArgs, &reply); err != nil { + if err := rc.Call(listLocksRPC, &listArgs, &reply); err != nil { return nil, err } return reply.volLocks, nil @@ -91,7 +106,7 @@ func (lc localAdminClient) ReInitDisks() error { func (rc remoteAdminClient) ReInitDisks() error { args := AuthRPCArgs{} reply := AuthRPCReply{} - return rc.Call("Admin.ReInitDisks", &args, &reply) + return rc.Call(reInitDisksRPC, &args, &reply) } // Uptime - Returns the uptime of this server. Timestamp is taken @@ -108,7 +123,7 @@ func (lc localAdminClient) Uptime() (time.Duration, error) { func (rc remoteAdminClient) Uptime() (time.Duration, error) { args := AuthRPCArgs{} reply := UptimeReply{} - err := rc.Call("Admin.Uptime", &args, &reply) + err := rc.Call(uptimeRPC, &args, &reply) if err != nil { return time.Duration(0), err } @@ -129,12 +144,70 @@ func (lc localAdminClient) GetConfig() ([]byte, error) { func (rc remoteAdminClient) GetConfig() ([]byte, error) { args := AuthRPCArgs{} reply := ConfigReply{} - if err := rc.Call("Admin.GetConfig", &args, &reply); err != nil { + if err := rc.Call(getConfigRPC, &args, &reply); err != nil { return nil, err } return reply.Config, nil } +// WriteTmpConfig - writes config file content to a temporary file on +// the local server. +func (lc localAdminClient) WriteTmpConfig(tmpFileName string, configBytes []byte) error { + return writeTmpConfigCommon(tmpFileName, configBytes) +} + +// WriteTmpConfig - writes config file content to a temporary file on +// a remote node. +func (rc remoteAdminClient) WriteTmpConfig(tmpFileName string, configBytes []byte) error { + wArgs := WriteConfigArgs{ + TmpFileName: tmpFileName, + Buf: configBytes, + } + + err := rc.Call(writeTmpConfigRPC, &wArgs, &WriteConfigReply{}) + if err != nil { + errorIf(err, "Failed to write temporary config file.") + return err + } + + return nil +} + +// CommitConfig - Move the new config in tmpFileName onto config.json +// on a local node. +func (lc localAdminClient) CommitConfig(tmpFileName string) error { + configDir, err := getConfigPath() + if err != nil { + errorIf(err, "Failed to get config directory path.") + return err + } + + configFilePath := filepath.Join(configDir, globalMinioConfigFile) + err = os.Rename(filepath.Join(configDir, tmpFileName), configFilePath) + if err != nil { + errorIf(err, "Failed to rename to config.json") + return err + } + + return nil +} + +// CommitConfig - Move the new config in tmpFileName onto config.json +// on a remote node. +func (rc remoteAdminClient) CommitConfig(tmpFileName string) error { + cArgs := CommitConfigArgs{ + FileName: tmpFileName, + } + cReply := CommitConfigReply{} + err := rc.Call(commitConfigRPC, &cArgs, &cReply) + if err != nil { + errorIf(err, "Failed to rename config file.") + return err + } + + return nil +} + // adminPeer - represents an entity that implements Restart methods. type adminPeer struct { addr string @@ -489,3 +562,55 @@ func getValidServerConfig(serverConfigs []serverConfigV13, errs []error) (server return configJSON, nil } + +// Write config contents into a temporary file on all nodes. +func writeTmpConfigPeers(peers adminPeers, tmpFileName string, configBytes []byte) []error { + // For a single-node minio server setup. + if !globalIsDistXL { + err := peers[0].cmdRunner.WriteTmpConfig(tmpFileName, configBytes) + return []error{err} + } + + errs := make([]error, len(peers)) + + // Write config into temporary file on all nodes. + wg := sync.WaitGroup{} + for i, peer := range peers { + wg.Add(1) + go func(idx int, peer adminPeer) { + defer wg.Done() + errs[idx] = peer.cmdRunner.WriteTmpConfig(tmpFileName, configBytes) + }(i, peer) + } + wg.Wait() + + // Return bytes written and errors (if any) during writing + // temporary config file. + return errs +} + +// Move config contents from the given temporary file onto config.json +// on all nodes. +func commitConfigPeers(peers adminPeers, tmpFileName string) []error { + // For a single-node minio server setup. + if !globalIsDistXL { + return []error{peers[0].cmdRunner.CommitConfig(tmpFileName)} + } + + errs := make([]error, len(peers)) + + // Rename temporary config file into configDir/config.json on + // all nodes. + wg := sync.WaitGroup{} + for i, peer := range peers { + wg.Add(1) + go func(idx int, peer adminPeer) { + defer wg.Done() + errs[idx] = peer.cmdRunner.CommitConfig(tmpFileName) + }(i, peer) + } + wg.Wait() + + // Return errors (if any) received during rename. + return errs +} diff --git a/cmd/admin-rpc-server.go b/cmd/admin-rpc-server.go index 213fbdd8e..6109b9c43 100644 --- a/cmd/admin-rpc-server.go +++ b/cmd/admin-rpc-server.go @@ -19,7 +19,10 @@ package cmd import ( "encoding/json" "errors" + "io/ioutil" "net/rpc" + "os" + "path/filepath" "time" router "github.com/gorilla/mux" @@ -158,6 +161,75 @@ func (s *adminCmd) GetConfig(args *AuthRPCArgs, reply *ConfigReply) error { return nil } +// WriteConfigArgs - wraps the bytes to be written and temporary file name. +type WriteConfigArgs struct { + AuthRPCArgs + TmpFileName string + Buf []byte +} + +// WriteConfigReply - wraps the result of a writing config into a temporary file. +// the remote node. +type WriteConfigReply struct { + AuthRPCReply +} + +func writeTmpConfigCommon(tmpFileName string, configBytes []byte) error { + configDir, err := getConfigPath() + if err != nil { + errorIf(err, "Failed to get config path") + return err + } + + err = ioutil.WriteFile(filepath.Join(configDir, tmpFileName), configBytes, 0666) + if err != nil { + errorIf(err, "Failed to write to temporary config file.") + return err + } + return err +} + +// WriteTmpConfig - writes the supplied config contents onto the +// supplied temporary file. +func (s *adminCmd) WriteTmpConfig(wArgs *WriteConfigArgs, wReply *WriteConfigReply) error { + if err := wArgs.IsAuthenticated(); err != nil { + return err + } + + return writeTmpConfigCommon(wArgs.TmpFileName, wArgs.Buf) +} + +// CommitConfigArgs - wraps the config file name that needs to be +// committed into config.json on this node. +type CommitConfigArgs struct { + AuthRPCArgs + FileName string +} + +// CommitConfigReply - represents response to commit of config file on +// this node. +type CommitConfigReply struct { + AuthRPCReply +} + +// CommitConfig - Renames the temporary file into config.json on this node. +func (s *adminCmd) CommitConfig(cArgs *CommitConfigArgs, cReply *CommitConfigReply) error { + configDir, err := getConfigPath() + if err != nil { + errorIf(err, "Failed to get config path.") + return err + } + + configFilePath := filepath.Join(configDir, globalMinioConfigFile) + err = os.Rename(filepath.Join(configDir, cArgs.FileName), configFilePath) + if err != nil { + errorIf(err, "Failed to rename config file.") + return err + } + + return nil +} + // registerAdminRPCRouter - registers RPC methods for service status, // stop and restart commands. func registerAdminRPCRouter(mux *router.Router) error { diff --git a/cmd/admin-rpc-server_test.go b/cmd/admin-rpc-server_test.go index 44705a7a2..f41c4e28d 100644 --- a/cmd/admin-rpc-server_test.go +++ b/cmd/admin-rpc-server_test.go @@ -144,6 +144,7 @@ func TestReInitDisks(t *testing.T) { } } +// TestGetConfig - Test for GetConfig admin RPC. func TestGetConfig(t *testing.T) { // Reset global variables to start afresh. resetTestGlobals() @@ -185,3 +186,63 @@ func TestGetConfig(t *testing.T) { t.Errorf("Expected json unmarshal to pass but failed with %v", err) } } + +// TestWriteAndCommitConfig - test for WriteTmpConfig and CommitConfig +// RPC handler. +func TestWriteAndCommitConfig(t *testing.T) { + // Reset global variables to start afresh. + resetTestGlobals() + + rootPath, err := newTestConfig("us-east-1") + if err != nil { + t.Fatalf("Unable to initialize server config. %s", err) + } + defer removeAll(rootPath) + + adminServer := adminCmd{} + creds := serverConfig.GetCredential() + args := LoginRPCArgs{ + Username: creds.AccessKey, + Password: creds.SecretKey, + Version: Version, + RequestTime: time.Now().UTC(), + } + reply := LoginRPCReply{} + err = adminServer.Login(&args, &reply) + if err != nil { + t.Fatalf("Failed to login to admin server - %v", err) + } + + // Write temporary config. + buf := []byte("hello") + tmpFileName := mustGetUUID() + wArgs := WriteConfigArgs{ + AuthRPCArgs: AuthRPCArgs{ + AuthToken: reply.AuthToken, + }, + TmpFileName: tmpFileName, + Buf: buf, + } + + err = adminServer.WriteTmpConfig(&wArgs, &WriteConfigReply{}) + if err != nil { + t.Fatalf("Failed to write temporary config %v", err) + } + + if err != nil { + t.Errorf("Expected to succeed but failed %v", err) + } + + cArgs := CommitConfigArgs{ + AuthRPCArgs: AuthRPCArgs{ + AuthToken: reply.AuthToken, + }, + FileName: tmpFileName, + } + cReply := CommitConfigReply{} + + err = adminServer.CommitConfig(&cArgs, &cReply) + if err != nil { + t.Fatalf("Failed to commit config file %v", err) + } +} diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 8eb82761a..33cd41a75 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -144,6 +144,7 @@ const ( ErrAdminInvalidAccessKey ErrAdminInvalidSecretKey + ErrAdminConfigNoQuorum ) // error code to APIError structure, these fields carry respective @@ -593,6 +594,11 @@ var errorCodeResponse = map[APIErrorCode]APIError{ Description: "The secret key is invalid.", HTTPStatusCode: http.StatusBadRequest, }, + ErrAdminConfigNoQuorum: { + Code: "XMinioAdminConfigNoQuorum", + Description: "Configuration update failed because server quorum was not met", + HTTPStatusCode: http.StatusServiceUnavailable, + }, // Add your error structure here. } diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 0b3c7f3dc..9af4d6d14 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -351,7 +351,7 @@ func (h resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } // A put method on path "/" doesn't make sense, ignore it. - if r.Method == httpPUT && r.URL.Path == "/" { + if r.Method == httpPUT && r.URL.Path == "/" && r.Header.Get(minioAdminOpHeader) == "" { writeErrorResponse(w, ErrNotImplemented, r.URL) return } diff --git a/pkg/madmin/API.md b/pkg/madmin/API.md index 361034092..033bb0816 100644 --- a/pkg/madmin/API.md +++ b/pkg/madmin/API.md @@ -39,7 +39,7 @@ func main() { | Service operations|LockInfo operations|Healing operations|Config operations| Misc | |:---|:---|:---|:---|:---| |[`ServiceStatus`](#ServiceStatus)| [`ListLocks`](#ListLocks)| [`ListObjectsHeal`](#ListObjectsHeal)|[`GetConfig`](#GetConfig)| [`SetCredentials`](#SetCredentials)| -|[`ServiceRestart`](#ServiceRestart)| [`ClearLocks`](#ClearLocks)| [`ListBucketsHeal`](#ListBucketsHeal)||| +|[`ServiceRestart`](#ServiceRestart)| [`ClearLocks`](#ClearLocks)| [`ListBucketsHeal`](#ListBucketsHeal)|[`SetConfig`](#SetConfig)|| | | |[`HealBucket`](#HealBucket) ||| | | |[`HealObject`](#HealObject)||| | | |[`HealFormat`](#HealFormat)||| @@ -306,7 +306,7 @@ __Example__ -### SetCredentials() error +### SetCredentials() error Set new credentials of a Minio setup. __Example__ @@ -320,4 +320,35 @@ __Example__ ``` + +### SetConfig(config io.Reader) (SetConfigResult, error) +Set config.json of a minio setup and restart setup for configuration +change to take effect. + +| Param | Type | Description | +|---|---|---| +|`st.Status` | _bool_ | true if set-config succeeded, false otherwise. | +|`st.NodeSummary.Name` | _string_ | Network address of the node. | +|`st.NodeSummary.Err` | _string_ | String representation of the error (if any) on the node.| + + +__Example__ + +``` go + config := bytes.NewReader([]byte(`config.json contents go here`)) + result, err := madmClnt.SetConfig(config) + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + enc.SetEscapeHTML(false) + enc.SetIndent("", "\t") + err = enc.Encode(result) + if err != nil { + log.Fatalln(err) + } + log.Println("SetConfig: ", string(buf.Bytes())) +``` diff --git a/pkg/madmin/config-commands.go b/pkg/madmin/config-commands.go index 2e839bac3..d63aece4a 100644 --- a/pkg/madmin/config-commands.go +++ b/pkg/madmin/config-commands.go @@ -18,15 +18,36 @@ package madmin import ( + "bytes" + "encoding/json" + "io" "io/ioutil" "net/http" "net/url" ) +const ( + configQueryParam = "config" +) + +// NodeSummary - represents the result of an operation part of +// set-config on a node. +type NodeSummary struct { + Name string `json:"name"` + Err string `json:"err"` +} + +// SetConfigResult - represents detailed results of a set-config +// operation. +type SetConfigResult struct { + NodeResults []NodeSummary `json:"nodeResults"` + Status bool `json:"status"` +} + // GetConfig - returns the config.json of a minio setup. func (adm *AdminClient) GetConfig() ([]byte, error) { queryVal := make(url.Values) - queryVal.Set("config", "") + queryVal.Set(configQueryParam, "") hdrs := make(http.Header) hdrs.Set(minioAdminOpHeader, "get") @@ -36,7 +57,7 @@ func (adm *AdminClient) GetConfig() ([]byte, error) { customHeaders: hdrs, } - // Execute GET on /?lock to list locks. + // Execute GET on /?config to get config of a setup. resp, err := adm.executeMethod("GET", reqData) defer closeResponse(resp) @@ -44,6 +65,59 @@ func (adm *AdminClient) GetConfig() ([]byte, error) { return nil, err } + if resp.StatusCode != http.StatusOK { + return nil, httpRespToErrorResponse(resp) + } + // Return the JSON marshalled bytes to user. return ioutil.ReadAll(resp.Body) } + +// SetConfig - set config supplied as config.json for the setup. +func (adm *AdminClient) SetConfig(config io.Reader) (SetConfigResult, error) { + queryVal := url.Values{} + queryVal.Set(configQueryParam, "") + + // Set x-minio-operation to set. + hdrs := make(http.Header) + hdrs.Set(minioAdminOpHeader, "set") + + // Read config bytes to calculate MD5, SHA256 and content length. + configBytes, err := ioutil.ReadAll(config) + if err != nil { + return SetConfigResult{}, err + } + + reqData := requestData{ + queryValues: queryVal, + customHeaders: hdrs, + contentBody: bytes.NewReader(configBytes), + contentMD5Bytes: sumMD5(configBytes), + contentSHA256Bytes: sum256(configBytes), + } + + // Execute PUT on /?config to set config. + resp, err := adm.executeMethod("PUT", reqData) + + defer closeResponse(resp) + if err != nil { + return SetConfigResult{}, err + } + + if resp.StatusCode != http.StatusOK { + return SetConfigResult{}, httpRespToErrorResponse(resp) + } + + var result SetConfigResult + jsonBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return SetConfigResult{}, err + } + + err = json.Unmarshal(jsonBytes, &result) + if err != nil { + return SetConfigResult{}, err + } + + return result, nil +} diff --git a/pkg/madmin/examples/set-config.go b/pkg/madmin/examples/set-config.go new file mode 100644 index 000000000..6ab560121 --- /dev/null +++ b/pkg/madmin/examples/set-config.go @@ -0,0 +1,156 @@ +// +build ignore + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "log" + + "github.com/minio/minio/pkg/madmin" +) + +var configJSON = []byte(`{ + "version": "13", + "credential": { + "accessKey": "minio", + "secretKey": "minio123" + }, + "region": "us-west-1", + "logger": { + "console": { + "enable": true, + "level": "fatal" + }, + "file": { + "enable": false, + "fileName": "", + "level": "" + } + }, + "notify": { + "amqp": { + "1": { + "enable": false, + "url": "", + "exchange": "", + "routingKey": "", + "exchangeType": "", + "mandatory": false, + "immediate": false, + "durable": false, + "internal": false, + "noWait": false, + "autoDeleted": false + } + }, + "nats": { + "1": { + "enable": false, + "address": "", + "subject": "", + "username": "", + "password": "", + "token": "", + "secure": false, + "pingInterval": 0, + "streaming": { + "enable": false, + "clusterID": "", + "clientID": "", + "async": false, + "maxPubAcksInflight": 0 + } + } + }, + "elasticsearch": { + "1": { + "enable": false, + "url": "", + "index": "" + } + }, + "redis": { + "1": { + "enable": false, + "address": "", + "password": "", + "key": "" + } + }, + "postgresql": { + "1": { + "enable": false, + "connectionString": "", + "table": "", + "host": "", + "port": "", + "user": "", + "password": "", + "database": "" + } + }, + "kafka": { + "1": { + "enable": false, + "brokers": null, + "topic": "" + } + }, + "webhook": { + "1": { + "enable": false, + "endpoint": "" + } + } + } +}`) + +func main() { + // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are + // dummy values, please replace them with original values. + + // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are + // dummy values, please replace them with original values. + + // API requests are secure (HTTPS) if secure=true and insecure (HTTPS) otherwise. + // New returns an Minio Admin client object. + madmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true) + if err != nil { + log.Fatalln(err) + } + + result, err := madmClnt.SetConfig(bytes.NewReader(configJSON)) + if err != nil { + log.Fatalln(err) + } + + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + enc.SetEscapeHTML(false) + enc.SetIndent("", "\t") + err = enc.Encode(result) + if err != nil { + log.Fatalln(err) + } + + fmt.Println("SetConfig: ", string(buf.Bytes())) +} From 9b3c014bab416a7e8063399a389e75411b4f8606 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Mon, 27 Feb 2017 23:59:53 +0100 Subject: [PATCH 30/94] config: Add browser parameter (#3807) browser new parameter receives "on" or "off" parameter which is similar to MINIO_BROWSER --- cmd/config-migrate.go | 106 ++++++++++++++++++ cmd/config-migrate_test.go | 12 +- cmd/config-old.go | 28 +++++ cmd/{config-v13.go => config-v14.go} | 75 +++++++++---- ...{config-v13_test.go => config-v14_test.go} | 51 ++++++++- cmd/globals.go | 14 +-- cmd/main.go | 16 ++- cmd/test-utils_test.go | 2 +- cmd/utils.go | 24 ++++ 9 files changed, 290 insertions(+), 38 deletions(-) rename cmd/{config-v13.go => config-v14.go} (73%) rename cmd/{config-v13_test.go => config-v14_test.go} (78%) diff --git a/cmd/config-migrate.go b/cmd/config-migrate.go index d6a07b045..e38d1bf4c 100644 --- a/cmd/config-migrate.go +++ b/cmd/config-migrate.go @@ -74,6 +74,10 @@ func migrateConfig() error { if err := migrateV12ToV13(); err != nil { return err } + // Migration version '13' to '14'. + if err := migrateV13ToV14(); err != nil { + return err + } return nil } @@ -937,3 +941,105 @@ func migrateV12ToV13() error { ) return nil } + +// Version '13' to '14' migration. Add support for custom webhook endpoint. +func migrateV13ToV14() error { + cv13, err := loadConfigV13() + if err != nil { + if os.IsNotExist(err) { + return nil + } + return fmt.Errorf("Unable to load config version ‘13’. %v", err) + } + if cv13.Version != "13" { + return nil + } + + // Copy over fields from V13 into V14 config struct + srvConfig := &serverConfigV14{ + Logger: &logger{}, + Notify: ¬ifier{}, + } + srvConfig.Version = "14" + srvConfig.Credential = cv13.Credential + srvConfig.Region = cv13.Region + if srvConfig.Region == "" { + // Region needs to be set for AWS Signature Version 4. + srvConfig.Region = globalMinioDefaultRegion + } + srvConfig.Logger.Console = cv13.Logger.Console + srvConfig.Logger.File = cv13.Logger.File + + // check and set notifiers config + if len(cv13.Notify.AMQP) == 0 { + srvConfig.Notify.AMQP = make(map[string]amqpNotify) + srvConfig.Notify.AMQP["1"] = amqpNotify{} + } else { + srvConfig.Notify.AMQP = cv13.Notify.AMQP + } + if len(cv13.Notify.ElasticSearch) == 0 { + srvConfig.Notify.ElasticSearch = make(map[string]elasticSearchNotify) + srvConfig.Notify.ElasticSearch["1"] = elasticSearchNotify{} + } else { + srvConfig.Notify.ElasticSearch = cv13.Notify.ElasticSearch + } + if len(cv13.Notify.Redis) == 0 { + srvConfig.Notify.Redis = make(map[string]redisNotify) + srvConfig.Notify.Redis["1"] = redisNotify{} + } else { + srvConfig.Notify.Redis = cv13.Notify.Redis + } + if len(cv13.Notify.PostgreSQL) == 0 { + srvConfig.Notify.PostgreSQL = make(map[string]postgreSQLNotify) + srvConfig.Notify.PostgreSQL["1"] = postgreSQLNotify{} + } else { + srvConfig.Notify.PostgreSQL = cv13.Notify.PostgreSQL + } + if len(cv13.Notify.Kafka) == 0 { + srvConfig.Notify.Kafka = make(map[string]kafkaNotify) + srvConfig.Notify.Kafka["1"] = kafkaNotify{} + } else { + srvConfig.Notify.Kafka = cv13.Notify.Kafka + } + if len(cv13.Notify.NATS) == 0 { + srvConfig.Notify.NATS = make(map[string]natsNotify) + srvConfig.Notify.NATS["1"] = natsNotify{} + } else { + srvConfig.Notify.NATS = cv13.Notify.NATS + } + if len(cv13.Notify.Webhook) == 0 { + srvConfig.Notify.Webhook = make(map[string]webhookNotify) + srvConfig.Notify.Webhook["1"] = webhookNotify{} + } else { + srvConfig.Notify.Webhook = cv13.Notify.Webhook + } + + // Set the new browser parameter to true by default + srvConfig.Browser = "on" + + qc, err := quick.New(srvConfig) + if err != nil { + return fmt.Errorf("Unable to initialize the quick config. %v", + err) + } + configFile, err := getConfigFile() + if err != nil { + return fmt.Errorf("Unable to get config file. %v", err) + } + + err = qc.Save(configFile) + if err != nil { + return fmt.Errorf( + "Failed to migrate config from ‘"+ + cv13.Version+"’ to ‘"+srvConfig.Version+ + "’ failed. %v", err, + ) + } + + console.Println( + "Migration from version ‘" + + cv13.Version + "’ to ‘" + srvConfig.Version + + "’ completed successfully.", + ) + return nil +} diff --git a/cmd/config-migrate_test.go b/cmd/config-migrate_test.go index b1fb6e24e..35f2d802d 100644 --- a/cmd/config-migrate_test.go +++ b/cmd/config-migrate_test.go @@ -50,7 +50,7 @@ func TestServerConfigMigrateV1(t *testing.T) { } // Initialize server config and check again if everything is fine - if err := loadConfig(credential{}); err != nil { + if err := loadConfig(envParams{}); err != nil { t.Fatalf("Unable to initialize from updated config file %s", err) } } @@ -106,10 +106,13 @@ func TestServerConfigMigrateInexistentConfig(t *testing.T) { if err := migrateV12ToV13(); err != nil { t.Fatal("migrate v12 to v13 should succeed when no config file is found") } + if err := migrateV13ToV14(); err != nil { + t.Fatal("migrate v13 to v14 should succeed when no config file is found") + } } // Test if a config migration from v2 to v12 is successfully done -func TestServerConfigMigrateV2toV12(t *testing.T) { +func TestServerConfigMigrateV2toV14(t *testing.T) { rootPath, err := newTestConfig(globalMinioDefaultRegion) if err != nil { t.Fatalf("Init Test config failed") @@ -143,7 +146,7 @@ func TestServerConfigMigrateV2toV12(t *testing.T) { } // Initialize server config and check again if everything is fine - if err := loadConfig(credential{}); err != nil { + if err := loadConfig(envParams{}); err != nil { t.Fatalf("Unable to initialize from updated config file %s", err) } @@ -213,4 +216,7 @@ func TestServerConfigMigrateFaultyConfig(t *testing.T) { if err := migrateV12ToV13(); err == nil { t.Fatal("migrateConfigV12ToV13() should fail with a corrupted json") } + if err := migrateV13ToV14(); err == nil { + t.Fatal("migrateConfigV13ToV14() should fail with a corrupted json") + } } diff --git a/cmd/config-old.go b/cmd/config-old.go index c3cc6113c..d8fa5867f 100644 --- a/cmd/config-old.go +++ b/cmd/config-old.go @@ -522,3 +522,31 @@ func loadConfigV12() (*serverConfigV12, error) { } return config.(*serverConfigV12), err } + +// serverConfigV13 server configuration version '13' which is like +// version '12' except it adds support for webhook notification. +type serverConfigV13 struct { + Version string `json:"version"` + + // S3 API configuration. + Credential credential `json:"credential"` + Region string `json:"region"` + + // Additional error logging configuration. + Logger *logger `json:"logger"` + + // Notification queue configuration. + Notify *notifier `json:"notify"` +} + +func loadConfigV13() (*serverConfigV13, error) { + configFile, err := getConfigFile() + if err != nil { + return nil, err + } + config, err := loadOldConfig(configFile, &serverConfigV13{Version: "13"}) + if config == nil { + return nil, err + } + return config.(*serverConfigV13), err +} diff --git a/cmd/config-v13.go b/cmd/config-v14.go similarity index 73% rename from cmd/config-v13.go rename to cmd/config-v14.go index f1ee32b90..1ae69405b 100644 --- a/cmd/config-v13.go +++ b/cmd/config-v14.go @@ -18,6 +18,7 @@ package cmd import ( "os" + "strings" "sync" "github.com/minio/minio/pkg/quick" @@ -26,14 +27,15 @@ import ( // Read Write mutex for safe access to ServerConfig. var serverConfigMu sync.RWMutex -// serverConfigV13 server configuration version '13' which is like -// version '12' except it adds support for webhook notification. -type serverConfigV13 struct { +// serverConfigV14 server configuration version '14' which is like +// version '13' except it adds support of browser param. +type serverConfigV14 struct { Version string `json:"version"` // S3 API configuration. Credential credential `json:"credential"` Region string `json:"region"` + Browser string `json:"browser"` // Additional error logging configuration. Logger *logger `json:"logger"` @@ -42,12 +44,11 @@ type serverConfigV13 struct { Notify *notifier `json:"notify"` } -// newConfig - initialize a new server config, saves creds from env -// if globalIsEnvCreds is set otherwise generates a new set of keys -// and those are saved. -func newConfig(envCreds credential) error { +// newConfig - initialize a new server config, saves env parameters if +// found, otherwise use default parameters +func newConfig(envParams envParams) error { // Initialize server config. - srvCfg := &serverConfigV13{ + srvCfg := &serverConfigV14{ Logger: &logger{}, Notify: ¬ifier{}, } @@ -56,11 +57,17 @@ func newConfig(envCreds credential) error { // If env is set for a fresh start, save them to config file. if globalIsEnvCreds { - srvCfg.SetCredential(envCreds) + srvCfg.SetCredential(envParams.creds) } else { srvCfg.SetCredential(newCredential()) } + if globalIsEnvBrowser { + srvCfg.SetBrowser(envParams.browser) + } else { + srvCfg.SetBrowser("on") + } + // Enable console logger by default on a fresh run. srvCfg.Logger.Console = consoleLogger{ Enable: true, @@ -99,10 +106,9 @@ func newConfig(envCreds credential) error { return serverConfig.Save() } -// loadConfig - loads a new config from disk, overrides creds from env -// if globalIsEnvCreds is set otherwise serves the creds from loaded -// from the disk. -func loadConfig(envCreds credential) error { +// loadConfig - loads a new config from disk, overrides params from env +// if found and valid +func loadConfig(envParams envParams) error { configFile, err := getConfigFile() if err != nil { return err @@ -111,7 +117,7 @@ func loadConfig(envCreds credential) error { if _, err = os.Stat(configFile); err != nil { return err } - srvCfg := &serverConfigV13{} + srvCfg := &serverConfigV14{} srvCfg.Version = globalMinioConfigVersion qc, err := quick.New(srvCfg) if err != nil { @@ -124,11 +130,19 @@ func loadConfig(envCreds credential) error { // If env is set override the credentials from config file. if globalIsEnvCreds { - srvCfg.SetCredential(envCreds) + srvCfg.SetCredential(envParams.creds) } else { srvCfg.SetCredential(srvCfg.Credential) } + if globalIsEnvBrowser { + srvCfg.SetBrowser(envParams.browser) + } + + if strings.ToLower(srvCfg.GetBrowser()) == "off" { + globalIsBrowserEnabled = false + } + // hold the mutex lock before a new config is assigned. serverConfigMu.Lock() // Save the loaded config globally. @@ -141,10 +155,10 @@ func loadConfig(envCreds credential) error { } // serverConfig server config. -var serverConfig *serverConfigV13 +var serverConfig *serverConfigV14 // GetVersion get current config version. -func (s serverConfigV13) GetVersion() string { +func (s serverConfigV14) GetVersion() string { serverConfigMu.RLock() defer serverConfigMu.RUnlock() @@ -152,7 +166,7 @@ func (s serverConfigV13) GetVersion() string { } // SetRegion set new region. -func (s *serverConfigV13) SetRegion(region string) { +func (s *serverConfigV14) SetRegion(region string) { serverConfigMu.Lock() defer serverConfigMu.Unlock() @@ -160,7 +174,7 @@ func (s *serverConfigV13) SetRegion(region string) { } // GetRegion get current region. -func (s serverConfigV13) GetRegion() string { +func (s serverConfigV14) GetRegion() string { serverConfigMu.RLock() defer serverConfigMu.RUnlock() @@ -168,7 +182,7 @@ func (s serverConfigV13) GetRegion() string { } // SetCredentials set new credentials. -func (s *serverConfigV13) SetCredential(creds credential) { +func (s *serverConfigV14) SetCredential(creds credential) { serverConfigMu.Lock() defer serverConfigMu.Unlock() @@ -177,15 +191,32 @@ func (s *serverConfigV13) SetCredential(creds credential) { } // GetCredentials get current credentials. -func (s serverConfigV13) GetCredential() credential { +func (s serverConfigV14) GetCredential() credential { serverConfigMu.RLock() defer serverConfigMu.RUnlock() return s.Credential } +// SetBrowser set if browser is enabled. +func (s *serverConfigV14) SetBrowser(v string) { + serverConfigMu.Lock() + defer serverConfigMu.Unlock() + + // Set browser param + s.Browser = v +} + +// GetCredentials get current credentials. +func (s serverConfigV14) GetBrowser() string { + serverConfigMu.RLock() + defer serverConfigMu.RUnlock() + + return s.Browser +} + // Save config. -func (s serverConfigV13) Save() error { +func (s serverConfigV14) Save() error { serverConfigMu.RLock() defer serverConfigMu.RUnlock() diff --git a/cmd/config-v13_test.go b/cmd/config-v14_test.go similarity index 78% rename from cmd/config-v13_test.go rename to cmd/config-v14_test.go index 4b4e420f9..bbf786c3a 100644 --- a/cmd/config-v13_test.go +++ b/cmd/config-v14_test.go @@ -17,6 +17,7 @@ package cmd import ( + "os" "reflect" "testing" ) @@ -114,7 +115,55 @@ func TestServerConfig(t *testing.T) { setGlobalConfigPath(rootPath) // Initialize server config. - if err := loadConfig(credential{}); err != nil { + if err := loadConfig(envParams{}); err != nil { t.Fatalf("Unable to initialize from updated config file %s", err) } } + +func TestServerConfigWithEnvs(t *testing.T) { + + os.Setenv("MINIO_BROWSER", "off") + defer os.Unsetenv("MINIO_BROWSER") + + os.Setenv("MINIO_ACCESS_KEY", "minio") + defer os.Unsetenv("MINIO_ACCESS_KEY") + + os.Setenv("MINIO_SECRET_KEY", "minio123") + defer os.Unsetenv("MINIO_SECRET_KEY") + + defer func() { + globalIsEnvBrowser = false + globalIsEnvCreds = false + }() + + // Get test root. + rootPath, err := getTestRoot() + if err != nil { + t.Error(err) + } + + // Do this only once here. + setGlobalConfigPath(rootPath) + + // Init config + initConfig() + + // remove the root directory after the test ends. + defer removeAll(rootPath) + + // Check if serverConfig has + if serverConfig.GetBrowser() != "off" { + t.Errorf("Expecting browser `off` found %s", serverConfig.GetBrowser()) + } + + // Check if serverConfig has + cred := serverConfig.GetCredential() + + if cred.AccessKey != "minio" { + t.Errorf("Expecting access key to be `minio` found %s", cred.AccessKey) + } + + if cred.SecretKey != "minio123" { + t.Errorf("Expecting access key to be `minio123` found %s", cred.SecretKey) + } +} diff --git a/cmd/globals.go b/cmd/globals.go index 56439f635..deff7ae90 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -19,9 +19,7 @@ package cmd import ( "crypto/x509" "net/url" - "os" "runtime" - "strings" "time" humanize "github.com/dustin/go-humanize" @@ -74,9 +72,12 @@ var ( // Indicates if the running minio server is an erasure-code backend. globalIsXL = false - // This flag is set to 'true' by default, it is set to `false` - // when MINIO_BROWSER env is set to 'off'. - globalIsBrowserEnabled = !strings.EqualFold(os.Getenv("MINIO_BROWSER"), "off") + // This flag is set to 'true' by default + globalIsBrowserEnabled = true + // This flag is set to 'true' when MINIO_BROWSER env is set. + globalIsEnvBrowser = false + // Set to true if credentials were passed from env, default is false. + globalIsEnvCreds = false // Maximum cache size. Defaults to disabled. // Caching is enabled only for RAM size > 8GiB. @@ -113,9 +114,6 @@ var ( // Minio server user agent string. globalServerUserAgent = "Minio/" + ReleaseTag + " (" + runtime.GOOS + "; " + runtime.GOARCH + ")" - // Set to true if credentials were passed from env, default is false. - globalIsEnvCreds = false - // url.URL endpoints of disks that belong to the object storage. globalEndpoints = []*url.URL{} diff --git a/cmd/main.go b/cmd/main.go index 1516cd086..18d3ab20a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -159,14 +159,24 @@ func checkUpdate() { } } +// envParams holds all env parameters +type envParams struct { + creds credential + browser string +} + // Initializes a new config if it doesn't exist, else migrates any old config // to newer config and finally loads the config to memory. func initConfig() { - envCreds := mustGetCredentialFromEnv() + + envs := envParams{ + creds: mustGetCredentialFromEnv(), + browser: mustGetBrowserFromEnv(), + } // Config file does not exist, we create it fresh and return upon success. if !isConfigFileExists() { - if err := newConfig(envCreds); err != nil { + if err := newConfig(envs); err != nil { console.Fatalf("Unable to initialize minio config for the first time. Err: %s.\n", err) } console.Println("Created minio configuration file successfully at " + mustGetConfigPath()) @@ -177,7 +187,7 @@ func initConfig() { migrate() // Once we have migrated all the old config, now load them. - if err := loadConfig(envCreds); err != nil { + if err := loadConfig(envs); err != nil { console.Fatalf("Unable to initialize minio config. Err: %s.\n", err) } } diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index 7ef2f25b2..cb1d8d1e2 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -533,7 +533,7 @@ func newTestConfig(bucketLocation string) (rootPath string, err error) { setGlobalConfigPath(rootPath) // Initialize server config. - if err = newConfig(credential{}); err != nil { + if err = newConfig(envParams{}); err != nil { return "", err } diff --git a/cmd/utils.go b/cmd/utils.go index a6a158d48..46166147c 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -23,11 +23,13 @@ import ( "io" "net/http" "net/url" + "os" "strings" "encoding/json" humanize "github.com/dustin/go-humanize" + "github.com/minio/mc/pkg/console" "github.com/pkg/profile" ) @@ -238,3 +240,25 @@ func dumpRequest(r *http.Request) string { } return string(jsonBytes) } + +// Variant of getBrowserFromEnv but upon error fails right here. +func mustGetBrowserFromEnv() string { + browser, err := getBrowserFromEnv() + if err != nil { + console.Fatalf("Unable to load MINIO_BROWSER value from environment. Err: %s.\n", err) + } + return browser +} + +// +func getBrowserFromEnv() (string, error) { + b := os.Getenv("MINIO_BROWSER") + if strings.TrimSpace(b) == "" { + return "", nil + } + if !strings.EqualFold(b, "off") && !strings.EqualFold(b, "on") { + return "", errInvalidArgument + } + globalIsEnvBrowser = true + return strings.ToLower(b), nil +} From fcad4a44fd01279955921a8c4054820d396021da Mon Sep 17 00:00:00 2001 From: Rushan Date: Wed, 1 Mar 2017 02:41:34 +0530 Subject: [PATCH 31/94] Browser: Remove duplicate object entries while sorting (#3813) --- browser/app/js/reducers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/app/js/reducers.js b/browser/app/js/reducers.js index 9deec34cb..421d24cce 100644 --- a/browser/app/js/reducers.js +++ b/browser/app/js/reducers.js @@ -83,7 +83,7 @@ export default (state = { newState.marker = "" newState.istruncated = action.istruncated } else { - newState.objects = [...newState.objects, ...action.objects] + newState.objects = [...action.objects] newState.marker = action.marker newState.istruncated = action.istruncated } From 097cec676aa0e2bbd75a2cdd36f5fd3e7abe08f9 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Wed, 1 Mar 2017 06:21:52 +0530 Subject: [PATCH 32/94] fix: Set globalMaxCacheSize to allowable value. (#3816) If memory resource limit and total RAM are more than 8GiB, either 50% of memory resource limit or total RAM is set to globalMaxCacheSize. --- cmd/server-rlimit-nix.go | 30 ++++++++++++++++++++---------- cmd/server-rlimit-openbsd.go | 30 ++++++++++++++++++++---------- cmd/server-rlimit-win.go | 18 ++++++++++++------ 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/cmd/server-rlimit-nix.go b/cmd/server-rlimit-nix.go index 03341a6b1..b58720cbe 100644 --- a/cmd/server-rlimit-nix.go +++ b/cmd/server-rlimit-nix.go @@ -59,25 +59,35 @@ func setMaxMemory() error { if err != nil { return err } + err = syscall.Getrlimit(syscall.RLIMIT_AS, &rLimit) if err != nil { return err } - // Validate if rlimit memory is set to lower - // than max cache size. Then we should use such value. - if uint64(rLimit.Cur) < globalMaxCacheSize { - globalMaxCacheSize = uint64(float64(50*rLimit.Cur) / 100) + // If current rlimit is less than minRAMSize, do not set globalMaxCacheSize. + if rLimit.Cur < minRAMSize { + return nil } - // Make sure globalMaxCacheSize is less than RAM size. + // Get total RAM. stats, err := sys.GetStats() - if err != nil && err != sys.ErrNotImplemented { + if err != nil { + // Ignore sys.ErrNotImplemented error. + if err == sys.ErrNotImplemented { + err = nil + } + return err } - // If TotalRAM is >= minRAMSize we proceed to enable cache. - // cache is always 50% of the totalRAM. - if err == nil && stats.TotalRAM >= minRAMSize { - globalMaxCacheSize = uint64(float64(50*stats.TotalRAM) / 100) + + // Set 50% of current rlimit or total RAM to globalMaxCacheSize. + if stats.TotalRAM >= minRAMSize { + if rLimit.Cur < stats.TotalRAM { + globalMaxCacheSize = rLimit.Cur / 2 + } else { + globalMaxCacheSize = stats.TotalRAM / 2 + } } + return nil } diff --git a/cmd/server-rlimit-openbsd.go b/cmd/server-rlimit-openbsd.go index 16030447e..79cd7c8cb 100644 --- a/cmd/server-rlimit-openbsd.go +++ b/cmd/server-rlimit-openbsd.go @@ -59,25 +59,35 @@ func setMaxMemory() error { if err != nil { return err } + err = syscall.Getrlimit(syscall.RLIMIT_DATA, &rLimit) if err != nil { return err } - // Validate if rlimit memory is set to lower - // than max cache size. Then we should use such value. - if uint64(rLimit.Cur) < globalMaxCacheSize { - globalMaxCacheSize = uint64(float64(50*rLimit.Cur) / 100) + // If current rlimit is less than minRAMSize, do not set globalMaxCacheSize. + if rLimit.Cur < minRAMSize { + return nil } - // Make sure globalMaxCacheSize is less than RAM size. + // Get total RAM. stats, err := sys.GetStats() - if err != nil && err != sys.ErrNotImplemented { + if err != nil { + // Ignore sys.ErrNotImplemented error. + if err == sys.ErrNotImplemented { + err = nil + } + return err } - // If TotalRAM is >= minRAMSize we proceed to enable cache. - // cache is always 50% of the totalRAM. - if err == nil && stats.TotalRAM >= minRAMSize { - globalMaxCacheSize = uint64(float64(50*stats.TotalRAM) / 100) + + // Set 50% of current rlimit or total RAM to globalMaxCacheSize. + if stats.TotalRAM >= minRAMSize { + if rLimit.Cur < stats.TotalRAM { + globalMaxCacheSize = rLimit.Cur / 2 + } else { + globalMaxCacheSize = stats.TotalRAM / 2 + } } + return nil } diff --git a/cmd/server-rlimit-win.go b/cmd/server-rlimit-win.go index 954e0f734..b153392be 100644 --- a/cmd/server-rlimit-win.go +++ b/cmd/server-rlimit-win.go @@ -28,15 +28,21 @@ func setMaxOpenFiles() error { } func setMaxMemory() error { - // Make sure globalMaxCacheSize is less than RAM size. + // Get total RAM. stats, err := sys.GetStats() - if err != nil && err != sys.ErrNotImplemented { + if err != nil { + // Ignore sys.ErrNotImplemented error. + if err == sys.ErrNotImplemented { + err = nil + } + return err } - // If TotalRAM is <= minRAMSize we proceed to enable cache. - // cache is always 50% of the totalRAM. - if err == nil && stats.TotalRAM >= minRAMSize { - globalMaxCacheSize = uint64(float64(50*stats.TotalRAM) / 100) + + // Set 50% of total RAM to globalMaxCacheSize. + if stats.TotalRAM >= minRAMSize { + globalMaxCacheSize = stats.TotalRAM / 2 } + return nil } From 472fa4a6ca4074b4c80e6b7127cabfeede1d5c7c Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 28 Feb 2017 18:00:24 -0800 Subject: [PATCH 33/94] api: Multi object delete should be protected. (#3814) Add missing protection from deleting multiple objects in parallel. Currently we are deleting objects without proper locking through this API. This can cause significant amount of races. --- cmd/bucket-handlers.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 96a6971c0..0f8ef0151 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -277,7 +277,11 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, for index, object := range deleteObjects.Objects { wg.Add(1) go func(i int, obj ObjectIdentifier) { + objectLock := globalNSMutex.NewNSLock(bucket, obj.ObjectName) + objectLock.Lock() + defer objectLock.Unlock() defer wg.Done() + dErr := objectAPI.DeleteObject(bucket, obj.ObjectName) if dErr != nil { dErrs[i] = dErr From 2b0ed21f083e3333bc4508b8c1d0266d7385eca6 Mon Sep 17 00:00:00 2001 From: Karthic Rao Date: Wed, 1 Mar 2017 07:35:52 +0530 Subject: [PATCH 34/94] tests: Fix test server init - cleanup (#3806) --- cmd/benchmark-utils_test.go | 20 ++------------ cmd/fs-v1-rwpool.go | 28 +++++++++++++++++-- cmd/test-utils_test.go | 55 +++++++++++++++++++++---------------- 3 files changed, 59 insertions(+), 44 deletions(-) diff --git a/cmd/benchmark-utils_test.go b/cmd/benchmark-utils_test.go index bcd231568..0bd8f3c3d 100644 --- a/cmd/benchmark-utils_test.go +++ b/cmd/benchmark-utils_test.go @@ -28,25 +28,9 @@ import ( humanize "github.com/dustin/go-humanize" ) -// Prepare benchmark backend +// Prepare XL/FS backend for benchmark. func prepareBenchmarkBackend(instanceType string) (ObjectLayer, []string, error) { - switch instanceType { - // Total number of disks for FS backend is set to 1. - case FSTestStr: - obj, disk, err := prepareFS() - if err != nil { - return nil, nil, err - } - return obj, []string{disk}, nil - // Total number of disks for XL backend is set to 16. - case XLTestStr: - return prepareXL() - } - obj, disk, err := prepareFS() - if err != nil { - return nil, nil, err - } - return obj, []string{disk}, nil + return prepareTestBackend(instanceType) } // Benchmark utility functions for ObjectLayer.PutObject(). diff --git a/cmd/fs-v1-rwpool.go b/cmd/fs-v1-rwpool.go index b568c05d5..74a0f38b9 100644 --- a/cmd/fs-v1-rwpool.go +++ b/cmd/fs-v1-rwpool.go @@ -50,7 +50,6 @@ func (fsi *fsIOPool) Open(path string) (*lock.RLockedFile, error) { fsi.Lock() rlkFile, ok := fsi.readersMap[path] - // File reference exists on map, validate if its // really closed and we are safe to purge it. if ok && rlkFile != nil { @@ -76,8 +75,9 @@ func (fsi *fsIOPool) Open(path string) (*lock.RLockedFile, error) { // read lock mode. if !ok { var err error + var newRlkFile *lock.RLockedFile // Open file for reading. - rlkFile, err = lock.RLockedOpenFile(preparePath(path)) + newRlkFile, err = lock.RLockedOpenFile(preparePath(path)) if err != nil { if os.IsNotExist(err) { return nil, errFileNotFound @@ -95,6 +95,30 @@ func (fsi *fsIOPool) Open(path string) (*lock.RLockedFile, error) { // Save new reader on the map. fsi.Lock() + rlkFile, ok = fsi.readersMap[path] + if ok && rlkFile != nil { + // If the file is closed and not removed from map is a bug. + if rlkFile.IsClosed() { + // Log this as an error. + errorIf(errUnexpected, "Unexpected entry found on the map %s", path) + + // Purge the cached lock path from map. + delete(fsi.readersMap, path) + + // Save the newly acquired read locked file. + rlkFile = newRlkFile + } else { + // Increment the lock ref, since the file is not closed yet + // and caller requested to read the file again. + rlkFile.IncLockRef() + newRlkFile.Close() + } + } else { + // Save the newly acquired read locked file. + rlkFile = newRlkFile + } + + // Save the rlkFile back on the map. fsi.readersMap[path] = rlkFile fsi.Unlock() } diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index cb1d8d1e2..ef21fb881 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -75,19 +75,11 @@ func prepareFS() (ObjectLayer, string, error) { if err != nil { return nil, "", err } - endpoints, err := parseStorageEndpoints(fsDirs) + obj, err := newFSObjectLayer(fsDirs[0]) if err != nil { return nil, "", err } - fsPath, err := url.QueryUnescape(endpoints[0].String()) - if err != nil { - return nil, "", err - } - obj, err := newFSObjectLayer(fsPath) - if err != nil { - return nil, "", err - } - return obj, endpoints[0].Path, nil + return obj, fsDirs[0], nil } func prepareXL() (ObjectLayer, []string, error) { @@ -193,16 +185,18 @@ type TestServer struct { SrvCmdCfg serverCmdConfig } +// UnstartedTestServer - Configures a temp FS/XL backend, +// initializes the endpoints and configures the test server. +// The server should be started using the Start() method. func UnstartedTestServer(t TestErrHandler, instanceType string) TestServer { // create an instance of TestServer. testServer := TestServer{} - // create temporary backend for the test server. - nDisks := 16 - disks, err := getRandomDisks(nDisks) + // return FS/XL object layer and temp backend. + objLayer, disks, err := prepareTestBackend(instanceType) if err != nil { - t.Fatal("Failed to create disks for the backend") + t.Fatal(err) } - + // set the server configuration. root, err := newTestConfig(globalMinioDefaultRegion) if err != nil { t.Fatalf("%s", err) @@ -212,19 +206,15 @@ func UnstartedTestServer(t TestErrHandler, instanceType string) TestServer { // Get credential. credentials := serverConfig.GetCredential() - testServer.Root = root + testServer.Obj = objLayer testServer.Disks, err = parseStorageEndpoints(disks) if err != nil { - t.Fatalf("Unexpected error %s", err) + t.Fatalf("Unexpected error %v", err) } + testServer.Root = root testServer.AccessKey = credentials.AccessKey testServer.SecretKey = credentials.SecretKey - objLayer, _, err := initObjectLayer(testServer.Disks) - if err != nil { - t.Fatalf("Failed obtaining Temp Backend: %s", err) - } - srvCmdCfg := serverCmdConfig{ endpoints: testServer.Disks, } @@ -238,10 +228,9 @@ func UnstartedTestServer(t TestErrHandler, instanceType string) TestServer { // Run TestServer. testServer.Server = httptest.NewUnstartedServer(httpHandler) - + // obtain server address. srvCmdCfg.serverAddr = testServer.Server.Listener.Addr().String() - testServer.Obj = objLayer globalObjLayerMutex.Lock() globalObjectAPI = objLayer globalObjLayerMutex.Unlock() @@ -1774,6 +1763,24 @@ func initAPIHandlerTest(obj ObjectLayer, endpoints []string) (string, http.Handl return bucketName, f, nil } +// prepare test backend. +// create FS/XL bankend. +// return object layer, backend disks. +func prepareTestBackend(instanceType string) (ObjectLayer, []string, error) { + switch instanceType { + // Total number of disks for XL backend is set to 16. + case XLTestStr: + return prepareXL() + default: + // return FS backend by default. + obj, disk, err := prepareFS() + if err != nil { + return nil, nil, err + } + return obj, []string{disk}, nil + } +} + // ExecObjectLayerAPIAnonTest - Helper function to validate object Layer API handler // response for anonymous/unsigned and unknown signature type HTTP request. From 91cf54f895095dc0ec7ca6e41186790cac46876e Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Tue, 28 Feb 2017 19:07:28 -0800 Subject: [PATCH 35/94] web-handlers: Support removal of multiple objects at once. (#3810) --- appveyor.yml | 2 +- cmd/web-handlers.go | 86 ++++++++++++++++++++++++++++------------ cmd/web-handlers_test.go | 11 ++++- 3 files changed, 71 insertions(+), 28 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index cdb5719cb..5a87b661a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,7 +36,7 @@ test_script: # Unit tests - ps: Add-AppveyorTest "Unit Tests" -Outcome Running - mkdir build\coverage - - go test -timeout 15m -race github.com/minio/minio/cmd... + - go test -timeout 17m -race github.com/minio/minio/cmd... - go test -race github.com/minio/minio/pkg... - go test -coverprofile=build\coverage\coverage.txt -covermode=atomic github.com/minio/minio/cmd - ps: Update-AppveyorTest "Unit Tests" -Outcome Passed diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index 420338cb0..0170adc6a 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -249,10 +249,12 @@ func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, r } // RemoveObjectArgs - args to remove an object +// JSON will look like: +// '{"bucketname":"testbucket","prefix":"john/pics/","objects":["hawaii/","maldives/","sanjose.jpg"]}' type RemoveObjectArgs struct { - TargetHost string `json:"targetHost"` - BucketName string `json:"bucketName"` - ObjectName string `json:"objectName"` + Objects []string `json:"objects"` // can be files or sub-directories + Prefix string `json:"prefix"` // current directory in the browser-ui + BucketName string `json:"bucketname"` // bucket name. } // RemoveObject - removes an object. @@ -264,31 +266,65 @@ func (web *webAPIHandlers) RemoveObject(r *http.Request, args *RemoveObjectArgs, if !isHTTPRequestValid(r) { return toJSONError(errAuthentication) } - - objectLock := globalNSMutex.NewNSLock(args.BucketName, args.ObjectName) - objectLock.Lock() - defer objectLock.Unlock() - - if err := objectAPI.DeleteObject(args.BucketName, args.ObjectName); err != nil { - if isErrObjectNotFound(err) { - // Ignore object not found error. - reply.UIVersion = browser.UIVersion - return nil + if args.BucketName == "" || len(args.Objects) == 0 { + return toJSONError(errUnexpected) + } + var err error +objectLoop: + for _, object := range args.Objects { + remove := func(objectName string) error { + objectLock := globalNSMutex.NewNSLock(args.BucketName, objectName) + objectLock.Lock() + defer objectLock.Unlock() + err = objectAPI.DeleteObject(args.BucketName, objectName) + if err == nil { + // Notify object deleted event. + eventNotify(eventData{ + Type: ObjectRemovedDelete, + Bucket: args.BucketName, + ObjInfo: ObjectInfo{ + Name: objectName, + }, + ReqParams: map[string]string{ + "sourceIPAddress": r.RemoteAddr, + }, + }) + } + return err + } + if !hasSuffix(object, slashSeparator) { + // If not a directory, compress the file and write it to response. + err = remove(pathJoin(args.Prefix, object)) + if err != nil { + break objectLoop + } + continue + } + // For directories, list the contents recursively and remove. + marker := "" + for { + var lo ListObjectsInfo + lo, err = objectAPI.ListObjects(args.BucketName, pathJoin(args.Prefix, object), marker, "", 1000) + if err != nil { + break objectLoop + } + marker = lo.NextMarker + for _, obj := range lo.Objects { + err = remove(obj.Name) + if err != nil { + break objectLoop + } + } + if !lo.IsTruncated { + break + } } - return toJSONError(err, args.BucketName, args.ObjectName) } - // Notify object deleted event. - eventNotify(eventData{ - Type: ObjectRemovedDelete, - Bucket: args.BucketName, - ObjInfo: ObjectInfo{ - Name: args.ObjectName, - }, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, - }) + if err != nil && !isErrObjectNotFound(err) { + // Ignore object not found error. + return toJSONError(err, args.BucketName, "") + } reply.UIVersion = browser.UIVersion return nil diff --git a/cmd/web-handlers_test.go b/cmd/web-handlers_test.go index 912200624..15ec48a4f 100644 --- a/cmd/web-handlers_test.go +++ b/cmd/web-handlers_test.go @@ -468,7 +468,14 @@ func testRemoveObjectWebHandler(obj ObjectLayer, instanceType string, t TestErrH t.Fatalf("Was not able to upload an object, %v", err) } - removeObjectRequest := RemoveObjectArgs{BucketName: bucketName, ObjectName: objectName} + objectName = "a/object" + _, err = obj.PutObject(bucketName, objectName, int64(len(data)), bytes.NewReader(data), + map[string]string{"md5Sum": "c9a34cfc85d982698c6ac89f76071abd"}, "") + if err != nil { + t.Fatalf("Was not able to upload an object, %v", err) + } + + removeObjectRequest := RemoveObjectArgs{BucketName: bucketName, Prefix: "", Objects: []string{"a/", "object"}} removeObjectReply := &WebGenericRep{} req, err := newTestWebRPCRequest("Web.RemoveObject", authorization, removeObjectRequest) if err != nil { @@ -483,7 +490,7 @@ func testRemoveObjectWebHandler(obj ObjectLayer, instanceType string, t TestErrH t.Fatalf("Failed, %v", err) } - removeObjectRequest = RemoveObjectArgs{BucketName: bucketName, ObjectName: objectName} + removeObjectRequest = RemoveObjectArgs{BucketName: bucketName, Prefix: "", Objects: []string{"a/", "object"}} removeObjectReply = &WebGenericRep{} req, err = newTestWebRPCRequest("Web.RemoveObject", authorization, removeObjectRequest) if err != nil { From 77c1998a3830f12a7fe29a7b07d6cd34f9c57c1b Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Wed, 1 Mar 2017 18:17:04 +0100 Subject: [PATCH 36/94] config: Fix creating new config with wrong version (#3821) Simplify a little config code to avoid making mistake next time. --- cmd/config-migrate_test.go | 2 +- cmd/config-v14.go | 62 +++++++++++++++++++++----------------- cmd/config-v14_test.go | 4 +-- cmd/globals.go | 1 - 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/cmd/config-migrate_test.go b/cmd/config-migrate_test.go index 35f2d802d..c35b2ef89 100644 --- a/cmd/config-migrate_test.go +++ b/cmd/config-migrate_test.go @@ -151,7 +151,7 @@ func TestServerConfigMigrateV2toV14(t *testing.T) { } // Check the version number in the upgraded config file - expectedVersion := globalMinioConfigVersion + expectedVersion := v14 if serverConfig.Version != expectedVersion { t.Fatalf("Expect version "+expectedVersion+", found: %v", serverConfig.Version) } diff --git a/cmd/config-v14.go b/cmd/config-v14.go index 1ae69405b..fa4e3b0b3 100644 --- a/cmd/config-v14.go +++ b/cmd/config-v14.go @@ -17,6 +17,7 @@ package cmd import ( + "errors" "os" "strings" "sync" @@ -27,6 +28,9 @@ import ( // Read Write mutex for safe access to ServerConfig. var serverConfigMu sync.RWMutex +// Config version +var v14 = "14" + // serverConfigV14 server configuration version '14' which is like // version '13' except it adds support of browser param. type serverConfigV14 struct { @@ -44,30 +48,15 @@ type serverConfigV14 struct { Notify *notifier `json:"notify"` } -// newConfig - initialize a new server config, saves env parameters if -// found, otherwise use default parameters -func newConfig(envParams envParams) error { - // Initialize server config. +func newServerConfigV14() *serverConfigV14 { srvCfg := &serverConfigV14{ - Logger: &logger{}, - Notify: ¬ifier{}, + Version: v14, + Region: globalMinioDefaultRegion, + Logger: &logger{}, + Notify: ¬ifier{}, } - srvCfg.Version = globalMinioConfigVersion - srvCfg.Region = globalMinioDefaultRegion - - // If env is set for a fresh start, save them to config file. - if globalIsEnvCreds { - srvCfg.SetCredential(envParams.creds) - } else { - srvCfg.SetCredential(newCredential()) - } - - if globalIsEnvBrowser { - srvCfg.SetBrowser(envParams.browser) - } else { - srvCfg.SetBrowser("on") - } - + srvCfg.SetCredential(newCredential()) + srvCfg.SetBrowser("on") // Enable console logger by default on a fresh run. srvCfg.Logger.Console = consoleLogger{ Enable: true, @@ -90,6 +79,24 @@ func newConfig(envParams envParams) error { srvCfg.Notify.Webhook = make(map[string]webhookNotify) srvCfg.Notify.Webhook["1"] = webhookNotify{} + return srvCfg +} + +// newConfig - initialize a new server config, saves env parameters if +// found, otherwise use default parameters +func newConfig(envParams envParams) error { + // Initialize server config. + srvCfg := newServerConfigV14() + + // If env is set for a fresh start, save them to config file. + if globalIsEnvCreds { + srvCfg.SetCredential(envParams.creds) + } + + if globalIsEnvBrowser { + srvCfg.SetBrowser(envParams.browser) + } + // Create config path. if err := createConfigPath(); err != nil { return err @@ -117,8 +124,9 @@ func loadConfig(envParams envParams) error { if _, err = os.Stat(configFile); err != nil { return err } + srvCfg := &serverConfigV14{} - srvCfg.Version = globalMinioConfigVersion + qc, err := quick.New(srvCfg) if err != nil { return err @@ -131,8 +139,6 @@ func loadConfig(envParams envParams) error { // If env is set override the credentials from config file. if globalIsEnvCreds { srvCfg.SetCredential(envParams.creds) - } else { - srvCfg.SetCredential(srvCfg.Credential) } if globalIsEnvBrowser { @@ -149,8 +155,10 @@ func loadConfig(envParams envParams) error { serverConfig = srvCfg serverConfigMu.Unlock() - // Set the version properly after the unmarshalled json is loaded. - serverConfig.Version = globalMinioConfigVersion + if serverConfig.Version != v14 { + return errors.New("Unsupported config version `" + serverConfig.Version + "`.") + } + return nil } diff --git a/cmd/config-v14_test.go b/cmd/config-v14_test.go index bbf786c3a..63f0c4ebd 100644 --- a/cmd/config-v14_test.go +++ b/cmd/config-v14_test.go @@ -102,8 +102,8 @@ func TestServerConfig(t *testing.T) { }) // Match version. - if serverConfig.GetVersion() != globalMinioConfigVersion { - t.Errorf("Expecting version %s found %s", serverConfig.GetVersion(), globalMinioConfigVersion) + if serverConfig.GetVersion() != v14 { + t.Errorf("Expecting version %s found %s", serverConfig.GetVersion(), v14) } // Attempt to save. diff --git a/cmd/globals.go b/cmd/globals.go index deff7ae90..8ffd08712 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -31,7 +31,6 @@ import ( // minio configuration related constants. const ( - globalMinioConfigVersion = "13" globalMinioConfigDir = ".minio" globalMinioCertsDir = "certs" globalMinioCertsCADir = "CAs" From 09e9fd745ce1b58e2ede37e01f2f93c8e40772c2 Mon Sep 17 00:00:00 2001 From: Aditya Manthramurthy Date: Wed, 1 Mar 2017 22:48:55 +0530 Subject: [PATCH 37/94] Close client connection after checking for release update (#3820) --- cmd/update-main.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmd/update-main.go b/cmd/update-main.go index e1348a3a8..21498679d 100644 --- a/cmd/update-main.go +++ b/cmd/update-main.go @@ -155,6 +155,10 @@ func downloadReleaseData(releaseChecksumURL string, timeout time.Duration) (data client := &http.Client{ Timeout: timeout, + Transport: &http.Transport{ + // need to close connection after usage. + DisableKeepAlives: true, + }, } resp, err := client.Do(req) @@ -164,6 +168,7 @@ func downloadReleaseData(releaseChecksumURL string, timeout time.Duration) (data if resp == nil { return data, fmt.Errorf("No response from server to download URL %s", releaseChecksumURL) } + defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return data, fmt.Errorf("Error downloading URL %s. Response: %v", releaseChecksumURL, resp.Status) From 480ea826dcd3f3dad6d7739cea322f2245f55ab7 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Thu, 2 Mar 2017 11:21:57 +0530 Subject: [PATCH 38/94] Move rlimit functions into sys package. (#3824) This patch addresses below * go build works for bsd family * probe total RAM size for bsd family * make unit testable functions --- cmd/server-rlimit-nix.go | 93 -------------------------------- cmd/server-rlimit-openbsd.go | 93 -------------------------------- cmd/server-rlimit-win.go | 48 ----------------- cmd/server-rlimit.go | 73 +++++++++++++++++++++++++ cmd/server-rlimit_test.go | 43 +++++++++++++++ pkg/sys/rlimit-file_bsd.go | 40 ++++++++++++++ pkg/sys/rlimit-file_nix.go | 38 +++++++++++++ pkg/sys/rlimit-file_test.go | 40 ++++++++++++++ pkg/sys/rlimit-file_windows.go | 31 +++++++++++ pkg/sys/rlimit-memory_bsd.go | 38 +++++++++++++ pkg/sys/rlimit-memory_nix.go | 38 +++++++++++++ pkg/sys/rlimit-memory_openbsd.go | 38 +++++++++++++ pkg/sys/rlimit-memory_test.go | 40 ++++++++++++++ pkg/sys/rlimit-memory_windows.go | 31 +++++++++++ pkg/sys/stats.go | 7 +-- pkg/sys/stats_bsd.go | 31 +++++++++-- pkg/sys/stats_darwin.go | 14 ++--- pkg/sys/stats_linux.go | 15 +++--- pkg/sys/stats_test.go | 16 +++++- pkg/sys/stats_windows.go | 15 +++--- 20 files changed, 509 insertions(+), 273 deletions(-) delete mode 100644 cmd/server-rlimit-nix.go delete mode 100644 cmd/server-rlimit-openbsd.go delete mode 100644 cmd/server-rlimit-win.go create mode 100644 cmd/server-rlimit.go create mode 100644 cmd/server-rlimit_test.go create mode 100644 pkg/sys/rlimit-file_bsd.go create mode 100644 pkg/sys/rlimit-file_nix.go create mode 100644 pkg/sys/rlimit-file_test.go create mode 100644 pkg/sys/rlimit-file_windows.go create mode 100644 pkg/sys/rlimit-memory_bsd.go create mode 100644 pkg/sys/rlimit-memory_nix.go create mode 100644 pkg/sys/rlimit-memory_openbsd.go create mode 100644 pkg/sys/rlimit-memory_test.go create mode 100644 pkg/sys/rlimit-memory_windows.go diff --git a/cmd/server-rlimit-nix.go b/cmd/server-rlimit-nix.go deleted file mode 100644 index b58720cbe..000000000 --- a/cmd/server-rlimit-nix.go +++ /dev/null @@ -1,93 +0,0 @@ -// +build !windows,!plan9,!openbsd - -/* - * Minio Cloud Storage, (C) 2016 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import ( - "syscall" - - "github.com/minio/minio/pkg/sys" -) - -// For all unixes we need to bump allowed number of open files to a -// higher value than its usual default of '1024'. The reasoning is -// that this value is too small for a server. -func setMaxOpenFiles() error { - var rLimit syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - return err - } - // Set the current limit to Max, it is usually around 4096. - // TO increase this limit further user has to manually edit - // `/etc/security/limits.conf` - rLimit.Cur = rLimit.Max - return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) -} - -// Set max memory used by minio as a process, this value is usually -// set to 'unlimited' but we need to validate additionally to verify -// if any hard limit is set by the user, in such a scenario would need -// to reset the global max cache size to be 80% of the hardlimit set -// by the user. This is done to honor the system limits and not crash. -func setMaxMemory() error { - var rLimit syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_AS, &rLimit) - if err != nil { - return err - } - // Set the current limit to Max, it is default 'unlimited'. - // TO decrease this limit further user has to manually edit - // `/etc/security/limits.conf` - rLimit.Cur = rLimit.Max - err = syscall.Setrlimit(syscall.RLIMIT_AS, &rLimit) - if err != nil { - return err - } - - err = syscall.Getrlimit(syscall.RLIMIT_AS, &rLimit) - if err != nil { - return err - } - // If current rlimit is less than minRAMSize, do not set globalMaxCacheSize. - if rLimit.Cur < minRAMSize { - return nil - } - - // Get total RAM. - stats, err := sys.GetStats() - if err != nil { - // Ignore sys.ErrNotImplemented error. - if err == sys.ErrNotImplemented { - err = nil - } - - return err - } - - // Set 50% of current rlimit or total RAM to globalMaxCacheSize. - if stats.TotalRAM >= minRAMSize { - if rLimit.Cur < stats.TotalRAM { - globalMaxCacheSize = rLimit.Cur / 2 - } else { - globalMaxCacheSize = stats.TotalRAM / 2 - } - } - - return nil -} diff --git a/cmd/server-rlimit-openbsd.go b/cmd/server-rlimit-openbsd.go deleted file mode 100644 index 79cd7c8cb..000000000 --- a/cmd/server-rlimit-openbsd.go +++ /dev/null @@ -1,93 +0,0 @@ -// +build openbsd - -/* - * Minio Cloud Storage, (C) 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import ( - "syscall" - - "github.com/minio/minio/pkg/sys" -) - -// For all unixes we need to bump allowed number of open files to a -// higher value than its usual default of '1024'. The reasoning is -// that this value is too small for a server. -func setMaxOpenFiles() error { - var rLimit syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) - if err != nil { - return err - } - // Set the current limit to Max, it is usually around 4096. - // TO increase this limit further user has to manually edit - // `/etc/security/limits.conf` - rLimit.Cur = rLimit.Max - return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) -} - -// Set max memory used by minio as a process, this value is usually -// set to 'unlimited' but we need to validate additionally to verify -// if any hard limit is set by the user, in such a scenario would need -// to reset the global max cache size to be 80% of the hardlimit set -// by the user. This is done to honor the system limits and not crash. -func setMaxMemory() error { - var rLimit syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_DATA, &rLimit) - if err != nil { - return err - } - // Set the current limit to Max, it is default 'unlimited'. - // TO decrease this limit further user has to manually edit - // `/etc/security/limits.conf` - rLimit.Cur = rLimit.Max - err = syscall.Setrlimit(syscall.RLIMIT_DATA, &rLimit) - if err != nil { - return err - } - - err = syscall.Getrlimit(syscall.RLIMIT_DATA, &rLimit) - if err != nil { - return err - } - // If current rlimit is less than minRAMSize, do not set globalMaxCacheSize. - if rLimit.Cur < minRAMSize { - return nil - } - - // Get total RAM. - stats, err := sys.GetStats() - if err != nil { - // Ignore sys.ErrNotImplemented error. - if err == sys.ErrNotImplemented { - err = nil - } - - return err - } - - // Set 50% of current rlimit or total RAM to globalMaxCacheSize. - if stats.TotalRAM >= minRAMSize { - if rLimit.Cur < stats.TotalRAM { - globalMaxCacheSize = rLimit.Cur / 2 - } else { - globalMaxCacheSize = stats.TotalRAM / 2 - } - } - - return nil -} diff --git a/cmd/server-rlimit-win.go b/cmd/server-rlimit-win.go deleted file mode 100644 index b153392be..000000000 --- a/cmd/server-rlimit-win.go +++ /dev/null @@ -1,48 +0,0 @@ -// +build windows - -/* - * Minio Cloud Storage, (C) 2016 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import "github.com/minio/minio/pkg/sys" - -func setMaxOpenFiles() error { - // Golang uses Win32 file API (CreateFile, WriteFile, ReadFile, - // CloseHandle, etc.), then you don't have a limit on open files - // (well, you do but it is based on your resources like memory). - return nil -} - -func setMaxMemory() error { - // Get total RAM. - stats, err := sys.GetStats() - if err != nil { - // Ignore sys.ErrNotImplemented error. - if err == sys.ErrNotImplemented { - err = nil - } - - return err - } - - // Set 50% of total RAM to globalMaxCacheSize. - if stats.TotalRAM >= minRAMSize { - globalMaxCacheSize = stats.TotalRAM / 2 - } - - return nil -} diff --git a/cmd/server-rlimit.go b/cmd/server-rlimit.go new file mode 100644 index 000000000..2daf92a8b --- /dev/null +++ b/cmd/server-rlimit.go @@ -0,0 +1,73 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "github.com/minio/minio/pkg/sys" +) + +func setMaxOpenFiles() error { + _, maxLimit, err := sys.GetMaxOpenFileLimit() + if err != nil { + return err + } + + return sys.SetMaxOpenFileLimit(maxLimit, maxLimit) +} + +func getMaxCacheSize(curLimit, totalRAM uint64) (cacheSize uint64) { + // Return zero if current limit or totalTAM is less than minRAMSize. + if curLimit < minRAMSize || totalRAM < minRAMSize { + return cacheSize + } + + // Return 50% of current rlimit or total RAM as cache size. + if curLimit < totalRAM { + cacheSize = curLimit / 2 + } else { + cacheSize = totalRAM / 2 + } + + return cacheSize +} + +func setMaxMemory() error { + // Get max memory limit + _, maxLimit, err := sys.GetMaxMemoryLimit() + if err != nil { + return err + } + + // Set max memory limit as current memory limit. + if err = sys.SetMaxMemoryLimit(maxLimit, maxLimit); err != nil { + return err + } + + // Get total RAM. + stats, err := sys.GetStats() + if err != nil { + return err + } + + // In some OS like windows, maxLimit is zero. Set total RAM as maxLimit. + if maxLimit == 0 { + maxLimit = stats.TotalRAM + } + + globalMaxCacheSize = getMaxCacheSize(maxLimit, stats.TotalRAM) + return nil +} diff --git a/cmd/server-rlimit_test.go b/cmd/server-rlimit_test.go new file mode 100644 index 000000000..57b9d83e4 --- /dev/null +++ b/cmd/server-rlimit_test.go @@ -0,0 +1,43 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import "testing" + +func TestGetMaxCacheSize(t *testing.T) { + testCases := []struct { + curLimit uint64 + totalRAM uint64 + expectedResult uint64 + }{ + {uint64(0), uint64(0), uint64(0)}, + {minRAMSize, uint64(0), uint64(0)}, + {uint64(0), minRAMSize, uint64(0)}, + {uint64(18446744073709551615), uint64(8115998720), uint64(0)}, + {uint64(8115998720), uint64(16115998720), uint64(0)}, + {minRAMSize, minRAMSize, uint64(4294967296)}, + {minRAMSize, uint64(16115998720), uint64(4294967296)}, + {uint64(18446744073709551615), uint64(10115998720), uint64(5057999360)}, + } + + for _, testCase := range testCases { + cacheSize := getMaxCacheSize(testCase.curLimit, testCase.totalRAM) + if testCase.expectedResult != cacheSize { + t.Fatalf("expected: %v, got: %v", testCase.expectedResult, cacheSize) + } + } +} diff --git a/pkg/sys/rlimit-file_bsd.go b/pkg/sys/rlimit-file_bsd.go new file mode 100644 index 000000000..ca0c8b28f --- /dev/null +++ b/pkg/sys/rlimit-file_bsd.go @@ -0,0 +1,40 @@ +// +build freebsd dragonfly + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +import ( + "syscall" +) + +// GetMaxOpenFileLimit - returns maximum file descriptor number that can be opened by this process. +func GetMaxOpenFileLimit() (curLimit, maxLimit uint64, err error) { + var rlimit syscall.Rlimit + if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err == nil { + curLimit = uint64(rlimit.Cur) + maxLimit = uint64(rlimit.Max) + } + + return curLimit, maxLimit, err +} + +// SetMaxOpenFileLimit - sets maximum file descriptor number that can be opened by this process. +func SetMaxOpenFileLimit(curLimit, maxLimit uint64) error { + rlimit := syscall.Rlimit{Cur: int64(curLimit), Max: int64(curLimit)} + return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit) +} diff --git a/pkg/sys/rlimit-file_nix.go b/pkg/sys/rlimit-file_nix.go new file mode 100644 index 000000000..f6940c66c --- /dev/null +++ b/pkg/sys/rlimit-file_nix.go @@ -0,0 +1,38 @@ +// +build linux darwin openbsd netbsd + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +import "syscall" + +// GetMaxOpenFileLimit - returns maximum file descriptor number that can be opened by this process. +func GetMaxOpenFileLimit() (curLimit, maxLimit uint64, err error) { + var rlimit syscall.Rlimit + if err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err == nil { + curLimit = rlimit.Cur + maxLimit = rlimit.Max + } + + return curLimit, maxLimit, err +} + +// SetMaxOpenFileLimit - sets maximum file descriptor number that can be opened by this process. +func SetMaxOpenFileLimit(curLimit, maxLimit uint64) error { + rlimit := syscall.Rlimit{Cur: curLimit, Max: maxLimit} + return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit) +} diff --git a/pkg/sys/rlimit-file_test.go b/pkg/sys/rlimit-file_test.go new file mode 100644 index 000000000..e26cd9c24 --- /dev/null +++ b/pkg/sys/rlimit-file_test.go @@ -0,0 +1,40 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +import "testing" + +// Test get max open file limit. +func TestGetMaxOpenFileLimit(t *testing.T) { + _, _, err := GetMaxOpenFileLimit() + if err != nil { + t.Errorf("expected: nil, got: %v", err) + } +} + +// Test set open file limit +func TestSetMaxOpenFileLimit(t *testing.T) { + curLimit, maxLimit, err := GetMaxOpenFileLimit() + if err != nil { + t.Fatalf("Unable to get max open file limit. %v", err) + } + + err = SetMaxOpenFileLimit(curLimit, maxLimit) + if err != nil { + t.Errorf("expected: nil, got: %v", err) + } +} diff --git a/pkg/sys/rlimit-file_windows.go b/pkg/sys/rlimit-file_windows.go new file mode 100644 index 000000000..ed50f42d7 --- /dev/null +++ b/pkg/sys/rlimit-file_windows.go @@ -0,0 +1,31 @@ +// +build windows + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +// GetMaxOpenFileLimit - returns maximum file descriptor number that can be opened by this process. +func GetMaxOpenFileLimit() (curLimit, maxLimit uint64, err error) { + // Nothing to do for windows. + return curLimit, maxLimit, err +} + +// SetMaxOpenFileLimit - sets maximum file descriptor number that can be opened by this process. +func SetMaxOpenFileLimit(curLimit, maxLimit uint64) error { + // Nothing to do for windows. + return nil +} diff --git a/pkg/sys/rlimit-memory_bsd.go b/pkg/sys/rlimit-memory_bsd.go new file mode 100644 index 000000000..078577b4a --- /dev/null +++ b/pkg/sys/rlimit-memory_bsd.go @@ -0,0 +1,38 @@ +// +build freebsd dragonfly + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +import "syscall" + +// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. +func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { + var rlimit syscall.Rlimit + if err = syscall.Getrlimit(syscall.RLIMIT_DATA, &rlimit); err == nil { + curLimit = uint64(rlimit.Cur) + maxLimit = uint64(rlimit.Max) + } + + return curLimit, maxLimit, err +} + +// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. +func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { + rlimit := syscall.Rlimit{Cur: int64(curLimit), Max: int64(maxLimit)} + return syscall.Setrlimit(syscall.RLIMIT_DATA, &rlimit) +} diff --git a/pkg/sys/rlimit-memory_nix.go b/pkg/sys/rlimit-memory_nix.go new file mode 100644 index 000000000..797b4e187 --- /dev/null +++ b/pkg/sys/rlimit-memory_nix.go @@ -0,0 +1,38 @@ +// +build linux darwin netbsd + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +import "syscall" + +// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. +func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { + var rlimit syscall.Rlimit + if err = syscall.Getrlimit(syscall.RLIMIT_AS, &rlimit); err == nil { + curLimit = rlimit.Cur + maxLimit = rlimit.Max + } + + return curLimit, maxLimit, err +} + +// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. +func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { + rlimit := syscall.Rlimit{Cur: curLimit, Max: maxLimit} + return syscall.Setrlimit(syscall.RLIMIT_AS, &rlimit) +} diff --git a/pkg/sys/rlimit-memory_openbsd.go b/pkg/sys/rlimit-memory_openbsd.go new file mode 100644 index 000000000..83e8d858e --- /dev/null +++ b/pkg/sys/rlimit-memory_openbsd.go @@ -0,0 +1,38 @@ +// +build openbsd + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +import "syscall" + +// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. +func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { + var rlimit syscall.Rlimit + if err = syscall.Getrlimit(syscall.RLIMIT_DATA, &rlimit); err == nil { + curLimit = rlimit.Cur + maxLimit = rlimit.Max + } + + return curLimit, maxLimit, err +} + +// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. +func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { + rlimit := syscall.Rlimit{Cur: curLimit, Max: maxLimit} + return syscall.Setrlimit(syscall.RLIMIT_DATA, &rlimit) +} diff --git a/pkg/sys/rlimit-memory_test.go b/pkg/sys/rlimit-memory_test.go new file mode 100644 index 000000000..b01385004 --- /dev/null +++ b/pkg/sys/rlimit-memory_test.go @@ -0,0 +1,40 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +import "testing" + +// Test get max memory limit. +func TestGetMaxMemoryLimit(t *testing.T) { + _, _, err := GetMaxMemoryLimit() + if err != nil { + t.Errorf("expected: nil, got: %v", err) + } +} + +// Test set memory limit +func TestSetMaxMemoryLimit(t *testing.T) { + curLimit, maxLimit, err := GetMaxMemoryLimit() + if err != nil { + t.Fatalf("Unable to get max memory limit. %v", err) + } + + err = SetMaxMemoryLimit(curLimit, maxLimit) + if err != nil { + t.Errorf("expected: nil, got: %v", err) + } +} diff --git a/pkg/sys/rlimit-memory_windows.go b/pkg/sys/rlimit-memory_windows.go new file mode 100644 index 000000000..0a900d636 --- /dev/null +++ b/pkg/sys/rlimit-memory_windows.go @@ -0,0 +1,31 @@ +// +build windows + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sys + +// GetMaxMemoryLimit - returns the maximum size of the process's virtual memory (address space) in bytes. +func GetMaxMemoryLimit() (curLimit, maxLimit uint64, err error) { + // Nothing to do for windows. + return curLimit, maxLimit, err +} + +// SetMaxMemoryLimit - sets the maximum size of the process's virtual memory (address space) in bytes. +func SetMaxMemoryLimit(curLimit, maxLimit uint64) error { + // Nothing to do for windows. + return nil +} diff --git a/pkg/sys/stats.go b/pkg/sys/stats.go index ea89c7ec9..87aaabad9 100644 --- a/pkg/sys/stats.go +++ b/pkg/sys/stats.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,6 @@ package sys -import "errors" - -// ErrNotImplemented - GetStats() is not implemented on bsds. -var ErrNotImplemented = errors.New("not implemented") - // Stats - system statistics. type Stats struct { TotalRAM uint64 // Physical RAM size in bytes, diff --git a/pkg/sys/stats_bsd.go b/pkg/sys/stats_bsd.go index 276d0c01b..fa6488971 100644 --- a/pkg/sys/stats_bsd.go +++ b/pkg/sys/stats_bsd.go @@ -1,7 +1,7 @@ -// +build !linux,!windows,!darwin +// +build openbsd netbsd freebsd dragonfly /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016,2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,28 @@ package sys -// GetStats - return system statistics for windows. -func GetStats() (stats Stats, err error) { - return Stats{}, ErrNotImplemented +import ( + "encoding/binary" + "syscall" +) + +func getHwPhysmem() (uint64, error) { + totalString, err := syscall.Sysctl("hw.physmem") + if err != nil { + return 0, err + } + + // syscall.sysctl() helpfully assumes the result is a null-terminated string and + // removes the last byte of the result if it's 0 :/ + totalString += "\x00" + + total := uint64(binary.LittleEndian.Uint64([]byte(totalString))) + + return total, nil +} + +// GetStats - return system statistics for bsd. +func GetStats() (stats Stats, err error) { + stats.TotalRAM, err = getHwPhysmem() + return stats, err } diff --git a/pkg/sys/stats_darwin.go b/pkg/sys/stats_darwin.go index 98d9dcc31..01fae14a0 100644 --- a/pkg/sys/stats_darwin.go +++ b/pkg/sys/stats_darwin.go @@ -1,7 +1,7 @@ // +build darwin /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016,2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,14 +38,8 @@ func getHwMemsize() (uint64, error) { return total, nil } -// GetStats - return system statistics for windows. +// GetStats - return system statistics for macOS. func GetStats() (stats Stats, err error) { - memSize, err := getHwMemsize() - if err != nil { - return Stats{}, err - } - stats = Stats{ - TotalRAM: memSize, - } - return stats, nil + stats.TotalRAM, err = getHwMemsize() + return stats, err } diff --git a/pkg/sys/stats_linux.go b/pkg/sys/stats_linux.go index 090235bc4..6cd5c6002 100644 --- a/pkg/sys/stats_linux.go +++ b/pkg/sys/stats_linux.go @@ -1,7 +1,7 @@ // +build linux /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016,2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,13 +22,10 @@ import "syscall" // GetStats - return system statistics. func GetStats() (stats Stats, err error) { - si := syscall.Sysinfo_t{} - err = syscall.Sysinfo(&si) - if err != nil { - return + var si syscall.Sysinfo_t + if err = syscall.Sysinfo(&si); err == nil { + stats.TotalRAM = uint64(si.Totalram) } - stats = Stats{ - TotalRAM: uint64(si.Totalram), - } - return stats, nil + + return stats, err } diff --git a/pkg/sys/stats_test.go b/pkg/sys/stats_test.go index 1a713aed8..e2666639e 100644 --- a/pkg/sys/stats_test.go +++ b/pkg/sys/stats_test.go @@ -1,4 +1,18 @@ -// +build linux darwin windows +/* + * Minio Cloud Storage, (C) 2016,2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package sys diff --git a/pkg/sys/stats_windows.go b/pkg/sys/stats_windows.go index 7ae7b9437..08d168428 100644 --- a/pkg/sys/stats_windows.go +++ b/pkg/sys/stats_windows.go @@ -1,7 +1,7 @@ // +build windows /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016,2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,12 +44,11 @@ type memoryStatusEx struct { func GetStats() (stats Stats, err error) { var memInfo memoryStatusEx memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) - mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) - if mem == 0 { - return Stats{}, syscall.GetLastError() + if mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))); mem == 0 { + err = syscall.GetLastError() + } else { + stats.TotalRAM = memInfo.ullTotalPhys } - stats = Stats{ - TotalRAM: memInfo.ullTotalPhys, - } - return stats, nil + + return stats, err } From 2348ae7a193eb043c3277d253169584f84b5303b Mon Sep 17 00:00:00 2001 From: Bala FA Date: Thu, 2 Mar 2017 18:28:39 +0530 Subject: [PATCH 39/94] Make default values as constants (#3828) --- cmd/retry.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/retry.go b/cmd/retry.go index 5e42182c6..1624b0e2d 100644 --- a/cmd/retry.go +++ b/cmd/retry.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -122,7 +122,7 @@ func newRetryTimerWithJitter(unit time.Duration, cap time.Duration, jitter float } // Default retry constants. -var ( +const ( defaultRetryUnit = time.Second // 1 second. defaultRetryCap = 30 * time.Second // 30 seconds. ) From d1afd16955ac4474b598dc34ee6c9e2ce4e9b452 Mon Sep 17 00:00:00 2001 From: Zejun Li Date: Fri, 3 Mar 2017 02:00:22 +0800 Subject: [PATCH 40/94] Using RWMutex to guard closing and listeners (#3829) --- cmd/server-mux.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/server-mux.go b/cmd/server-mux.go index 4208a5807..3ef812a5e 100644 --- a/cmd/server-mux.go +++ b/cmd/server-mux.go @@ -334,7 +334,7 @@ type ServerMux struct { // Time to wait before forcing server shutdown gracefulTimeout time.Duration - mu sync.Mutex // guards closing, and listeners + mu sync.RWMutex // guards closing, and listeners closing bool } @@ -461,9 +461,9 @@ func (m *ServerMux) ListenAndServe(certFile, keyFile string) (err error) { // Return ServiceUnavailable for clients which are sending requests // in shutdown phase - m.mu.Lock() + m.mu.RLock() closing := m.closing - m.mu.Unlock() + m.mu.RUnlock() if closing { w.WriteHeader(http.StatusServiceUnavailable) return From a179fc96585ff58b9a5ef9b0e777202307bcc747 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Thu, 2 Mar 2017 19:29:07 +0100 Subject: [PATCH 41/94] quick: Simplify Load() and CheckVersion() (#3831) --- pkg/quick/quick.go | 53 +++++----------------------------------------- 1 file changed, 5 insertions(+), 48 deletions(-) diff --git a/pkg/quick/quick.go b/pkg/quick/quick.go index 15094e522..32b7e0390 100644 --- a/pkg/quick/quick.go +++ b/pkg/quick/quick.go @@ -85,34 +85,12 @@ func New(data interface{}) (Config, error) { // CheckVersion - loads json and compares the version number provided returns back true or false - any failure // is returned as error. func CheckVersion(filename string, version string) (bool, error) { - _, err := os.Stat(filename) - if err != nil { - return false, err - } - - fileData, err := ioutil.ReadFile(filename) - if err != nil { - return false, err - } - - if runtime.GOOS == "windows" { - fileData = []byte(strings.Replace(string(fileData), "\r\n", "\n", -1)) - } data := struct { Version string }{ Version: "", } - err = json.Unmarshal(fileData, &data) - if err != nil { - switch err := err.(type) { - case *json.SyntaxError: - return false, FormatJSONSyntaxError(bytes.NewReader(fileData), err) - default: - return false, err - } - } - config, err := New(data) + config, err := Load(filename, &data) if err != nil { return false, err } @@ -124,35 +102,14 @@ func CheckVersion(filename string, version string) (bool, error) { // Load - loads json config from filename for the a given struct data func Load(filename string, data interface{}) (Config, error) { - _, err := os.Stat(filename) - if err != nil { - return nil, err - } - - fileData, err := ioutil.ReadFile(filename) - if err != nil { - return nil, err - } - - if runtime.GOOS == "windows" { - fileData = []byte(strings.Replace(string(fileData), "\r\n", "\n", -1)) - } - - err = json.Unmarshal(fileData, &data) - if err != nil { - switch err := err.(type) { - case *json.SyntaxError: - return nil, FormatJSONSyntaxError(bytes.NewReader(fileData), err) - default: - return nil, err - } - } - config, err := New(data) if err != nil { return nil, err } - + err = config.Load(filename) + if err != nil { + return nil, err + } return config, nil } From 208dd152457a683b4b74245a0b9732be336ed95a Mon Sep 17 00:00:00 2001 From: Bala FA Date: Fri, 3 Mar 2017 00:04:37 +0530 Subject: [PATCH 42/94] Remove globalMaxCacheSize and globalCacheExpiry variables (#3826) This patch fixes below * Remove global variables globalMaxCacheSize and globalCacheExpiry. * Make global variables into constant in objcache package. --- cmd/globals.go | 8 ----- cmd/server-main.go | 12 ++----- cmd/server-rlimit.go | 52 ++++++++++++++++------------- cmd/test-utils_test.go | 4 +-- cmd/xl-v1.go | 17 +++++++--- pkg/objcache/README.md | 18 +++++----- pkg/objcache/objcache.go | 37 +++++++++++---------- pkg/objcache/objcache_test.go | 62 ++++++++++++++++++++++++++++------- 8 files changed, 127 insertions(+), 83 deletions(-) diff --git a/cmd/globals.go b/cmd/globals.go index 8ffd08712..4017c7a81 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -26,7 +26,6 @@ import ( "github.com/fatih/color" "github.com/minio/cli" "github.com/minio/mc/pkg/console" - "github.com/minio/minio/pkg/objcache" ) // minio configuration related constants. @@ -78,16 +77,9 @@ var ( // Set to true if credentials were passed from env, default is false. globalIsEnvCreds = false - // Maximum cache size. Defaults to disabled. - // Caching is enabled only for RAM size > 8GiB. - globalMaxCacheSize = uint64(0) - // Maximum size of internal objects parts globalPutPartSize = int64(64 * 1024 * 1024) - // Cache expiry. - globalCacheExpiry = objcache.DefaultExpiry - // Minio local server address (in `host:port` format) globalMinioAddr = "" // Minio default port, can be changed through command line. diff --git a/cmd/server-main.go b/cmd/server-main.go index 3222c07ce..75ce32465 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -138,16 +138,8 @@ func initServerConfig(c *cli.Context) { // Load user supplied root CAs loadRootCAs() - // Set maxOpenFiles, This is necessary since default operating - // system limits of 1024, 2048 are not enough for Minio server. - setMaxOpenFiles() - - // Set maxMemory, This is necessary since default operating - // system limits might be changed and we need to make sure we - // do not crash the server so the set the maxCacheSize appropriately. - setMaxMemory() - - // Do not fail if this is not allowed, lower limits are fine as well. + // Set system resources to maximum. + errorIf(setMaxResources(), "Unable to change resource limit") } // Validate if input disks are sufficient for initializing XL. diff --git a/cmd/server-rlimit.go b/cmd/server-rlimit.go index 2daf92a8b..16a1db4f7 100644 --- a/cmd/server-rlimit.go +++ b/cmd/server-rlimit.go @@ -16,17 +16,27 @@ package cmd -import ( - "github.com/minio/minio/pkg/sys" -) +import "github.com/minio/minio/pkg/sys" -func setMaxOpenFiles() error { - _, maxLimit, err := sys.GetMaxOpenFileLimit() - if err != nil { +func setMaxResources() (err error) { + var maxLimit uint64 + + // Set open files limit to maximum. + if _, maxLimit, err = sys.GetMaxOpenFileLimit(); err != nil { return err } - return sys.SetMaxOpenFileLimit(maxLimit, maxLimit) + if err = sys.SetMaxOpenFileLimit(maxLimit, maxLimit); err != nil { + return err + } + + // Set max memory limit as current memory limit. + if _, maxLimit, err = sys.GetMaxMemoryLimit(); err != nil { + return err + } + + err = sys.SetMaxMemoryLimit(maxLimit, maxLimit) + return err } func getMaxCacheSize(curLimit, totalRAM uint64) (cacheSize uint64) { @@ -45,29 +55,25 @@ func getMaxCacheSize(curLimit, totalRAM uint64) (cacheSize uint64) { return cacheSize } -func setMaxMemory() error { +// GetMaxCacheSize returns maximum cache size based on current RAM size and memory limit. +func GetMaxCacheSize() (cacheSize uint64, err error) { // Get max memory limit - _, maxLimit, err := sys.GetMaxMemoryLimit() - if err != nil { - return err - } - - // Set max memory limit as current memory limit. - if err = sys.SetMaxMemoryLimit(maxLimit, maxLimit); err != nil { - return err + var curLimit uint64 + if curLimit, _, err = sys.GetMaxMemoryLimit(); err != nil { + return cacheSize, err } // Get total RAM. - stats, err := sys.GetStats() - if err != nil { - return err + var stats sys.Stats + if stats, err = sys.GetStats(); err != nil { + return cacheSize, err } // In some OS like windows, maxLimit is zero. Set total RAM as maxLimit. - if maxLimit == 0 { - maxLimit = stats.TotalRAM + if curLimit == 0 { + curLimit = stats.TotalRAM } - globalMaxCacheSize = getMaxCacheSize(maxLimit, stats.TotalRAM) - return nil + cacheSize = getMaxCacheSize(curLimit, stats.TotalRAM) + return cacheSize, err } diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index ef21fb881..63387ef69 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -65,8 +65,8 @@ func init() { // Disable printing console messages during tests. color.Output = ioutil.Discard - // Enable caching. - setMaxMemory() + // Set system resources to maximum. + setMaxResources() } func prepareFS() (ObjectLayer, string, error) { diff --git a/cmd/xl-v1.go b/cmd/xl-v1.go index 4f6083d75..510662e47 100644 --- a/cmd/xl-v1.go +++ b/cmd/xl-v1.go @@ -127,14 +127,23 @@ func newXLObjects(storageDisks []StorageAPI) (ObjectLayer, error) { listPool: listPool, } - // Object cache is enabled when _MINIO_CACHE env is missing. - // and cache size is > 0. - xl.objCacheEnabled = !objCacheDisabled && globalMaxCacheSize > 0 + // Get cache size if _MINIO_CACHE environment variable is set. + var maxCacheSize uint64 + if !objCacheDisabled { + maxCacheSize, err = GetMaxCacheSize() + errorIf(err, "Unable to get maximum cache size") + + // Enable object cache if cache size is more than zero + xl.objCacheEnabled = maxCacheSize > 0 + } // Check if object cache is enabled. if xl.objCacheEnabled { // Initialize object cache. - objCache := objcache.New(globalMaxCacheSize, globalCacheExpiry) + objCache, err := objcache.New(maxCacheSize, objcache.DefaultExpiry) + if err != nil { + return nil, err + } objCache.OnEviction = func(key string) { debug.FreeOSMemory() } diff --git a/pkg/objcache/README.md b/pkg/objcache/README.md index 283ceff6f..fdafea98d 100644 --- a/pkg/objcache/README.md +++ b/pkg/objcache/README.md @@ -6,22 +6,24 @@ package objcache Package objcache implements in memory caching methods. +CONSTANTS + + const ( + // NoExpiry represents caches to be permanent and can only be deleted. + NoExpiry = time.Duration(0) + + // DefaultExpiry represents three days time duration when individual entries will be expired. + DefaultExpiry = time.Duration(3 * 24 * time.Hour) + ) + VARIABLES -var DefaultExpiry = time.Duration(72 * time.Hour) // 72hrs. - - DefaultExpiry represents default time duration value when individual - entries will be expired. - var ErrCacheFull = errors.New("Not enough space in cache") ErrCacheFull - cache is full. var ErrKeyNotFoundInCache = errors.New("Key not found in cache") ErrKeyNotFoundInCache - key not found in cache. -var NoExpiry = time.Duration(0) - NoExpiry represents caches to be permanent and can only be deleted. - TYPES type Cache struct { diff --git a/pkg/objcache/objcache.go b/pkg/objcache/objcache.go index d07a86214..43eb31dc2 100644 --- a/pkg/objcache/objcache.go +++ b/pkg/objcache/objcache.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,18 +27,20 @@ import ( "time" ) -// NoExpiry represents caches to be permanent and can only be deleted. -var NoExpiry = time.Duration(0) +const ( + // NoExpiry represents caches to be permanent and can only be deleted. + NoExpiry = time.Duration(0) -// DefaultExpiry represents default time duration value when individual entries will be expired. -var DefaultExpiry = time.Duration(72 * time.Hour) // 72hrs. + // DefaultExpiry represents three days time duration when individual entries will be expired. + DefaultExpiry = time.Duration(3 * 24 * time.Hour) -// DefaultBufferRatio represents default ratio used to calculate the -// individual cache entry buffer size. -var DefaultBufferRatio = uint64(10) + // defaultBufferRatio represents default ratio used to calculate the + // individual cache entry buffer size. + defaultBufferRatio = uint64(10) -// DefaultGCPercent represents default garbage collection target percentage. -var DefaultGCPercent = 20 + // defaultGCPercent represents default garbage collection target percentage. + defaultGCPercent = 20 +) // buffer represents the in memory cache of a single entry. // buffer carries value of the data and last accessed time. @@ -87,9 +89,10 @@ type Cache struct { // duration. If the expiry duration is less than one // (or NoExpiry), the items in the cache never expire // (by default), and must be deleted manually. -func New(maxSize uint64, expiry time.Duration) *Cache { +func New(maxSize uint64, expiry time.Duration) (c *Cache, err error) { if maxSize == 0 { - panic("objcache: setting maximum cache size to zero is forbidden.") + err = errors.New("invalid maximum cache size") + return c, err } // A garbage collection is triggered when the ratio @@ -106,20 +109,20 @@ func New(maxSize uint64, expiry time.Duration) *Cache { // when we get to 8M. // // Set this value to 20% if caching is enabled. - debug.SetGCPercent(DefaultGCPercent) + debug.SetGCPercent(defaultGCPercent) // Max cache entry size - indicates the // maximum buffer per key that can be held in // memory. Currently this value is 1/10th // the size of requested cache size. maxCacheEntrySize := func() uint64 { - i := maxSize / DefaultBufferRatio + i := maxSize / defaultBufferRatio if i == 0 { i = maxSize } return i }() - c := &Cache{ + c = &Cache{ onceGC: sync.Once{}, maxSize: maxSize, maxCacheEntrySize: maxCacheEntrySize, @@ -134,7 +137,7 @@ func New(maxSize uint64, expiry time.Duration) *Cache { // Start garbage collection routine to expire objects. c.StartGC() } - return c + return c, nil } // ErrKeyNotFoundInCache - key not found in cache. @@ -177,7 +180,7 @@ func (c *Cache) Create(key string, size int64) (w io.WriteCloser, err error) { // Change GC percent if the current cache usage // is already 75% of the maximum allowed usage. if c.currentSize > (75 * c.maxSize / 100) { - c.onceGC.Do(func() { debug.SetGCPercent(DefaultGCPercent - 10) }) + c.onceGC.Do(func() { debug.SetGCPercent(defaultGCPercent - 10) }) } c.mutex.Unlock() diff --git a/pkg/objcache/objcache_test.go b/pkg/objcache/objcache_test.go index 25cd1c69a..147c2fcc4 100644 --- a/pkg/objcache/objcache_test.go +++ b/pkg/objcache/objcache_test.go @@ -43,7 +43,11 @@ func TestObjExpiry(t *testing.T) { // Test case 1 validates running of GC. testCase := testCases[0] - cache := New(testCase.cacheSize, testCase.expiry) + cache, err := New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + cache.OnEviction = func(key string) {} w, err := cache.Create("test", 1) if err != nil { @@ -126,15 +130,23 @@ func TestObjCache(t *testing.T) { // Test 1 validating Open failure. testCase := testCases[0] - cache := New(testCase.cacheSize, testCase.expiry) - _, err := cache.Open("test", fakeObjModTime) + cache, err := New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + + _, err = cache.Open("test", fakeObjModTime) if testCase.err != err { t.Errorf("Test case 2 expected to pass, failed instead %s", err) } // Test 2 validating Create failure. testCase = testCases[1] - cache = New(testCase.cacheSize, testCase.expiry) + cache, err = New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + _, err = cache.Create("test", 2) if testCase.err != err { t.Errorf("Test case 2 expected to pass, failed instead %s", err) @@ -144,7 +156,11 @@ func TestObjCache(t *testing.T) { // Subsequently we Close() without writing any data, to receive // `io.ErrShortBuffer` testCase = testCases[2] - cache = New(testCase.cacheSize, testCase.expiry) + cache, err = New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + w, err := cache.Create("test", 1) if testCase.err != err { t.Errorf("Test case 3 expected to pass, failed instead %s", err) @@ -156,7 +172,11 @@ func TestObjCache(t *testing.T) { // Test 4 validates Create and Close succeeds successfully caching // the writes. testCase = testCases[3] - cache = New(testCase.cacheSize, testCase.expiry) + cache, err = New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + w, err = cache.Create("test", 5) if testCase.err != err { t.Errorf("Test case 4 expected to pass, failed instead %s", err) @@ -184,7 +204,11 @@ func TestObjCache(t *testing.T) { // Test 5 validates Delete succeeds and Open fails with err testCase = testCases[4] - cache = New(testCase.cacheSize, testCase.expiry) + cache, err = New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + w, err = cache.Create("test", 5) if err != nil { t.Errorf("Test case 5 expected to pass, failed instead %s", err) @@ -204,7 +228,11 @@ func TestObjCache(t *testing.T) { // Test 6 validates OnEviction being called upon Delete is being invoked. testCase = testCases[5] - cache = New(testCase.cacheSize, testCase.expiry) + cache, err = New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + w, err = cache.Create("test", 5) if err != nil { t.Errorf("Test case 6 expected to pass, failed instead %s", err) @@ -227,7 +255,11 @@ func TestObjCache(t *testing.T) { // Test 7 validates rejecting requests when excess data is being saved. testCase = testCases[6] - cache = New(testCase.cacheSize, testCase.expiry) + cache, err = New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + w, err = cache.Create("test1", 5) if err != nil { t.Errorf("Test case 7 expected to pass, failed instead %s", err) @@ -245,7 +277,11 @@ func TestObjCache(t *testing.T) { // Test 8 validates rejecting Writes which write excess data. testCase = testCases[7] - cache = New(testCase.cacheSize, testCase.expiry) + cache, err = New(testCase.cacheSize, testCase.expiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + w, err = cache.Create("test1", 5) if err != nil { t.Errorf("Test case 8 expected to pass, failed instead %s", err) @@ -267,7 +303,11 @@ func TestObjCache(t *testing.T) { // TestStateEntryPurge - tests if objCache purges stale entry and returns ErrKeyNotFoundInCache. func TestStaleEntryPurge(t *testing.T) { - cache := New(1024, NoExpiry) + cache, err := New(1024, NoExpiry) + if err != nil { + t.Fatalf("Unable to create new objcache") + } + w, err := cache.Create("test", 5) if err != nil { t.Errorf("Test case expected to pass, failed instead %s", err) From 98d17d2a97e6db184a6b86104624610dfe124d17 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Fri, 3 Mar 2017 03:51:30 +0530 Subject: [PATCH 43/94] Remove globalQuiet and globalConfigDir global variables (#3830) --- cmd/admin-rpc-client.go | 19 +++---- cmd/admin-rpc-server.go | 33 ++++-------- cmd/certs.go | 102 ++++++++++++++----------------------- cmd/certs_test.go | 11 ++-- cmd/config-migrate.go | 73 ++++++-------------------- cmd/config-migrate_test.go | 8 +-- cmd/config-old.go | 66 +++++------------------- cmd/config-v14.go | 15 ++---- cmd/config-v14_test.go | 4 +- cmd/config.go | 97 +++++++++++++++-------------------- cmd/globals.go | 23 --------- cmd/main.go | 35 ++----------- cmd/prepare-storage-msg.go | 4 +- cmd/server-main.go | 26 ++++++++-- cmd/server-mux_test.go | 8 +-- cmd/server-startup-msg.go | 5 -- cmd/test-utils_test.go | 4 +- cmd/utils.go | 9 ++++ 18 files changed, 178 insertions(+), 364 deletions(-) diff --git a/cmd/admin-rpc-client.go b/cmd/admin-rpc-client.go index 9241731e1..a1a482878 100644 --- a/cmd/admin-rpc-client.go +++ b/cmd/admin-rpc-client.go @@ -19,6 +19,7 @@ package cmd import ( "encoding/json" "errors" + "fmt" "net/url" "os" "path" @@ -176,20 +177,12 @@ func (rc remoteAdminClient) WriteTmpConfig(tmpFileName string, configBytes []byt // CommitConfig - Move the new config in tmpFileName onto config.json // on a local node. func (lc localAdminClient) CommitConfig(tmpFileName string) error { - configDir, err := getConfigPath() - if err != nil { - errorIf(err, "Failed to get config directory path.") - return err - } + configFile := getConfigFile() + tmpConfigFile := filepath.Join(getConfigDir(), tmpFileName) - configFilePath := filepath.Join(configDir, globalMinioConfigFile) - err = os.Rename(filepath.Join(configDir, tmpFileName), configFilePath) - if err != nil { - errorIf(err, "Failed to rename to config.json") - return err - } - - return nil + err := os.Rename(tmpConfigFile, configFile) + errorIf(err, fmt.Sprintf("Failed to rename %s to %s", tmpConfigFile, configFile)) + return err } // CommitConfig - Move the new config in tmpFileName onto config.json diff --git a/cmd/admin-rpc-server.go b/cmd/admin-rpc-server.go index 6109b9c43..855044a64 100644 --- a/cmd/admin-rpc-server.go +++ b/cmd/admin-rpc-server.go @@ -19,6 +19,7 @@ package cmd import ( "encoding/json" "errors" + "fmt" "io/ioutil" "net/rpc" "os" @@ -175,17 +176,9 @@ type WriteConfigReply struct { } func writeTmpConfigCommon(tmpFileName string, configBytes []byte) error { - configDir, err := getConfigPath() - if err != nil { - errorIf(err, "Failed to get config path") - return err - } - - err = ioutil.WriteFile(filepath.Join(configDir, tmpFileName), configBytes, 0666) - if err != nil { - errorIf(err, "Failed to write to temporary config file.") - return err - } + tmpConfigFile := filepath.Join(getConfigDir(), tmpFileName) + err := ioutil.WriteFile(tmpConfigFile, configBytes, 0666) + errorIf(err, fmt.Sprintf("Failed to write to temporary config file %s", tmpConfigFile)) return err } @@ -214,20 +207,12 @@ type CommitConfigReply struct { // CommitConfig - Renames the temporary file into config.json on this node. func (s *adminCmd) CommitConfig(cArgs *CommitConfigArgs, cReply *CommitConfigReply) error { - configDir, err := getConfigPath() - if err != nil { - errorIf(err, "Failed to get config path.") - return err - } + configFile := getConfigFile() + tmpConfigFile := filepath.Join(getConfigDir(), cArgs.FileName) - configFilePath := filepath.Join(configDir, globalMinioConfigFile) - err = os.Rename(filepath.Join(configDir, cArgs.FileName), configFilePath) - if err != nil { - errorIf(err, "Failed to rename config file.") - return err - } - - return nil + err := os.Rename(tmpConfigFile, configFile) + errorIf(err, fmt.Sprintf("Failed to rename %s to %s", tmpConfigFile, configFile)) + return err } // registerAdminRPCRouter - registers RPC methods for service status, diff --git a/cmd/certs.go b/cmd/certs.go index ce24bf37f..4c8311122 100644 --- a/cmd/certs.go +++ b/cmd/certs.go @@ -21,90 +21,62 @@ import ( "encoding/pem" "errors" "io/ioutil" - "os" "path/filepath" ) +// getCertsPath get certs path. +func getCertsPath() string { + return filepath.Join(getConfigDir(), globalMinioCertsDir) +} + +// getCertFile must get cert file. +func getCertFile() string { + return filepath.Join(getCertsPath(), globalMinioCertFile) +} + +// getKeyFile must get key file. +func getKeyFile() string { + return filepath.Join(getCertsPath(), globalMinioKeyFile) +} + // createCertsPath create certs path. func createCertsPath() error { - certsPath, err := getCertsPath() - if err != nil { - return err + rootCAsPath := filepath.Join(getCertsPath(), globalMinioCertsCADir) + return mkdirAll(rootCAsPath, 0700) +} + +// getCAFiles must get the list of the CA certificates stored in minio config dir +func getCAFiles() (caCerts []string) { + CAsDir := filepath.Join(getCertsPath(), globalMinioCertsCADir) + if caFiles, err := ioutil.ReadDir(CAsDir); err == nil { + // Ignore any error. + for _, cert := range caFiles { + caCerts = append(caCerts, filepath.Join(CAsDir, cert.Name())) + } } - if err := os.MkdirAll(certsPath, 0700); err != nil { - return err - } - rootCAsPath := filepath.Join(certsPath, globalMinioCertsCADir) - return os.MkdirAll(rootCAsPath, 0700) + return caCerts } -// getCertsPath get certs path. -func getCertsPath() (string, error) { - var certsPath string - configDir, err := getConfigPath() - if err != nil { - return "", err - } - certsPath = filepath.Join(configDir, globalMinioCertsDir) - return certsPath, nil -} - -// mustGetCertsPath must get certs path. -func mustGetCertsPath() string { - certsPath, err := getCertsPath() - fatalIf(err, "Failed to get certificate path.") - return certsPath -} - -// mustGetCertFile must get cert file. -func mustGetCertFile() string { - return filepath.Join(mustGetCertsPath(), globalMinioCertFile) -} - -// mustGetKeyFile must get key file. -func mustGetKeyFile() string { - return filepath.Join(mustGetCertsPath(), globalMinioKeyFile) -} - -// mustGetCAFiles must get the list of the CA certificates stored in minio config dir -func mustGetCAFiles() (caCerts []string) { - CAsDir := filepath.Join(mustGetCertsPath(), globalMinioCertsCADir) - caFiles, _ := ioutil.ReadDir(CAsDir) - for _, cert := range caFiles { - caCerts = append(caCerts, filepath.Join(CAsDir, cert.Name())) - } - return -} - -// mustGetSystemCertPool returns empty cert pool in case of error (windows) -func mustGetSystemCertPool() *x509.CertPool { +// getSystemCertPool returns empty cert pool in case of error (windows) +func getSystemCertPool() *x509.CertPool { pool, err := x509.SystemCertPool() if err != nil { - return x509.NewCertPool() + pool = x509.NewCertPool() } + return pool } // isCertFileExists verifies if cert file exists, returns true if // found, false otherwise. func isCertFileExists() bool { - st, e := os.Stat(filepath.Join(mustGetCertsPath(), globalMinioCertFile)) - // If file exists and is regular return true. - if e == nil && st.Mode().IsRegular() { - return true - } - return false + return isFile(getCertFile()) } // isKeyFileExists verifies if key file exists, returns true if found, // false otherwise. func isKeyFileExists() bool { - st, e := os.Stat(filepath.Join(mustGetCertsPath(), globalMinioKeyFile)) - // If file exists and is regular return true. - if e == nil && st.Mode().IsRegular() { - return true - } - return false + return isFile(getKeyFile()) } // isSSL - returns true with both cert and key exists. @@ -114,7 +86,7 @@ func isSSL() bool { // Reads certificated file and returns a list of parsed certificates. func readCertificateChain() ([]*x509.Certificate, error) { - bytes, err := ioutil.ReadFile(mustGetCertFile()) + bytes, err := ioutil.ReadFile(getCertFile()) if err != nil { return nil, err } @@ -149,12 +121,12 @@ func parseCertificateChain(bytes []byte) ([]*x509.Certificate, error) { // loadRootCAs fetches CA files provided in minio config and adds them to globalRootCAs // Currently under Windows, there is no way to load system + user CAs at the same time func loadRootCAs() { - caFiles := mustGetCAFiles() + caFiles := getCAFiles() if len(caFiles) == 0 { return } // Get system cert pool, and empty cert pool under Windows because it is not supported - globalRootCAs = mustGetSystemCertPool() + globalRootCAs = getSystemCertPool() // Load custom root CAs for client requests for _, caFile := range caFiles { caCert, err := ioutil.ReadFile(caFile) diff --git a/cmd/certs_test.go b/cmd/certs_test.go index a68f8176e..5d8c649a9 100644 --- a/cmd/certs_test.go +++ b/cmd/certs_test.go @@ -25,10 +25,7 @@ import ( // Make sure we have a valid certs path. func TestGetCertsPath(t *testing.T) { - path, err := getCertsPath() - if err != nil { - t.Error(err) - } + path := getCertsPath() if path == "" { t.Errorf("expected path to not be an empty string, got: '%s'", path) } @@ -42,18 +39,18 @@ func TestGetCertsPath(t *testing.T) { } // This will error if something goes wrong, so just call it. - mustGetCertsPath() + getCertsPath() } // Ensure that the certificate and key file getters contain their respective // file name and endings. func TestGetFiles(t *testing.T) { - file := mustGetCertFile() + file := getCertFile() if !strings.Contains(file, globalMinioCertFile) { t.Errorf("CertFile does not contain %s", globalMinioCertFile) } - file = mustGetKeyFile() + file = getKeyFile() if !strings.Contains(file, globalMinioKeyFile) { t.Errorf("KeyFile does not contain %s", globalMinioKeyFile) } diff --git a/cmd/config-migrate.go b/cmd/config-migrate.go index e38d1bf4c..e45bdfae5 100644 --- a/cmd/config-migrate.go +++ b/cmd/config-migrate.go @@ -94,15 +94,10 @@ func purgeV1() error { } if cv1.Version == "1" { - console.Println("Removed unsupported config version ‘1’.") - /// Purge old fsUsers.json file - configPath, err := getConfigPath() - if err != nil { - return fmt.Errorf("Unable to retrieve config path. %v", err) - } - - configFile := filepath.Join(configPath, "fsUsers.json") + // Purge old fsUsers.json file + configFile := filepath.Join(getConfigDir(), "fsUsers.json") removeAll(configFile) + console.Println("Removed unsupported config version ‘1’.") return nil } return fmt.Errorf("Failed to migrate unrecognized config version ‘" + cv1.Version + "’.") @@ -158,12 +153,7 @@ func migrateV2ToV3() error { return fmt.Errorf("Unable to initialize config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } - - // Migrate the config. + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf("Failed to migrate config from ‘"+cv2.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) @@ -205,11 +195,8 @@ func migrateV3ToV4() error { if err != nil { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf("Failed to migrate config from ‘"+cv3.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) @@ -254,11 +241,8 @@ func migrateV4ToV5() error { if err != nil { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf("Failed to migrate config from ‘"+cv4.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) @@ -330,11 +314,8 @@ func migrateV5ToV6() error { if err != nil { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf("Failed to migrate config from ‘"+cv5.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) @@ -394,11 +375,8 @@ func migrateV6ToV7() error { if err != nil { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf("Failed to migrate config from ‘"+cv6.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) @@ -465,11 +443,8 @@ func migrateV7ToV8() error { if err != nil { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf("Failed to migrate config from ‘"+cv7.Version+"’ to ‘"+srvConfig.Version+"’ failed. %v", err) @@ -544,11 +519,8 @@ func migrateV8ToV9() error { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf( @@ -629,11 +601,8 @@ func migrateV9ToV10() error { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf( @@ -717,11 +686,8 @@ func migrateV10ToV11() error { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf( @@ -823,11 +789,8 @@ func migrateV11ToV12() error { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf( @@ -920,11 +883,8 @@ func migrateV12ToV13() error { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf( @@ -1022,11 +982,8 @@ func migrateV13ToV14() error { return fmt.Errorf("Unable to initialize the quick config. %v", err) } - configFile, err := getConfigFile() - if err != nil { - return fmt.Errorf("Unable to get config file. %v", err) - } + configFile := getConfigFile() err = qc.Save(configFile) if err != nil { return fmt.Errorf( diff --git a/cmd/config-migrate_test.go b/cmd/config-migrate_test.go index c35b2ef89..359936be3 100644 --- a/cmd/config-migrate_test.go +++ b/cmd/config-migrate_test.go @@ -31,7 +31,7 @@ func TestServerConfigMigrateV1(t *testing.T) { // remove the root directory after the test ends. defer removeAll(rootPath) - setGlobalConfigPath(rootPath) + setConfigDir(rootPath) // Create a V1 config json file and store it configJSON := "{ \"version\":\"1\", \"accessKeyId\":\"abcde\", \"secretAccessKey\":\"abcdefgh\"}" @@ -65,7 +65,7 @@ func TestServerConfigMigrateInexistentConfig(t *testing.T) { // remove the root directory after the test ends. defer removeAll(rootPath) - setGlobalConfigPath(rootPath) + setConfigDir(rootPath) configPath := rootPath + "/" + globalMinioConfigFile // Remove config file @@ -120,7 +120,7 @@ func TestServerConfigMigrateV2toV14(t *testing.T) { // remove the root directory after the test ends. defer removeAll(rootPath) - setGlobalConfigPath(rootPath) + setConfigDir(rootPath) configPath := rootPath + "/" + globalMinioConfigFile // Create a corrupted config file @@ -174,7 +174,7 @@ func TestServerConfigMigrateFaultyConfig(t *testing.T) { // remove the root directory after the test ends. defer removeAll(rootPath) - setGlobalConfigPath(rootPath) + setConfigDir(rootPath) configPath := rootPath + "/" + globalMinioConfigFile // Create a corrupted config file diff --git a/cmd/config-old.go b/cmd/config-old.go index d8fa5867f..7f65003e3 100644 --- a/cmd/config-old.go +++ b/cmd/config-old.go @@ -50,11 +50,7 @@ type configV1 struct { // loadConfigV1 load config func loadConfigV1() (*configV1, error) { - configPath, err := getConfigPath() - if err != nil { - return nil, err - } - configFile := filepath.Join(configPath, "fsUsers.json") + configFile := filepath.Join(getConfigDir(), "fsUsers.json") config, err := loadOldConfig(configFile, &configV1{Version: "1"}) if config == nil { return nil, err @@ -86,10 +82,7 @@ type configV2 struct { // loadConfigV2 load config version '2'. func loadConfigV2() (*configV2, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &configV2{Version: "2"}) if config == nil { return nil, err @@ -152,10 +145,7 @@ type configV3 struct { // loadConfigV3 load config version '3'. func loadConfigV3() (*configV3, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &configV3{Version: "3"}) if config == nil { return nil, err @@ -195,10 +185,7 @@ type configV4 struct { // loadConfigV4 load config version '4'. func loadConfigV4() (*configV4, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &configV4{Version: "4"}) if config == nil { return nil, err @@ -265,10 +252,7 @@ type configV5 struct { // loadConfigV5 load config version '5'. func loadConfigV5() (*configV5, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &configV5{Version: "5"}) if config == nil { return nil, err @@ -299,10 +283,7 @@ type configV6 struct { // loadConfigV6 load config version '6'. func loadConfigV6() (*configV6, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &configV6{Version: "6"}) if config == nil { return nil, err @@ -352,10 +333,7 @@ type serverConfigV7 struct { // loadConfigV7 load config version '7'. func loadConfigV7() (*serverConfigV7, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &serverConfigV7{Version: "7"}) if config == nil { return nil, err @@ -384,10 +362,7 @@ type serverConfigV8 struct { // loadConfigV8 load config version '8'. func loadConfigV8() (*serverConfigV8, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &serverConfigV8{Version: "8"}) if config == nil { return nil, err @@ -415,10 +390,7 @@ type serverConfigV9 struct { } func loadConfigV9() (*serverConfigV9, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &serverConfigV9{Version: "9"}) if config == nil { return nil, err @@ -444,10 +416,7 @@ type serverConfigV10 struct { } func loadConfigV10() (*serverConfigV10, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &serverConfigV10{Version: "10"}) if config == nil { return nil, err @@ -484,10 +453,7 @@ type serverConfigV11 struct { } func loadConfigV11() (*serverConfigV11, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &serverConfigV11{Version: "11"}) if config == nil { return nil, err @@ -512,10 +478,7 @@ type serverConfigV12 struct { } func loadConfigV12() (*serverConfigV12, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &serverConfigV12{Version: "12"}) if config == nil { return nil, err @@ -540,10 +503,7 @@ type serverConfigV13 struct { } func loadConfigV13() (*serverConfigV13, error) { - configFile, err := getConfigFile() - if err != nil { - return nil, err - } + configFile := getConfigFile() config, err := loadOldConfig(configFile, &serverConfigV13{Version: "13"}) if config == nil { return nil, err diff --git a/cmd/config-v14.go b/cmd/config-v14.go index fa4e3b0b3..14ae16725 100644 --- a/cmd/config-v14.go +++ b/cmd/config-v14.go @@ -98,7 +98,7 @@ func newConfig(envParams envParams) error { } // Create config path. - if err := createConfigPath(); err != nil { + if err := createConfigDir(); err != nil { return err } @@ -116,12 +116,8 @@ func newConfig(envParams envParams) error { // loadConfig - loads a new config from disk, overrides params from env // if found and valid func loadConfig(envParams envParams) error { - configFile, err := getConfigFile() - if err != nil { - return err - } - - if _, err = os.Stat(configFile); err != nil { + configFile := getConfigFile() + if _, err := os.Stat(configFile); err != nil { return err } @@ -229,10 +225,7 @@ func (s serverConfigV14) Save() error { defer serverConfigMu.RUnlock() // get config file. - configFile, err := getConfigFile() - if err != nil { - return err - } + configFile := getConfigFile() // initialize quick. qc, err := quick.New(&s) diff --git a/cmd/config-v14_test.go b/cmd/config-v14_test.go index 63f0c4ebd..d3ca1aba4 100644 --- a/cmd/config-v14_test.go +++ b/cmd/config-v14_test.go @@ -112,7 +112,7 @@ func TestServerConfig(t *testing.T) { } // Do this only once here. - setGlobalConfigPath(rootPath) + setConfigDir(rootPath) // Initialize server config. if err := loadConfig(envParams{}); err != nil { @@ -143,7 +143,7 @@ func TestServerConfigWithEnvs(t *testing.T) { } // Do this only once here. - setGlobalConfigPath(rootPath) + setConfigDir(rootPath) // Init config initConfig() diff --git a/cmd/config.go b/cmd/config.go index 618bc2388..59dd831ab 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,77 +17,62 @@ package cmd import ( - "os" "path/filepath" "sync" - "github.com/minio/go-homedir" + homedir "github.com/minio/go-homedir" + "github.com/minio/mc/pkg/console" ) -// configPath for custom config path only for testing purposes -var customConfigPath string -var configMu sync.Mutex - -// Sets a new config path. -func setGlobalConfigPath(configPath string) { - configMu.Lock() - defer configMu.Unlock() - customConfigPath = configPath +// ConfigDir - configuration directory with locking. +type ConfigDir struct { + sync.Mutex + dir string } -// getConfigPath get server config path -func getConfigPath() (string, error) { - configMu.Lock() - defer configMu.Unlock() +// Set - saves given directory as configuration directory. +func (config *ConfigDir) Set(dir string) { + config.Lock() + defer config.Unlock() - if customConfigPath != "" { - return customConfigPath, nil - } + config.dir = dir +} + +// Get - returns current configuration directory. +func (config *ConfigDir) Get() string { + config.Lock() + defer config.Unlock() + + return config.dir +} + +func mustGetDefaultConfigDir() string { homeDir, err := homedir.Dir() if err != nil { - return "", err + console.Fatalln("Unable to get home directory.", err) } - configPath := filepath.Join(homeDir, globalMinioConfigDir) - return configPath, nil + + return filepath.Join(homeDir, globalMinioConfigDir) } -// mustGetConfigPath must get server config path. -func mustGetConfigPath() string { - configPath, err := getConfigPath() - if err != nil { - return "" - } - return configPath +var configDir = &ConfigDir{dir: mustGetDefaultConfigDir()} + +func setConfigDir(dir string) { + configDir.Set(dir) } -// createConfigPath create server config path. -func createConfigPath() error { - configPath, err := getConfigPath() - if err != nil { - return err - } - return os.MkdirAll(configPath, 0700) +func getConfigDir() string { + return configDir.Get() +} + +func createConfigDir() error { + return mkdirAll(getConfigDir(), 0700) +} + +func getConfigFile() string { + return filepath.Join(getConfigDir(), globalMinioConfigFile) } -// isConfigFileExists - returns true if config file exists. func isConfigFileExists() bool { - path, err := getConfigFile() - if err != nil { - return false - } - st, err := os.Stat(path) - // If file exists and is regular return true. - if err == nil && st.Mode().IsRegular() { - return true - } - return false -} - -// getConfigFile get server config file. -func getConfigFile() (string, error) { - configPath, err := getConfigPath() - if err != nil { - return "", err - } - return filepath.Join(configPath, globalMinioConfigFile), nil + return isFile(getConfigFile()) } diff --git a/cmd/globals.go b/cmd/globals.go index 4017c7a81..4f04ce0e9 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -24,8 +24,6 @@ import ( humanize "github.com/dustin/go-humanize" "github.com/fatih/color" - "github.com/minio/cli" - "github.com/minio/mc/pkg/console" ) // minio configuration related constants. @@ -60,10 +58,6 @@ const ( ) var ( - globalQuiet = false // quiet flag set via command line. - globalConfigDir = mustGetConfigPath() // config-dir flag set via command line - // Add new global flags here. - // Indicates if the running minio server is distributed setup. globalIsDistXL = false @@ -131,20 +125,3 @@ var ( colorBold = color.New(color.Bold).SprintFunc() colorBlue = color.New(color.FgBlue).SprintfFunc() ) - -// Parse command arguments and set global variables accordingly -func setGlobalsFromContext(c *cli.Context) { - // Set config dir - switch { - case c.IsSet("config-dir"): - globalConfigDir = c.String("config-dir") - case c.GlobalIsSet("config-dir"): - globalConfigDir = c.GlobalString("config-dir") - } - if globalConfigDir == "" { - console.Fatalf("Unable to get config file. Config directory is empty.") - } - - // Set global quiet flag. - globalQuiet = c.Bool("quiet") || c.GlobalBool("quiet") -} diff --git a/cmd/main.go b/cmd/main.go index 18d3ab20a..d31406d36 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -31,7 +31,7 @@ var ( globalFlags = []cli.Flag{ cli.StringFlag{ Name: "config-dir, C", - Value: mustGetConfigPath(), + Value: getConfigDir(), Usage: "Path to configuration directory.", }, cli.BoolFlag{ @@ -133,26 +133,10 @@ func registerApp() *cli.App { return app } -// Verify main command syntax. -func checkMainSyntax(c *cli.Context) { - configPath, err := getConfigPath() - if err != nil { - console.Fatalf("Unable to obtain user's home directory. \nError: %s\n", err) - } - if configPath == "" { - console.Fatalln("Config directory cannot be empty, please specify --config-dir .") - } -} - // Check for updates and print a notification message func checkUpdate() { - // Do not print update messages, if quiet flag is set. - if !globalQuiet { - older, downloadURL, err := getUpdateInfo(1 * time.Second) - if err != nil { - // Its OK to ignore any errors during getUpdateInfo() here. - return - } + // Its OK to ignore any errors during getUpdateInfo() here. + if older, downloadURL, err := getUpdateInfo(1 * time.Second); err == nil { if older > time.Duration(0) { console.Println(colorizeUpdateMessage(downloadURL, older)) } @@ -179,7 +163,7 @@ func initConfig() { if err := newConfig(envs); err != nil { console.Fatalf("Unable to initialize minio config for the first time. Err: %s.\n", err) } - console.Println("Created minio configuration file successfully at " + mustGetConfigPath()) + console.Println("Created minio configuration file successfully at " + getConfigDir()) return } @@ -194,12 +178,6 @@ func initConfig() { // Generic Minio initialization to create/load config, prepare loggers, etc.. func minioInit(ctx *cli.Context) { - // Set global variables after parsing passed arguments - setGlobalsFromContext(ctx) - - // Sets new config directory. - setGlobalConfigPath(globalConfigDir) - // Is TLS configured?. globalIsSSL = isSSL() @@ -217,11 +195,6 @@ func minioInit(ctx *cli.Context) { // Main main for minio server. func Main(args []string, exitFn func(int)) { app := registerApp() - app.Before = func(c *cli.Context) error { - // Valid input arguments to main. - checkMainSyntax(c) - return nil - } // Start profiler if env is set. if profiler := os.Getenv("_MINIO_PROFILER"); profiler != "" { diff --git a/cmd/prepare-storage-msg.go b/cmd/prepare-storage-msg.go index 445bbefca..58e4d70e1 100644 --- a/cmd/prepare-storage-msg.go +++ b/cmd/prepare-storage-msg.go @@ -46,9 +46,7 @@ func printOnceFn() printOnceFunc { var once sync.Once return func(msg string) { once.Do(func() { - if !globalQuiet { - console.Println(msg) - } + console.Println(msg) }) } } diff --git a/cmd/server-main.go b/cmd/server-main.go index 75ce32465..d06765d2c 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -30,6 +30,7 @@ import ( "runtime" "github.com/minio/cli" + "github.com/minio/mc/pkg/console" ) var serverFlags = []cli.Flag{ @@ -358,11 +359,28 @@ func serverMain(c *cli.Context) { cli.ShowCommandHelpAndExit(c, "server", 1) } + // Get quiet flag from command line argument. + quietFlag := c.Bool("quiet") || c.GlobalBool("quiet") + + // Get configuration directory from command line argument. + configDir := c.String("config-dir") + if !c.IsSet("config-dir") && c.GlobalIsSet("config-dir") { + configDir = c.GlobalString("config-dir") + } + if configDir == "" { + console.Fatalf("Configuration directory cannot be empty.") + } + + // Set configuration directory. + setConfigDir(configDir) + // Initializes server config, certs, logging and system settings. initServerConfig(c) // Check for new updates from dl.minio.io. - checkUpdate() + if !quietFlag { + checkUpdate() + } // Server address. serverAddr := c.String("address") @@ -442,7 +460,7 @@ func serverMain(c *cli.Context) { go func() { cert, key := "", "" if globalIsSSL { - cert, key = mustGetCertFile(), mustGetKeyFile() + cert, key = getCertFile(), getKeyFile() } fatalIf(apiServer.ListenAndServe(cert, key), "Failed to start minio server.") }() @@ -458,7 +476,9 @@ func serverMain(c *cli.Context) { globalObjLayerMutex.Unlock() // Prints the formatted startup message once object layer is initialized. - printStartupMessage(apiEndPoints) + if !quietFlag { + printStartupMessage(apiEndPoints) + } // Set uptime time after object layer has initialized. globalBootTime = time.Now().UTC() diff --git a/cmd/server-mux_test.go b/cmd/server-mux_test.go index 24802abed..c7c39278e 100644 --- a/cmd/server-mux_test.go +++ b/cmd/server-mux_test.go @@ -358,8 +358,8 @@ func TestServerListenAndServeTLS(t *testing.T) { if err != nil { t.Fatal(err) } - certFile := mustGetCertFile() - keyFile := mustGetKeyFile() + certFile := getCertFile() + keyFile := getKeyFile() defer os.RemoveAll(certFile) defer os.RemoveAll(keyFile) @@ -420,8 +420,8 @@ func TestServerListenAndServeTLS(t *testing.T) { // generateTestCert creates a cert and a key used for testing only func generateTestCert(host string) error { - certPath := mustGetCertFile() - keyPath := mustGetKeyFile() + certPath := getCertFile() + keyPath := getKeyFile() priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err diff --git a/cmd/server-startup-msg.go b/cmd/server-startup-msg.go index 53718aa74..dbdecdca6 100644 --- a/cmd/server-startup-msg.go +++ b/cmd/server-startup-msg.go @@ -44,11 +44,6 @@ func getFormatStr(strLen int, padding int) string { // Prints the formatted startup message. func printStartupMessage(apiEndPoints []string) { - // If quiet flag is set do not print startup message. - if globalQuiet { - return - } - // Prints credential, region and browser access. printServerCommonMsg(apiEndPoints) diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index 63387ef69..7d518f267 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -440,7 +440,7 @@ func StartTestPeersRPCServer(t TestErrHandler, instanceType string) TestServer { // Sets the global config path to empty string. func resetGlobalConfigPath() { - setGlobalConfigPath("") + setConfigDir("") } // sets globalObjectAPI to `nil`. @@ -519,7 +519,7 @@ func newTestConfig(bucketLocation string) (rootPath string, err error) { } // Do this only once here. - setGlobalConfigPath(rootPath) + setConfigDir(rootPath) // Initialize server config. if err = newConfig(envParams{}); err != nil { diff --git a/cmd/utils.go b/cmd/utils.go index 46166147c..49657cf13 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -262,3 +262,12 @@ func getBrowserFromEnv() (string, error) { globalIsEnvBrowser = true return strings.ToLower(b), nil } + +// isFile - returns whether given path is a file or not. +func isFile(path string) bool { + if fi, err := os.Stat(path); err == nil { + return fi.Mode().IsRegular() + } + + return false +} From 32d0d3d4ac5f2e3ec88f8fd0357eaacfd0f034b6 Mon Sep 17 00:00:00 2001 From: Zejun Li Date: Fri, 3 Mar 2017 17:07:45 +0800 Subject: [PATCH 44/94] Enhanced newObjectLayerFn (#3837) --- cmd/object-api-common.go | 4 ++-- cmd/routers.go | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cmd/object-api-common.go b/cmd/object-api-common.go index e27131ac6..b5feed0fb 100644 --- a/cmd/object-api-common.go +++ b/cmd/object-api-common.go @@ -38,14 +38,14 @@ const ( ) // Global object layer mutex, used for safely updating object layer. -var globalObjLayerMutex *sync.Mutex +var globalObjLayerMutex *sync.RWMutex // Global object layer, only accessed by newObjectLayerFn(). var globalObjectAPI ObjectLayer func init() { // Initialize this once per server initialization. - globalObjLayerMutex = &sync.Mutex{} + globalObjLayerMutex = &sync.RWMutex{} } // Check if the disk is remote. diff --git a/cmd/routers.go b/cmd/routers.go index 9213f65be..8d386e4fb 100644 --- a/cmd/routers.go +++ b/cmd/routers.go @@ -22,10 +22,11 @@ import ( router "github.com/gorilla/mux" ) -func newObjectLayerFn() ObjectLayer { - globalObjLayerMutex.Lock() - defer globalObjLayerMutex.Unlock() - return globalObjectAPI +func newObjectLayerFn() (layer ObjectLayer) { + globalObjLayerMutex.RLock() + layer = globalObjectAPI + globalObjLayerMutex.RUnlock() + return } // Composed function registering routers for only distributed XL setup. From cddc6845590d1de2c53f34915db3dffe0f4ae232 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Fri, 3 Mar 2017 11:53:48 +0100 Subject: [PATCH 45/94] admin: Set Config returns errSet and errMsg (#3822) There is no way to see if a node encountered an error when trying to set a new config set, this commit adds a bool errSet field. --- cmd/admin-handlers.go | 11 +++++++---- cmd/admin-handlers_test.go | 10 +++++++--- pkg/madmin/API.md | 3 ++- pkg/madmin/config-commands.go | 5 +++-- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 4a21d2cee..98ede6b53 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -718,9 +718,11 @@ func toAdminAPIErrCode(err error) APIErrorCode { // SetConfigResult - represents detailed results of a set-config // operation. type nodeSummary struct { - Name string `json:"name"` - Err string `json:"err"` + Name string `json:"name"` + ErrSet bool `json:"errSet"` + ErrMsg string `json:"errMsg"` } + type setConfigResult struct { NodeResults []nodeSummary `json:"nodeResults"` Status bool `json:"status"` @@ -733,8 +735,9 @@ func writeSetConfigResponse(w http.ResponseWriter, peers adminPeers, errs []erro // set-config operation. for i := range errs { nodeResults = append(nodeResults, nodeSummary{ - Name: peers[i].addr, - Err: fmt.Sprintf("%v", errs[i]), + Name: peers[i].addr, + ErrSet: errs[i] != nil, + ErrMsg: fmt.Sprintf("%v", errs[i]), }) } diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index 931c0c208..a1018d7d0 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -1279,9 +1279,13 @@ func TestWriteSetConfigResponse(t *testing.T) { if res.Name != testPeers[p].addr { t.Errorf("Test %d: Expected node name %s but received %s", i+1, testPeers[p].addr, res.Name) } - expectedErrStr := fmt.Sprintf("%v", test.errs[p]) - if res.Err != expectedErrStr { - t.Errorf("Test %d: Expected error %s but received %s", i+1, expectedErrStr, res.Err) + expectedErrMsg := fmt.Sprintf("%v", test.errs[p]) + if res.ErrMsg != expectedErrMsg { + t.Errorf("Test %d: Expected error %s but received %s", i+1, expectedErrMsg, res.ErrMsg) + } + expectedErrSet := test.errs[p] != nil + if res.ErrSet != expectedErrSet { + t.Errorf("Test %d: Expected ErrSet %v but received %v", i+1, expectedErrSet, res.ErrSet) } } } diff --git a/pkg/madmin/API.md b/pkg/madmin/API.md index 033bb0816..8a6222bce 100644 --- a/pkg/madmin/API.md +++ b/pkg/madmin/API.md @@ -330,7 +330,8 @@ change to take effect. |---|---|---| |`st.Status` | _bool_ | true if set-config succeeded, false otherwise. | |`st.NodeSummary.Name` | _string_ | Network address of the node. | -|`st.NodeSummary.Err` | _string_ | String representation of the error (if any) on the node.| +|`st.NodeSummary.ErrSet` | _bool_ | Bool representation indicating if an error is encountered with the node.| +|`st.NodeSummary.ErrMsg` | _string_ | String representation of the error (if any) on the node.| __Example__ diff --git a/pkg/madmin/config-commands.go b/pkg/madmin/config-commands.go index d63aece4a..e4f8afb53 100644 --- a/pkg/madmin/config-commands.go +++ b/pkg/madmin/config-commands.go @@ -33,8 +33,9 @@ const ( // NodeSummary - represents the result of an operation part of // set-config on a node. type NodeSummary struct { - Name string `json:"name"` - Err string `json:"err"` + Name string `json:"name"` + ErrSet bool `json:"errSet"` + ErrMsg string `json:"errMsg"` } // SetConfigResult - represents detailed results of a set-config From e5d4e7aa9d7ba16bbf0c0fe135eb05102132b528 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 3 Mar 2017 03:01:42 -0800 Subject: [PATCH 46/94] web: Validate if bucket names are reserved (#3841) Both '.minio.sys' and 'minio' should be never allowed to be created from web-ui and then fail to list it by filtering them out. Fixes #3840 --- cmd/generic-handlers.go | 11 +++++------ cmd/object-api-utils.go | 12 +++++++++++- cmd/typed-errors.go | 4 ++++ cmd/web-handlers.go | 22 +++++++++++++++++++++- cmd/web-handlers_test.go | 2 ++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 9af4d6d14..3f94789f5 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -20,7 +20,6 @@ import ( "bufio" "net" "net/http" - "path" "strings" "time" @@ -161,17 +160,17 @@ func (h cacheControlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Adds verification for incoming paths. type minioPrivateBucketHandler struct { - handler http.Handler - reservedBucketPath string + handler http.Handler } func setPrivateBucketHandler(h http.Handler) http.Handler { - return minioPrivateBucketHandler{h, minioReservedBucketPath} + return minioPrivateBucketHandler{h} } func (h minioPrivateBucketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // For all non browser requests, reject access to 'reservedBucketPath'. - if !guessIsBrowserReq(r) && path.Clean(r.URL.Path) == h.reservedBucketPath { + // For all non browser requests, reject access to 'minioReservedBucketPath'. + bucketName, _ := urlPath2BucketObjectName(r.URL) + if !guessIsBrowserReq(r) && isMinioReservedBucket(bucketName) && isMinioMetaBucket(bucketName) { writeErrorResponse(w, ErrAllAccessDisabled, r.URL) return } diff --git a/cmd/object-api-utils.go b/cmd/object-api-utils.go index 9c1878a23..40047657d 100644 --- a/cmd/object-api-utils.go +++ b/cmd/object-api-utils.go @@ -194,7 +194,17 @@ func isReservedOrInvalidBucket(bucketEntry string) bool { if !IsValidBucketName(bucketEntry) { return true } - return bucketEntry == minioMetaBucket || bucketEntry == minioReservedBucket + return isMinioMetaBucket(bucketEntry) || isMinioReservedBucket(bucketEntry) +} + +// Returns true if input bucket is a reserved minio meta bucket '.minio.sys'. +func isMinioMetaBucket(bucketName string) bool { + return bucketName == minioMetaBucket +} + +// Returns true if input bucket is a reserved minio bucket 'minio'. +func isMinioReservedBucket(bucketName string) bool { + return bucketName == minioReservedBucket } // byBucketName is a collection satisfying sort.Interface. diff --git a/cmd/typed-errors.go b/cmd/typed-errors.go index 5a7568568..4b561bf22 100644 --- a/cmd/typed-errors.go +++ b/cmd/typed-errors.go @@ -50,3 +50,7 @@ var errServerVersionMismatch = errors.New("Server versions do not match") // errServerTimeMismatch - server times are too far apart. var errServerTimeMismatch = errors.New("Server times are too far apart") + +// errReservedBucket - bucket name is reserved for Minio, usually +// returned for 'minio', '.minio.sys' +var errReservedBucket = errors.New("All access to this bucket is disabled") diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index 0170adc6a..cfe9cbb48 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -113,7 +113,7 @@ type MakeBucketArgs struct { BucketName string `json:"bucketName"` } -// MakeBucket - make a bucket. +// MakeBucket - creates a new bucket. func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *WebGenericRep) error { objectAPI := web.ObjectAPI() if objectAPI == nil { @@ -122,12 +122,19 @@ func (web *webAPIHandlers) MakeBucket(r *http.Request, args *MakeBucketArgs, rep if !isHTTPRequestValid(r) { return toJSONError(errAuthentication) } + + // Check if bucket is a reserved bucket name. + if isMinioMetaBucket(args.BucketName) || isMinioReservedBucket(args.BucketName) { + return toJSONError(errReservedBucket) + } + bucketLock := globalNSMutex.NewNSLock(args.BucketName, "") bucketLock.Lock() defer bucketLock.Unlock() if err := objectAPI.MakeBucket(args.BucketName); err != nil { return toJSONError(err, args.BucketName) } + reply.UIVersion = browser.UIVersion return nil } @@ -890,6 +897,13 @@ func toJSONError(err error, params ...string) (jerr *json2.Error) { Message: apiErr.Description, } switch apiErr.Code { + // Reserved bucket name provided. + case "AllAccessDisabled": + if len(params) > 0 { + jerr = &json2.Error{ + Message: fmt.Sprintf("All access to this bucket %s has been disabled.", params[0]), + } + } // Bucket name invalid with custom error message. case "InvalidBucketName": if len(params) > 0 { @@ -961,6 +975,12 @@ func toWebAPIError(err error) APIError { HTTPStatusCode: http.StatusMethodNotAllowed, Description: err.Error(), } + } else if err == errReservedBucket { + return APIError{ + Code: "AllAccessDisabled", + HTTPStatusCode: http.StatusForbidden, + Description: err.Error(), + } } // Convert error type to api error code. var apiErrCode APIErrorCode diff --git a/cmd/web-handlers_test.go b/cmd/web-handlers_test.go index 15ec48a4f..5c33334ed 100644 --- a/cmd/web-handlers_test.go +++ b/cmd/web-handlers_test.go @@ -265,6 +265,8 @@ func testMakeBucketWebHandler(obj ObjectLayer, instanceType string, t TestErrHan {"", false}, {".", false}, {"ab", false}, + {"minio", false}, + {".minio.sys", false}, {bucketName, true}, } From 28c53a3555a44d8ef90b521dc777b88553ec563c Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Fri, 3 Mar 2017 19:12:43 +0100 Subject: [PATCH 47/94] obj: Make checkBucketExist() returns all errors (#3843) This function was returning BucketNotFound for all errors which at least hides the fact that disks could be corrupted. This commit fixes the behavior by returning all errors that, are, by the way, Object API errors. --- cmd/object-api-input-checks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/object-api-input-checks.go b/cmd/object-api-input-checks.go index 62e77ab16..2975f117b 100644 --- a/cmd/object-api-input-checks.go +++ b/cmd/object-api-input-checks.go @@ -151,7 +151,7 @@ func checkBucketExist(bucket string, obj ObjectLayer) error { } _, err := obj.GetBucketInfo(bucket) if err != nil { - return BucketNotFound{Bucket: bucket} + return errorCause(err) } return nil } From bc52d911ef723e63e4bdc312840ded2e4ca64be6 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 3 Mar 2017 10:14:17 -0800 Subject: [PATCH 48/94] api: Increase the maximum object size limit from 5GiB to 16GiB. (#3834) The globalMaxObjectSize limit is instilled in S3 spec perhaps due to certain limitations on S3 infrastructure. For minio we don't have such limitations and we can stream a larger file instead. So we are going to bump this limit to 16GiB. Fixes #3825 --- cmd/admin-handlers_test.go | 8 ++++---- cmd/bucket-handlers.go | 2 +- cmd/generic-handlers.go | 6 +++--- cmd/object-handlers.go | 5 +++-- cmd/object-handlers_test.go | 8 ++++---- cmd/utils.go | 32 +++++++++++++++++++++++--------- cmd/utils_test.go | 12 ++++++------ 7 files changed, 44 insertions(+), 29 deletions(-) diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index a1018d7d0..7b1a20f99 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -1239,16 +1239,16 @@ func TestWriteSetConfigResponse(t *testing.T) { } testPeers := []adminPeer{ - adminPeer{ + { addr: "localhost:9001", }, - adminPeer{ + { addr: "localhost:9002", }, - adminPeer{ + { addr: "localhost:9003", }, - adminPeer{ + { addr: "localhost:9004", }, } diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 0f8ef0151..1c6bc67c6 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -486,7 +486,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h return } - if fileSize > lengthRange.Max || fileSize > maxObjectSize { + if fileSize > lengthRange.Max || isMaxObjectSize(fileSize) { errorIf(err, "Unable to create object.") writeErrorResponse(w, toAPIErrorCode(errDataTooLarge), r.URL) return diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 3f94789f5..1f69e5930 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -46,9 +46,9 @@ func registerHandlers(mux *router.Router, handlerFns ...HandlerFunc) http.Handle // which is more than enough to accommodate any form data fields and headers. const requestFormDataSize = 64 * humanize.MiByte -// For any HTTP request, request body should be not more than 5GiB + requestFormDataSize -// where, 5GiB is the maximum allowed object size for object upload. -const requestMaxBodySize = 5*humanize.GiByte + requestFormDataSize +// For any HTTP request, request body should be not more than 16GiB + requestFormDataSize +// where, 16GiB is the maximum allowed object size for object upload. +const requestMaxBodySize = globalMaxObjectSize + requestFormDataSize type requestSizeLimitHandler struct { handler http.Handler diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index cb6d2b39c..2e2717688 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -628,7 +628,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt } /// maximum copy size for multipart objects in a single operation - if isMaxObjectSize(length) { + if isMaxAllowedPartSize(length) { writeErrorResponse(w, ErrEntityTooLarge, r.URL) return } @@ -637,6 +637,7 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt // object is same then only metadata is updated. partInfo, err := objectAPI.CopyObjectPart(srcBucket, srcObject, dstBucket, dstObject, uploadID, partID, startOffset, length) if err != nil { + errorIf(err, "Unable to perform CopyObjectPart %s/%s", srcBucket, srcObject) writeErrorResponse(w, toAPIErrorCode(err), r.URL) return } @@ -687,7 +688,7 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http } /// maximum Upload size for multipart objects in a single operation - if isMaxObjectSize(size) { + if isMaxAllowedPartSize(size) { writeErrorResponse(w, ErrEntityTooLarge, r.URL) return } diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index e68a80ae4..3cf72167c 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -840,7 +840,7 @@ func testAPIPutObjectHandler(obj ObjectLayer, instanceType, bucketName string, a req.ContentLength = -1 req.TransferEncoding = []string{} case TooBigObject: - req.ContentLength = maxObjectSize + 1 + req.ContentLength = globalMaxObjectSize + 1 } // Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler. // Call the ServeHTTP to execute the handler,`func (api objectAPIHandlers) GetObjectHandler` handles the request. @@ -883,7 +883,7 @@ func testAPIPutObjectHandler(obj ObjectLayer, instanceType, bucketName string, a reqV2.ContentLength = -1 reqV2.TransferEncoding = []string{} case TooBigObject: - reqV2.ContentLength = maxObjectSize + 1 + reqV2.ContentLength = globalMaxObjectSize + 1 } // Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler. @@ -2722,7 +2722,7 @@ func testAPIPutObjectPartHandler(obj ObjectLayer, instanceType, bucketName strin { objectName: testObject, reader: bytes.NewReader([]byte("hello")), - partNumber: strconv.Itoa(maxPartID + 1), + partNumber: strconv.Itoa(globalMaxPartID + 1), fault: None, accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, @@ -2880,7 +2880,7 @@ func testAPIPutObjectPartHandler(obj ObjectLayer, instanceType, bucketName strin // Setting the content length to a value greater than the max allowed size of a part. // Used in test case 4. case TooBigObject: - req.ContentLength = maxObjectSize + 1 + req.ContentLength = globalMaxObjectSize + 1 // Malformed signature. // Used in test case 6. case BadSignature: diff --git a/cmd/utils.go b/cmd/utils.go index 49657cf13..3eeedae09 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -170,27 +170,41 @@ func checkValidMD5(md5 string) ([]byte, error) { /// http://docs.aws.amazon.com/AmazonS3/latest/dev/UploadingObjects.html const ( - // maximum object size per PUT request is 5GiB - maxObjectSize = 5 * humanize.GiByte - // minimum Part size for multipart upload is 5MiB - minPartSize = 5 * humanize.MiByte - // maximum Part ID for multipart upload is 10000 (Acceptable values range from 1 to 10000 inclusive) - maxPartID = 10000 + // Maximum object size per PUT request is 16GiB. + // This is a divergence from S3 limit on purpose to support + // use cases where users are going to upload large files + // using 'curl' and presigned URL. + globalMaxObjectSize = 16 * humanize.GiByte + + // Minimum Part size for multipart upload is 5MiB + globalMinPartSize = 5 * humanize.MiByte + + // Maximum Part size for multipart upload is 5GiB + globalMaxPartSize = 5 * humanize.GiByte + + // Maximum Part ID for multipart upload is 10000 + // (Acceptable values range from 1 to 10000 inclusive) + globalMaxPartID = 10000 ) // isMaxObjectSize - verify if max object size func isMaxObjectSize(size int64) bool { - return size > maxObjectSize + return size > globalMaxObjectSize +} + +// // Check if part size is more than maximum allowed size. +func isMaxAllowedPartSize(size int64) bool { + return size > globalMaxPartSize } // Check if part size is more than or equal to minimum allowed size. func isMinAllowedPartSize(size int64) bool { - return size >= minPartSize + return size >= globalMinPartSize } // isMaxPartNumber - Check if part ID is greater than the maximum allowed ID. func isMaxPartID(partID int) bool { - return partID > maxPartID + return partID > globalMaxPartID } func contains(stringList []string, element string) bool { diff --git a/cmd/utils_test.go b/cmd/utils_test.go index d2b2ba9f6..d0d11c3f4 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -110,12 +110,12 @@ func TestMaxObjectSize(t *testing.T) { // Test - 1 - maximum object size. { true, - maxObjectSize + 1, + globalMaxObjectSize + 1, }, // Test - 2 - not maximum object size. { false, - maxObjectSize - 1, + globalMaxObjectSize - 1, }, } for i, s := range sizes { @@ -135,12 +135,12 @@ func TestMinAllowedPartSize(t *testing.T) { // Test - 1 - within minimum part size. { true, - minPartSize + 1, + globalMinPartSize + 1, }, // Test - 2 - smaller than minimum part size. { false, - minPartSize - 1, + globalMinPartSize - 1, }, } @@ -161,12 +161,12 @@ func TestMaxPartID(t *testing.T) { // Test - 1 part number within max part number. { false, - maxPartID - 1, + globalMaxPartID - 1, }, // Test - 2 part number bigger than max part number. { true, - maxPartID + 1, + globalMaxPartID + 1, }, } From 6c00a57a7c0bb8703dcc30e795ca0cc45d5f5f08 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Fri, 3 Mar 2017 19:22:09 +0100 Subject: [PATCH 49/94] quick: Add yaml format support (#3833) quick Save() and Load() infers config file's format from file name extension. --- pkg/quick/encoding.go | 142 ++ pkg/quick/errorutil.go | 2 +- pkg/quick/quick.go | 48 +- pkg/quick/quick_test.go | 106 +- vendor/gopkg.in/yaml.v2/LICENSE | 13 + vendor/gopkg.in/yaml.v2/LICENSE.libyaml | 31 + vendor/gopkg.in/yaml.v2/README.md | 131 ++ vendor/gopkg.in/yaml.v2/apic.go | 742 +++++++ vendor/gopkg.in/yaml.v2/decode.go | 683 ++++++ vendor/gopkg.in/yaml.v2/emitterc.go | 1685 ++++++++++++++ vendor/gopkg.in/yaml.v2/encode.go | 306 +++ vendor/gopkg.in/yaml.v2/parserc.go | 1096 +++++++++ vendor/gopkg.in/yaml.v2/readerc.go | 394 ++++ vendor/gopkg.in/yaml.v2/resolve.go | 203 ++ vendor/gopkg.in/yaml.v2/scannerc.go | 2710 +++++++++++++++++++++++ vendor/gopkg.in/yaml.v2/sorter.go | 104 + vendor/gopkg.in/yaml.v2/writerc.go | 89 + vendor/gopkg.in/yaml.v2/yaml.go | 346 +++ vendor/gopkg.in/yaml.v2/yamlh.go | 716 ++++++ vendor/gopkg.in/yaml.v2/yamlprivateh.go | 173 ++ vendor/vendor.json | 6 + 21 files changed, 9686 insertions(+), 40 deletions(-) create mode 100644 pkg/quick/encoding.go create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE create mode 100644 vendor/gopkg.in/yaml.v2/LICENSE.libyaml create mode 100644 vendor/gopkg.in/yaml.v2/README.md create mode 100644 vendor/gopkg.in/yaml.v2/apic.go create mode 100644 vendor/gopkg.in/yaml.v2/decode.go create mode 100644 vendor/gopkg.in/yaml.v2/emitterc.go create mode 100644 vendor/gopkg.in/yaml.v2/encode.go create mode 100644 vendor/gopkg.in/yaml.v2/parserc.go create mode 100644 vendor/gopkg.in/yaml.v2/readerc.go create mode 100644 vendor/gopkg.in/yaml.v2/resolve.go create mode 100644 vendor/gopkg.in/yaml.v2/scannerc.go create mode 100644 vendor/gopkg.in/yaml.v2/sorter.go create mode 100644 vendor/gopkg.in/yaml.v2/writerc.go create mode 100644 vendor/gopkg.in/yaml.v2/yaml.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlh.go create mode 100644 vendor/gopkg.in/yaml.v2/yamlprivateh.go diff --git a/pkg/quick/encoding.go b/pkg/quick/encoding.go new file mode 100644 index 000000000..c8a3a3b6d --- /dev/null +++ b/pkg/quick/encoding.go @@ -0,0 +1,142 @@ +/* + * Quick - Quick key value store for config files and persistent state files + * + * Quick (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package quick + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "strings" + + yaml "gopkg.in/yaml.v2" +) + +// ConfigEncoding is a generic interface which +// marshal/unmarshal configuration. +type ConfigEncoding interface { + Unmarshal([]byte, interface{}) error + Marshal(interface{}) ([]byte, error) +} + +// YAML encoding implements ConfigEncoding +type yamlEncoding struct{} + +func (y yamlEncoding) Unmarshal(b []byte, v interface{}) error { + return yaml.Unmarshal(b, v) +} + +func (y yamlEncoding) Marshal(v interface{}) ([]byte, error) { + return yaml.Marshal(v) +} + +// JSON encoding implements ConfigEncoding +type jsonEncoding struct{} + +func (j jsonEncoding) Unmarshal(b []byte, v interface{}) error { + err := json.Unmarshal(b, v) + if err != nil { + // Try to return a sophisticated json error message if possible + switch err := err.(type) { + case *json.SyntaxError: + return FormatJSONSyntaxError(bytes.NewReader(b), err) + default: + return err + } + } + return nil +} + +func (j jsonEncoding) Marshal(v interface{}) ([]byte, error) { + return json.MarshalIndent(v, "", "\t") +} + +// Convert a file extension to the appropriate struct capable +// to marshal/unmarshal data +func ext2EncFormat(fileExtension string) ConfigEncoding { + // Lower the file extension + ext := strings.ToLower(fileExtension) + ext = strings.TrimPrefix(ext, ".") + // Return the appropriate encoder/decoder according + // to the extension + switch ext { + case "yml", "yaml": + // YAML + return yamlEncoding{} + default: + // JSON + return jsonEncoding{} + } +} + +// toMarshaller returns the right marshal function according +// to the given file extension +func toMarshaller(ext string) func(interface{}) ([]byte, error) { + return ext2EncFormat(ext).Marshal +} + +// toUnmarshaller returns the right marshal function according +// to the given file extension +func toUnmarshaller(ext string) func([]byte, interface{}) error { + return ext2EncFormat(ext).Unmarshal +} + +// saveFileConfig marshals with the right encoding format +// according to the filename extension, if no extension is +// provided, json will be selected. +func saveFileConfig(filename string, v interface{}) error { + // Fetch filename's extension + ext := filepath.Ext(filename) + // Marshal data + dataBytes, err := toMarshaller(ext)(v) + if err != nil { + return err + } + if runtime.GOOS == "windows" { + dataBytes = []byte(strings.Replace(string(dataBytes), "\n", "\r\n", -1)) + } + // Save data. + return writeFile(filename, dataBytes) + +} + +// loadFileConfig unmarshals the file's content with the right +// decoder format according to the filename extension. If no +// extension is provided, json will be selected by default. +func loadFileConfig(filename string, v interface{}) error { + _, err := os.Stat(filename) + if err != nil { + return err + } + fileData, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + if runtime.GOOS == "windows" { + fileData = []byte(strings.Replace(string(fileData), "\r\n", "\n", -1)) + } + ext := filepath.Ext(filename) + // Unmarshal file's content + if err := toUnmarshaller(ext)(fileData, v); err != nil { + return err + } + return nil +} diff --git a/pkg/quick/errorutil.go b/pkg/quick/errorutil.go index b6bb92edf..063af3d5d 100644 --- a/pkg/quick/errorutil.go +++ b/pkg/quick/errorutil.go @@ -1,7 +1,7 @@ /* * Quick - Quick key value store for config files and persistent state files * - * Minio Client (C) 2015 Minio, Inc. + * Quick (C) 2015 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkg/quick/quick.go b/pkg/quick/quick.go index 32b7e0390..26cae6983 100644 --- a/pkg/quick/quick.go +++ b/pkg/quick/quick.go @@ -1,7 +1,7 @@ /* * Quick - Quick key value store for config files and persistent state files * - * Minio Client (C) 2015 Minio, Inc. + * Quick (C) 2015 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,11 @@ package quick import ( - "bytes" "encoding/json" "fmt" "io/ioutil" "os" "reflect" - "runtime" - "strings" "sync" "github.com/fatih/structs" @@ -151,7 +148,9 @@ func (d config) String() string { return string(configBytes) } -// Save writes config data in JSON format to a file. +// Save writes config data to a file. Data format +// is selected based on file extension or JSON if +// not provided. func (d config) Save(filename string) error { d.lock.Lock() defer d.lock.Unlock() @@ -179,53 +178,26 @@ func (d config) Save(filename string) error { return err } } - // Proceed to create or overwrite file. - jsonData, err := json.MarshalIndent(d.data, "", "\t") - if err != nil { - return err - } - - if runtime.GOOS == "windows" { - jsonData = []byte(strings.Replace(string(jsonData), "\n", "\r\n", -1)) - } // Save data. - return writeFile(filename, jsonData) + return saveFileConfig(filename, d.data) } -// Load - loads JSON config from file and merge with currently set values +// Load - loads config from file and merge with currently set values +// File content format is guessed from the file name extension, if not +// available, consider that we have JSON. func (d *config) Load(filename string) error { d.lock.Lock() defer d.lock.Unlock() - _, err := os.Stat(filename) - if err != nil { - return err - } - - fileData, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - - if runtime.GOOS == "windows" { - fileData = []byte(strings.Replace(string(fileData), "\r\n", "\n", -1)) - } - st := structs.New(d.data) f, ok := st.FieldOk("Version") if !ok { return fmt.Errorf("Argument struct [%s] does not contain field \"Version\"", st.Name()) } - err = json.Unmarshal(fileData, d.data) - if err != nil { - switch err := err.(type) { - case *json.SyntaxError: - return FormatJSONSyntaxError(bytes.NewReader(fileData), err) - default: - return err - } + if err := loadFileConfig(filename, d.data); err != nil { + return err } if err := CheckData(d.data); err != nil { diff --git a/pkg/quick/quick_test.go b/pkg/quick/quick_test.go index d14a505e7..561255af3 100644 --- a/pkg/quick/quick_test.go +++ b/pkg/quick/quick_test.go @@ -1,7 +1,7 @@ /* * Quick - Quick key value store for config files and persistent state files * - * Minio Client (C) 2015 Minio, Inc. + * Quick (C) 2015 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,11 @@ package quick_test import ( "encoding/json" + "io/ioutil" "os" + "reflect" + "runtime" + "strings" "testing" "github.com/minio/minio/pkg/quick" @@ -122,6 +126,106 @@ func (s *MySuite) TestLoadFile(c *C) { c.Assert(saveMe2, DeepEquals, saveMe1) } +func (s *MySuite) TestYAMLFormat(c *C) { + testYAML := "test.yaml" + defer os.RemoveAll(testYAML) + + type myStruct struct { + Version string + User string + Password string + Directories []string + } + + plainYAML := `version: "1" +user: guest +password: nopassword +directories: +- Work +- Documents +- Music +` + + if runtime.GOOS == "windows" { + plainYAML = strings.Replace(plainYAML, "\n", "\r\n", -1) + } + + saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} + + // Save format using + config, err := quick.New(&saveMe) + c.Assert(err, IsNil) + c.Assert(config, Not(IsNil)) + + err = config.Save(testYAML) + c.Assert(err, IsNil) + + // Check if the saved structure in actually an YAML format + bytes, err := ioutil.ReadFile(testYAML) + c.Assert(err, IsNil) + + c.Assert(plainYAML, Equals, string(bytes)) + + // Check if the loaded data is the same as the saved one + loadMe := myStruct{} + config, err = quick.New(&loadMe) + err = config.Load(testYAML) + c.Assert(err, IsNil) + + c.Assert(reflect.DeepEqual(saveMe, loadMe), Equals, true) +} + +func (s *MySuite) TestJSONFormat(c *C) { + testJSON := "test.json" + defer os.RemoveAll(testJSON) + + type myStruct struct { + Version string + User string + Password string + Directories []string + } + + plainJSON := `{ + "Version": "1", + "User": "guest", + "Password": "nopassword", + "Directories": [ + "Work", + "Documents", + "Music" + ] +}` + + if runtime.GOOS == "windows" { + plainJSON = strings.Replace(plainJSON, "\n", "\r\n", -1) + } + + saveMe := myStruct{"1", "guest", "nopassword", []string{"Work", "Documents", "Music"}} + + // Save format using + config, err := quick.New(&saveMe) + c.Assert(err, IsNil) + c.Assert(config, Not(IsNil)) + + err = config.Save(testJSON) + c.Assert(err, IsNil) + + // Check if the saved structure in actually an JSON format + bytes, err := ioutil.ReadFile(testJSON) + c.Assert(err, IsNil) + + c.Assert(plainJSON, Equals, string(bytes)) + + // Check if the loaded data is the same as the saved one + loadMe := myStruct{} + config, err = quick.New(&loadMe) + err = config.Load(testJSON) + c.Assert(err, IsNil) + + c.Assert(reflect.DeepEqual(saveMe, loadMe), Equals, true) +} + func (s *MySuite) TestVersion(c *C) { defer os.RemoveAll("test.json") type myStruct struct { diff --git a/vendor/gopkg.in/yaml.v2/LICENSE b/vendor/gopkg.in/yaml.v2/LICENSE new file mode 100644 index 000000000..866d74a7a --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/LICENSE @@ -0,0 +1,13 @@ +Copyright 2011-2016 Canonical Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/gopkg.in/yaml.v2/LICENSE.libyaml b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml new file mode 100644 index 000000000..8da58fbf6 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/LICENSE.libyaml @@ -0,0 +1,31 @@ +The following files were ported to Go from C files of libyaml, and thus +are still covered by their original copyright and license: + + apic.go + emitterc.go + parserc.go + readerc.go + scannerc.go + writerc.go + yamlh.go + yamlprivateh.go + +Copyright (c) 2006 Kirill Simonov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/gopkg.in/yaml.v2/README.md b/vendor/gopkg.in/yaml.v2/README.md new file mode 100644 index 000000000..1884de6a7 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/README.md @@ -0,0 +1,131 @@ +# YAML support for the Go language + +Introduction +------------ + +The yaml package enables Go programs to comfortably encode and decode YAML +values. It was developed within [Canonical](https://www.canonical.com) as +part of the [juju](https://juju.ubuntu.com) project, and is based on a +pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML) +C library to parse and generate YAML data quickly and reliably. + +Compatibility +------------- + +The yaml package supports most of YAML 1.1 and 1.2, including support for +anchors, tags, map merging, etc. Multi-document unmarshalling is not yet +implemented, and base-60 floats from YAML 1.1 are purposefully not +supported since they're a poor design and are gone in YAML 1.2. + +Installation and usage +---------------------- + +The import path for the package is *gopkg.in/yaml.v2*. + +To install it, run: + + go get gopkg.in/yaml.v2 + +API documentation +----------------- + +If opened in a browser, the import path itself leads to the API documentation: + + * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) + +API stability +------------- + +The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in). + + +License +------- + +The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details. + + +Example +------- + +```Go +package main + +import ( + "fmt" + "log" + + "gopkg.in/yaml.v2" +) + +var data = ` +a: Easy! +b: + c: 2 + d: [3, 4] +` + +type T struct { + A string + B struct { + RenamedC int `yaml:"c"` + D []int `yaml:",flow"` + } +} + +func main() { + t := T{} + + err := yaml.Unmarshal([]byte(data), &t) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- t:\n%v\n\n", t) + + d, err := yaml.Marshal(&t) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- t dump:\n%s\n\n", string(d)) + + m := make(map[interface{}]interface{}) + + err = yaml.Unmarshal([]byte(data), &m) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- m:\n%v\n\n", m) + + d, err = yaml.Marshal(&m) + if err != nil { + log.Fatalf("error: %v", err) + } + fmt.Printf("--- m dump:\n%s\n\n", string(d)) +} +``` + +This example will generate the following output: + +``` +--- t: +{Easy! {2 [3 4]}} + +--- t dump: +a: Easy! +b: + c: 2 + d: [3, 4] + + +--- m: +map[a:Easy! b:map[c:2 d:[3 4]]] + +--- m dump: +a: Easy! +b: + c: 2 + d: + - 3 + - 4 +``` + diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go new file mode 100644 index 000000000..95ec014e8 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/apic.go @@ -0,0 +1,742 @@ +package yaml + +import ( + "io" + "os" +) + +func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) { + //fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens)) + + // Check if we can move the queue at the beginning of the buffer. + if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) { + if parser.tokens_head != len(parser.tokens) { + copy(parser.tokens, parser.tokens[parser.tokens_head:]) + } + parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head] + parser.tokens_head = 0 + } + parser.tokens = append(parser.tokens, *token) + if pos < 0 { + return + } + copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:]) + parser.tokens[parser.tokens_head+pos] = *token +} + +// Create a new parser object. +func yaml_parser_initialize(parser *yaml_parser_t) bool { + *parser = yaml_parser_t{ + raw_buffer: make([]byte, 0, input_raw_buffer_size), + buffer: make([]byte, 0, input_buffer_size), + } + return true +} + +// Destroy a parser object. +func yaml_parser_delete(parser *yaml_parser_t) { + *parser = yaml_parser_t{} +} + +// String read handler. +func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { + if parser.input_pos == len(parser.input) { + return 0, io.EOF + } + n = copy(buffer, parser.input[parser.input_pos:]) + parser.input_pos += n + return n, nil +} + +// File read handler. +func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) { + return parser.input_file.Read(buffer) +} + +// Set a string input. +func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) { + if parser.read_handler != nil { + panic("must set the input source only once") + } + parser.read_handler = yaml_string_read_handler + parser.input = input + parser.input_pos = 0 +} + +// Set a file input. +func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) { + if parser.read_handler != nil { + panic("must set the input source only once") + } + parser.read_handler = yaml_file_read_handler + parser.input_file = file +} + +// Set the source encoding. +func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) { + if parser.encoding != yaml_ANY_ENCODING { + panic("must set the encoding only once") + } + parser.encoding = encoding +} + +// Create a new emitter object. +func yaml_emitter_initialize(emitter *yaml_emitter_t) bool { + *emitter = yaml_emitter_t{ + buffer: make([]byte, output_buffer_size), + raw_buffer: make([]byte, 0, output_raw_buffer_size), + states: make([]yaml_emitter_state_t, 0, initial_stack_size), + events: make([]yaml_event_t, 0, initial_queue_size), + } + return true +} + +// Destroy an emitter object. +func yaml_emitter_delete(emitter *yaml_emitter_t) { + *emitter = yaml_emitter_t{} +} + +// String write handler. +func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error { + *emitter.output_buffer = append(*emitter.output_buffer, buffer...) + return nil +} + +// File write handler. +func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error { + _, err := emitter.output_file.Write(buffer) + return err +} + +// Set a string output. +func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) { + if emitter.write_handler != nil { + panic("must set the output target only once") + } + emitter.write_handler = yaml_string_write_handler + emitter.output_buffer = output_buffer +} + +// Set a file output. +func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) { + if emitter.write_handler != nil { + panic("must set the output target only once") + } + emitter.write_handler = yaml_file_write_handler + emitter.output_file = file +} + +// Set the output encoding. +func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) { + if emitter.encoding != yaml_ANY_ENCODING { + panic("must set the output encoding only once") + } + emitter.encoding = encoding +} + +// Set the canonical output style. +func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) { + emitter.canonical = canonical +} + +//// Set the indentation increment. +func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) { + if indent < 2 || indent > 9 { + indent = 2 + } + emitter.best_indent = indent +} + +// Set the preferred line width. +func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) { + if width < 0 { + width = -1 + } + emitter.best_width = width +} + +// Set if unescaped non-ASCII characters are allowed. +func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) { + emitter.unicode = unicode +} + +// Set the preferred line break character. +func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) { + emitter.line_break = line_break +} + +///* +// * Destroy a token object. +// */ +// +//YAML_DECLARE(void) +//yaml_token_delete(yaml_token_t *token) +//{ +// assert(token); // Non-NULL token object expected. +// +// switch (token.type) +// { +// case YAML_TAG_DIRECTIVE_TOKEN: +// yaml_free(token.data.tag_directive.handle); +// yaml_free(token.data.tag_directive.prefix); +// break; +// +// case YAML_ALIAS_TOKEN: +// yaml_free(token.data.alias.value); +// break; +// +// case YAML_ANCHOR_TOKEN: +// yaml_free(token.data.anchor.value); +// break; +// +// case YAML_TAG_TOKEN: +// yaml_free(token.data.tag.handle); +// yaml_free(token.data.tag.suffix); +// break; +// +// case YAML_SCALAR_TOKEN: +// yaml_free(token.data.scalar.value); +// break; +// +// default: +// break; +// } +// +// memset(token, 0, sizeof(yaml_token_t)); +//} +// +///* +// * Check if a string is a valid UTF-8 sequence. +// * +// * Check 'reader.c' for more details on UTF-8 encoding. +// */ +// +//static int +//yaml_check_utf8(yaml_char_t *start, size_t length) +//{ +// yaml_char_t *end = start+length; +// yaml_char_t *pointer = start; +// +// while (pointer < end) { +// unsigned char octet; +// unsigned int width; +// unsigned int value; +// size_t k; +// +// octet = pointer[0]; +// width = (octet & 0x80) == 0x00 ? 1 : +// (octet & 0xE0) == 0xC0 ? 2 : +// (octet & 0xF0) == 0xE0 ? 3 : +// (octet & 0xF8) == 0xF0 ? 4 : 0; +// value = (octet & 0x80) == 0x00 ? octet & 0x7F : +// (octet & 0xE0) == 0xC0 ? octet & 0x1F : +// (octet & 0xF0) == 0xE0 ? octet & 0x0F : +// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; +// if (!width) return 0; +// if (pointer+width > end) return 0; +// for (k = 1; k < width; k ++) { +// octet = pointer[k]; +// if ((octet & 0xC0) != 0x80) return 0; +// value = (value << 6) + (octet & 0x3F); +// } +// if (!((width == 1) || +// (width == 2 && value >= 0x80) || +// (width == 3 && value >= 0x800) || +// (width == 4 && value >= 0x10000))) return 0; +// +// pointer += width; +// } +// +// return 1; +//} +// + +// Create STREAM-START. +func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool { + *event = yaml_event_t{ + typ: yaml_STREAM_START_EVENT, + encoding: encoding, + } + return true +} + +// Create STREAM-END. +func yaml_stream_end_event_initialize(event *yaml_event_t) bool { + *event = yaml_event_t{ + typ: yaml_STREAM_END_EVENT, + } + return true +} + +// Create DOCUMENT-START. +func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t, + tag_directives []yaml_tag_directive_t, implicit bool) bool { + *event = yaml_event_t{ + typ: yaml_DOCUMENT_START_EVENT, + version_directive: version_directive, + tag_directives: tag_directives, + implicit: implicit, + } + return true +} + +// Create DOCUMENT-END. +func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool { + *event = yaml_event_t{ + typ: yaml_DOCUMENT_END_EVENT, + implicit: implicit, + } + return true +} + +///* +// * Create ALIAS. +// */ +// +//YAML_DECLARE(int) +//yaml_alias_event_initialize(event *yaml_event_t, anchor *yaml_char_t) +//{ +// mark yaml_mark_t = { 0, 0, 0 } +// anchor_copy *yaml_char_t = NULL +// +// assert(event) // Non-NULL event object is expected. +// assert(anchor) // Non-NULL anchor is expected. +// +// if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0 +// +// anchor_copy = yaml_strdup(anchor) +// if (!anchor_copy) +// return 0 +// +// ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark) +// +// return 1 +//} + +// Create SCALAR. +func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool { + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + anchor: anchor, + tag: tag, + value: value, + implicit: plain_implicit, + quoted_implicit: quoted_implicit, + style: yaml_style_t(style), + } + return true +} + +// Create SEQUENCE-START. +func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool { + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(style), + } + return true +} + +// Create SEQUENCE-END. +func yaml_sequence_end_event_initialize(event *yaml_event_t) bool { + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + } + return true +} + +// Create MAPPING-START. +func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool { + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(style), + } + return true +} + +// Create MAPPING-END. +func yaml_mapping_end_event_initialize(event *yaml_event_t) bool { + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + } + return true +} + +// Destroy an event object. +func yaml_event_delete(event *yaml_event_t) { + *event = yaml_event_t{} +} + +///* +// * Create a document object. +// */ +// +//YAML_DECLARE(int) +//yaml_document_initialize(document *yaml_document_t, +// version_directive *yaml_version_directive_t, +// tag_directives_start *yaml_tag_directive_t, +// tag_directives_end *yaml_tag_directive_t, +// start_implicit int, end_implicit int) +//{ +// struct { +// error yaml_error_type_t +// } context +// struct { +// start *yaml_node_t +// end *yaml_node_t +// top *yaml_node_t +// } nodes = { NULL, NULL, NULL } +// version_directive_copy *yaml_version_directive_t = NULL +// struct { +// start *yaml_tag_directive_t +// end *yaml_tag_directive_t +// top *yaml_tag_directive_t +// } tag_directives_copy = { NULL, NULL, NULL } +// value yaml_tag_directive_t = { NULL, NULL } +// mark yaml_mark_t = { 0, 0, 0 } +// +// assert(document) // Non-NULL document object is expected. +// assert((tag_directives_start && tag_directives_end) || +// (tag_directives_start == tag_directives_end)) +// // Valid tag directives are expected. +// +// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error +// +// if (version_directive) { +// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)) +// if (!version_directive_copy) goto error +// version_directive_copy.major = version_directive.major +// version_directive_copy.minor = version_directive.minor +// } +// +// if (tag_directives_start != tag_directives_end) { +// tag_directive *yaml_tag_directive_t +// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) +// goto error +// for (tag_directive = tag_directives_start +// tag_directive != tag_directives_end; tag_directive ++) { +// assert(tag_directive.handle) +// assert(tag_directive.prefix) +// if (!yaml_check_utf8(tag_directive.handle, +// strlen((char *)tag_directive.handle))) +// goto error +// if (!yaml_check_utf8(tag_directive.prefix, +// strlen((char *)tag_directive.prefix))) +// goto error +// value.handle = yaml_strdup(tag_directive.handle) +// value.prefix = yaml_strdup(tag_directive.prefix) +// if (!value.handle || !value.prefix) goto error +// if (!PUSH(&context, tag_directives_copy, value)) +// goto error +// value.handle = NULL +// value.prefix = NULL +// } +// } +// +// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, +// tag_directives_copy.start, tag_directives_copy.top, +// start_implicit, end_implicit, mark, mark) +// +// return 1 +// +//error: +// STACK_DEL(&context, nodes) +// yaml_free(version_directive_copy) +// while (!STACK_EMPTY(&context, tag_directives_copy)) { +// value yaml_tag_directive_t = POP(&context, tag_directives_copy) +// yaml_free(value.handle) +// yaml_free(value.prefix) +// } +// STACK_DEL(&context, tag_directives_copy) +// yaml_free(value.handle) +// yaml_free(value.prefix) +// +// return 0 +//} +// +///* +// * Destroy a document object. +// */ +// +//YAML_DECLARE(void) +//yaml_document_delete(document *yaml_document_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// tag_directive *yaml_tag_directive_t +// +// context.error = YAML_NO_ERROR // Eliminate a compliler warning. +// +// assert(document) // Non-NULL document object is expected. +// +// while (!STACK_EMPTY(&context, document.nodes)) { +// node yaml_node_t = POP(&context, document.nodes) +// yaml_free(node.tag) +// switch (node.type) { +// case YAML_SCALAR_NODE: +// yaml_free(node.data.scalar.value) +// break +// case YAML_SEQUENCE_NODE: +// STACK_DEL(&context, node.data.sequence.items) +// break +// case YAML_MAPPING_NODE: +// STACK_DEL(&context, node.data.mapping.pairs) +// break +// default: +// assert(0) // Should not happen. +// } +// } +// STACK_DEL(&context, document.nodes) +// +// yaml_free(document.version_directive) +// for (tag_directive = document.tag_directives.start +// tag_directive != document.tag_directives.end +// tag_directive++) { +// yaml_free(tag_directive.handle) +// yaml_free(tag_directive.prefix) +// } +// yaml_free(document.tag_directives.start) +// +// memset(document, 0, sizeof(yaml_document_t)) +//} +// +///** +// * Get a document node. +// */ +// +//YAML_DECLARE(yaml_node_t *) +//yaml_document_get_node(document *yaml_document_t, index int) +//{ +// assert(document) // Non-NULL document object is expected. +// +// if (index > 0 && document.nodes.start + index <= document.nodes.top) { +// return document.nodes.start + index - 1 +// } +// return NULL +//} +// +///** +// * Get the root object. +// */ +// +//YAML_DECLARE(yaml_node_t *) +//yaml_document_get_root_node(document *yaml_document_t) +//{ +// assert(document) // Non-NULL document object is expected. +// +// if (document.nodes.top != document.nodes.start) { +// return document.nodes.start +// } +// return NULL +//} +// +///* +// * Add a scalar node to a document. +// */ +// +//YAML_DECLARE(int) +//yaml_document_add_scalar(document *yaml_document_t, +// tag *yaml_char_t, value *yaml_char_t, length int, +// style yaml_scalar_style_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// mark yaml_mark_t = { 0, 0, 0 } +// tag_copy *yaml_char_t = NULL +// value_copy *yaml_char_t = NULL +// node yaml_node_t +// +// assert(document) // Non-NULL document object is expected. +// assert(value) // Non-NULL value is expected. +// +// if (!tag) { +// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG +// } +// +// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error +// tag_copy = yaml_strdup(tag) +// if (!tag_copy) goto error +// +// if (length < 0) { +// length = strlen((char *)value) +// } +// +// if (!yaml_check_utf8(value, length)) goto error +// value_copy = yaml_malloc(length+1) +// if (!value_copy) goto error +// memcpy(value_copy, value, length) +// value_copy[length] = '\0' +// +// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark) +// if (!PUSH(&context, document.nodes, node)) goto error +// +// return document.nodes.top - document.nodes.start +// +//error: +// yaml_free(tag_copy) +// yaml_free(value_copy) +// +// return 0 +//} +// +///* +// * Add a sequence node to a document. +// */ +// +//YAML_DECLARE(int) +//yaml_document_add_sequence(document *yaml_document_t, +// tag *yaml_char_t, style yaml_sequence_style_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// mark yaml_mark_t = { 0, 0, 0 } +// tag_copy *yaml_char_t = NULL +// struct { +// start *yaml_node_item_t +// end *yaml_node_item_t +// top *yaml_node_item_t +// } items = { NULL, NULL, NULL } +// node yaml_node_t +// +// assert(document) // Non-NULL document object is expected. +// +// if (!tag) { +// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG +// } +// +// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error +// tag_copy = yaml_strdup(tag) +// if (!tag_copy) goto error +// +// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error +// +// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, +// style, mark, mark) +// if (!PUSH(&context, document.nodes, node)) goto error +// +// return document.nodes.top - document.nodes.start +// +//error: +// STACK_DEL(&context, items) +// yaml_free(tag_copy) +// +// return 0 +//} +// +///* +// * Add a mapping node to a document. +// */ +// +//YAML_DECLARE(int) +//yaml_document_add_mapping(document *yaml_document_t, +// tag *yaml_char_t, style yaml_mapping_style_t) +//{ +// struct { +// error yaml_error_type_t +// } context +// mark yaml_mark_t = { 0, 0, 0 } +// tag_copy *yaml_char_t = NULL +// struct { +// start *yaml_node_pair_t +// end *yaml_node_pair_t +// top *yaml_node_pair_t +// } pairs = { NULL, NULL, NULL } +// node yaml_node_t +// +// assert(document) // Non-NULL document object is expected. +// +// if (!tag) { +// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG +// } +// +// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error +// tag_copy = yaml_strdup(tag) +// if (!tag_copy) goto error +// +// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error +// +// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, +// style, mark, mark) +// if (!PUSH(&context, document.nodes, node)) goto error +// +// return document.nodes.top - document.nodes.start +// +//error: +// STACK_DEL(&context, pairs) +// yaml_free(tag_copy) +// +// return 0 +//} +// +///* +// * Append an item to a sequence node. +// */ +// +//YAML_DECLARE(int) +//yaml_document_append_sequence_item(document *yaml_document_t, +// sequence int, item int) +//{ +// struct { +// error yaml_error_type_t +// } context +// +// assert(document) // Non-NULL document is required. +// assert(sequence > 0 +// && document.nodes.start + sequence <= document.nodes.top) +// // Valid sequence id is required. +// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE) +// // A sequence node is required. +// assert(item > 0 && document.nodes.start + item <= document.nodes.top) +// // Valid item id is required. +// +// if (!PUSH(&context, +// document.nodes.start[sequence-1].data.sequence.items, item)) +// return 0 +// +// return 1 +//} +// +///* +// * Append a pair of a key and a value to a mapping node. +// */ +// +//YAML_DECLARE(int) +//yaml_document_append_mapping_pair(document *yaml_document_t, +// mapping int, key int, value int) +//{ +// struct { +// error yaml_error_type_t +// } context +// +// pair yaml_node_pair_t +// +// assert(document) // Non-NULL document is required. +// assert(mapping > 0 +// && document.nodes.start + mapping <= document.nodes.top) +// // Valid mapping id is required. +// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE) +// // A mapping node is required. +// assert(key > 0 && document.nodes.start + key <= document.nodes.top) +// // Valid key id is required. +// assert(value > 0 && document.nodes.start + value <= document.nodes.top) +// // Valid value id is required. +// +// pair.key = key +// pair.value = value +// +// if (!PUSH(&context, +// document.nodes.start[mapping-1].data.mapping.pairs, pair)) +// return 0 +// +// return 1 +//} +// +// diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go new file mode 100644 index 000000000..b13ab9f07 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/decode.go @@ -0,0 +1,683 @@ +package yaml + +import ( + "encoding" + "encoding/base64" + "fmt" + "math" + "reflect" + "strconv" + "time" +) + +const ( + documentNode = 1 << iota + mappingNode + sequenceNode + scalarNode + aliasNode +) + +type node struct { + kind int + line, column int + tag string + value string + implicit bool + children []*node + anchors map[string]*node +} + +// ---------------------------------------------------------------------------- +// Parser, produces a node tree out of a libyaml event stream. + +type parser struct { + parser yaml_parser_t + event yaml_event_t + doc *node +} + +func newParser(b []byte) *parser { + p := parser{} + if !yaml_parser_initialize(&p.parser) { + panic("failed to initialize YAML emitter") + } + + if len(b) == 0 { + b = []byte{'\n'} + } + + yaml_parser_set_input_string(&p.parser, b) + + p.skip() + if p.event.typ != yaml_STREAM_START_EVENT { + panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ))) + } + p.skip() + return &p +} + +func (p *parser) destroy() { + if p.event.typ != yaml_NO_EVENT { + yaml_event_delete(&p.event) + } + yaml_parser_delete(&p.parser) +} + +func (p *parser) skip() { + if p.event.typ != yaml_NO_EVENT { + if p.event.typ == yaml_STREAM_END_EVENT { + failf("attempted to go past the end of stream; corrupted value?") + } + yaml_event_delete(&p.event) + } + if !yaml_parser_parse(&p.parser, &p.event) { + p.fail() + } +} + +func (p *parser) fail() { + var where string + var line int + if p.parser.problem_mark.line != 0 { + line = p.parser.problem_mark.line + } else if p.parser.context_mark.line != 0 { + line = p.parser.context_mark.line + } + if line != 0 { + where = "line " + strconv.Itoa(line) + ": " + } + var msg string + if len(p.parser.problem) > 0 { + msg = p.parser.problem + } else { + msg = "unknown problem parsing YAML content" + } + failf("%s%s", where, msg) +} + +func (p *parser) anchor(n *node, anchor []byte) { + if anchor != nil { + p.doc.anchors[string(anchor)] = n + } +} + +func (p *parser) parse() *node { + switch p.event.typ { + case yaml_SCALAR_EVENT: + return p.scalar() + case yaml_ALIAS_EVENT: + return p.alias() + case yaml_MAPPING_START_EVENT: + return p.mapping() + case yaml_SEQUENCE_START_EVENT: + return p.sequence() + case yaml_DOCUMENT_START_EVENT: + return p.document() + case yaml_STREAM_END_EVENT: + // Happens when attempting to decode an empty buffer. + return nil + default: + panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ))) + } + panic("unreachable") +} + +func (p *parser) node(kind int) *node { + return &node{ + kind: kind, + line: p.event.start_mark.line, + column: p.event.start_mark.column, + } +} + +func (p *parser) document() *node { + n := p.node(documentNode) + n.anchors = make(map[string]*node) + p.doc = n + p.skip() + n.children = append(n.children, p.parse()) + if p.event.typ != yaml_DOCUMENT_END_EVENT { + panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ))) + } + p.skip() + return n +} + +func (p *parser) alias() *node { + n := p.node(aliasNode) + n.value = string(p.event.anchor) + p.skip() + return n +} + +func (p *parser) scalar() *node { + n := p.node(scalarNode) + n.value = string(p.event.value) + n.tag = string(p.event.tag) + n.implicit = p.event.implicit + p.anchor(n, p.event.anchor) + p.skip() + return n +} + +func (p *parser) sequence() *node { + n := p.node(sequenceNode) + p.anchor(n, p.event.anchor) + p.skip() + for p.event.typ != yaml_SEQUENCE_END_EVENT { + n.children = append(n.children, p.parse()) + } + p.skip() + return n +} + +func (p *parser) mapping() *node { + n := p.node(mappingNode) + p.anchor(n, p.event.anchor) + p.skip() + for p.event.typ != yaml_MAPPING_END_EVENT { + n.children = append(n.children, p.parse(), p.parse()) + } + p.skip() + return n +} + +// ---------------------------------------------------------------------------- +// Decoder, unmarshals a node into a provided value. + +type decoder struct { + doc *node + aliases map[string]bool + mapType reflect.Type + terrors []string +} + +var ( + mapItemType = reflect.TypeOf(MapItem{}) + durationType = reflect.TypeOf(time.Duration(0)) + defaultMapType = reflect.TypeOf(map[interface{}]interface{}{}) + ifaceType = defaultMapType.Elem() +) + +func newDecoder() *decoder { + d := &decoder{mapType: defaultMapType} + d.aliases = make(map[string]bool) + return d +} + +func (d *decoder) terror(n *node, tag string, out reflect.Value) { + if n.tag != "" { + tag = n.tag + } + value := n.value + if tag != yaml_SEQ_TAG && tag != yaml_MAP_TAG { + if len(value) > 10 { + value = " `" + value[:7] + "...`" + } else { + value = " `" + value + "`" + } + } + d.terrors = append(d.terrors, fmt.Sprintf("line %d: cannot unmarshal %s%s into %s", n.line+1, shortTag(tag), value, out.Type())) +} + +func (d *decoder) callUnmarshaler(n *node, u Unmarshaler) (good bool) { + terrlen := len(d.terrors) + err := u.UnmarshalYAML(func(v interface{}) (err error) { + defer handleErr(&err) + d.unmarshal(n, reflect.ValueOf(v)) + if len(d.terrors) > terrlen { + issues := d.terrors[terrlen:] + d.terrors = d.terrors[:terrlen] + return &TypeError{issues} + } + return nil + }) + if e, ok := err.(*TypeError); ok { + d.terrors = append(d.terrors, e.Errors...) + return false + } + if err != nil { + fail(err) + } + return true +} + +// d.prepare initializes and dereferences pointers and calls UnmarshalYAML +// if a value is found to implement it. +// It returns the initialized and dereferenced out value, whether +// unmarshalling was already done by UnmarshalYAML, and if so whether +// its types unmarshalled appropriately. +// +// If n holds a null value, prepare returns before doing anything. +func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) { + if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "" && n.implicit) { + return out, false, false + } + again := true + for again { + again = false + if out.Kind() == reflect.Ptr { + if out.IsNil() { + out.Set(reflect.New(out.Type().Elem())) + } + out = out.Elem() + again = true + } + if out.CanAddr() { + if u, ok := out.Addr().Interface().(Unmarshaler); ok { + good = d.callUnmarshaler(n, u) + return out, true, good + } + } + } + return out, false, false +} + +func (d *decoder) unmarshal(n *node, out reflect.Value) (good bool) { + switch n.kind { + case documentNode: + return d.document(n, out) + case aliasNode: + return d.alias(n, out) + } + out, unmarshaled, good := d.prepare(n, out) + if unmarshaled { + return good + } + switch n.kind { + case scalarNode: + good = d.scalar(n, out) + case mappingNode: + good = d.mapping(n, out) + case sequenceNode: + good = d.sequence(n, out) + default: + panic("internal error: unknown node kind: " + strconv.Itoa(n.kind)) + } + return good +} + +func (d *decoder) document(n *node, out reflect.Value) (good bool) { + if len(n.children) == 1 { + d.doc = n + d.unmarshal(n.children[0], out) + return true + } + return false +} + +func (d *decoder) alias(n *node, out reflect.Value) (good bool) { + an, ok := d.doc.anchors[n.value] + if !ok { + failf("unknown anchor '%s' referenced", n.value) + } + if d.aliases[n.value] { + failf("anchor '%s' value contains itself", n.value) + } + d.aliases[n.value] = true + good = d.unmarshal(an, out) + delete(d.aliases, n.value) + return good +} + +var zeroValue reflect.Value + +func resetMap(out reflect.Value) { + for _, k := range out.MapKeys() { + out.SetMapIndex(k, zeroValue) + } +} + +func (d *decoder) scalar(n *node, out reflect.Value) (good bool) { + var tag string + var resolved interface{} + if n.tag == "" && !n.implicit { + tag = yaml_STR_TAG + resolved = n.value + } else { + tag, resolved = resolve(n.tag, n.value) + if tag == yaml_BINARY_TAG { + data, err := base64.StdEncoding.DecodeString(resolved.(string)) + if err != nil { + failf("!!binary value contains invalid base64 data") + } + resolved = string(data) + } + } + if resolved == nil { + if out.Kind() == reflect.Map && !out.CanAddr() { + resetMap(out) + } else { + out.Set(reflect.Zero(out.Type())) + } + return true + } + if s, ok := resolved.(string); ok && out.CanAddr() { + if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok { + err := u.UnmarshalText([]byte(s)) + if err != nil { + fail(err) + } + return true + } + } + switch out.Kind() { + case reflect.String: + if tag == yaml_BINARY_TAG { + out.SetString(resolved.(string)) + good = true + } else if resolved != nil { + out.SetString(n.value) + good = true + } + case reflect.Interface: + if resolved == nil { + out.Set(reflect.Zero(out.Type())) + } else { + out.Set(reflect.ValueOf(resolved)) + } + good = true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch resolved := resolved.(type) { + case int: + if !out.OverflowInt(int64(resolved)) { + out.SetInt(int64(resolved)) + good = true + } + case int64: + if !out.OverflowInt(resolved) { + out.SetInt(resolved) + good = true + } + case uint64: + if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { + out.SetInt(int64(resolved)) + good = true + } + case float64: + if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) { + out.SetInt(int64(resolved)) + good = true + } + case string: + if out.Type() == durationType { + d, err := time.ParseDuration(resolved) + if err == nil { + out.SetInt(int64(d)) + good = true + } + } + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + switch resolved := resolved.(type) { + case int: + if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + case int64: + if resolved >= 0 && !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + case uint64: + if !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + case float64: + if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) { + out.SetUint(uint64(resolved)) + good = true + } + } + case reflect.Bool: + switch resolved := resolved.(type) { + case bool: + out.SetBool(resolved) + good = true + } + case reflect.Float32, reflect.Float64: + switch resolved := resolved.(type) { + case int: + out.SetFloat(float64(resolved)) + good = true + case int64: + out.SetFloat(float64(resolved)) + good = true + case uint64: + out.SetFloat(float64(resolved)) + good = true + case float64: + out.SetFloat(resolved) + good = true + } + case reflect.Ptr: + if out.Type().Elem() == reflect.TypeOf(resolved) { + // TODO DOes this make sense? When is out a Ptr except when decoding a nil value? + elem := reflect.New(out.Type().Elem()) + elem.Elem().Set(reflect.ValueOf(resolved)) + out.Set(elem) + good = true + } + } + if !good { + d.terror(n, tag, out) + } + return good +} + +func settableValueOf(i interface{}) reflect.Value { + v := reflect.ValueOf(i) + sv := reflect.New(v.Type()).Elem() + sv.Set(v) + return sv +} + +func (d *decoder) sequence(n *node, out reflect.Value) (good bool) { + l := len(n.children) + + var iface reflect.Value + switch out.Kind() { + case reflect.Slice: + out.Set(reflect.MakeSlice(out.Type(), l, l)) + case reflect.Interface: + // No type hints. Will have to use a generic sequence. + iface = out + out = settableValueOf(make([]interface{}, l)) + default: + d.terror(n, yaml_SEQ_TAG, out) + return false + } + et := out.Type().Elem() + + j := 0 + for i := 0; i < l; i++ { + e := reflect.New(et).Elem() + if ok := d.unmarshal(n.children[i], e); ok { + out.Index(j).Set(e) + j++ + } + } + out.Set(out.Slice(0, j)) + if iface.IsValid() { + iface.Set(out) + } + return true +} + +func (d *decoder) mapping(n *node, out reflect.Value) (good bool) { + switch out.Kind() { + case reflect.Struct: + return d.mappingStruct(n, out) + case reflect.Slice: + return d.mappingSlice(n, out) + case reflect.Map: + // okay + case reflect.Interface: + if d.mapType.Kind() == reflect.Map { + iface := out + out = reflect.MakeMap(d.mapType) + iface.Set(out) + } else { + slicev := reflect.New(d.mapType).Elem() + if !d.mappingSlice(n, slicev) { + return false + } + out.Set(slicev) + return true + } + default: + d.terror(n, yaml_MAP_TAG, out) + return false + } + outt := out.Type() + kt := outt.Key() + et := outt.Elem() + + mapType := d.mapType + if outt.Key() == ifaceType && outt.Elem() == ifaceType { + d.mapType = outt + } + + if out.IsNil() { + out.Set(reflect.MakeMap(outt)) + } + l := len(n.children) + for i := 0; i < l; i += 2 { + if isMerge(n.children[i]) { + d.merge(n.children[i+1], out) + continue + } + k := reflect.New(kt).Elem() + if d.unmarshal(n.children[i], k) { + kkind := k.Kind() + if kkind == reflect.Interface { + kkind = k.Elem().Kind() + } + if kkind == reflect.Map || kkind == reflect.Slice { + failf("invalid map key: %#v", k.Interface()) + } + e := reflect.New(et).Elem() + if d.unmarshal(n.children[i+1], e) { + out.SetMapIndex(k, e) + } + } + } + d.mapType = mapType + return true +} + +func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) { + outt := out.Type() + if outt.Elem() != mapItemType { + d.terror(n, yaml_MAP_TAG, out) + return false + } + + mapType := d.mapType + d.mapType = outt + + var slice []MapItem + var l = len(n.children) + for i := 0; i < l; i += 2 { + if isMerge(n.children[i]) { + d.merge(n.children[i+1], out) + continue + } + item := MapItem{} + k := reflect.ValueOf(&item.Key).Elem() + if d.unmarshal(n.children[i], k) { + v := reflect.ValueOf(&item.Value).Elem() + if d.unmarshal(n.children[i+1], v) { + slice = append(slice, item) + } + } + } + out.Set(reflect.ValueOf(slice)) + d.mapType = mapType + return true +} + +func (d *decoder) mappingStruct(n *node, out reflect.Value) (good bool) { + sinfo, err := getStructInfo(out.Type()) + if err != nil { + panic(err) + } + name := settableValueOf("") + l := len(n.children) + + var inlineMap reflect.Value + var elemType reflect.Type + if sinfo.InlineMap != -1 { + inlineMap = out.Field(sinfo.InlineMap) + inlineMap.Set(reflect.New(inlineMap.Type()).Elem()) + elemType = inlineMap.Type().Elem() + } + + for i := 0; i < l; i += 2 { + ni := n.children[i] + if isMerge(ni) { + d.merge(n.children[i+1], out) + continue + } + if !d.unmarshal(ni, name) { + continue + } + if info, ok := sinfo.FieldsMap[name.String()]; ok { + var field reflect.Value + if info.Inline == nil { + field = out.Field(info.Num) + } else { + field = out.FieldByIndex(info.Inline) + } + d.unmarshal(n.children[i+1], field) + } else if sinfo.InlineMap != -1 { + if inlineMap.IsNil() { + inlineMap.Set(reflect.MakeMap(inlineMap.Type())) + } + value := reflect.New(elemType).Elem() + d.unmarshal(n.children[i+1], value) + inlineMap.SetMapIndex(name, value) + } + } + return true +} + +func failWantMap() { + failf("map merge requires map or sequence of maps as the value") +} + +func (d *decoder) merge(n *node, out reflect.Value) { + switch n.kind { + case mappingNode: + d.unmarshal(n, out) + case aliasNode: + an, ok := d.doc.anchors[n.value] + if ok && an.kind != mappingNode { + failWantMap() + } + d.unmarshal(n, out) + case sequenceNode: + // Step backwards as earlier nodes take precedence. + for i := len(n.children) - 1; i >= 0; i-- { + ni := n.children[i] + if ni.kind == aliasNode { + an, ok := d.doc.anchors[ni.value] + if ok && an.kind != mappingNode { + failWantMap() + } + } else if ni.kind != mappingNode { + failWantMap() + } + d.unmarshal(ni, out) + } + default: + failWantMap() + } +} + +func isMerge(n *node) bool { + return n.kind == scalarNode && n.value == "<<" && (n.implicit == true || n.tag == yaml_MERGE_TAG) +} diff --git a/vendor/gopkg.in/yaml.v2/emitterc.go b/vendor/gopkg.in/yaml.v2/emitterc.go new file mode 100644 index 000000000..2befd553e --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/emitterc.go @@ -0,0 +1,1685 @@ +package yaml + +import ( + "bytes" +) + +// Flush the buffer if needed. +func flush(emitter *yaml_emitter_t) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) { + return yaml_emitter_flush(emitter) + } + return true +} + +// Put a character to the output buffer. +func put(emitter *yaml_emitter_t, value byte) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { + return false + } + emitter.buffer[emitter.buffer_pos] = value + emitter.buffer_pos++ + emitter.column++ + return true +} + +// Put a line break to the output buffer. +func put_break(emitter *yaml_emitter_t) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { + return false + } + switch emitter.line_break { + case yaml_CR_BREAK: + emitter.buffer[emitter.buffer_pos] = '\r' + emitter.buffer_pos += 1 + case yaml_LN_BREAK: + emitter.buffer[emitter.buffer_pos] = '\n' + emitter.buffer_pos += 1 + case yaml_CRLN_BREAK: + emitter.buffer[emitter.buffer_pos+0] = '\r' + emitter.buffer[emitter.buffer_pos+1] = '\n' + emitter.buffer_pos += 2 + default: + panic("unknown line break setting") + } + emitter.column = 0 + emitter.line++ + return true +} + +// Copy a character from a string into buffer. +func write(emitter *yaml_emitter_t, s []byte, i *int) bool { + if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) { + return false + } + p := emitter.buffer_pos + w := width(s[*i]) + switch w { + case 4: + emitter.buffer[p+3] = s[*i+3] + fallthrough + case 3: + emitter.buffer[p+2] = s[*i+2] + fallthrough + case 2: + emitter.buffer[p+1] = s[*i+1] + fallthrough + case 1: + emitter.buffer[p+0] = s[*i+0] + default: + panic("unknown character width") + } + emitter.column++ + emitter.buffer_pos += w + *i += w + return true +} + +// Write a whole string into buffer. +func write_all(emitter *yaml_emitter_t, s []byte) bool { + for i := 0; i < len(s); { + if !write(emitter, s, &i) { + return false + } + } + return true +} + +// Copy a line break character from a string into buffer. +func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool { + if s[*i] == '\n' { + if !put_break(emitter) { + return false + } + *i++ + } else { + if !write(emitter, s, i) { + return false + } + emitter.column = 0 + emitter.line++ + } + return true +} + +// Set an emitter error and return false. +func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool { + emitter.error = yaml_EMITTER_ERROR + emitter.problem = problem + return false +} + +// Emit an event. +func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool { + emitter.events = append(emitter.events, *event) + for !yaml_emitter_need_more_events(emitter) { + event := &emitter.events[emitter.events_head] + if !yaml_emitter_analyze_event(emitter, event) { + return false + } + if !yaml_emitter_state_machine(emitter, event) { + return false + } + yaml_event_delete(event) + emitter.events_head++ + } + return true +} + +// Check if we need to accumulate more events before emitting. +// +// We accumulate extra +// - 1 event for DOCUMENT-START +// - 2 events for SEQUENCE-START +// - 3 events for MAPPING-START +// +func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool { + if emitter.events_head == len(emitter.events) { + return true + } + var accumulate int + switch emitter.events[emitter.events_head].typ { + case yaml_DOCUMENT_START_EVENT: + accumulate = 1 + break + case yaml_SEQUENCE_START_EVENT: + accumulate = 2 + break + case yaml_MAPPING_START_EVENT: + accumulate = 3 + break + default: + return false + } + if len(emitter.events)-emitter.events_head > accumulate { + return false + } + var level int + for i := emitter.events_head; i < len(emitter.events); i++ { + switch emitter.events[i].typ { + case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT: + level++ + case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT: + level-- + } + if level == 0 { + return false + } + } + return true +} + +// Append a directive to the directives stack. +func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool { + for i := 0; i < len(emitter.tag_directives); i++ { + if bytes.Equal(value.handle, emitter.tag_directives[i].handle) { + if allow_duplicates { + return true + } + return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive") + } + } + + // [Go] Do we actually need to copy this given garbage collection + // and the lack of deallocating destructors? + tag_copy := yaml_tag_directive_t{ + handle: make([]byte, len(value.handle)), + prefix: make([]byte, len(value.prefix)), + } + copy(tag_copy.handle, value.handle) + copy(tag_copy.prefix, value.prefix) + emitter.tag_directives = append(emitter.tag_directives, tag_copy) + return true +} + +// Increase the indentation level. +func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool { + emitter.indents = append(emitter.indents, emitter.indent) + if emitter.indent < 0 { + if flow { + emitter.indent = emitter.best_indent + } else { + emitter.indent = 0 + } + } else if !indentless { + emitter.indent += emitter.best_indent + } + return true +} + +// State dispatcher. +func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool { + switch emitter.state { + default: + case yaml_EMIT_STREAM_START_STATE: + return yaml_emitter_emit_stream_start(emitter, event) + + case yaml_EMIT_FIRST_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, true) + + case yaml_EMIT_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, false) + + case yaml_EMIT_DOCUMENT_CONTENT_STATE: + return yaml_emitter_emit_document_content(emitter, event) + + case yaml_EMIT_DOCUMENT_END_STATE: + return yaml_emitter_emit_document_end(emitter, event) + + case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, true) + + case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, false) + + case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, true) + + case yaml_EMIT_FLOW_MAPPING_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, false) + + case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, true) + + case yaml_EMIT_FLOW_MAPPING_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, false) + + case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, true) + + case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, false) + + case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, true) + + case yaml_EMIT_BLOCK_MAPPING_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, false) + + case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, true) + + case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, false) + + case yaml_EMIT_END_STATE: + return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END") + } + panic("invalid emitter state") +} + +// Expect STREAM-START. +func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if event.typ != yaml_STREAM_START_EVENT { + return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START") + } + if emitter.encoding == yaml_ANY_ENCODING { + emitter.encoding = event.encoding + if emitter.encoding == yaml_ANY_ENCODING { + emitter.encoding = yaml_UTF8_ENCODING + } + } + if emitter.best_indent < 2 || emitter.best_indent > 9 { + emitter.best_indent = 2 + } + if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 { + emitter.best_width = 80 + } + if emitter.best_width < 0 { + emitter.best_width = 1<<31 - 1 + } + if emitter.line_break == yaml_ANY_BREAK { + emitter.line_break = yaml_LN_BREAK + } + + emitter.indent = -1 + emitter.line = 0 + emitter.column = 0 + emitter.whitespace = true + emitter.indention = true + + if emitter.encoding != yaml_UTF8_ENCODING { + if !yaml_emitter_write_bom(emitter) { + return false + } + } + emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE + return true +} + +// Expect DOCUMENT-START or STREAM-END. +func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + + if event.typ == yaml_DOCUMENT_START_EVENT { + + if event.version_directive != nil { + if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) { + return false + } + } + + for i := 0; i < len(event.tag_directives); i++ { + tag_directive := &event.tag_directives[i] + if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) { + return false + } + if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) { + return false + } + } + + for i := 0; i < len(default_tag_directives); i++ { + tag_directive := &default_tag_directives[i] + if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) { + return false + } + } + + implicit := event.implicit + if !first || emitter.canonical { + implicit = false + } + + if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) { + if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + + if event.version_directive != nil { + implicit = false + if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + + if len(event.tag_directives) > 0 { + implicit = false + for i := 0; i < len(event.tag_directives); i++ { + tag_directive := &event.tag_directives[i] + if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) { + return false + } + if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) { + return false + } + if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + } + + if yaml_emitter_check_empty_document(emitter) { + implicit = false + } + if !implicit { + if !yaml_emitter_write_indent(emitter) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) { + return false + } + if emitter.canonical { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + } + + emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE + return true + } + + if event.typ == yaml_STREAM_END_EVENT { + if emitter.open_ended { + if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_flush(emitter) { + return false + } + emitter.state = yaml_EMIT_END_STATE + return true + } + + return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END") +} + +// Expect the root node. +func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool { + emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE) + return yaml_emitter_emit_node(emitter, event, true, false, false, false) +} + +// Expect DOCUMENT-END. +func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if event.typ != yaml_DOCUMENT_END_EVENT { + return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END") + } + if !yaml_emitter_write_indent(emitter) { + return false + } + if !event.implicit { + // [Go] Allocate the slice elsewhere. + if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_flush(emitter) { + return false + } + emitter.state = yaml_EMIT_DOCUMENT_START_STATE + emitter.tag_directives = emitter.tag_directives[:0] + return true +} + +// Expect a flow item node. +func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) { + return false + } + if !yaml_emitter_increase_indent(emitter, true, false) { + return false + } + emitter.flow_level++ + } + + if event.typ == yaml_SEQUENCE_END_EVENT { + emitter.flow_level-- + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + if emitter.canonical && !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) { + return false + } + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + + return true + } + + if !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + } + + if emitter.canonical || emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE) + return yaml_emitter_emit_node(emitter, event, false, true, false, false) +} + +// Expect a flow key node. +func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) { + return false + } + if !yaml_emitter_increase_indent(emitter, true, false) { + return false + } + emitter.flow_level++ + } + + if event.typ == yaml_MAPPING_END_EVENT { + emitter.flow_level-- + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + if emitter.canonical && !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) { + return false + } + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true + } + + if !first { + if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) { + return false + } + } + if emitter.canonical || emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + + if !emitter.canonical && yaml_emitter_check_simple_key(emitter) { + emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, true) + } + if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) { + return false + } + emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a flow value node. +func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { + if simple { + if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { + return false + } + } else { + if emitter.canonical || emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) { + return false + } + } + emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a block item node. +func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) { + return false + } + } + if event.typ == yaml_SEQUENCE_END_EVENT { + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true + } + if !yaml_emitter_write_indent(emitter) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) { + return false + } + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE) + return yaml_emitter_emit_node(emitter, event, false, true, false, false) +} + +// Expect a block key node. +func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool { + if first { + if !yaml_emitter_increase_indent(emitter, false, false) { + return false + } + } + if event.typ == yaml_MAPPING_END_EVENT { + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true + } + if !yaml_emitter_write_indent(emitter) { + return false + } + if yaml_emitter_check_simple_key(emitter) { + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, true) + } + if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) { + return false + } + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a block value node. +func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool { + if simple { + if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) { + return false + } + } else { + if !yaml_emitter_write_indent(emitter) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) { + return false + } + } + emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE) + return yaml_emitter_emit_node(emitter, event, false, false, true, false) +} + +// Expect a node. +func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t, + root bool, sequence bool, mapping bool, simple_key bool) bool { + + emitter.root_context = root + emitter.sequence_context = sequence + emitter.mapping_context = mapping + emitter.simple_key_context = simple_key + + switch event.typ { + case yaml_ALIAS_EVENT: + return yaml_emitter_emit_alias(emitter, event) + case yaml_SCALAR_EVENT: + return yaml_emitter_emit_scalar(emitter, event) + case yaml_SEQUENCE_START_EVENT: + return yaml_emitter_emit_sequence_start(emitter, event) + case yaml_MAPPING_START_EVENT: + return yaml_emitter_emit_mapping_start(emitter, event) + default: + return yaml_emitter_set_emitter_error(emitter, + "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS") + } + return false +} + +// Expect ALIAS. +func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_process_anchor(emitter) { + return false + } + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true +} + +// Expect SCALAR. +func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_select_scalar_style(emitter, event) { + return false + } + if !yaml_emitter_process_anchor(emitter) { + return false + } + if !yaml_emitter_process_tag(emitter) { + return false + } + if !yaml_emitter_increase_indent(emitter, true, false) { + return false + } + if !yaml_emitter_process_scalar(emitter) { + return false + } + emitter.indent = emitter.indents[len(emitter.indents)-1] + emitter.indents = emitter.indents[:len(emitter.indents)-1] + emitter.state = emitter.states[len(emitter.states)-1] + emitter.states = emitter.states[:len(emitter.states)-1] + return true +} + +// Expect SEQUENCE-START. +func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_process_anchor(emitter) { + return false + } + if !yaml_emitter_process_tag(emitter) { + return false + } + if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || + yaml_emitter_check_empty_sequence(emitter) { + emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE + } else { + emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE + } + return true +} + +// Expect MAPPING-START. +func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool { + if !yaml_emitter_process_anchor(emitter) { + return false + } + if !yaml_emitter_process_tag(emitter) { + return false + } + if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE || + yaml_emitter_check_empty_mapping(emitter) { + emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE + } else { + emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE + } + return true +} + +// Check if the document content is an empty scalar. +func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool { + return false // [Go] Huh? +} + +// Check if the next events represent an empty sequence. +func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool { + if len(emitter.events)-emitter.events_head < 2 { + return false + } + return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT && + emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT +} + +// Check if the next events represent an empty mapping. +func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool { + if len(emitter.events)-emitter.events_head < 2 { + return false + } + return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT && + emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT +} + +// Check if the next node can be expressed as a simple key. +func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool { + length := 0 + switch emitter.events[emitter.events_head].typ { + case yaml_ALIAS_EVENT: + length += len(emitter.anchor_data.anchor) + case yaml_SCALAR_EVENT: + if emitter.scalar_data.multiline { + return false + } + length += len(emitter.anchor_data.anchor) + + len(emitter.tag_data.handle) + + len(emitter.tag_data.suffix) + + len(emitter.scalar_data.value) + case yaml_SEQUENCE_START_EVENT: + if !yaml_emitter_check_empty_sequence(emitter) { + return false + } + length += len(emitter.anchor_data.anchor) + + len(emitter.tag_data.handle) + + len(emitter.tag_data.suffix) + case yaml_MAPPING_START_EVENT: + if !yaml_emitter_check_empty_mapping(emitter) { + return false + } + length += len(emitter.anchor_data.anchor) + + len(emitter.tag_data.handle) + + len(emitter.tag_data.suffix) + default: + return false + } + return length <= 128 +} + +// Determine an acceptable scalar style. +func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool { + + no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 + if no_tag && !event.implicit && !event.quoted_implicit { + return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified") + } + + style := event.scalar_style() + if style == yaml_ANY_SCALAR_STYLE { + style = yaml_PLAIN_SCALAR_STYLE + } + if emitter.canonical { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + if emitter.simple_key_context && emitter.scalar_data.multiline { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + + if style == yaml_PLAIN_SCALAR_STYLE { + if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed || + emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed { + style = yaml_SINGLE_QUOTED_SCALAR_STYLE + } + if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) { + style = yaml_SINGLE_QUOTED_SCALAR_STYLE + } + if no_tag && !event.implicit { + style = yaml_SINGLE_QUOTED_SCALAR_STYLE + } + } + if style == yaml_SINGLE_QUOTED_SCALAR_STYLE { + if !emitter.scalar_data.single_quoted_allowed { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + } + if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE { + if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + } + + if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE { + emitter.tag_data.handle = []byte{'!'} + } + emitter.scalar_data.style = style + return true +} + +// Write an achor. +func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool { + if emitter.anchor_data.anchor == nil { + return true + } + c := []byte{'&'} + if emitter.anchor_data.alias { + c[0] = '*' + } + if !yaml_emitter_write_indicator(emitter, c, true, false, false) { + return false + } + return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor) +} + +// Write a tag. +func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool { + if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 { + return true + } + if len(emitter.tag_data.handle) > 0 { + if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) { + return false + } + if len(emitter.tag_data.suffix) > 0 { + if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { + return false + } + } + } else { + // [Go] Allocate these slices elsewhere. + if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) { + return false + } + if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) { + return false + } + if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) { + return false + } + } + return true +} + +// Write a scalar. +func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool { + switch emitter.scalar_data.style { + case yaml_PLAIN_SCALAR_STYLE: + return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) + + case yaml_SINGLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) + + case yaml_DOUBLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context) + + case yaml_LITERAL_SCALAR_STYLE: + return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value) + + case yaml_FOLDED_SCALAR_STYLE: + return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value) + } + panic("unknown scalar style") +} + +// Check if a %YAML directive is valid. +func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool { + if version_directive.major != 1 || version_directive.minor != 1 { + return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive") + } + return true +} + +// Check if a %TAG directive is valid. +func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool { + handle := tag_directive.handle + prefix := tag_directive.prefix + if len(handle) == 0 { + return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty") + } + if handle[0] != '!' { + return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'") + } + if handle[len(handle)-1] != '!' { + return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'") + } + for i := 1; i < len(handle)-1; i += width(handle[i]) { + if !is_alpha(handle, i) { + return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only") + } + } + if len(prefix) == 0 { + return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty") + } + return true +} + +// Check if an anchor is valid. +func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool { + if len(anchor) == 0 { + problem := "anchor value must not be empty" + if alias { + problem = "alias value must not be empty" + } + return yaml_emitter_set_emitter_error(emitter, problem) + } + for i := 0; i < len(anchor); i += width(anchor[i]) { + if !is_alpha(anchor, i) { + problem := "anchor value must contain alphanumerical characters only" + if alias { + problem = "alias value must contain alphanumerical characters only" + } + return yaml_emitter_set_emitter_error(emitter, problem) + } + } + emitter.anchor_data.anchor = anchor + emitter.anchor_data.alias = alias + return true +} + +// Check if a tag is valid. +func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool { + if len(tag) == 0 { + return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty") + } + for i := 0; i < len(emitter.tag_directives); i++ { + tag_directive := &emitter.tag_directives[i] + if bytes.HasPrefix(tag, tag_directive.prefix) { + emitter.tag_data.handle = tag_directive.handle + emitter.tag_data.suffix = tag[len(tag_directive.prefix):] + return true + } + } + emitter.tag_data.suffix = tag + return true +} + +// Check if a scalar is valid. +func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool { + var ( + block_indicators = false + flow_indicators = false + line_breaks = false + special_characters = false + + leading_space = false + leading_break = false + trailing_space = false + trailing_break = false + break_space = false + space_break = false + + preceeded_by_whitespace = false + followed_by_whitespace = false + previous_space = false + previous_break = false + ) + + emitter.scalar_data.value = value + + if len(value) == 0 { + emitter.scalar_data.multiline = false + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = true + emitter.scalar_data.single_quoted_allowed = true + emitter.scalar_data.block_allowed = false + return true + } + + if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) { + block_indicators = true + flow_indicators = true + } + + preceeded_by_whitespace = true + for i, w := 0, 0; i < len(value); i += w { + w = width(value[i]) + followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w) + + if i == 0 { + switch value[i] { + case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`': + flow_indicators = true + block_indicators = true + case '?', ':': + flow_indicators = true + if followed_by_whitespace { + block_indicators = true + } + case '-': + if followed_by_whitespace { + flow_indicators = true + block_indicators = true + } + } + } else { + switch value[i] { + case ',', '?', '[', ']', '{', '}': + flow_indicators = true + case ':': + flow_indicators = true + if followed_by_whitespace { + block_indicators = true + } + case '#': + if preceeded_by_whitespace { + flow_indicators = true + block_indicators = true + } + } + } + + if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode { + special_characters = true + } + if is_space(value, i) { + if i == 0 { + leading_space = true + } + if i+width(value[i]) == len(value) { + trailing_space = true + } + if previous_break { + break_space = true + } + previous_space = true + previous_break = false + } else if is_break(value, i) { + line_breaks = true + if i == 0 { + leading_break = true + } + if i+width(value[i]) == len(value) { + trailing_break = true + } + if previous_space { + space_break = true + } + previous_space = false + previous_break = true + } else { + previous_space = false + previous_break = false + } + + // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition. + preceeded_by_whitespace = is_blankz(value, i) + } + + emitter.scalar_data.multiline = line_breaks + emitter.scalar_data.flow_plain_allowed = true + emitter.scalar_data.block_plain_allowed = true + emitter.scalar_data.single_quoted_allowed = true + emitter.scalar_data.block_allowed = true + + if leading_space || leading_break || trailing_space || trailing_break { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + } + if trailing_space { + emitter.scalar_data.block_allowed = false + } + if break_space { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + emitter.scalar_data.single_quoted_allowed = false + } + if space_break || special_characters { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + emitter.scalar_data.single_quoted_allowed = false + emitter.scalar_data.block_allowed = false + } + if line_breaks { + emitter.scalar_data.flow_plain_allowed = false + emitter.scalar_data.block_plain_allowed = false + } + if flow_indicators { + emitter.scalar_data.flow_plain_allowed = false + } + if block_indicators { + emitter.scalar_data.block_plain_allowed = false + } + return true +} + +// Check if the event data is valid. +func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool { + + emitter.anchor_data.anchor = nil + emitter.tag_data.handle = nil + emitter.tag_data.suffix = nil + emitter.scalar_data.value = nil + + switch event.typ { + case yaml_ALIAS_EVENT: + if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) { + return false + } + + case yaml_SCALAR_EVENT: + if len(event.anchor) > 0 { + if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { + return false + } + } + if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) { + if !yaml_emitter_analyze_tag(emitter, event.tag) { + return false + } + } + if !yaml_emitter_analyze_scalar(emitter, event.value) { + return false + } + + case yaml_SEQUENCE_START_EVENT: + if len(event.anchor) > 0 { + if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { + return false + } + } + if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { + if !yaml_emitter_analyze_tag(emitter, event.tag) { + return false + } + } + + case yaml_MAPPING_START_EVENT: + if len(event.anchor) > 0 { + if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) { + return false + } + } + if len(event.tag) > 0 && (emitter.canonical || !event.implicit) { + if !yaml_emitter_analyze_tag(emitter, event.tag) { + return false + } + } + } + return true +} + +// Write the BOM character. +func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool { + if !flush(emitter) { + return false + } + pos := emitter.buffer_pos + emitter.buffer[pos+0] = '\xEF' + emitter.buffer[pos+1] = '\xBB' + emitter.buffer[pos+2] = '\xBF' + emitter.buffer_pos += 3 + return true +} + +func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool { + indent := emitter.indent + if indent < 0 { + indent = 0 + } + if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) { + if !put_break(emitter) { + return false + } + } + for emitter.column < indent { + if !put(emitter, ' ') { + return false + } + } + emitter.whitespace = true + emitter.indention = true + return true +} + +func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool { + if need_whitespace && !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + if !write_all(emitter, indicator) { + return false + } + emitter.whitespace = is_whitespace + emitter.indention = (emitter.indention && is_indention) + emitter.open_ended = false + return true +} + +func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool { + if !write_all(emitter, value) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool { + if !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + if !write_all(emitter, value) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool { + if need_whitespace && !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + for i := 0; i < len(value); { + var must_write bool + switch value[i] { + case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']': + must_write = true + default: + must_write = is_alpha(value, i) + } + if must_write { + if !write(emitter, value, &i) { + return false + } + } else { + w := width(value[i]) + for k := 0; k < w; k++ { + octet := value[i] + i++ + if !put(emitter, '%') { + return false + } + + c := octet >> 4 + if c < 10 { + c += '0' + } else { + c += 'A' - 10 + } + if !put(emitter, c) { + return false + } + + c = octet & 0x0f + if c < 10 { + c += '0' + } else { + c += 'A' - 10 + } + if !put(emitter, c) { + return false + } + } + } + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { + if !emitter.whitespace { + if !put(emitter, ' ') { + return false + } + } + + spaces := false + breaks := false + for i := 0; i < len(value); { + if is_space(value, i) { + if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) { + if !yaml_emitter_write_indent(emitter) { + return false + } + i += width(value[i]) + } else { + if !write(emitter, value, &i) { + return false + } + } + spaces = true + } else if is_break(value, i) { + if !breaks && value[i] == '\n' { + if !put_break(emitter) { + return false + } + } + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !write(emitter, value, &i) { + return false + } + emitter.indention = false + spaces = false + breaks = false + } + } + + emitter.whitespace = false + emitter.indention = false + if emitter.root_context { + emitter.open_ended = true + } + + return true +} + +func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { + + if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) { + return false + } + + spaces := false + breaks := false + for i := 0; i < len(value); { + if is_space(value, i) { + if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) { + if !yaml_emitter_write_indent(emitter) { + return false + } + i += width(value[i]) + } else { + if !write(emitter, value, &i) { + return false + } + } + spaces = true + } else if is_break(value, i) { + if !breaks && value[i] == '\n' { + if !put_break(emitter) { + return false + } + } + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if value[i] == '\'' { + if !put(emitter, '\'') { + return false + } + } + if !write(emitter, value, &i) { + return false + } + emitter.indention = false + spaces = false + breaks = false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool { + spaces := false + if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) { + return false + } + + for i := 0; i < len(value); { + if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) || + is_bom(value, i) || is_break(value, i) || + value[i] == '"' || value[i] == '\\' { + + octet := value[i] + + var w int + var v rune + switch { + case octet&0x80 == 0x00: + w, v = 1, rune(octet&0x7F) + case octet&0xE0 == 0xC0: + w, v = 2, rune(octet&0x1F) + case octet&0xF0 == 0xE0: + w, v = 3, rune(octet&0x0F) + case octet&0xF8 == 0xF0: + w, v = 4, rune(octet&0x07) + } + for k := 1; k < w; k++ { + octet = value[i+k] + v = (v << 6) + (rune(octet) & 0x3F) + } + i += w + + if !put(emitter, '\\') { + return false + } + + var ok bool + switch v { + case 0x00: + ok = put(emitter, '0') + case 0x07: + ok = put(emitter, 'a') + case 0x08: + ok = put(emitter, 'b') + case 0x09: + ok = put(emitter, 't') + case 0x0A: + ok = put(emitter, 'n') + case 0x0b: + ok = put(emitter, 'v') + case 0x0c: + ok = put(emitter, 'f') + case 0x0d: + ok = put(emitter, 'r') + case 0x1b: + ok = put(emitter, 'e') + case 0x22: + ok = put(emitter, '"') + case 0x5c: + ok = put(emitter, '\\') + case 0x85: + ok = put(emitter, 'N') + case 0xA0: + ok = put(emitter, '_') + case 0x2028: + ok = put(emitter, 'L') + case 0x2029: + ok = put(emitter, 'P') + default: + if v <= 0xFF { + ok = put(emitter, 'x') + w = 2 + } else if v <= 0xFFFF { + ok = put(emitter, 'u') + w = 4 + } else { + ok = put(emitter, 'U') + w = 8 + } + for k := (w - 1) * 4; ok && k >= 0; k -= 4 { + digit := byte((v >> uint(k)) & 0x0F) + if digit < 10 { + ok = put(emitter, digit+'0') + } else { + ok = put(emitter, digit+'A'-10) + } + } + } + if !ok { + return false + } + spaces = false + } else if is_space(value, i) { + if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 { + if !yaml_emitter_write_indent(emitter) { + return false + } + if is_space(value, i+1) { + if !put(emitter, '\\') { + return false + } + } + i += width(value[i]) + } else if !write(emitter, value, &i) { + return false + } + spaces = true + } else { + if !write(emitter, value, &i) { + return false + } + spaces = false + } + } + if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) { + return false + } + emitter.whitespace = false + emitter.indention = false + return true +} + +func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool { + if is_space(value, 0) || is_break(value, 0) { + indent_hint := []byte{'0' + byte(emitter.best_indent)} + if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) { + return false + } + } + + emitter.open_ended = false + + var chomp_hint [1]byte + if len(value) == 0 { + chomp_hint[0] = '-' + } else { + i := len(value) - 1 + for value[i]&0xC0 == 0x80 { + i-- + } + if !is_break(value, i) { + chomp_hint[0] = '-' + } else if i == 0 { + chomp_hint[0] = '+' + emitter.open_ended = true + } else { + i-- + for value[i]&0xC0 == 0x80 { + i-- + } + if is_break(value, i) { + chomp_hint[0] = '+' + emitter.open_ended = true + } + } + } + if chomp_hint[0] != 0 { + if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) { + return false + } + } + return true +} + +func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool { + if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) { + return false + } + if !yaml_emitter_write_block_scalar_hints(emitter, value) { + return false + } + if !put_break(emitter) { + return false + } + emitter.indention = true + emitter.whitespace = true + breaks := true + for i := 0; i < len(value); { + if is_break(value, i) { + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + } + if !write(emitter, value, &i) { + return false + } + emitter.indention = false + breaks = false + } + } + + return true +} + +func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool { + if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) { + return false + } + if !yaml_emitter_write_block_scalar_hints(emitter, value) { + return false + } + + if !put_break(emitter) { + return false + } + emitter.indention = true + emitter.whitespace = true + + breaks := true + leading_spaces := true + for i := 0; i < len(value); { + if is_break(value, i) { + if !breaks && !leading_spaces && value[i] == '\n' { + k := 0 + for is_break(value, k) { + k += width(value[k]) + } + if !is_blankz(value, k) { + if !put_break(emitter) { + return false + } + } + } + if !write_break(emitter, value, &i) { + return false + } + emitter.indention = true + breaks = true + } else { + if breaks { + if !yaml_emitter_write_indent(emitter) { + return false + } + leading_spaces = is_blank(value, i) + } + if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width { + if !yaml_emitter_write_indent(emitter) { + return false + } + i += width(value[i]) + } else { + if !write(emitter, value, &i) { + return false + } + } + emitter.indention = false + breaks = false + } + } + return true +} diff --git a/vendor/gopkg.in/yaml.v2/encode.go b/vendor/gopkg.in/yaml.v2/encode.go new file mode 100644 index 000000000..84f849955 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/encode.go @@ -0,0 +1,306 @@ +package yaml + +import ( + "encoding" + "fmt" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "time" +) + +type encoder struct { + emitter yaml_emitter_t + event yaml_event_t + out []byte + flow bool +} + +func newEncoder() (e *encoder) { + e = &encoder{} + e.must(yaml_emitter_initialize(&e.emitter)) + yaml_emitter_set_output_string(&e.emitter, &e.out) + yaml_emitter_set_unicode(&e.emitter, true) + e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)) + e.emit() + e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true)) + e.emit() + return e +} + +func (e *encoder) finish() { + e.must(yaml_document_end_event_initialize(&e.event, true)) + e.emit() + e.emitter.open_ended = false + e.must(yaml_stream_end_event_initialize(&e.event)) + e.emit() +} + +func (e *encoder) destroy() { + yaml_emitter_delete(&e.emitter) +} + +func (e *encoder) emit() { + // This will internally delete the e.event value. + if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT { + e.must(false) + } +} + +func (e *encoder) must(ok bool) { + if !ok { + msg := e.emitter.problem + if msg == "" { + msg = "unknown problem generating YAML content" + } + failf("%s", msg) + } +} + +func (e *encoder) marshal(tag string, in reflect.Value) { + if !in.IsValid() { + e.nilv() + return + } + iface := in.Interface() + if m, ok := iface.(Marshaler); ok { + v, err := m.MarshalYAML() + if err != nil { + fail(err) + } + if v == nil { + e.nilv() + return + } + in = reflect.ValueOf(v) + } else if m, ok := iface.(encoding.TextMarshaler); ok { + text, err := m.MarshalText() + if err != nil { + fail(err) + } + in = reflect.ValueOf(string(text)) + } + switch in.Kind() { + case reflect.Interface: + if in.IsNil() { + e.nilv() + } else { + e.marshal(tag, in.Elem()) + } + case reflect.Map: + e.mapv(tag, in) + case reflect.Ptr: + if in.IsNil() { + e.nilv() + } else { + e.marshal(tag, in.Elem()) + } + case reflect.Struct: + e.structv(tag, in) + case reflect.Slice: + if in.Type().Elem() == mapItemType { + e.itemsv(tag, in) + } else { + e.slicev(tag, in) + } + case reflect.String: + e.stringv(tag, in) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if in.Type() == durationType { + e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String())) + } else { + e.intv(tag, in) + } + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + e.uintv(tag, in) + case reflect.Float32, reflect.Float64: + e.floatv(tag, in) + case reflect.Bool: + e.boolv(tag, in) + default: + panic("cannot marshal type: " + in.Type().String()) + } +} + +func (e *encoder) mapv(tag string, in reflect.Value) { + e.mappingv(tag, func() { + keys := keyList(in.MapKeys()) + sort.Sort(keys) + for _, k := range keys { + e.marshal("", k) + e.marshal("", in.MapIndex(k)) + } + }) +} + +func (e *encoder) itemsv(tag string, in reflect.Value) { + e.mappingv(tag, func() { + slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem) + for _, item := range slice { + e.marshal("", reflect.ValueOf(item.Key)) + e.marshal("", reflect.ValueOf(item.Value)) + } + }) +} + +func (e *encoder) structv(tag string, in reflect.Value) { + sinfo, err := getStructInfo(in.Type()) + if err != nil { + panic(err) + } + e.mappingv(tag, func() { + for _, info := range sinfo.FieldsList { + var value reflect.Value + if info.Inline == nil { + value = in.Field(info.Num) + } else { + value = in.FieldByIndex(info.Inline) + } + if info.OmitEmpty && isZero(value) { + continue + } + e.marshal("", reflect.ValueOf(info.Key)) + e.flow = info.Flow + e.marshal("", value) + } + if sinfo.InlineMap >= 0 { + m := in.Field(sinfo.InlineMap) + if m.Len() > 0 { + e.flow = false + keys := keyList(m.MapKeys()) + sort.Sort(keys) + for _, k := range keys { + if _, found := sinfo.FieldsMap[k.String()]; found { + panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String())) + } + e.marshal("", k) + e.flow = false + e.marshal("", m.MapIndex(k)) + } + } + } + }) +} + +func (e *encoder) mappingv(tag string, f func()) { + implicit := tag == "" + style := yaml_BLOCK_MAPPING_STYLE + if e.flow { + e.flow = false + style = yaml_FLOW_MAPPING_STYLE + } + e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) + e.emit() + f() + e.must(yaml_mapping_end_event_initialize(&e.event)) + e.emit() +} + +func (e *encoder) slicev(tag string, in reflect.Value) { + implicit := tag == "" + style := yaml_BLOCK_SEQUENCE_STYLE + if e.flow { + e.flow = false + style = yaml_FLOW_SEQUENCE_STYLE + } + e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)) + e.emit() + n := in.Len() + for i := 0; i < n; i++ { + e.marshal("", in.Index(i)) + } + e.must(yaml_sequence_end_event_initialize(&e.event)) + e.emit() +} + +// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1. +// +// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported +// in YAML 1.2 and by this package, but these should be marshalled quoted for +// the time being for compatibility with other parsers. +func isBase60Float(s string) (result bool) { + // Fast path. + if s == "" { + return false + } + c := s[0] + if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 { + return false + } + // Do the full match. + return base60float.MatchString(s) +} + +// From http://yaml.org/type/float.html, except the regular expression there +// is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix. +var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`) + +func (e *encoder) stringv(tag string, in reflect.Value) { + var style yaml_scalar_style_t + s := in.String() + rtag, rs := resolve("", s) + if rtag == yaml_BINARY_TAG { + if tag == "" || tag == yaml_STR_TAG { + tag = rtag + s = rs.(string) + } else if tag == yaml_BINARY_TAG { + failf("explicitly tagged !!binary data must be base64-encoded") + } else { + failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag)) + } + } + if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) { + style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } else if strings.Contains(s, "\n") { + style = yaml_LITERAL_SCALAR_STYLE + } else { + style = yaml_PLAIN_SCALAR_STYLE + } + e.emitScalar(s, "", tag, style) +} + +func (e *encoder) boolv(tag string, in reflect.Value) { + var s string + if in.Bool() { + s = "true" + } else { + s = "false" + } + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) intv(tag string, in reflect.Value) { + s := strconv.FormatInt(in.Int(), 10) + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) uintv(tag string, in reflect.Value) { + s := strconv.FormatUint(in.Uint(), 10) + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) floatv(tag string, in reflect.Value) { + // FIXME: Handle 64 bits here. + s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32) + switch s { + case "+Inf": + s = ".inf" + case "-Inf": + s = "-.inf" + case "NaN": + s = ".nan" + } + e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) nilv() { + e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE) +} + +func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) { + implicit := tag == "" + e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style)) + e.emit() +} diff --git a/vendor/gopkg.in/yaml.v2/parserc.go b/vendor/gopkg.in/yaml.v2/parserc.go new file mode 100644 index 000000000..0a7037ad1 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/parserc.go @@ -0,0 +1,1096 @@ +package yaml + +import ( + "bytes" +) + +// The parser implements the following grammar: +// +// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +// implicit_document ::= block_node DOCUMENT-END* +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// block_node_or_indentless_sequence ::= +// ALIAS +// | properties (block_content | indentless_block_sequence)? +// | block_content +// | indentless_block_sequence +// block_node ::= ALIAS +// | properties block_content? +// | block_content +// flow_node ::= ALIAS +// | properties flow_content? +// | flow_content +// properties ::= TAG ANCHOR? | ANCHOR TAG? +// block_content ::= block_collection | flow_collection | SCALAR +// flow_content ::= flow_collection | SCALAR +// block_collection ::= block_sequence | block_mapping +// flow_collection ::= flow_sequence | flow_mapping +// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +// block_mapping ::= BLOCK-MAPPING_START +// ((KEY block_node_or_indentless_sequence?)? +// (VALUE block_node_or_indentless_sequence?)?)* +// BLOCK-END +// flow_sequence ::= FLOW-SEQUENCE-START +// (flow_sequence_entry FLOW-ENTRY)* +// flow_sequence_entry? +// FLOW-SEQUENCE-END +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// flow_mapping ::= FLOW-MAPPING-START +// (flow_mapping_entry FLOW-ENTRY)* +// flow_mapping_entry? +// FLOW-MAPPING-END +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + +// Peek the next token in the token queue. +func peek_token(parser *yaml_parser_t) *yaml_token_t { + if parser.token_available || yaml_parser_fetch_more_tokens(parser) { + return &parser.tokens[parser.tokens_head] + } + return nil +} + +// Remove the next token from the queue (must be called after peek_token). +func skip_token(parser *yaml_parser_t) { + parser.token_available = false + parser.tokens_parsed++ + parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN + parser.tokens_head++ +} + +// Get the next event. +func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { + // Erase the event object. + *event = yaml_event_t{} + + // No events after the end of the stream or error. + if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { + return true + } + + // Generate the next event. + return yaml_parser_state_machine(parser, event) +} + +// Set parser error. +func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { + parser.error = yaml_PARSER_ERROR + parser.problem = problem + parser.problem_mark = problem_mark + return false +} + +func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { + parser.error = yaml_PARSER_ERROR + parser.context = context + parser.context_mark = context_mark + parser.problem = problem + parser.problem_mark = problem_mark + return false +} + +// State dispatcher. +func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { + //trace("yaml_parser_state_machine", "state:", parser.state.String()) + + switch parser.state { + case yaml_PARSE_STREAM_START_STATE: + return yaml_parser_parse_stream_start(parser, event) + + case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, true) + + case yaml_PARSE_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, false) + + case yaml_PARSE_DOCUMENT_CONTENT_STATE: + return yaml_parser_parse_document_content(parser, event) + + case yaml_PARSE_DOCUMENT_END_STATE: + return yaml_parser_parse_document_end(parser, event) + + case yaml_PARSE_BLOCK_NODE_STATE: + return yaml_parser_parse_node(parser, event, true, false) + + case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: + return yaml_parser_parse_node(parser, event, true, true) + + case yaml_PARSE_FLOW_NODE_STATE: + return yaml_parser_parse_node(parser, event, false, false) + + case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, true) + + case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, false) + + case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_indentless_sequence_entry(parser, event) + + case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, true) + + case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, false) + + case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: + return yaml_parser_parse_block_mapping_value(parser, event) + + case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, true) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, false) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) + + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) + + case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, true) + + case yaml_PARSE_FLOW_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, false) + + case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, false) + + case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, true) + + default: + panic("invalid parser state") + } + return false +} + +// Parse the production: +// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +// ************ +func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_STREAM_START_TOKEN { + return yaml_parser_set_parser_error(parser, "did not find expected ", token.start_mark) + } + parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE + *event = yaml_event_t{ + typ: yaml_STREAM_START_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + encoding: token.encoding, + } + skip_token(parser) + return true +} + +// Parse the productions: +// implicit_document ::= block_node DOCUMENT-END* +// * +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// ************************* +func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { + + token := peek_token(parser) + if token == nil { + return false + } + + // Parse extra document end indicators. + if !implicit { + for token.typ == yaml_DOCUMENT_END_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + } + + if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && + token.typ != yaml_TAG_DIRECTIVE_TOKEN && + token.typ != yaml_DOCUMENT_START_TOKEN && + token.typ != yaml_STREAM_END_TOKEN { + // Parse an implicit document. + if !yaml_parser_process_directives(parser, nil, nil) { + return false + } + parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) + parser.state = yaml_PARSE_BLOCK_NODE_STATE + + *event = yaml_event_t{ + typ: yaml_DOCUMENT_START_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + + } else if token.typ != yaml_STREAM_END_TOKEN { + // Parse an explicit document. + var version_directive *yaml_version_directive_t + var tag_directives []yaml_tag_directive_t + start_mark := token.start_mark + if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { + return false + } + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_DOCUMENT_START_TOKEN { + yaml_parser_set_parser_error(parser, + "did not find expected ", token.start_mark) + return false + } + parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) + parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE + end_mark := token.end_mark + + *event = yaml_event_t{ + typ: yaml_DOCUMENT_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + version_directive: version_directive, + tag_directives: tag_directives, + implicit: false, + } + skip_token(parser) + + } else { + // Parse the stream end. + parser.state = yaml_PARSE_END_STATE + *event = yaml_event_t{ + typ: yaml_STREAM_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + skip_token(parser) + } + + return true +} + +// Parse the productions: +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// *********** +// +func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || + token.typ == yaml_TAG_DIRECTIVE_TOKEN || + token.typ == yaml_DOCUMENT_START_TOKEN || + token.typ == yaml_DOCUMENT_END_TOKEN || + token.typ == yaml_STREAM_END_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + return yaml_parser_process_empty_scalar(parser, event, + token.start_mark) + } + return yaml_parser_parse_node(parser, event, true, false) +} + +// Parse the productions: +// implicit_document ::= block_node DOCUMENT-END* +// ************* +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// +func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + + start_mark := token.start_mark + end_mark := token.start_mark + + implicit := true + if token.typ == yaml_DOCUMENT_END_TOKEN { + end_mark = token.end_mark + skip_token(parser) + implicit = false + } + + parser.tag_directives = parser.tag_directives[:0] + + parser.state = yaml_PARSE_DOCUMENT_START_STATE + *event = yaml_event_t{ + typ: yaml_DOCUMENT_END_EVENT, + start_mark: start_mark, + end_mark: end_mark, + implicit: implicit, + } + return true +} + +// Parse the productions: +// block_node_or_indentless_sequence ::= +// ALIAS +// ***** +// | properties (block_content | indentless_block_sequence)? +// ********** * +// | block_content | indentless_block_sequence +// * +// block_node ::= ALIAS +// ***** +// | properties block_content? +// ********** * +// | block_content +// * +// flow_node ::= ALIAS +// ***** +// | properties flow_content? +// ********** * +// | flow_content +// * +// properties ::= TAG ANCHOR? | ANCHOR TAG? +// ************************* +// block_content ::= block_collection | flow_collection | SCALAR +// ****** +// flow_content ::= flow_collection | SCALAR +// ****** +func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { + //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_ALIAS_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + *event = yaml_event_t{ + typ: yaml_ALIAS_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + anchor: token.value, + } + skip_token(parser) + return true + } + + start_mark := token.start_mark + end_mark := token.start_mark + + var tag_token bool + var tag_handle, tag_suffix, anchor []byte + var tag_mark yaml_mark_t + if token.typ == yaml_ANCHOR_TOKEN { + anchor = token.value + start_mark = token.start_mark + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_TAG_TOKEN { + tag_token = true + tag_handle = token.value + tag_suffix = token.suffix + tag_mark = token.start_mark + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + } else if token.typ == yaml_TAG_TOKEN { + tag_token = true + tag_handle = token.value + tag_suffix = token.suffix + start_mark = token.start_mark + tag_mark = token.start_mark + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_ANCHOR_TOKEN { + anchor = token.value + end_mark = token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + } + + var tag []byte + if tag_token { + if len(tag_handle) == 0 { + tag = tag_suffix + tag_suffix = nil + } else { + for i := range parser.tag_directives { + if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { + tag = append([]byte(nil), parser.tag_directives[i].prefix...) + tag = append(tag, tag_suffix...) + break + } + } + if len(tag) == 0 { + yaml_parser_set_parser_error_context(parser, + "while parsing a node", start_mark, + "found undefined tag handle", tag_mark) + return false + } + } + } + + implicit := len(tag) == 0 + if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), + } + return true + } + if token.typ == yaml_SCALAR_TOKEN { + var plain_implicit, quoted_implicit bool + end_mark = token.end_mark + if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { + plain_implicit = true + } else if len(tag) == 0 { + quoted_implicit = true + } + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + value: token.value, + implicit: plain_implicit, + quoted_implicit: quoted_implicit, + style: yaml_style_t(token.style), + } + skip_token(parser) + return true + } + if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { + // [Go] Some of the events below can be merged as they differ only on style. + end_mark = token.end_mark + parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), + } + return true + } + if token.typ == yaml_FLOW_MAPPING_START_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), + } + return true + } + if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_SEQUENCE_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), + } + return true + } + if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { + end_mark = token.end_mark + parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), + } + return true + } + if len(anchor) > 0 || len(tag) > 0 { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + start_mark: start_mark, + end_mark: end_mark, + anchor: anchor, + tag: tag, + implicit: implicit, + quoted_implicit: false, + style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), + } + return true + } + + context := "while parsing a flow node" + if block { + context = "while parsing a block node" + } + yaml_parser_set_parser_error_context(parser, context, start_mark, + "did not find expected node content", token.start_mark) + return false +} + +// Parse the productions: +// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +// ******************** *********** * ********* +// +func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_BLOCK_ENTRY_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) + return yaml_parser_parse_node(parser, event, true, false) + } else { + parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + } + if token.typ == yaml_BLOCK_END_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + + skip_token(parser) + return true + } + + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a block collection", context_mark, + "did not find expected '-' indicator", token.start_mark) +} + +// Parse the productions: +// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +// *********** * +func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_BLOCK_ENTRY_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_BLOCK_ENTRY_TOKEN && + token.typ != yaml_KEY_TOKEN && + token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) + return yaml_parser_parse_node(parser, event, true, false) + } + parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + start_mark: token.start_mark, + end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? + } + return true +} + +// Parse the productions: +// block_mapping ::= BLOCK-MAPPING_START +// ******************* +// ((KEY block_node_or_indentless_sequence?)? +// *** * +// (VALUE block_node_or_indentless_sequence?)?)* +// +// BLOCK-END +// ********* +// +func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ == yaml_KEY_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_KEY_TOKEN && + token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) + return yaml_parser_parse_node(parser, event, true, true) + } else { + parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + } else if token.typ == yaml_BLOCK_END_TOKEN { + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + skip_token(parser) + return true + } + + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a block mapping", context_mark, + "did not find expected key", token.start_mark) +} + +// Parse the productions: +// block_mapping ::= BLOCK-MAPPING_START +// +// ((KEY block_node_or_indentless_sequence?)? +// +// (VALUE block_node_or_indentless_sequence?)?)* +// ***** * +// BLOCK-END +// +// +func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_VALUE_TOKEN { + mark := token.end_mark + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_KEY_TOKEN && + token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_BLOCK_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) + return yaml_parser_parse_node(parser, event, true, true) + } + parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) + } + parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) +} + +// Parse the productions: +// flow_sequence ::= FLOW-SEQUENCE-START +// ******************* +// (flow_sequence_entry FLOW-ENTRY)* +// * ********** +// flow_sequence_entry? +// * +// FLOW-SEQUENCE-END +// ***************** +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * +// +func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + if !first { + if token.typ == yaml_FLOW_ENTRY_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } else { + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow sequence", context_mark, + "did not find expected ',' or ']'", token.start_mark) + } + } + + if token.typ == yaml_KEY_TOKEN { + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_START_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + implicit: true, + style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), + } + skip_token(parser) + return true + } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + + *event = yaml_event_t{ + typ: yaml_SEQUENCE_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + + skip_token(parser) + return true +} + +// +// Parse the productions: +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// *** * +// +func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_FLOW_ENTRY_TOKEN && + token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + mark := token.end_mark + skip_token(parser) + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE + return yaml_parser_process_empty_scalar(parser, event, mark) +} + +// Parse the productions: +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// ***** * +// +func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + if token.typ == yaml_VALUE_TOKEN { + skip_token(parser) + token := peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) +} + +// Parse the productions: +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * +// +func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { + token := peek_token(parser) + if token == nil { + return false + } + parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + start_mark: token.start_mark, + end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? + } + return true +} + +// Parse the productions: +// flow_mapping ::= FLOW-MAPPING-START +// ****************** +// (flow_mapping_entry FLOW-ENTRY)* +// * ********** +// flow_mapping_entry? +// ****************** +// FLOW-MAPPING-END +// **************** +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * *** * +// +func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { + if first { + token := peek_token(parser) + parser.marks = append(parser.marks, token.start_mark) + skip_token(parser) + } + + token := peek_token(parser) + if token == nil { + return false + } + + if token.typ != yaml_FLOW_MAPPING_END_TOKEN { + if !first { + if token.typ == yaml_FLOW_ENTRY_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } else { + context_mark := parser.marks[len(parser.marks)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow mapping", context_mark, + "did not find expected ',' or '}'", token.start_mark) + } + } + + if token.typ == yaml_KEY_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_VALUE_TOKEN && + token.typ != yaml_FLOW_ENTRY_TOKEN && + token.typ != yaml_FLOW_MAPPING_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } else { + parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) + } + } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + + parser.state = parser.states[len(parser.states)-1] + parser.states = parser.states[:len(parser.states)-1] + parser.marks = parser.marks[:len(parser.marks)-1] + *event = yaml_event_t{ + typ: yaml_MAPPING_END_EVENT, + start_mark: token.start_mark, + end_mark: token.end_mark, + } + skip_token(parser) + return true +} + +// Parse the productions: +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * ***** * +// +func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { + token := peek_token(parser) + if token == nil { + return false + } + if empty { + parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) + } + if token.typ == yaml_VALUE_TOKEN { + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { + parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) + return yaml_parser_parse_node(parser, event, false, false) + } + } + parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE + return yaml_parser_process_empty_scalar(parser, event, token.start_mark) +} + +// Generate an empty scalar event. +func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { + *event = yaml_event_t{ + typ: yaml_SCALAR_EVENT, + start_mark: mark, + end_mark: mark, + value: nil, // Empty + implicit: true, + style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), + } + return true +} + +var default_tag_directives = []yaml_tag_directive_t{ + {[]byte("!"), []byte("!")}, + {[]byte("!!"), []byte("tag:yaml.org,2002:")}, +} + +// Parse directives. +func yaml_parser_process_directives(parser *yaml_parser_t, + version_directive_ref **yaml_version_directive_t, + tag_directives_ref *[]yaml_tag_directive_t) bool { + + var version_directive *yaml_version_directive_t + var tag_directives []yaml_tag_directive_t + + token := peek_token(parser) + if token == nil { + return false + } + + for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { + if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { + if version_directive != nil { + yaml_parser_set_parser_error(parser, + "found duplicate %YAML directive", token.start_mark) + return false + } + if token.major != 1 || token.minor != 1 { + yaml_parser_set_parser_error(parser, + "found incompatible YAML document", token.start_mark) + return false + } + version_directive = &yaml_version_directive_t{ + major: token.major, + minor: token.minor, + } + } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { + value := yaml_tag_directive_t{ + handle: token.value, + prefix: token.prefix, + } + if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { + return false + } + tag_directives = append(tag_directives, value) + } + + skip_token(parser) + token = peek_token(parser) + if token == nil { + return false + } + } + + for i := range default_tag_directives { + if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { + return false + } + } + + if version_directive_ref != nil { + *version_directive_ref = version_directive + } + if tag_directives_ref != nil { + *tag_directives_ref = tag_directives + } + return true +} + +// Append a tag directive to the directives stack. +func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { + for i := range parser.tag_directives { + if bytes.Equal(value.handle, parser.tag_directives[i].handle) { + if allow_duplicates { + return true + } + return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) + } + } + + // [Go] I suspect the copy is unnecessary. This was likely done + // because there was no way to track ownership of the data. + value_copy := yaml_tag_directive_t{ + handle: make([]byte, len(value.handle)), + prefix: make([]byte, len(value.prefix)), + } + copy(value_copy.handle, value.handle) + copy(value_copy.prefix, value.prefix) + parser.tag_directives = append(parser.tag_directives, value_copy) + return true +} diff --git a/vendor/gopkg.in/yaml.v2/readerc.go b/vendor/gopkg.in/yaml.v2/readerc.go new file mode 100644 index 000000000..f45079171 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/readerc.go @@ -0,0 +1,394 @@ +package yaml + +import ( + "io" +) + +// Set the reader error and return 0. +func yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool { + parser.error = yaml_READER_ERROR + parser.problem = problem + parser.problem_offset = offset + parser.problem_value = value + return false +} + +// Byte order marks. +const ( + bom_UTF8 = "\xef\xbb\xbf" + bom_UTF16LE = "\xff\xfe" + bom_UTF16BE = "\xfe\xff" +) + +// Determine the input stream encoding by checking the BOM symbol. If no BOM is +// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. +func yaml_parser_determine_encoding(parser *yaml_parser_t) bool { + // Ensure that we had enough bytes in the raw buffer. + for !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 { + if !yaml_parser_update_raw_buffer(parser) { + return false + } + } + + // Determine the encoding. + buf := parser.raw_buffer + pos := parser.raw_buffer_pos + avail := len(buf) - pos + if avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] { + parser.encoding = yaml_UTF16LE_ENCODING + parser.raw_buffer_pos += 2 + parser.offset += 2 + } else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] { + parser.encoding = yaml_UTF16BE_ENCODING + parser.raw_buffer_pos += 2 + parser.offset += 2 + } else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] { + parser.encoding = yaml_UTF8_ENCODING + parser.raw_buffer_pos += 3 + parser.offset += 3 + } else { + parser.encoding = yaml_UTF8_ENCODING + } + return true +} + +// Update the raw buffer. +func yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool { + size_read := 0 + + // Return if the raw buffer is full. + if parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) { + return true + } + + // Return on EOF. + if parser.eof { + return true + } + + // Move the remaining bytes in the raw buffer to the beginning. + if parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) { + copy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:]) + } + parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos] + parser.raw_buffer_pos = 0 + + // Call the read handler to fill the buffer. + size_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)]) + parser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read] + if err == io.EOF { + parser.eof = true + } else if err != nil { + return yaml_parser_set_reader_error(parser, "input error: "+err.Error(), parser.offset, -1) + } + return true +} + +// Ensure that the buffer contains at least `length` characters. +// Return true on success, false on failure. +// +// The length is supposed to be significantly less that the buffer size. +func yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool { + if parser.read_handler == nil { + panic("read handler must be set") + } + + // If the EOF flag is set and the raw buffer is empty, do nothing. + if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) { + return true + } + + // Return if the buffer contains enough characters. + if parser.unread >= length { + return true + } + + // Determine the input encoding if it is not known yet. + if parser.encoding == yaml_ANY_ENCODING { + if !yaml_parser_determine_encoding(parser) { + return false + } + } + + // Move the unread characters to the beginning of the buffer. + buffer_len := len(parser.buffer) + if parser.buffer_pos > 0 && parser.buffer_pos < buffer_len { + copy(parser.buffer, parser.buffer[parser.buffer_pos:]) + buffer_len -= parser.buffer_pos + parser.buffer_pos = 0 + } else if parser.buffer_pos == buffer_len { + buffer_len = 0 + parser.buffer_pos = 0 + } + + // Open the whole buffer for writing, and cut it before returning. + parser.buffer = parser.buffer[:cap(parser.buffer)] + + // Fill the buffer until it has enough characters. + first := true + for parser.unread < length { + + // Fill the raw buffer if necessary. + if !first || parser.raw_buffer_pos == len(parser.raw_buffer) { + if !yaml_parser_update_raw_buffer(parser) { + parser.buffer = parser.buffer[:buffer_len] + return false + } + } + first = false + + // Decode the raw buffer. + inner: + for parser.raw_buffer_pos != len(parser.raw_buffer) { + var value rune + var width int + + raw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos + + // Decode the next character. + switch parser.encoding { + case yaml_UTF8_ENCODING: + // Decode a UTF-8 character. Check RFC 3629 + // (http://www.ietf.org/rfc/rfc3629.txt) for more details. + // + // The following table (taken from the RFC) is used for + // decoding. + // + // Char. number range | UTF-8 octet sequence + // (hexadecimal) | (binary) + // --------------------+------------------------------------ + // 0000 0000-0000 007F | 0xxxxxxx + // 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + // 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + // 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + // + // Additionally, the characters in the range 0xD800-0xDFFF + // are prohibited as they are reserved for use with UTF-16 + // surrogate pairs. + + // Determine the length of the UTF-8 sequence. + octet := parser.raw_buffer[parser.raw_buffer_pos] + switch { + case octet&0x80 == 0x00: + width = 1 + case octet&0xE0 == 0xC0: + width = 2 + case octet&0xF0 == 0xE0: + width = 3 + case octet&0xF8 == 0xF0: + width = 4 + default: + // The leading octet is invalid. + return yaml_parser_set_reader_error(parser, + "invalid leading UTF-8 octet", + parser.offset, int(octet)) + } + + // Check if the raw buffer contains an incomplete character. + if width > raw_unread { + if parser.eof { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-8 octet sequence", + parser.offset, -1) + } + break inner + } + + // Decode the leading octet. + switch { + case octet&0x80 == 0x00: + value = rune(octet & 0x7F) + case octet&0xE0 == 0xC0: + value = rune(octet & 0x1F) + case octet&0xF0 == 0xE0: + value = rune(octet & 0x0F) + case octet&0xF8 == 0xF0: + value = rune(octet & 0x07) + default: + value = 0 + } + + // Check and decode the trailing octets. + for k := 1; k < width; k++ { + octet = parser.raw_buffer[parser.raw_buffer_pos+k] + + // Check if the octet is valid. + if (octet & 0xC0) != 0x80 { + return yaml_parser_set_reader_error(parser, + "invalid trailing UTF-8 octet", + parser.offset+k, int(octet)) + } + + // Decode the octet. + value = (value << 6) + rune(octet&0x3F) + } + + // Check the length of the sequence against the value. + switch { + case width == 1: + case width == 2 && value >= 0x80: + case width == 3 && value >= 0x800: + case width == 4 && value >= 0x10000: + default: + return yaml_parser_set_reader_error(parser, + "invalid length of a UTF-8 sequence", + parser.offset, -1) + } + + // Check the range of the value. + if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF { + return yaml_parser_set_reader_error(parser, + "invalid Unicode character", + parser.offset, int(value)) + } + + case yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING: + var low, high int + if parser.encoding == yaml_UTF16LE_ENCODING { + low, high = 0, 1 + } else { + low, high = 1, 0 + } + + // The UTF-16 encoding is not as simple as one might + // naively think. Check RFC 2781 + // (http://www.ietf.org/rfc/rfc2781.txt). + // + // Normally, two subsequent bytes describe a Unicode + // character. However a special technique (called a + // surrogate pair) is used for specifying character + // values larger than 0xFFFF. + // + // A surrogate pair consists of two pseudo-characters: + // high surrogate area (0xD800-0xDBFF) + // low surrogate area (0xDC00-0xDFFF) + // + // The following formulas are used for decoding + // and encoding characters using surrogate pairs: + // + // U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) + // U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) + // W1 = 110110yyyyyyyyyy + // W2 = 110111xxxxxxxxxx + // + // where U is the character value, W1 is the high surrogate + // area, W2 is the low surrogate area. + + // Check for incomplete UTF-16 character. + if raw_unread < 2 { + if parser.eof { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 character", + parser.offset, -1) + } + break inner + } + + // Get the character. + value = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) + + (rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8) + + // Check for unexpected low surrogate area. + if value&0xFC00 == 0xDC00 { + return yaml_parser_set_reader_error(parser, + "unexpected low surrogate area", + parser.offset, int(value)) + } + + // Check for a high surrogate area. + if value&0xFC00 == 0xD800 { + width = 4 + + // Check for incomplete surrogate pair. + if raw_unread < 4 { + if parser.eof { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 surrogate pair", + parser.offset, -1) + } + break inner + } + + // Get the next character. + value2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) + + (rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8) + + // Check for a low surrogate area. + if value2&0xFC00 != 0xDC00 { + return yaml_parser_set_reader_error(parser, + "expected low surrogate area", + parser.offset+2, int(value2)) + } + + // Generate the value of the surrogate pair. + value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF) + } else { + width = 2 + } + + default: + panic("impossible") + } + + // Check if the character is in the allowed range: + // #x9 | #xA | #xD | [#x20-#x7E] (8 bit) + // | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) + // | [#x10000-#x10FFFF] (32 bit) + switch { + case value == 0x09: + case value == 0x0A: + case value == 0x0D: + case value >= 0x20 && value <= 0x7E: + case value == 0x85: + case value >= 0xA0 && value <= 0xD7FF: + case value >= 0xE000 && value <= 0xFFFD: + case value >= 0x10000 && value <= 0x10FFFF: + default: + return yaml_parser_set_reader_error(parser, + "control characters are not allowed", + parser.offset, int(value)) + } + + // Move the raw pointers. + parser.raw_buffer_pos += width + parser.offset += width + + // Finally put the character into the buffer. + if value <= 0x7F { + // 0000 0000-0000 007F . 0xxxxxxx + parser.buffer[buffer_len+0] = byte(value) + buffer_len += 1 + } else if value <= 0x7FF { + // 0000 0080-0000 07FF . 110xxxxx 10xxxxxx + parser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6)) + parser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F)) + buffer_len += 2 + } else if value <= 0xFFFF { + // 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx + parser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12)) + parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F)) + parser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F)) + buffer_len += 3 + } else { + // 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + parser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18)) + parser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F)) + parser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F)) + parser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F)) + buffer_len += 4 + } + + parser.unread++ + } + + // On EOF, put NUL into the buffer and return. + if parser.eof { + parser.buffer[buffer_len] = 0 + buffer_len++ + parser.unread++ + break + } + } + parser.buffer = parser.buffer[:buffer_len] + return true +} diff --git a/vendor/gopkg.in/yaml.v2/resolve.go b/vendor/gopkg.in/yaml.v2/resolve.go new file mode 100644 index 000000000..93a863274 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/resolve.go @@ -0,0 +1,203 @@ +package yaml + +import ( + "encoding/base64" + "math" + "strconv" + "strings" + "unicode/utf8" +) + +type resolveMapItem struct { + value interface{} + tag string +} + +var resolveTable = make([]byte, 256) +var resolveMap = make(map[string]resolveMapItem) + +func init() { + t := resolveTable + t[int('+')] = 'S' // Sign + t[int('-')] = 'S' + for _, c := range "0123456789" { + t[int(c)] = 'D' // Digit + } + for _, c := range "yYnNtTfFoO~" { + t[int(c)] = 'M' // In map + } + t[int('.')] = '.' // Float (potentially in map) + + var resolveMapList = []struct { + v interface{} + tag string + l []string + }{ + {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}}, + {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}}, + {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}}, + {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}}, + {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}}, + {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}}, + {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}}, + {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}}, + {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}}, + {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}}, + {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}}, + {"<<", yaml_MERGE_TAG, []string{"<<"}}, + } + + m := resolveMap + for _, item := range resolveMapList { + for _, s := range item.l { + m[s] = resolveMapItem{item.v, item.tag} + } + } +} + +const longTagPrefix = "tag:yaml.org,2002:" + +func shortTag(tag string) string { + // TODO This can easily be made faster and produce less garbage. + if strings.HasPrefix(tag, longTagPrefix) { + return "!!" + tag[len(longTagPrefix):] + } + return tag +} + +func longTag(tag string) string { + if strings.HasPrefix(tag, "!!") { + return longTagPrefix + tag[2:] + } + return tag +} + +func resolvableTag(tag string) bool { + switch tag { + case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG: + return true + } + return false +} + +func resolve(tag string, in string) (rtag string, out interface{}) { + if !resolvableTag(tag) { + return tag, in + } + + defer func() { + switch tag { + case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG: + return + } + failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag)) + }() + + // Any data is accepted as a !!str or !!binary. + // Otherwise, the prefix is enough of a hint about what it might be. + hint := byte('N') + if in != "" { + hint = resolveTable[in[0]] + } + if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG { + // Handle things we can lookup in a map. + if item, ok := resolveMap[in]; ok { + return item.tag, item.value + } + + // Base 60 floats are a bad idea, were dropped in YAML 1.2, and + // are purposefully unsupported here. They're still quoted on + // the way out for compatibility with other parser, though. + + switch hint { + case 'M': + // We've already checked the map above. + + case '.': + // Not in the map, so maybe a normal float. + floatv, err := strconv.ParseFloat(in, 64) + if err == nil { + return yaml_FLOAT_TAG, floatv + } + + case 'D', 'S': + // Int, float, or timestamp. + plain := strings.Replace(in, "_", "", -1) + intv, err := strconv.ParseInt(plain, 0, 64) + if err == nil { + if intv == int64(int(intv)) { + return yaml_INT_TAG, int(intv) + } else { + return yaml_INT_TAG, intv + } + } + uintv, err := strconv.ParseUint(plain, 0, 64) + if err == nil { + return yaml_INT_TAG, uintv + } + floatv, err := strconv.ParseFloat(plain, 64) + if err == nil { + return yaml_FLOAT_TAG, floatv + } + if strings.HasPrefix(plain, "0b") { + intv, err := strconv.ParseInt(plain[2:], 2, 64) + if err == nil { + if intv == int64(int(intv)) { + return yaml_INT_TAG, int(intv) + } else { + return yaml_INT_TAG, intv + } + } + uintv, err := strconv.ParseUint(plain[2:], 2, 64) + if err == nil { + return yaml_INT_TAG, uintv + } + } else if strings.HasPrefix(plain, "-0b") { + intv, err := strconv.ParseInt(plain[3:], 2, 64) + if err == nil { + if intv == int64(int(intv)) { + return yaml_INT_TAG, -int(intv) + } else { + return yaml_INT_TAG, -intv + } + } + } + // XXX Handle timestamps here. + + default: + panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")") + } + } + if tag == yaml_BINARY_TAG { + return yaml_BINARY_TAG, in + } + if utf8.ValidString(in) { + return yaml_STR_TAG, in + } + return yaml_BINARY_TAG, encodeBase64(in) +} + +// encodeBase64 encodes s as base64 that is broken up into multiple lines +// as appropriate for the resulting length. +func encodeBase64(s string) string { + const lineLen = 70 + encLen := base64.StdEncoding.EncodedLen(len(s)) + lines := encLen/lineLen + 1 + buf := make([]byte, encLen*2+lines) + in := buf[0:encLen] + out := buf[encLen:] + base64.StdEncoding.Encode(in, []byte(s)) + k := 0 + for i := 0; i < len(in); i += lineLen { + j := i + lineLen + if j > len(in) { + j = len(in) + } + k += copy(out[k:], in[i:j]) + if lines > 1 { + out[k] = '\n' + k++ + } + } + return string(out[:k]) +} diff --git a/vendor/gopkg.in/yaml.v2/scannerc.go b/vendor/gopkg.in/yaml.v2/scannerc.go new file mode 100644 index 000000000..25808000f --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/scannerc.go @@ -0,0 +1,2710 @@ +package yaml + +import ( + "bytes" + "fmt" +) + +// Introduction +// ************ +// +// The following notes assume that you are familiar with the YAML specification +// (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in +// some cases we are less restrictive that it requires. +// +// The process of transforming a YAML stream into a sequence of events is +// divided on two steps: Scanning and Parsing. +// +// The Scanner transforms the input stream into a sequence of tokens, while the +// parser transform the sequence of tokens produced by the Scanner into a +// sequence of parsing events. +// +// The Scanner is rather clever and complicated. The Parser, on the contrary, +// is a straightforward implementation of a recursive-descendant parser (or, +// LL(1) parser, as it is usually called). +// +// Actually there are two issues of Scanning that might be called "clever", the +// rest is quite straightforward. The issues are "block collection start" and +// "simple keys". Both issues are explained below in details. +// +// Here the Scanning step is explained and implemented. We start with the list +// of all the tokens produced by the Scanner together with short descriptions. +// +// Now, tokens: +// +// STREAM-START(encoding) # The stream start. +// STREAM-END # The stream end. +// VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. +// TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. +// DOCUMENT-START # '---' +// DOCUMENT-END # '...' +// BLOCK-SEQUENCE-START # Indentation increase denoting a block +// BLOCK-MAPPING-START # sequence or a block mapping. +// BLOCK-END # Indentation decrease. +// FLOW-SEQUENCE-START # '[' +// FLOW-SEQUENCE-END # ']' +// BLOCK-SEQUENCE-START # '{' +// BLOCK-SEQUENCE-END # '}' +// BLOCK-ENTRY # '-' +// FLOW-ENTRY # ',' +// KEY # '?' or nothing (simple keys). +// VALUE # ':' +// ALIAS(anchor) # '*anchor' +// ANCHOR(anchor) # '&anchor' +// TAG(handle,suffix) # '!handle!suffix' +// SCALAR(value,style) # A scalar. +// +// The following two tokens are "virtual" tokens denoting the beginning and the +// end of the stream: +// +// STREAM-START(encoding) +// STREAM-END +// +// We pass the information about the input stream encoding with the +// STREAM-START token. +// +// The next two tokens are responsible for tags: +// +// VERSION-DIRECTIVE(major,minor) +// TAG-DIRECTIVE(handle,prefix) +// +// Example: +// +// %YAML 1.1 +// %TAG ! !foo +// %TAG !yaml! tag:yaml.org,2002: +// --- +// +// The correspoding sequence of tokens: +// +// STREAM-START(utf-8) +// VERSION-DIRECTIVE(1,1) +// TAG-DIRECTIVE("!","!foo") +// TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") +// DOCUMENT-START +// STREAM-END +// +// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole +// line. +// +// The document start and end indicators are represented by: +// +// DOCUMENT-START +// DOCUMENT-END +// +// Note that if a YAML stream contains an implicit document (without '---' +// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be +// produced. +// +// In the following examples, we present whole documents together with the +// produced tokens. +// +// 1. An implicit document: +// +// 'a scalar' +// +// Tokens: +// +// STREAM-START(utf-8) +// SCALAR("a scalar",single-quoted) +// STREAM-END +// +// 2. An explicit document: +// +// --- +// 'a scalar' +// ... +// +// Tokens: +// +// STREAM-START(utf-8) +// DOCUMENT-START +// SCALAR("a scalar",single-quoted) +// DOCUMENT-END +// STREAM-END +// +// 3. Several documents in a stream: +// +// 'a scalar' +// --- +// 'another scalar' +// --- +// 'yet another scalar' +// +// Tokens: +// +// STREAM-START(utf-8) +// SCALAR("a scalar",single-quoted) +// DOCUMENT-START +// SCALAR("another scalar",single-quoted) +// DOCUMENT-START +// SCALAR("yet another scalar",single-quoted) +// STREAM-END +// +// We have already introduced the SCALAR token above. The following tokens are +// used to describe aliases, anchors, tag, and scalars: +// +// ALIAS(anchor) +// ANCHOR(anchor) +// TAG(handle,suffix) +// SCALAR(value,style) +// +// The following series of examples illustrate the usage of these tokens: +// +// 1. A recursive sequence: +// +// &A [ *A ] +// +// Tokens: +// +// STREAM-START(utf-8) +// ANCHOR("A") +// FLOW-SEQUENCE-START +// ALIAS("A") +// FLOW-SEQUENCE-END +// STREAM-END +// +// 2. A tagged scalar: +// +// !!float "3.14" # A good approximation. +// +// Tokens: +// +// STREAM-START(utf-8) +// TAG("!!","float") +// SCALAR("3.14",double-quoted) +// STREAM-END +// +// 3. Various scalar styles: +// +// --- # Implicit empty plain scalars do not produce tokens. +// --- a plain scalar +// --- 'a single-quoted scalar' +// --- "a double-quoted scalar" +// --- |- +// a literal scalar +// --- >- +// a folded +// scalar +// +// Tokens: +// +// STREAM-START(utf-8) +// DOCUMENT-START +// DOCUMENT-START +// SCALAR("a plain scalar",plain) +// DOCUMENT-START +// SCALAR("a single-quoted scalar",single-quoted) +// DOCUMENT-START +// SCALAR("a double-quoted scalar",double-quoted) +// DOCUMENT-START +// SCALAR("a literal scalar",literal) +// DOCUMENT-START +// SCALAR("a folded scalar",folded) +// STREAM-END +// +// Now it's time to review collection-related tokens. We will start with +// flow collections: +// +// FLOW-SEQUENCE-START +// FLOW-SEQUENCE-END +// FLOW-MAPPING-START +// FLOW-MAPPING-END +// FLOW-ENTRY +// KEY +// VALUE +// +// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and +// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' +// correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the +// indicators '?' and ':', which are used for denoting mapping keys and values, +// are represented by the KEY and VALUE tokens. +// +// The following examples show flow collections: +// +// 1. A flow sequence: +// +// [item 1, item 2, item 3] +// +// Tokens: +// +// STREAM-START(utf-8) +// FLOW-SEQUENCE-START +// SCALAR("item 1",plain) +// FLOW-ENTRY +// SCALAR("item 2",plain) +// FLOW-ENTRY +// SCALAR("item 3",plain) +// FLOW-SEQUENCE-END +// STREAM-END +// +// 2. A flow mapping: +// +// { +// a simple key: a value, # Note that the KEY token is produced. +// ? a complex key: another value, +// } +// +// Tokens: +// +// STREAM-START(utf-8) +// FLOW-MAPPING-START +// KEY +// SCALAR("a simple key",plain) +// VALUE +// SCALAR("a value",plain) +// FLOW-ENTRY +// KEY +// SCALAR("a complex key",plain) +// VALUE +// SCALAR("another value",plain) +// FLOW-ENTRY +// FLOW-MAPPING-END +// STREAM-END +// +// A simple key is a key which is not denoted by the '?' indicator. Note that +// the Scanner still produce the KEY token whenever it encounters a simple key. +// +// For scanning block collections, the following tokens are used (note that we +// repeat KEY and VALUE here): +// +// BLOCK-SEQUENCE-START +// BLOCK-MAPPING-START +// BLOCK-END +// BLOCK-ENTRY +// KEY +// VALUE +// +// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation +// increase that precedes a block collection (cf. the INDENT token in Python). +// The token BLOCK-END denote indentation decrease that ends a block collection +// (cf. the DEDENT token in Python). However YAML has some syntax pecularities +// that makes detections of these tokens more complex. +// +// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators +// '-', '?', and ':' correspondingly. +// +// The following examples show how the tokens BLOCK-SEQUENCE-START, +// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: +// +// 1. Block sequences: +// +// - item 1 +// - item 2 +// - +// - item 3.1 +// - item 3.2 +// - +// key 1: value 1 +// key 2: value 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-ENTRY +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 3.1",plain) +// BLOCK-ENTRY +// SCALAR("item 3.2",plain) +// BLOCK-END +// BLOCK-ENTRY +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// 2. Block mappings: +// +// a simple key: a value # The KEY token is produced here. +// ? a complex key +// : another value +// a mapping: +// key 1: value 1 +// key 2: value 2 +// a sequence: +// - item 1 +// - item 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-MAPPING-START +// KEY +// SCALAR("a simple key",plain) +// VALUE +// SCALAR("a value",plain) +// KEY +// SCALAR("a complex key",plain) +// VALUE +// SCALAR("another value",plain) +// KEY +// SCALAR("a mapping",plain) +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// KEY +// SCALAR("a sequence",plain) +// VALUE +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// YAML does not always require to start a new block collection from a new +// line. If the current line contains only '-', '?', and ':' indicators, a new +// block collection may start at the current line. The following examples +// illustrate this case: +// +// 1. Collections in a sequence: +// +// - - item 1 +// - item 2 +// - key 1: value 1 +// key 2: value 2 +// - ? complex key +// : complex value +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// BLOCK-ENTRY +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// BLOCK-ENTRY +// BLOCK-MAPPING-START +// KEY +// SCALAR("complex key") +// VALUE +// SCALAR("complex value") +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// 2. Collections in a mapping: +// +// ? a sequence +// : - item 1 +// - item 2 +// ? a mapping +// : key 1: value 1 +// key 2: value 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-MAPPING-START +// KEY +// SCALAR("a sequence",plain) +// VALUE +// BLOCK-SEQUENCE-START +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// KEY +// SCALAR("a mapping",plain) +// VALUE +// BLOCK-MAPPING-START +// KEY +// SCALAR("key 1",plain) +// VALUE +// SCALAR("value 1",plain) +// KEY +// SCALAR("key 2",plain) +// VALUE +// SCALAR("value 2",plain) +// BLOCK-END +// BLOCK-END +// STREAM-END +// +// YAML also permits non-indented sequences if they are included into a block +// mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: +// +// key: +// - item 1 # BLOCK-SEQUENCE-START is NOT produced here. +// - item 2 +// +// Tokens: +// +// STREAM-START(utf-8) +// BLOCK-MAPPING-START +// KEY +// SCALAR("key",plain) +// VALUE +// BLOCK-ENTRY +// SCALAR("item 1",plain) +// BLOCK-ENTRY +// SCALAR("item 2",plain) +// BLOCK-END +// + +// Ensure that the buffer contains the required number of characters. +// Return true on success, false on failure (reader error or memory error). +func cache(parser *yaml_parser_t, length int) bool { + // [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B) + return parser.unread >= length || yaml_parser_update_buffer(parser, length) +} + +// Advance the buffer pointer. +func skip(parser *yaml_parser_t) { + parser.mark.index++ + parser.mark.column++ + parser.unread-- + parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) +} + +func skip_line(parser *yaml_parser_t) { + if is_crlf(parser.buffer, parser.buffer_pos) { + parser.mark.index += 2 + parser.mark.column = 0 + parser.mark.line++ + parser.unread -= 2 + parser.buffer_pos += 2 + } else if is_break(parser.buffer, parser.buffer_pos) { + parser.mark.index++ + parser.mark.column = 0 + parser.mark.line++ + parser.unread-- + parser.buffer_pos += width(parser.buffer[parser.buffer_pos]) + } +} + +// Copy a character to a string buffer and advance pointers. +func read(parser *yaml_parser_t, s []byte) []byte { + w := width(parser.buffer[parser.buffer_pos]) + if w == 0 { + panic("invalid character sequence") + } + if len(s) == 0 { + s = make([]byte, 0, 32) + } + if w == 1 && len(s)+w <= cap(s) { + s = s[:len(s)+1] + s[len(s)-1] = parser.buffer[parser.buffer_pos] + parser.buffer_pos++ + } else { + s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...) + parser.buffer_pos += w + } + parser.mark.index++ + parser.mark.column++ + parser.unread-- + return s +} + +// Copy a line break character to a string buffer and advance pointers. +func read_line(parser *yaml_parser_t, s []byte) []byte { + buf := parser.buffer + pos := parser.buffer_pos + switch { + case buf[pos] == '\r' && buf[pos+1] == '\n': + // CR LF . LF + s = append(s, '\n') + parser.buffer_pos += 2 + parser.mark.index++ + parser.unread-- + case buf[pos] == '\r' || buf[pos] == '\n': + // CR|LF . LF + s = append(s, '\n') + parser.buffer_pos += 1 + case buf[pos] == '\xC2' && buf[pos+1] == '\x85': + // NEL . LF + s = append(s, '\n') + parser.buffer_pos += 2 + case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'): + // LS|PS . LS|PS + s = append(s, buf[parser.buffer_pos:pos+3]...) + parser.buffer_pos += 3 + default: + return s + } + parser.mark.index++ + parser.mark.column = 0 + parser.mark.line++ + parser.unread-- + return s +} + +// Get the next token. +func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool { + // Erase the token object. + *token = yaml_token_t{} // [Go] Is this necessary? + + // No tokens after STREAM-END or error. + if parser.stream_end_produced || parser.error != yaml_NO_ERROR { + return true + } + + // Ensure that the tokens queue contains enough tokens. + if !parser.token_available { + if !yaml_parser_fetch_more_tokens(parser) { + return false + } + } + + // Fetch the next token from the queue. + *token = parser.tokens[parser.tokens_head] + parser.tokens_head++ + parser.tokens_parsed++ + parser.token_available = false + + if token.typ == yaml_STREAM_END_TOKEN { + parser.stream_end_produced = true + } + return true +} + +// Set the scanner error and return false. +func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool { + parser.error = yaml_SCANNER_ERROR + parser.context = context + parser.context_mark = context_mark + parser.problem = problem + parser.problem_mark = parser.mark + return false +} + +func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool { + context := "while parsing a tag" + if directive { + context = "while parsing a %TAG directive" + } + return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet") +} + +func trace(args ...interface{}) func() { + pargs := append([]interface{}{"+++"}, args...) + fmt.Println(pargs...) + pargs = append([]interface{}{"---"}, args...) + return func() { fmt.Println(pargs...) } +} + +// Ensure that the tokens queue contains at least one token which can be +// returned to the Parser. +func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool { + // While we need more tokens to fetch, do it. + for { + // Check if we really need to fetch more tokens. + need_more_tokens := false + + if parser.tokens_head == len(parser.tokens) { + // Queue is empty. + need_more_tokens = true + } else { + // Check if any potential simple key may occupy the head position. + if !yaml_parser_stale_simple_keys(parser) { + return false + } + + for i := range parser.simple_keys { + simple_key := &parser.simple_keys[i] + if simple_key.possible && simple_key.token_number == parser.tokens_parsed { + need_more_tokens = true + break + } + } + } + + // We are finished. + if !need_more_tokens { + break + } + // Fetch the next token. + if !yaml_parser_fetch_next_token(parser) { + return false + } + } + + parser.token_available = true + return true +} + +// The dispatcher for token fetchers. +func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool { + // Ensure that the buffer is initialized. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + // Check if we just started scanning. Fetch STREAM-START then. + if !parser.stream_start_produced { + return yaml_parser_fetch_stream_start(parser) + } + + // Eat whitespaces and comments until we reach the next token. + if !yaml_parser_scan_to_next_token(parser) { + return false + } + + // Remove obsolete potential simple keys. + if !yaml_parser_stale_simple_keys(parser) { + return false + } + + // Check the indentation level against the current column. + if !yaml_parser_unroll_indent(parser, parser.mark.column) { + return false + } + + // Ensure that the buffer contains at least 4 characters. 4 is the length + // of the longest indicators ('--- ' and '... '). + if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { + return false + } + + // Is it the end of the stream? + if is_z(parser.buffer, parser.buffer_pos) { + return yaml_parser_fetch_stream_end(parser) + } + + // Is it a directive? + if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' { + return yaml_parser_fetch_directive(parser) + } + + buf := parser.buffer + pos := parser.buffer_pos + + // Is it the document start indicator? + if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) { + return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN) + } + + // Is it the document end indicator? + if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) { + return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN) + } + + // Is it the flow sequence start indicator? + if buf[pos] == '[' { + return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN) + } + + // Is it the flow mapping start indicator? + if parser.buffer[parser.buffer_pos] == '{' { + return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN) + } + + // Is it the flow sequence end indicator? + if parser.buffer[parser.buffer_pos] == ']' { + return yaml_parser_fetch_flow_collection_end(parser, + yaml_FLOW_SEQUENCE_END_TOKEN) + } + + // Is it the flow mapping end indicator? + if parser.buffer[parser.buffer_pos] == '}' { + return yaml_parser_fetch_flow_collection_end(parser, + yaml_FLOW_MAPPING_END_TOKEN) + } + + // Is it the flow entry indicator? + if parser.buffer[parser.buffer_pos] == ',' { + return yaml_parser_fetch_flow_entry(parser) + } + + // Is it the block entry indicator? + if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) { + return yaml_parser_fetch_block_entry(parser) + } + + // Is it the key indicator? + if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { + return yaml_parser_fetch_key(parser) + } + + // Is it the value indicator? + if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) { + return yaml_parser_fetch_value(parser) + } + + // Is it an alias? + if parser.buffer[parser.buffer_pos] == '*' { + return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN) + } + + // Is it an anchor? + if parser.buffer[parser.buffer_pos] == '&' { + return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN) + } + + // Is it a tag? + if parser.buffer[parser.buffer_pos] == '!' { + return yaml_parser_fetch_tag(parser) + } + + // Is it a literal scalar? + if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 { + return yaml_parser_fetch_block_scalar(parser, true) + } + + // Is it a folded scalar? + if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 { + return yaml_parser_fetch_block_scalar(parser, false) + } + + // Is it a single-quoted scalar? + if parser.buffer[parser.buffer_pos] == '\'' { + return yaml_parser_fetch_flow_scalar(parser, true) + } + + // Is it a double-quoted scalar? + if parser.buffer[parser.buffer_pos] == '"' { + return yaml_parser_fetch_flow_scalar(parser, false) + } + + // Is it a plain scalar? + // + // A plain scalar may start with any non-blank characters except + // + // '-', '?', ':', ',', '[', ']', '{', '}', + // '#', '&', '*', '!', '|', '>', '\'', '\"', + // '%', '@', '`'. + // + // In the block context (and, for the '-' indicator, in the flow context + // too), it may also start with the characters + // + // '-', '?', ':' + // + // if it is followed by a non-space character. + // + // The last rule is more restrictive than the specification requires. + // [Go] Make this logic more reasonable. + //switch parser.buffer[parser.buffer_pos] { + //case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '"', '\'', '@', '%', '-', '`': + //} + if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' || + parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' || + parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' || + parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || + parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' || + parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' || + parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' || + parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' || + parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' || + parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') || + (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) || + (parser.flow_level == 0 && + (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') && + !is_blankz(parser.buffer, parser.buffer_pos+1)) { + return yaml_parser_fetch_plain_scalar(parser) + } + + // If we don't determine the token type so far, it is an error. + return yaml_parser_set_scanner_error(parser, + "while scanning for the next token", parser.mark, + "found character that cannot start any token") +} + +// Check the list of potential simple keys and remove the positions that +// cannot contain simple keys anymore. +func yaml_parser_stale_simple_keys(parser *yaml_parser_t) bool { + // Check for a potential simple key for each flow level. + for i := range parser.simple_keys { + simple_key := &parser.simple_keys[i] + + // The specification requires that a simple key + // + // - is limited to a single line, + // - is shorter than 1024 characters. + if simple_key.possible && (simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index) { + + // Check if the potential simple key to be removed is required. + if simple_key.required { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", simple_key.mark, + "could not find expected ':'") + } + simple_key.possible = false + } + } + return true +} + +// Check if a simple key may start at the current position and add it if +// needed. +func yaml_parser_save_simple_key(parser *yaml_parser_t) bool { + // A simple key is required at the current position if the scanner is in + // the block context and the current column coincides with the indentation + // level. + + required := parser.flow_level == 0 && parser.indent == parser.mark.column + + // A simple key is required only when it is the first token in the current + // line. Therefore it is always allowed. But we add a check anyway. + if required && !parser.simple_key_allowed { + panic("should not happen") + } + + // + // If the current position may start a simple key, save it. + // + if parser.simple_key_allowed { + simple_key := yaml_simple_key_t{ + possible: true, + required: required, + token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head), + } + simple_key.mark = parser.mark + + if !yaml_parser_remove_simple_key(parser) { + return false + } + parser.simple_keys[len(parser.simple_keys)-1] = simple_key + } + return true +} + +// Remove a potential simple key at the current flow level. +func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool { + i := len(parser.simple_keys) - 1 + if parser.simple_keys[i].possible { + // If the key is required, it is an error. + if parser.simple_keys[i].required { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", parser.simple_keys[i].mark, + "could not find expected ':'") + } + } + // Remove the key from the stack. + parser.simple_keys[i].possible = false + return true +} + +// Increase the flow level and resize the simple key list if needed. +func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool { + // Reset the simple key on the next level. + parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) + + // Increase the flow level. + parser.flow_level++ + return true +} + +// Decrease the flow level. +func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool { + if parser.flow_level > 0 { + parser.flow_level-- + parser.simple_keys = parser.simple_keys[:len(parser.simple_keys)-1] + } + return true +} + +// Push the current indentation level to the stack and set the new level +// the current column is greater than the indentation level. In this case, +// append or insert the specified token into the token queue. +func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool { + // In the flow context, do nothing. + if parser.flow_level > 0 { + return true + } + + if parser.indent < column { + // Push the current indentation level to the stack and set the new + // indentation level. + parser.indents = append(parser.indents, parser.indent) + parser.indent = column + + // Create a token and insert it into the queue. + token := yaml_token_t{ + typ: typ, + start_mark: mark, + end_mark: mark, + } + if number > -1 { + number -= parser.tokens_parsed + } + yaml_insert_token(parser, number, &token) + } + return true +} + +// Pop indentation levels from the indents stack until the current level +// becomes less or equal to the column. For each indentation level, append +// the BLOCK-END token. +func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool { + // In the flow context, do nothing. + if parser.flow_level > 0 { + return true + } + + // Loop through the indentation levels in the stack. + for parser.indent > column { + // Create a token and append it to the queue. + token := yaml_token_t{ + typ: yaml_BLOCK_END_TOKEN, + start_mark: parser.mark, + end_mark: parser.mark, + } + yaml_insert_token(parser, -1, &token) + + // Pop the indentation level. + parser.indent = parser.indents[len(parser.indents)-1] + parser.indents = parser.indents[:len(parser.indents)-1] + } + return true +} + +// Initialize the scanner and produce the STREAM-START token. +func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool { + + // Set the initial indentation. + parser.indent = -1 + + // Initialize the simple key stack. + parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{}) + + // A simple key is allowed at the beginning of the stream. + parser.simple_key_allowed = true + + // We have started. + parser.stream_start_produced = true + + // Create the STREAM-START token and append it to the queue. + token := yaml_token_t{ + typ: yaml_STREAM_START_TOKEN, + start_mark: parser.mark, + end_mark: parser.mark, + encoding: parser.encoding, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the STREAM-END token and shut down the scanner. +func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool { + + // Force new line. + if parser.mark.column != 0 { + parser.mark.column = 0 + parser.mark.line++ + } + + // Reset the indentation level. + if !yaml_parser_unroll_indent(parser, -1) { + return false + } + + // Reset simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + parser.simple_key_allowed = false + + // Create the STREAM-END token and append it to the queue. + token := yaml_token_t{ + typ: yaml_STREAM_END_TOKEN, + start_mark: parser.mark, + end_mark: parser.mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. +func yaml_parser_fetch_directive(parser *yaml_parser_t) bool { + // Reset the indentation level. + if !yaml_parser_unroll_indent(parser, -1) { + return false + } + + // Reset simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + parser.simple_key_allowed = false + + // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. + token := yaml_token_t{} + if !yaml_parser_scan_directive(parser, &token) { + return false + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the DOCUMENT-START or DOCUMENT-END token. +func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // Reset the indentation level. + if !yaml_parser_unroll_indent(parser, -1) { + return false + } + + // Reset simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + parser.simple_key_allowed = false + + // Consume the token. + start_mark := parser.mark + + skip(parser) + skip(parser) + skip(parser) + + end_mark := parser.mark + + // Create the DOCUMENT-START or DOCUMENT-END token. + token := yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. +func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // The indicators '[' and '{' may start a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // Increase the flow level. + if !yaml_parser_increase_flow_level(parser) { + return false + } + + // A simple key may follow the indicators '[' and '{'. + parser.simple_key_allowed = true + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. + token := yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. +func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // Reset any potential simple key on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Decrease the flow level. + if !yaml_parser_decrease_flow_level(parser) { + return false + } + + // No simple keys after the indicators ']' and '}'. + parser.simple_key_allowed = false + + // Consume the token. + + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. + token := yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + } + // Append the token to the queue. + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the FLOW-ENTRY token. +func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool { + // Reset any potential simple keys on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Simple keys are allowed after ','. + parser.simple_key_allowed = true + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the FLOW-ENTRY token and append it to the queue. + token := yaml_token_t{ + typ: yaml_FLOW_ENTRY_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the BLOCK-ENTRY token. +func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool { + // Check if the scanner is in the block context. + if parser.flow_level == 0 { + // Check if we are allowed to start a new entry. + if !parser.simple_key_allowed { + return yaml_parser_set_scanner_error(parser, "", parser.mark, + "block sequence entries are not allowed in this context") + } + // Add the BLOCK-SEQUENCE-START token if needed. + if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) { + return false + } + } else { + // It is an error for the '-' indicator to occur in the flow context, + // but we let the Parser detect and report about it because the Parser + // is able to point to the context. + } + + // Reset any potential simple keys on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Simple keys are allowed after '-'. + parser.simple_key_allowed = true + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the BLOCK-ENTRY token and append it to the queue. + token := yaml_token_t{ + typ: yaml_BLOCK_ENTRY_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the KEY token. +func yaml_parser_fetch_key(parser *yaml_parser_t) bool { + + // In the block context, additional checks are required. + if parser.flow_level == 0 { + // Check if we are allowed to start a new key (not nessesary simple). + if !parser.simple_key_allowed { + return yaml_parser_set_scanner_error(parser, "", parser.mark, + "mapping keys are not allowed in this context") + } + // Add the BLOCK-MAPPING-START token if needed. + if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { + return false + } + } + + // Reset any potential simple keys on the current flow level. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // Simple keys are allowed after '?' in the block context. + parser.simple_key_allowed = parser.flow_level == 0 + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the KEY token and append it to the queue. + token := yaml_token_t{ + typ: yaml_KEY_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the VALUE token. +func yaml_parser_fetch_value(parser *yaml_parser_t) bool { + + simple_key := &parser.simple_keys[len(parser.simple_keys)-1] + + // Have we found a simple key? + if simple_key.possible { + // Create the KEY token and insert it into the queue. + token := yaml_token_t{ + typ: yaml_KEY_TOKEN, + start_mark: simple_key.mark, + end_mark: simple_key.mark, + } + yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token) + + // In the block context, we may need to add the BLOCK-MAPPING-START token. + if !yaml_parser_roll_indent(parser, simple_key.mark.column, + simple_key.token_number, + yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) { + return false + } + + // Remove the simple key. + simple_key.possible = false + + // A simple key cannot follow another simple key. + parser.simple_key_allowed = false + + } else { + // The ':' indicator follows a complex key. + + // In the block context, extra checks are required. + if parser.flow_level == 0 { + + // Check if we are allowed to start a complex value. + if !parser.simple_key_allowed { + return yaml_parser_set_scanner_error(parser, "", parser.mark, + "mapping values are not allowed in this context") + } + + // Add the BLOCK-MAPPING-START token if needed. + if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) { + return false + } + } + + // Simple keys after ':' are allowed in the block context. + parser.simple_key_allowed = parser.flow_level == 0 + } + + // Consume the token. + start_mark := parser.mark + skip(parser) + end_mark := parser.mark + + // Create the VALUE token and append it to the queue. + token := yaml_token_t{ + typ: yaml_VALUE_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the ALIAS or ANCHOR token. +func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool { + // An anchor or an alias could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow an anchor or an alias. + parser.simple_key_allowed = false + + // Create the ALIAS or ANCHOR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_anchor(parser, &token, typ) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the TAG token. +func yaml_parser_fetch_tag(parser *yaml_parser_t) bool { + // A tag could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow a tag. + parser.simple_key_allowed = false + + // Create the TAG token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_tag(parser, &token) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. +func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool { + // Remove any potential simple keys. + if !yaml_parser_remove_simple_key(parser) { + return false + } + + // A simple key may follow a block scalar. + parser.simple_key_allowed = true + + // Create the SCALAR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_block_scalar(parser, &token, literal) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. +func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool { + // A plain scalar could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow a flow scalar. + parser.simple_key_allowed = false + + // Create the SCALAR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_flow_scalar(parser, &token, single) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Produce the SCALAR(...,plain) token. +func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool { + // A plain scalar could be a simple key. + if !yaml_parser_save_simple_key(parser) { + return false + } + + // A simple key cannot follow a flow scalar. + parser.simple_key_allowed = false + + // Create the SCALAR token and append it to the queue. + var token yaml_token_t + if !yaml_parser_scan_plain_scalar(parser, &token) { + return false + } + yaml_insert_token(parser, -1, &token) + return true +} + +// Eat whitespaces and comments until the next token is found. +func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool { + + // Until the next token is not found. + for { + // Allow the BOM mark to start a line. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) { + skip(parser) + } + + // Eat whitespaces. + // Tabs are allowed: + // - in the flow context + // - in the block context, but not at the beginning of the line or + // after '-', '?', or ':' (complex value). + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Eat a comment until a line break. + if parser.buffer[parser.buffer_pos] == '#' { + for !is_breakz(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + } + + // If it is a line break, eat it. + if is_break(parser.buffer, parser.buffer_pos) { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + skip_line(parser) + + // In the block context, a new line may start a simple key. + if parser.flow_level == 0 { + parser.simple_key_allowed = true + } + } else { + break // We have found a token. + } + } + + return true +} + +// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// %TAG !yaml! tag:yaml.org,2002: \n +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// +func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool { + // Eat '%'. + start_mark := parser.mark + skip(parser) + + // Scan the directive name. + var name []byte + if !yaml_parser_scan_directive_name(parser, start_mark, &name) { + return false + } + + // Is it a YAML directive? + if bytes.Equal(name, []byte("YAML")) { + // Scan the VERSION directive value. + var major, minor int8 + if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) { + return false + } + end_mark := parser.mark + + // Create a VERSION-DIRECTIVE token. + *token = yaml_token_t{ + typ: yaml_VERSION_DIRECTIVE_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + major: major, + minor: minor, + } + + // Is it a TAG directive? + } else if bytes.Equal(name, []byte("TAG")) { + // Scan the TAG directive value. + var handle, prefix []byte + if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) { + return false + } + end_mark := parser.mark + + // Create a TAG-DIRECTIVE token. + *token = yaml_token_t{ + typ: yaml_TAG_DIRECTIVE_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: handle, + prefix: prefix, + } + + // Unknown directive. + } else { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found unknown directive name") + return false + } + + // Eat the rest of the line including any comments. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + if parser.buffer[parser.buffer_pos] == '#' { + for !is_breakz(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + } + + // Check if we are at the end of the line. + if !is_breakz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "did not find expected comment or line break") + return false + } + + // Eat a line break. + if is_break(parser.buffer, parser.buffer_pos) { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + skip_line(parser) + } + + return true +} + +// Scan the directive name. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^^^^ +// %TAG !yaml! tag:yaml.org,2002: \n +// ^^^ +// +func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool { + // Consume the directive name. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + var s []byte + for is_alpha(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the name is empty. + if len(s) == 0 { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "could not find expected directive name") + return false + } + + // Check for an blank character after the name. + if !is_blankz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found unexpected non-alphabetical character") + return false + } + *name = s + return true +} + +// Scan the value of VERSION-DIRECTIVE. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^^^^^^ +func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool { + // Eat whitespaces. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Consume the major version number. + if !yaml_parser_scan_version_directive_number(parser, start_mark, major) { + return false + } + + // Eat '.'. + if parser.buffer[parser.buffer_pos] != '.' { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected digit or '.' character") + } + + skip(parser) + + // Consume the minor version number. + if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) { + return false + } + return true +} + +const max_number_length = 2 + +// Scan the version number of VERSION-DIRECTIVE. +// +// Scope: +// %YAML 1.1 # a comment \n +// ^ +// %YAML 1.1 # a comment \n +// ^ +func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool { + + // Repeat while the next character is digit. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + var value, length int8 + for is_digit(parser.buffer, parser.buffer_pos) { + // Check if the number is too long. + length++ + if length > max_number_length { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "found extremely long version number") + } + value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos)) + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the number was present. + if length == 0 { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected version number") + } + *number = value + return true +} + +// Scan the value of a TAG-DIRECTIVE token. +// +// Scope: +// %TAG !yaml! tag:yaml.org,2002: \n +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// +func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool { + var handle_value, prefix_value []byte + + // Eat whitespaces. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Scan a handle. + if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) { + return false + } + + // Expect a whitespace. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if !is_blank(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace") + return false + } + + // Eat whitespaces. + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Scan a prefix. + if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) { + return false + } + + // Expect a whitespace or line break. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if !is_blankz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace or line break") + return false + } + + *handle = handle_value + *prefix = prefix_value + return true +} + +func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool { + var s []byte + + // Eat the indicator character. + start_mark := parser.mark + skip(parser) + + // Consume the value. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_alpha(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + end_mark := parser.mark + + /* + * Check if length of the anchor is greater than 0 and it is followed by + * a whitespace character or one of the indicators: + * + * '?', ':', ',', ']', '}', '%', '@', '`'. + */ + + if len(s) == 0 || + !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' || + parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' || + parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' || + parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' || + parser.buffer[parser.buffer_pos] == '`') { + context := "while scanning an alias" + if typ == yaml_ANCHOR_TOKEN { + context = "while scanning an anchor" + } + yaml_parser_set_scanner_error(parser, context, start_mark, + "did not find expected alphabetic or numeric character") + return false + } + + // Create a token. + *token = yaml_token_t{ + typ: typ, + start_mark: start_mark, + end_mark: end_mark, + value: s, + } + + return true +} + +/* + * Scan a TAG token. + */ + +func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool { + var handle, suffix []byte + + start_mark := parser.mark + + // Check if the tag is in the canonical form. + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + if parser.buffer[parser.buffer_pos+1] == '<' { + // Keep the handle as '' + + // Eat '!<' + skip(parser) + skip(parser) + + // Consume the tag value. + if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { + return false + } + + // Check for '>' and eat it. + if parser.buffer[parser.buffer_pos] != '>' { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find the expected '>'") + return false + } + + skip(parser) + } else { + // The tag has either the '!suffix' or the '!handle!suffix' form. + + // First, try to scan a handle. + if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) { + return false + } + + // Check if it is, indeed, handle. + if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' { + // Scan the suffix now. + if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) { + return false + } + } else { + // It wasn't a handle after all. Scan the rest of the tag. + if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) { + return false + } + + // Set the handle to '!'. + handle = []byte{'!'} + + // A special case: the '!' tag. Set the handle to '' and the + // suffix to '!'. + if len(suffix) == 0 { + handle, suffix = suffix, handle + } + } + } + + // Check the character which ends the tag. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if !is_blankz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find expected whitespace or line break") + return false + } + + end_mark := parser.mark + + // Create a token. + *token = yaml_token_t{ + typ: yaml_TAG_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: handle, + suffix: suffix, + } + return true +} + +// Scan a tag handle. +func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool { + // Check the initial '!' character. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if parser.buffer[parser.buffer_pos] != '!' { + yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find expected '!'") + return false + } + + var s []byte + + // Copy the '!' character. + s = read(parser, s) + + // Copy all subsequent alphabetical and numerical characters. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for is_alpha(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the trailing character is '!' and copy it. + if parser.buffer[parser.buffer_pos] == '!' { + s = read(parser, s) + } else { + // It's either the '!' tag or not really a tag handle. If it's a %TAG + // directive, it's an error. If it's a tag token, it must be a part of URI. + if directive && !(s[0] == '!' && s[1] == 0) { + yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find expected '!'") + return false + } + } + + *handle = s + return true +} + +// Scan a tag. +func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool { + //size_t length = head ? strlen((char *)head) : 0 + var s []byte + + // Copy the head if needed. + // + // Note that we don't copy the leading '!' character. + if len(head) > 1 { + s = append(s, head[1:]...) + } + + // Scan the tag. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + // The set of characters that may appear in URI is as follows: + // + // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', + // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', + // '%'. + // [Go] Convert this into more reasonable logic. + for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' || + parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' || + parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' || + parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' || + parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' || + parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' || + parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' || + parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' || + parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' || + parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' || + parser.buffer[parser.buffer_pos] == '%' { + // Check if it is a URI-escape sequence. + if parser.buffer[parser.buffer_pos] == '%' { + if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) { + return false + } + } else { + s = read(parser, s) + } + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check if the tag is non-empty. + if len(s) == 0 { + yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find expected tag URI") + return false + } + *uri = s + return true +} + +// Decode an URI-escape sequence corresponding to a single UTF-8 character. +func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool { + + // Decode the required number of characters. + w := 1024 + for w > 0 { + // Check for a URI-escaped octet. + if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { + return false + } + + if !(parser.buffer[parser.buffer_pos] == '%' && + is_hex(parser.buffer, parser.buffer_pos+1) && + is_hex(parser.buffer, parser.buffer_pos+2)) { + return yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "did not find URI escaped octet") + } + + // Get the octet. + octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2)) + + // If it is the leading octet, determine the length of the UTF-8 sequence. + if w == 1024 { + w = width(octet) + if w == 0 { + return yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "found an incorrect leading UTF-8 octet") + } + } else { + // Check if the trailing octet is correct. + if octet&0xC0 != 0x80 { + return yaml_parser_set_scanner_tag_error(parser, directive, + start_mark, "found an incorrect trailing UTF-8 octet") + } + } + + // Copy the octet and move the pointers. + *s = append(*s, octet) + skip(parser) + skip(parser) + skip(parser) + w-- + } + return true +} + +// Scan a block scalar. +func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool { + // Eat the indicator '|' or '>'. + start_mark := parser.mark + skip(parser) + + // Scan the additional block scalar indicators. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + // Check for a chomping indicator. + var chomping, increment int + if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { + // Set the chomping method and eat the indicator. + if parser.buffer[parser.buffer_pos] == '+' { + chomping = +1 + } else { + chomping = -1 + } + skip(parser) + + // Check for an indentation indicator. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if is_digit(parser.buffer, parser.buffer_pos) { + // Check that the indentation is greater than 0. + if parser.buffer[parser.buffer_pos] == '0' { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an indentation indicator equal to 0") + return false + } + + // Get the indentation level and eat the indicator. + increment = as_digit(parser.buffer, parser.buffer_pos) + skip(parser) + } + + } else if is_digit(parser.buffer, parser.buffer_pos) { + // Do the same as above, but in the opposite order. + + if parser.buffer[parser.buffer_pos] == '0' { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an indentation indicator equal to 0") + return false + } + increment = as_digit(parser.buffer, parser.buffer_pos) + skip(parser) + + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' { + if parser.buffer[parser.buffer_pos] == '+' { + chomping = +1 + } else { + chomping = -1 + } + skip(parser) + } + } + + // Eat whitespaces and comments to the end of the line. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for is_blank(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + if parser.buffer[parser.buffer_pos] == '#' { + for !is_breakz(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + } + + // Check if we are at the end of the line. + if !is_breakz(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "did not find expected comment or line break") + return false + } + + // Eat a line break. + if is_break(parser.buffer, parser.buffer_pos) { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + skip_line(parser) + } + + end_mark := parser.mark + + // Set the indentation level if it was specified. + var indent int + if increment > 0 { + if parser.indent >= 0 { + indent = parser.indent + increment + } else { + indent = increment + } + } + + // Scan the leading line breaks and determine the indentation level if needed. + var s, leading_break, trailing_breaks []byte + if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { + return false + } + + // Scan the block scalar content. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + var leading_blank, trailing_blank bool + for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) { + // We are at the beginning of a non-empty line. + + // Is it a trailing whitespace? + trailing_blank = is_blank(parser.buffer, parser.buffer_pos) + + // Check if we need to fold the leading line break. + if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' { + // Do we need to join the lines by space? + if len(trailing_breaks) == 0 { + s = append(s, ' ') + } + } else { + s = append(s, leading_break...) + } + leading_break = leading_break[:0] + + // Append the remaining line breaks. + s = append(s, trailing_breaks...) + trailing_breaks = trailing_breaks[:0] + + // Is it a leading whitespace? + leading_blank = is_blank(parser.buffer, parser.buffer_pos) + + // Consume the current line. + for !is_breakz(parser.buffer, parser.buffer_pos) { + s = read(parser, s) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Consume the line break. + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + leading_break = read_line(parser, leading_break) + + // Eat the following indentation spaces and line breaks. + if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) { + return false + } + } + + // Chomp the tail. + if chomping != -1 { + s = append(s, leading_break...) + } + if chomping == 1 { + s = append(s, trailing_breaks...) + } + + // Create a token. + *token = yaml_token_t{ + typ: yaml_SCALAR_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: s, + style: yaml_LITERAL_SCALAR_STYLE, + } + if !literal { + token.style = yaml_FOLDED_SCALAR_STYLE + } + return true +} + +// Scan indentation spaces and line breaks for a block scalar. Determine the +// indentation level if needed. +func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool { + *end_mark = parser.mark + + // Eat the indentation spaces and line breaks. + max_indent := 0 + for { + // Eat the indentation spaces. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) { + skip(parser) + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + if parser.mark.column > max_indent { + max_indent = parser.mark.column + } + + // Check for a tab character messing the indentation. + if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) { + return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found a tab character where an indentation space is expected") + } + + // Have we found a non-empty line? + if !is_break(parser.buffer, parser.buffer_pos) { + break + } + + // Consume the line break. + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + // [Go] Should really be returning breaks instead. + *breaks = read_line(parser, *breaks) + *end_mark = parser.mark + } + + // Determine the indentation level if needed. + if *indent == 0 { + *indent = max_indent + if *indent < parser.indent+1 { + *indent = parser.indent + 1 + } + if *indent < 1 { + *indent = 1 + } + } + return true +} + +// Scan a quoted scalar. +func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool { + // Eat the left quote. + start_mark := parser.mark + skip(parser) + + // Consume the content of the quoted scalar. + var s, leading_break, trailing_breaks, whitespaces []byte + for { + // Check that there are no document indicators at the beginning of the line. + if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { + return false + } + + if parser.mark.column == 0 && + ((parser.buffer[parser.buffer_pos+0] == '-' && + parser.buffer[parser.buffer_pos+1] == '-' && + parser.buffer[parser.buffer_pos+2] == '-') || + (parser.buffer[parser.buffer_pos+0] == '.' && + parser.buffer[parser.buffer_pos+1] == '.' && + parser.buffer[parser.buffer_pos+2] == '.')) && + is_blankz(parser.buffer, parser.buffer_pos+3) { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected document indicator") + return false + } + + // Check for EOF. + if is_z(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected end of stream") + return false + } + + // Consume non-blank characters. + leading_blanks := false + for !is_blankz(parser.buffer, parser.buffer_pos) { + if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' { + // Is is an escaped single quote. + s = append(s, '\'') + skip(parser) + skip(parser) + + } else if single && parser.buffer[parser.buffer_pos] == '\'' { + // It is a right single quote. + break + } else if !single && parser.buffer[parser.buffer_pos] == '"' { + // It is a right double quote. + break + + } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) { + // It is an escaped line break. + if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) { + return false + } + skip(parser) + skip_line(parser) + leading_blanks = true + break + + } else if !single && parser.buffer[parser.buffer_pos] == '\\' { + // It is an escape sequence. + code_length := 0 + + // Check the escape character. + switch parser.buffer[parser.buffer_pos+1] { + case '0': + s = append(s, 0) + case 'a': + s = append(s, '\x07') + case 'b': + s = append(s, '\x08') + case 't', '\t': + s = append(s, '\x09') + case 'n': + s = append(s, '\x0A') + case 'v': + s = append(s, '\x0B') + case 'f': + s = append(s, '\x0C') + case 'r': + s = append(s, '\x0D') + case 'e': + s = append(s, '\x1B') + case ' ': + s = append(s, '\x20') + case '"': + s = append(s, '"') + case '\'': + s = append(s, '\'') + case '\\': + s = append(s, '\\') + case 'N': // NEL (#x85) + s = append(s, '\xC2') + s = append(s, '\x85') + case '_': // #xA0 + s = append(s, '\xC2') + s = append(s, '\xA0') + case 'L': // LS (#x2028) + s = append(s, '\xE2') + s = append(s, '\x80') + s = append(s, '\xA8') + case 'P': // PS (#x2029) + s = append(s, '\xE2') + s = append(s, '\x80') + s = append(s, '\xA9') + case 'x': + code_length = 2 + case 'u': + code_length = 4 + case 'U': + code_length = 8 + default: + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found unknown escape character") + return false + } + + skip(parser) + skip(parser) + + // Consume an arbitrary escape code. + if code_length > 0 { + var value int + + // Scan the character value. + if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) { + return false + } + for k := 0; k < code_length; k++ { + if !is_hex(parser.buffer, parser.buffer_pos+k) { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "did not find expected hexdecimal number") + return false + } + value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k) + } + + // Check the value and write the character. + if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found invalid Unicode character escape code") + return false + } + if value <= 0x7F { + s = append(s, byte(value)) + } else if value <= 0x7FF { + s = append(s, byte(0xC0+(value>>6))) + s = append(s, byte(0x80+(value&0x3F))) + } else if value <= 0xFFFF { + s = append(s, byte(0xE0+(value>>12))) + s = append(s, byte(0x80+((value>>6)&0x3F))) + s = append(s, byte(0x80+(value&0x3F))) + } else { + s = append(s, byte(0xF0+(value>>18))) + s = append(s, byte(0x80+((value>>12)&0x3F))) + s = append(s, byte(0x80+((value>>6)&0x3F))) + s = append(s, byte(0x80+(value&0x3F))) + } + + // Advance the pointer. + for k := 0; k < code_length; k++ { + skip(parser) + } + } + } else { + // It is a non-escaped non-blank character. + s = read(parser, s) + } + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + } + + // Check if we are at the end of the scalar. + if single { + if parser.buffer[parser.buffer_pos] == '\'' { + break + } + } else { + if parser.buffer[parser.buffer_pos] == '"' { + break + } + } + + // Consume blank characters. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { + if is_blank(parser.buffer, parser.buffer_pos) { + // Consume a space or a tab character. + if !leading_blanks { + whitespaces = read(parser, whitespaces) + } else { + skip(parser) + } + } else { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + // Check if it is a first line break. + if !leading_blanks { + whitespaces = whitespaces[:0] + leading_break = read_line(parser, leading_break) + leading_blanks = true + } else { + trailing_breaks = read_line(parser, trailing_breaks) + } + } + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Join the whitespaces or fold line breaks. + if leading_blanks { + // Do we need to fold line breaks? + if len(leading_break) > 0 && leading_break[0] == '\n' { + if len(trailing_breaks) == 0 { + s = append(s, ' ') + } else { + s = append(s, trailing_breaks...) + } + } else { + s = append(s, leading_break...) + s = append(s, trailing_breaks...) + } + trailing_breaks = trailing_breaks[:0] + leading_break = leading_break[:0] + } else { + s = append(s, whitespaces...) + whitespaces = whitespaces[:0] + } + } + + // Eat the right quote. + skip(parser) + end_mark := parser.mark + + // Create a token. + *token = yaml_token_t{ + typ: yaml_SCALAR_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: s, + style: yaml_SINGLE_QUOTED_SCALAR_STYLE, + } + if !single { + token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE + } + return true +} + +// Scan a plain scalar. +func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool { + + var s, leading_break, trailing_breaks, whitespaces []byte + var leading_blanks bool + var indent = parser.indent + 1 + + start_mark := parser.mark + end_mark := parser.mark + + // Consume the content of the plain scalar. + for { + // Check for a document indicator. + if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) { + return false + } + if parser.mark.column == 0 && + ((parser.buffer[parser.buffer_pos+0] == '-' && + parser.buffer[parser.buffer_pos+1] == '-' && + parser.buffer[parser.buffer_pos+2] == '-') || + (parser.buffer[parser.buffer_pos+0] == '.' && + parser.buffer[parser.buffer_pos+1] == '.' && + parser.buffer[parser.buffer_pos+2] == '.')) && + is_blankz(parser.buffer, parser.buffer_pos+3) { + break + } + + // Check for a comment. + if parser.buffer[parser.buffer_pos] == '#' { + break + } + + // Consume non-blank characters. + for !is_blankz(parser.buffer, parser.buffer_pos) { + + // Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". + if parser.flow_level > 0 && + parser.buffer[parser.buffer_pos] == ':' && + !is_blankz(parser.buffer, parser.buffer_pos+1) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found unexpected ':'") + return false + } + + // Check for indicators that may end a plain scalar. + if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) || + (parser.flow_level > 0 && + (parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' || + parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' || + parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' || + parser.buffer[parser.buffer_pos] == '}')) { + break + } + + // Check if we need to join whitespaces and breaks. + if leading_blanks || len(whitespaces) > 0 { + if leading_blanks { + // Do we need to fold line breaks? + if leading_break[0] == '\n' { + if len(trailing_breaks) == 0 { + s = append(s, ' ') + } else { + s = append(s, trailing_breaks...) + } + } else { + s = append(s, leading_break...) + s = append(s, trailing_breaks...) + } + trailing_breaks = trailing_breaks[:0] + leading_break = leading_break[:0] + leading_blanks = false + } else { + s = append(s, whitespaces...) + whitespaces = whitespaces[:0] + } + } + + // Copy the character. + s = read(parser, s) + + end_mark = parser.mark + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + } + + // Is it the end? + if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) { + break + } + + // Consume blank characters. + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + + for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) { + if is_blank(parser.buffer, parser.buffer_pos) { + + // Check for tab character that abuse indentation. + if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found a tab character that violate indentation") + return false + } + + // Consume a space or a tab character. + if !leading_blanks { + whitespaces = read(parser, whitespaces) + } else { + skip(parser) + } + } else { + if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) { + return false + } + + // Check if it is a first line break. + if !leading_blanks { + whitespaces = whitespaces[:0] + leading_break = read_line(parser, leading_break) + leading_blanks = true + } else { + trailing_breaks = read_line(parser, trailing_breaks) + } + } + if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) { + return false + } + } + + // Check indentation level. + if parser.flow_level == 0 && parser.mark.column < indent { + break + } + } + + // Create a token. + *token = yaml_token_t{ + typ: yaml_SCALAR_TOKEN, + start_mark: start_mark, + end_mark: end_mark, + value: s, + style: yaml_PLAIN_SCALAR_STYLE, + } + + // Note that we change the 'simple_key_allowed' flag. + if leading_blanks { + parser.simple_key_allowed = true + } + return true +} diff --git a/vendor/gopkg.in/yaml.v2/sorter.go b/vendor/gopkg.in/yaml.v2/sorter.go new file mode 100644 index 000000000..5958822f9 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/sorter.go @@ -0,0 +1,104 @@ +package yaml + +import ( + "reflect" + "unicode" +) + +type keyList []reflect.Value + +func (l keyList) Len() int { return len(l) } +func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l keyList) Less(i, j int) bool { + a := l[i] + b := l[j] + ak := a.Kind() + bk := b.Kind() + for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() { + a = a.Elem() + ak = a.Kind() + } + for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() { + b = b.Elem() + bk = b.Kind() + } + af, aok := keyFloat(a) + bf, bok := keyFloat(b) + if aok && bok { + if af != bf { + return af < bf + } + if ak != bk { + return ak < bk + } + return numLess(a, b) + } + if ak != reflect.String || bk != reflect.String { + return ak < bk + } + ar, br := []rune(a.String()), []rune(b.String()) + for i := 0; i < len(ar) && i < len(br); i++ { + if ar[i] == br[i] { + continue + } + al := unicode.IsLetter(ar[i]) + bl := unicode.IsLetter(br[i]) + if al && bl { + return ar[i] < br[i] + } + if al || bl { + return bl + } + var ai, bi int + var an, bn int64 + for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ { + an = an*10 + int64(ar[ai]-'0') + } + for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ { + bn = bn*10 + int64(br[bi]-'0') + } + if an != bn { + return an < bn + } + if ai != bi { + return ai < bi + } + return ar[i] < br[i] + } + return len(ar) < len(br) +} + +// keyFloat returns a float value for v if it is a number/bool +// and whether it is a number/bool or not. +func keyFloat(v reflect.Value) (f float64, ok bool) { + switch v.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return float64(v.Int()), true + case reflect.Float32, reflect.Float64: + return v.Float(), true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return float64(v.Uint()), true + case reflect.Bool: + if v.Bool() { + return 1, true + } + return 0, true + } + return 0, false +} + +// numLess returns whether a < b. +// a and b must necessarily have the same kind. +func numLess(a, b reflect.Value) bool { + switch a.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return a.Int() < b.Int() + case reflect.Float32, reflect.Float64: + return a.Float() < b.Float() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return a.Uint() < b.Uint() + case reflect.Bool: + return !a.Bool() && b.Bool() + } + panic("not a number") +} diff --git a/vendor/gopkg.in/yaml.v2/writerc.go b/vendor/gopkg.in/yaml.v2/writerc.go new file mode 100644 index 000000000..190362f25 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/writerc.go @@ -0,0 +1,89 @@ +package yaml + +// Set the writer error and return false. +func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { + emitter.error = yaml_WRITER_ERROR + emitter.problem = problem + return false +} + +// Flush the output buffer. +func yaml_emitter_flush(emitter *yaml_emitter_t) bool { + if emitter.write_handler == nil { + panic("write handler not set") + } + + // Check if the buffer is empty. + if emitter.buffer_pos == 0 { + return true + } + + // If the output encoding is UTF-8, we don't need to recode the buffer. + if emitter.encoding == yaml_UTF8_ENCODING { + if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { + return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) + } + emitter.buffer_pos = 0 + return true + } + + // Recode the buffer into the raw buffer. + var low, high int + if emitter.encoding == yaml_UTF16LE_ENCODING { + low, high = 0, 1 + } else { + high, low = 1, 0 + } + + pos := 0 + for pos < emitter.buffer_pos { + // See the "reader.c" code for more details on UTF-8 encoding. Note + // that we assume that the buffer contains a valid UTF-8 sequence. + + // Read the next UTF-8 character. + octet := emitter.buffer[pos] + + var w int + var value rune + switch { + case octet&0x80 == 0x00: + w, value = 1, rune(octet&0x7F) + case octet&0xE0 == 0xC0: + w, value = 2, rune(octet&0x1F) + case octet&0xF0 == 0xE0: + w, value = 3, rune(octet&0x0F) + case octet&0xF8 == 0xF0: + w, value = 4, rune(octet&0x07) + } + for k := 1; k < w; k++ { + octet = emitter.buffer[pos+k] + value = (value << 6) + (rune(octet) & 0x3F) + } + pos += w + + // Write the character. + if value < 0x10000 { + var b [2]byte + b[high] = byte(value >> 8) + b[low] = byte(value & 0xFF) + emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1]) + } else { + // Write the character using a surrogate pair (check "reader.c"). + var b [4]byte + value -= 0x10000 + b[high] = byte(0xD8 + (value >> 18)) + b[low] = byte((value >> 10) & 0xFF) + b[high+2] = byte(0xDC + ((value >> 8) & 0xFF)) + b[low+2] = byte(value & 0xFF) + emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3]) + } + } + + // Write the raw buffer. + if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil { + return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) + } + emitter.buffer_pos = 0 + emitter.raw_buffer = emitter.raw_buffer[:0] + return true +} diff --git a/vendor/gopkg.in/yaml.v2/yaml.go b/vendor/gopkg.in/yaml.v2/yaml.go new file mode 100644 index 000000000..36d6b883a --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/yaml.go @@ -0,0 +1,346 @@ +// Package yaml implements YAML support for the Go language. +// +// Source code and other details for the project are available at GitHub: +// +// https://github.com/go-yaml/yaml +// +package yaml + +import ( + "errors" + "fmt" + "reflect" + "strings" + "sync" +) + +// MapSlice encodes and decodes as a YAML map. +// The order of keys is preserved when encoding and decoding. +type MapSlice []MapItem + +// MapItem is an item in a MapSlice. +type MapItem struct { + Key, Value interface{} +} + +// The Unmarshaler interface may be implemented by types to customize their +// behavior when being unmarshaled from a YAML document. The UnmarshalYAML +// method receives a function that may be called to unmarshal the original +// YAML value into a field or variable. It is safe to call the unmarshal +// function parameter more than once if necessary. +type Unmarshaler interface { + UnmarshalYAML(unmarshal func(interface{}) error) error +} + +// The Marshaler interface may be implemented by types to customize their +// behavior when being marshaled into a YAML document. The returned value +// is marshaled in place of the original value implementing Marshaler. +// +// If an error is returned by MarshalYAML, the marshaling procedure stops +// and returns with the provided error. +type Marshaler interface { + MarshalYAML() (interface{}, error) +} + +// Unmarshal decodes the first document found within the in byte slice +// and assigns decoded values into the out value. +// +// Maps and pointers (to a struct, string, int, etc) are accepted as out +// values. If an internal pointer within a struct is not initialized, +// the yaml package will initialize it if necessary for unmarshalling +// the provided data. The out parameter must not be nil. +// +// The type of the decoded values should be compatible with the respective +// values in out. If one or more values cannot be decoded due to a type +// mismatches, decoding continues partially until the end of the YAML +// content, and a *yaml.TypeError is returned with details for all +// missed values. +// +// Struct fields are only unmarshalled if they are exported (have an +// upper case first letter), and are unmarshalled using the field name +// lowercased as the default key. Custom keys may be defined via the +// "yaml" name in the field tag: the content preceding the first comma +// is used as the key, and the following comma-separated options are +// used to tweak the marshalling process (see Marshal). +// Conflicting names result in a runtime error. +// +// For example: +// +// type T struct { +// F int `yaml:"a,omitempty"` +// B int +// } +// var t T +// yaml.Unmarshal([]byte("a: 1\nb: 2"), &t) +// +// See the documentation of Marshal for the format of tags and a list of +// supported tag options. +// +func Unmarshal(in []byte, out interface{}) (err error) { + defer handleErr(&err) + d := newDecoder() + p := newParser(in) + defer p.destroy() + node := p.parse() + if node != nil { + v := reflect.ValueOf(out) + if v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + } + d.unmarshal(node, v) + } + if len(d.terrors) > 0 { + return &TypeError{d.terrors} + } + return nil +} + +// Marshal serializes the value provided into a YAML document. The structure +// of the generated document will reflect the structure of the value itself. +// Maps and pointers (to struct, string, int, etc) are accepted as the in value. +// +// Struct fields are only unmarshalled if they are exported (have an upper case +// first letter), and are unmarshalled using the field name lowercased as the +// default key. Custom keys may be defined via the "yaml" name in the field +// tag: the content preceding the first comma is used as the key, and the +// following comma-separated options are used to tweak the marshalling process. +// Conflicting names result in a runtime error. +// +// The field tag format accepted is: +// +// `(...) yaml:"[][,[,]]" (...)` +// +// The following flags are currently supported: +// +// omitempty Only include the field if it's not set to the zero +// value for the type or to empty slices or maps. +// Does not apply to zero valued structs. +// +// flow Marshal using a flow style (useful for structs, +// sequences and maps). +// +// inline Inline the field, which must be a struct or a map, +// causing all of its fields or keys to be processed as if +// they were part of the outer struct. For maps, keys must +// not conflict with the yaml keys of other struct fields. +// +// In addition, if the key is "-", the field is ignored. +// +// For example: +// +// type T struct { +// F int "a,omitempty" +// B int +// } +// yaml.Marshal(&T{B: 2}) // Returns "b: 2\n" +// yaml.Marshal(&T{F: 1}} // Returns "a: 1\nb: 0\n" +// +func Marshal(in interface{}) (out []byte, err error) { + defer handleErr(&err) + e := newEncoder() + defer e.destroy() + e.marshal("", reflect.ValueOf(in)) + e.finish() + out = e.out + return +} + +func handleErr(err *error) { + if v := recover(); v != nil { + if e, ok := v.(yamlError); ok { + *err = e.err + } else { + panic(v) + } + } +} + +type yamlError struct { + err error +} + +func fail(err error) { + panic(yamlError{err}) +} + +func failf(format string, args ...interface{}) { + panic(yamlError{fmt.Errorf("yaml: "+format, args...)}) +} + +// A TypeError is returned by Unmarshal when one or more fields in +// the YAML document cannot be properly decoded into the requested +// types. When this error is returned, the value is still +// unmarshaled partially. +type TypeError struct { + Errors []string +} + +func (e *TypeError) Error() string { + return fmt.Sprintf("yaml: unmarshal errors:\n %s", strings.Join(e.Errors, "\n ")) +} + +// -------------------------------------------------------------------------- +// Maintain a mapping of keys to structure field indexes + +// The code in this section was copied from mgo/bson. + +// structInfo holds details for the serialization of fields of +// a given struct. +type structInfo struct { + FieldsMap map[string]fieldInfo + FieldsList []fieldInfo + + // InlineMap is the number of the field in the struct that + // contains an ,inline map, or -1 if there's none. + InlineMap int +} + +type fieldInfo struct { + Key string + Num int + OmitEmpty bool + Flow bool + + // Inline holds the field index if the field is part of an inlined struct. + Inline []int +} + +var structMap = make(map[reflect.Type]*structInfo) +var fieldMapMutex sync.RWMutex + +func getStructInfo(st reflect.Type) (*structInfo, error) { + fieldMapMutex.RLock() + sinfo, found := structMap[st] + fieldMapMutex.RUnlock() + if found { + return sinfo, nil + } + + n := st.NumField() + fieldsMap := make(map[string]fieldInfo) + fieldsList := make([]fieldInfo, 0, n) + inlineMap := -1 + for i := 0; i != n; i++ { + field := st.Field(i) + if field.PkgPath != "" && !field.Anonymous { + continue // Private field + } + + info := fieldInfo{Num: i} + + tag := field.Tag.Get("yaml") + if tag == "" && strings.Index(string(field.Tag), ":") < 0 { + tag = string(field.Tag) + } + if tag == "-" { + continue + } + + inline := false + fields := strings.Split(tag, ",") + if len(fields) > 1 { + for _, flag := range fields[1:] { + switch flag { + case "omitempty": + info.OmitEmpty = true + case "flow": + info.Flow = true + case "inline": + inline = true + default: + return nil, errors.New(fmt.Sprintf("Unsupported flag %q in tag %q of type %s", flag, tag, st)) + } + } + tag = fields[0] + } + + if inline { + switch field.Type.Kind() { + case reflect.Map: + if inlineMap >= 0 { + return nil, errors.New("Multiple ,inline maps in struct " + st.String()) + } + if field.Type.Key() != reflect.TypeOf("") { + return nil, errors.New("Option ,inline needs a map with string keys in struct " + st.String()) + } + inlineMap = info.Num + case reflect.Struct: + sinfo, err := getStructInfo(field.Type) + if err != nil { + return nil, err + } + for _, finfo := range sinfo.FieldsList { + if _, found := fieldsMap[finfo.Key]; found { + msg := "Duplicated key '" + finfo.Key + "' in struct " + st.String() + return nil, errors.New(msg) + } + if finfo.Inline == nil { + finfo.Inline = []int{i, finfo.Num} + } else { + finfo.Inline = append([]int{i}, finfo.Inline...) + } + fieldsMap[finfo.Key] = finfo + fieldsList = append(fieldsList, finfo) + } + default: + //return nil, errors.New("Option ,inline needs a struct value or map field") + return nil, errors.New("Option ,inline needs a struct value field") + } + continue + } + + if tag != "" { + info.Key = tag + } else { + info.Key = strings.ToLower(field.Name) + } + + if _, found = fieldsMap[info.Key]; found { + msg := "Duplicated key '" + info.Key + "' in struct " + st.String() + return nil, errors.New(msg) + } + + fieldsList = append(fieldsList, info) + fieldsMap[info.Key] = info + } + + sinfo = &structInfo{fieldsMap, fieldsList, inlineMap} + + fieldMapMutex.Lock() + structMap[st] = sinfo + fieldMapMutex.Unlock() + return sinfo, nil +} + +func isZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.String: + return len(v.String()) == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflect.Slice: + return v.Len() == 0 + case reflect.Map: + return v.Len() == 0 + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Struct: + vt := v.Type() + for i := v.NumField() - 1; i >= 0; i-- { + if vt.Field(i).PkgPath != "" { + continue // Private field + } + if !isZero(v.Field(i)) { + return false + } + } + return true + } + return false +} diff --git a/vendor/gopkg.in/yaml.v2/yamlh.go b/vendor/gopkg.in/yaml.v2/yamlh.go new file mode 100644 index 000000000..d60a6b6b0 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/yamlh.go @@ -0,0 +1,716 @@ +package yaml + +import ( + "io" +) + +// The version directive data. +type yaml_version_directive_t struct { + major int8 // The major version number. + minor int8 // The minor version number. +} + +// The tag directive data. +type yaml_tag_directive_t struct { + handle []byte // The tag handle. + prefix []byte // The tag prefix. +} + +type yaml_encoding_t int + +// The stream encoding. +const ( + // Let the parser choose the encoding. + yaml_ANY_ENCODING yaml_encoding_t = iota + + yaml_UTF8_ENCODING // The default UTF-8 encoding. + yaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM. + yaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM. +) + +type yaml_break_t int + +// Line break types. +const ( + // Let the parser choose the break type. + yaml_ANY_BREAK yaml_break_t = iota + + yaml_CR_BREAK // Use CR for line breaks (Mac style). + yaml_LN_BREAK // Use LN for line breaks (Unix style). + yaml_CRLN_BREAK // Use CR LN for line breaks (DOS style). +) + +type yaml_error_type_t int + +// Many bad things could happen with the parser and emitter. +const ( + // No error is produced. + yaml_NO_ERROR yaml_error_type_t = iota + + yaml_MEMORY_ERROR // Cannot allocate or reallocate a block of memory. + yaml_READER_ERROR // Cannot read or decode the input stream. + yaml_SCANNER_ERROR // Cannot scan the input stream. + yaml_PARSER_ERROR // Cannot parse the input stream. + yaml_COMPOSER_ERROR // Cannot compose a YAML document. + yaml_WRITER_ERROR // Cannot write to the output stream. + yaml_EMITTER_ERROR // Cannot emit a YAML stream. +) + +// The pointer position. +type yaml_mark_t struct { + index int // The position index. + line int // The position line. + column int // The position column. +} + +// Node Styles + +type yaml_style_t int8 + +type yaml_scalar_style_t yaml_style_t + +// Scalar styles. +const ( + // Let the emitter choose the style. + yaml_ANY_SCALAR_STYLE yaml_scalar_style_t = iota + + yaml_PLAIN_SCALAR_STYLE // The plain scalar style. + yaml_SINGLE_QUOTED_SCALAR_STYLE // The single-quoted scalar style. + yaml_DOUBLE_QUOTED_SCALAR_STYLE // The double-quoted scalar style. + yaml_LITERAL_SCALAR_STYLE // The literal scalar style. + yaml_FOLDED_SCALAR_STYLE // The folded scalar style. +) + +type yaml_sequence_style_t yaml_style_t + +// Sequence styles. +const ( + // Let the emitter choose the style. + yaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota + + yaml_BLOCK_SEQUENCE_STYLE // The block sequence style. + yaml_FLOW_SEQUENCE_STYLE // The flow sequence style. +) + +type yaml_mapping_style_t yaml_style_t + +// Mapping styles. +const ( + // Let the emitter choose the style. + yaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota + + yaml_BLOCK_MAPPING_STYLE // The block mapping style. + yaml_FLOW_MAPPING_STYLE // The flow mapping style. +) + +// Tokens + +type yaml_token_type_t int + +// Token types. +const ( + // An empty token. + yaml_NO_TOKEN yaml_token_type_t = iota + + yaml_STREAM_START_TOKEN // A STREAM-START token. + yaml_STREAM_END_TOKEN // A STREAM-END token. + + yaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token. + yaml_TAG_DIRECTIVE_TOKEN // A TAG-DIRECTIVE token. + yaml_DOCUMENT_START_TOKEN // A DOCUMENT-START token. + yaml_DOCUMENT_END_TOKEN // A DOCUMENT-END token. + + yaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token. + yaml_BLOCK_MAPPING_START_TOKEN // A BLOCK-SEQUENCE-END token. + yaml_BLOCK_END_TOKEN // A BLOCK-END token. + + yaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token. + yaml_FLOW_SEQUENCE_END_TOKEN // A FLOW-SEQUENCE-END token. + yaml_FLOW_MAPPING_START_TOKEN // A FLOW-MAPPING-START token. + yaml_FLOW_MAPPING_END_TOKEN // A FLOW-MAPPING-END token. + + yaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token. + yaml_FLOW_ENTRY_TOKEN // A FLOW-ENTRY token. + yaml_KEY_TOKEN // A KEY token. + yaml_VALUE_TOKEN // A VALUE token. + + yaml_ALIAS_TOKEN // An ALIAS token. + yaml_ANCHOR_TOKEN // An ANCHOR token. + yaml_TAG_TOKEN // A TAG token. + yaml_SCALAR_TOKEN // A SCALAR token. +) + +func (tt yaml_token_type_t) String() string { + switch tt { + case yaml_NO_TOKEN: + return "yaml_NO_TOKEN" + case yaml_STREAM_START_TOKEN: + return "yaml_STREAM_START_TOKEN" + case yaml_STREAM_END_TOKEN: + return "yaml_STREAM_END_TOKEN" + case yaml_VERSION_DIRECTIVE_TOKEN: + return "yaml_VERSION_DIRECTIVE_TOKEN" + case yaml_TAG_DIRECTIVE_TOKEN: + return "yaml_TAG_DIRECTIVE_TOKEN" + case yaml_DOCUMENT_START_TOKEN: + return "yaml_DOCUMENT_START_TOKEN" + case yaml_DOCUMENT_END_TOKEN: + return "yaml_DOCUMENT_END_TOKEN" + case yaml_BLOCK_SEQUENCE_START_TOKEN: + return "yaml_BLOCK_SEQUENCE_START_TOKEN" + case yaml_BLOCK_MAPPING_START_TOKEN: + return "yaml_BLOCK_MAPPING_START_TOKEN" + case yaml_BLOCK_END_TOKEN: + return "yaml_BLOCK_END_TOKEN" + case yaml_FLOW_SEQUENCE_START_TOKEN: + return "yaml_FLOW_SEQUENCE_START_TOKEN" + case yaml_FLOW_SEQUENCE_END_TOKEN: + return "yaml_FLOW_SEQUENCE_END_TOKEN" + case yaml_FLOW_MAPPING_START_TOKEN: + return "yaml_FLOW_MAPPING_START_TOKEN" + case yaml_FLOW_MAPPING_END_TOKEN: + return "yaml_FLOW_MAPPING_END_TOKEN" + case yaml_BLOCK_ENTRY_TOKEN: + return "yaml_BLOCK_ENTRY_TOKEN" + case yaml_FLOW_ENTRY_TOKEN: + return "yaml_FLOW_ENTRY_TOKEN" + case yaml_KEY_TOKEN: + return "yaml_KEY_TOKEN" + case yaml_VALUE_TOKEN: + return "yaml_VALUE_TOKEN" + case yaml_ALIAS_TOKEN: + return "yaml_ALIAS_TOKEN" + case yaml_ANCHOR_TOKEN: + return "yaml_ANCHOR_TOKEN" + case yaml_TAG_TOKEN: + return "yaml_TAG_TOKEN" + case yaml_SCALAR_TOKEN: + return "yaml_SCALAR_TOKEN" + } + return "" +} + +// The token structure. +type yaml_token_t struct { + // The token type. + typ yaml_token_type_t + + // The start/end of the token. + start_mark, end_mark yaml_mark_t + + // The stream encoding (for yaml_STREAM_START_TOKEN). + encoding yaml_encoding_t + + // The alias/anchor/scalar value or tag/tag directive handle + // (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN). + value []byte + + // The tag suffix (for yaml_TAG_TOKEN). + suffix []byte + + // The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN). + prefix []byte + + // The scalar style (for yaml_SCALAR_TOKEN). + style yaml_scalar_style_t + + // The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN). + major, minor int8 +} + +// Events + +type yaml_event_type_t int8 + +// Event types. +const ( + // An empty event. + yaml_NO_EVENT yaml_event_type_t = iota + + yaml_STREAM_START_EVENT // A STREAM-START event. + yaml_STREAM_END_EVENT // A STREAM-END event. + yaml_DOCUMENT_START_EVENT // A DOCUMENT-START event. + yaml_DOCUMENT_END_EVENT // A DOCUMENT-END event. + yaml_ALIAS_EVENT // An ALIAS event. + yaml_SCALAR_EVENT // A SCALAR event. + yaml_SEQUENCE_START_EVENT // A SEQUENCE-START event. + yaml_SEQUENCE_END_EVENT // A SEQUENCE-END event. + yaml_MAPPING_START_EVENT // A MAPPING-START event. + yaml_MAPPING_END_EVENT // A MAPPING-END event. +) + +// The event structure. +type yaml_event_t struct { + + // The event type. + typ yaml_event_type_t + + // The start and end of the event. + start_mark, end_mark yaml_mark_t + + // The document encoding (for yaml_STREAM_START_EVENT). + encoding yaml_encoding_t + + // The version directive (for yaml_DOCUMENT_START_EVENT). + version_directive *yaml_version_directive_t + + // The list of tag directives (for yaml_DOCUMENT_START_EVENT). + tag_directives []yaml_tag_directive_t + + // The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT). + anchor []byte + + // The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). + tag []byte + + // The scalar value (for yaml_SCALAR_EVENT). + value []byte + + // Is the document start/end indicator implicit, or the tag optional? + // (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT). + implicit bool + + // Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT). + quoted_implicit bool + + // The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT). + style yaml_style_t +} + +func (e *yaml_event_t) scalar_style() yaml_scalar_style_t { return yaml_scalar_style_t(e.style) } +func (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) } +func (e *yaml_event_t) mapping_style() yaml_mapping_style_t { return yaml_mapping_style_t(e.style) } + +// Nodes + +const ( + yaml_NULL_TAG = "tag:yaml.org,2002:null" // The tag !!null with the only possible value: null. + yaml_BOOL_TAG = "tag:yaml.org,2002:bool" // The tag !!bool with the values: true and false. + yaml_STR_TAG = "tag:yaml.org,2002:str" // The tag !!str for string values. + yaml_INT_TAG = "tag:yaml.org,2002:int" // The tag !!int for integer values. + yaml_FLOAT_TAG = "tag:yaml.org,2002:float" // The tag !!float for float values. + yaml_TIMESTAMP_TAG = "tag:yaml.org,2002:timestamp" // The tag !!timestamp for date and time values. + + yaml_SEQ_TAG = "tag:yaml.org,2002:seq" // The tag !!seq is used to denote sequences. + yaml_MAP_TAG = "tag:yaml.org,2002:map" // The tag !!map is used to denote mapping. + + // Not in original libyaml. + yaml_BINARY_TAG = "tag:yaml.org,2002:binary" + yaml_MERGE_TAG = "tag:yaml.org,2002:merge" + + yaml_DEFAULT_SCALAR_TAG = yaml_STR_TAG // The default scalar tag is !!str. + yaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq. + yaml_DEFAULT_MAPPING_TAG = yaml_MAP_TAG // The default mapping tag is !!map. +) + +type yaml_node_type_t int + +// Node types. +const ( + // An empty node. + yaml_NO_NODE yaml_node_type_t = iota + + yaml_SCALAR_NODE // A scalar node. + yaml_SEQUENCE_NODE // A sequence node. + yaml_MAPPING_NODE // A mapping node. +) + +// An element of a sequence node. +type yaml_node_item_t int + +// An element of a mapping node. +type yaml_node_pair_t struct { + key int // The key of the element. + value int // The value of the element. +} + +// The node structure. +type yaml_node_t struct { + typ yaml_node_type_t // The node type. + tag []byte // The node tag. + + // The node data. + + // The scalar parameters (for yaml_SCALAR_NODE). + scalar struct { + value []byte // The scalar value. + length int // The length of the scalar value. + style yaml_scalar_style_t // The scalar style. + } + + // The sequence parameters (for YAML_SEQUENCE_NODE). + sequence struct { + items_data []yaml_node_item_t // The stack of sequence items. + style yaml_sequence_style_t // The sequence style. + } + + // The mapping parameters (for yaml_MAPPING_NODE). + mapping struct { + pairs_data []yaml_node_pair_t // The stack of mapping pairs (key, value). + pairs_start *yaml_node_pair_t // The beginning of the stack. + pairs_end *yaml_node_pair_t // The end of the stack. + pairs_top *yaml_node_pair_t // The top of the stack. + style yaml_mapping_style_t // The mapping style. + } + + start_mark yaml_mark_t // The beginning of the node. + end_mark yaml_mark_t // The end of the node. + +} + +// The document structure. +type yaml_document_t struct { + + // The document nodes. + nodes []yaml_node_t + + // The version directive. + version_directive *yaml_version_directive_t + + // The list of tag directives. + tag_directives_data []yaml_tag_directive_t + tag_directives_start int // The beginning of the tag directives list. + tag_directives_end int // The end of the tag directives list. + + start_implicit int // Is the document start indicator implicit? + end_implicit int // Is the document end indicator implicit? + + // The start/end of the document. + start_mark, end_mark yaml_mark_t +} + +// The prototype of a read handler. +// +// The read handler is called when the parser needs to read more bytes from the +// source. The handler should write not more than size bytes to the buffer. +// The number of written bytes should be set to the size_read variable. +// +// [in,out] data A pointer to an application data specified by +// yaml_parser_set_input(). +// [out] buffer The buffer to write the data from the source. +// [in] size The size of the buffer. +// [out] size_read The actual number of bytes read from the source. +// +// On success, the handler should return 1. If the handler failed, +// the returned value should be 0. On EOF, the handler should set the +// size_read to 0 and return 1. +type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error) + +// This structure holds information about a potential simple key. +type yaml_simple_key_t struct { + possible bool // Is a simple key possible? + required bool // Is a simple key required? + token_number int // The number of the token. + mark yaml_mark_t // The position mark. +} + +// The states of the parser. +type yaml_parser_state_t int + +const ( + yaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota + + yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE // Expect the beginning of an implicit document. + yaml_PARSE_DOCUMENT_START_STATE // Expect DOCUMENT-START. + yaml_PARSE_DOCUMENT_CONTENT_STATE // Expect the content of a document. + yaml_PARSE_DOCUMENT_END_STATE // Expect DOCUMENT-END. + yaml_PARSE_BLOCK_NODE_STATE // Expect a block node. + yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence. + yaml_PARSE_FLOW_NODE_STATE // Expect a flow node. + yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a block sequence. + yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE // Expect an entry of a block sequence. + yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE // Expect an entry of an indentless sequence. + yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. + yaml_PARSE_BLOCK_MAPPING_KEY_STATE // Expect a block mapping key. + yaml_PARSE_BLOCK_MAPPING_VALUE_STATE // Expect a block mapping value. + yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE // Expect the first entry of a flow sequence. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE // Expect an entry of a flow sequence. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE // Expect a key of an ordered mapping. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping. + yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE // Expect the and of an ordered mapping entry. + yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. + yaml_PARSE_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. + yaml_PARSE_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. + yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE // Expect an empty value of a flow mapping. + yaml_PARSE_END_STATE // Expect nothing. +) + +func (ps yaml_parser_state_t) String() string { + switch ps { + case yaml_PARSE_STREAM_START_STATE: + return "yaml_PARSE_STREAM_START_STATE" + case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: + return "yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE" + case yaml_PARSE_DOCUMENT_START_STATE: + return "yaml_PARSE_DOCUMENT_START_STATE" + case yaml_PARSE_DOCUMENT_CONTENT_STATE: + return "yaml_PARSE_DOCUMENT_CONTENT_STATE" + case yaml_PARSE_DOCUMENT_END_STATE: + return "yaml_PARSE_DOCUMENT_END_STATE" + case yaml_PARSE_BLOCK_NODE_STATE: + return "yaml_PARSE_BLOCK_NODE_STATE" + case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: + return "yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE" + case yaml_PARSE_FLOW_NODE_STATE: + return "yaml_PARSE_FLOW_NODE_STATE" + case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: + return "yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE" + case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: + return "yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE" + case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: + return "yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE" + case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: + return "yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE" + case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: + return "yaml_PARSE_BLOCK_MAPPING_KEY_STATE" + case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: + return "yaml_PARSE_BLOCK_MAPPING_VALUE_STATE" + case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE" + case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: + return "yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE" + case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: + return "yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE" + case yaml_PARSE_FLOW_MAPPING_KEY_STATE: + return "yaml_PARSE_FLOW_MAPPING_KEY_STATE" + case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: + return "yaml_PARSE_FLOW_MAPPING_VALUE_STATE" + case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: + return "yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE" + case yaml_PARSE_END_STATE: + return "yaml_PARSE_END_STATE" + } + return "" +} + +// This structure holds aliases data. +type yaml_alias_data_t struct { + anchor []byte // The anchor. + index int // The node id. + mark yaml_mark_t // The anchor mark. +} + +// The parser structure. +// +// All members are internal. Manage the structure using the +// yaml_parser_ family of functions. +type yaml_parser_t struct { + + // Error handling + + error yaml_error_type_t // Error type. + + problem string // Error description. + + // The byte about which the problem occured. + problem_offset int + problem_value int + problem_mark yaml_mark_t + + // The error context. + context string + context_mark yaml_mark_t + + // Reader stuff + + read_handler yaml_read_handler_t // Read handler. + + input_file io.Reader // File input data. + input []byte // String input data. + input_pos int + + eof bool // EOF flag + + buffer []byte // The working buffer. + buffer_pos int // The current position of the buffer. + + unread int // The number of unread characters in the buffer. + + raw_buffer []byte // The raw buffer. + raw_buffer_pos int // The current position of the buffer. + + encoding yaml_encoding_t // The input encoding. + + offset int // The offset of the current position (in bytes). + mark yaml_mark_t // The mark of the current position. + + // Scanner stuff + + stream_start_produced bool // Have we started to scan the input stream? + stream_end_produced bool // Have we reached the end of the input stream? + + flow_level int // The number of unclosed '[' and '{' indicators. + + tokens []yaml_token_t // The tokens queue. + tokens_head int // The head of the tokens queue. + tokens_parsed int // The number of tokens fetched from the queue. + token_available bool // Does the tokens queue contain a token ready for dequeueing. + + indent int // The current indentation level. + indents []int // The indentation levels stack. + + simple_key_allowed bool // May a simple key occur at the current position? + simple_keys []yaml_simple_key_t // The stack of simple keys. + + // Parser stuff + + state yaml_parser_state_t // The current parser state. + states []yaml_parser_state_t // The parser states stack. + marks []yaml_mark_t // The stack of marks. + tag_directives []yaml_tag_directive_t // The list of TAG directives. + + // Dumper stuff + + aliases []yaml_alias_data_t // The alias data. + + document *yaml_document_t // The currently parsed document. +} + +// Emitter Definitions + +// The prototype of a write handler. +// +// The write handler is called when the emitter needs to flush the accumulated +// characters to the output. The handler should write @a size bytes of the +// @a buffer to the output. +// +// @param[in,out] data A pointer to an application data specified by +// yaml_emitter_set_output(). +// @param[in] buffer The buffer with bytes to be written. +// @param[in] size The size of the buffer. +// +// @returns On success, the handler should return @c 1. If the handler failed, +// the returned value should be @c 0. +// +type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error + +type yaml_emitter_state_t int + +// The emitter states. +const ( + // Expect STREAM-START. + yaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota + + yaml_EMIT_FIRST_DOCUMENT_START_STATE // Expect the first DOCUMENT-START or STREAM-END. + yaml_EMIT_DOCUMENT_START_STATE // Expect DOCUMENT-START or STREAM-END. + yaml_EMIT_DOCUMENT_CONTENT_STATE // Expect the content of a document. + yaml_EMIT_DOCUMENT_END_STATE // Expect DOCUMENT-END. + yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a flow sequence. + yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE // Expect an item of a flow sequence. + yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE // Expect the first key of a flow mapping. + yaml_EMIT_FLOW_MAPPING_KEY_STATE // Expect a key of a flow mapping. + yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a flow mapping. + yaml_EMIT_FLOW_MAPPING_VALUE_STATE // Expect a value of a flow mapping. + yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE // Expect the first item of a block sequence. + yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE // Expect an item of a block sequence. + yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE // Expect the first key of a block mapping. + yaml_EMIT_BLOCK_MAPPING_KEY_STATE // Expect the key of a block mapping. + yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping. + yaml_EMIT_BLOCK_MAPPING_VALUE_STATE // Expect a value of a block mapping. + yaml_EMIT_END_STATE // Expect nothing. +) + +// The emitter structure. +// +// All members are internal. Manage the structure using the @c yaml_emitter_ +// family of functions. +type yaml_emitter_t struct { + + // Error handling + + error yaml_error_type_t // Error type. + problem string // Error description. + + // Writer stuff + + write_handler yaml_write_handler_t // Write handler. + + output_buffer *[]byte // String output data. + output_file io.Writer // File output data. + + buffer []byte // The working buffer. + buffer_pos int // The current position of the buffer. + + raw_buffer []byte // The raw buffer. + raw_buffer_pos int // The current position of the buffer. + + encoding yaml_encoding_t // The stream encoding. + + // Emitter stuff + + canonical bool // If the output is in the canonical style? + best_indent int // The number of indentation spaces. + best_width int // The preferred width of the output lines. + unicode bool // Allow unescaped non-ASCII characters? + line_break yaml_break_t // The preferred line break. + + state yaml_emitter_state_t // The current emitter state. + states []yaml_emitter_state_t // The stack of states. + + events []yaml_event_t // The event queue. + events_head int // The head of the event queue. + + indents []int // The stack of indentation levels. + + tag_directives []yaml_tag_directive_t // The list of tag directives. + + indent int // The current indentation level. + + flow_level int // The current flow level. + + root_context bool // Is it the document root context? + sequence_context bool // Is it a sequence context? + mapping_context bool // Is it a mapping context? + simple_key_context bool // Is it a simple mapping key context? + + line int // The current line. + column int // The current column. + whitespace bool // If the last character was a whitespace? + indention bool // If the last character was an indentation character (' ', '-', '?', ':')? + open_ended bool // If an explicit document end is required? + + // Anchor analysis. + anchor_data struct { + anchor []byte // The anchor value. + alias bool // Is it an alias? + } + + // Tag analysis. + tag_data struct { + handle []byte // The tag handle. + suffix []byte // The tag suffix. + } + + // Scalar analysis. + scalar_data struct { + value []byte // The scalar value. + multiline bool // Does the scalar contain line breaks? + flow_plain_allowed bool // Can the scalar be expessed in the flow plain style? + block_plain_allowed bool // Can the scalar be expressed in the block plain style? + single_quoted_allowed bool // Can the scalar be expressed in the single quoted style? + block_allowed bool // Can the scalar be expressed in the literal or folded styles? + style yaml_scalar_style_t // The output style. + } + + // Dumper stuff + + opened bool // If the stream was already opened? + closed bool // If the stream was already closed? + + // The information associated with the document nodes. + anchors *struct { + references int // The number of references. + anchor int // The anchor id. + serialized bool // If the node has been emitted? + } + + last_anchor_id int // The last assigned anchor id. + + document *yaml_document_t // The currently emitted document. +} diff --git a/vendor/gopkg.in/yaml.v2/yamlprivateh.go b/vendor/gopkg.in/yaml.v2/yamlprivateh.go new file mode 100644 index 000000000..8110ce3c3 --- /dev/null +++ b/vendor/gopkg.in/yaml.v2/yamlprivateh.go @@ -0,0 +1,173 @@ +package yaml + +const ( + // The size of the input raw buffer. + input_raw_buffer_size = 512 + + // The size of the input buffer. + // It should be possible to decode the whole raw buffer. + input_buffer_size = input_raw_buffer_size * 3 + + // The size of the output buffer. + output_buffer_size = 128 + + // The size of the output raw buffer. + // It should be possible to encode the whole output buffer. + output_raw_buffer_size = (output_buffer_size*2 + 2) + + // The size of other stacks and queues. + initial_stack_size = 16 + initial_queue_size = 16 + initial_string_size = 16 +) + +// Check if the character at the specified position is an alphabetical +// character, a digit, '_', or '-'. +func is_alpha(b []byte, i int) bool { + return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-' +} + +// Check if the character at the specified position is a digit. +func is_digit(b []byte, i int) bool { + return b[i] >= '0' && b[i] <= '9' +} + +// Get the value of a digit. +func as_digit(b []byte, i int) int { + return int(b[i]) - '0' +} + +// Check if the character at the specified position is a hex-digit. +func is_hex(b []byte, i int) bool { + return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f' +} + +// Get the value of a hex-digit. +func as_hex(b []byte, i int) int { + bi := b[i] + if bi >= 'A' && bi <= 'F' { + return int(bi) - 'A' + 10 + } + if bi >= 'a' && bi <= 'f' { + return int(bi) - 'a' + 10 + } + return int(bi) - '0' +} + +// Check if the character is ASCII. +func is_ascii(b []byte, i int) bool { + return b[i] <= 0x7F +} + +// Check if the character at the start of the buffer can be printed unescaped. +func is_printable(b []byte, i int) bool { + return ((b[i] == 0x0A) || // . == #x0A + (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E + (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF + (b[i] > 0xC2 && b[i] < 0xED) || + (b[i] == 0xED && b[i+1] < 0xA0) || + (b[i] == 0xEE) || + (b[i] == 0xEF && // #xE000 <= . <= #xFFFD + !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF + !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF)))) +} + +// Check if the character at the specified position is NUL. +func is_z(b []byte, i int) bool { + return b[i] == 0x00 +} + +// Check if the beginning of the buffer is a BOM. +func is_bom(b []byte, i int) bool { + return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF +} + +// Check if the character at the specified position is space. +func is_space(b []byte, i int) bool { + return b[i] == ' ' +} + +// Check if the character at the specified position is tab. +func is_tab(b []byte, i int) bool { + return b[i] == '\t' +} + +// Check if the character at the specified position is blank (space or tab). +func is_blank(b []byte, i int) bool { + //return is_space(b, i) || is_tab(b, i) + return b[i] == ' ' || b[i] == '\t' +} + +// Check if the character at the specified position is a line break. +func is_break(b []byte, i int) bool { + return (b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029) +} + +func is_crlf(b []byte, i int) bool { + return b[i] == '\r' && b[i+1] == '\n' +} + +// Check if the character is a line break or NUL. +func is_breakz(b []byte, i int) bool { + //return is_break(b, i) || is_z(b, i) + return ( // is_break: + b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) + // is_z: + b[i] == 0) +} + +// Check if the character is a line break, space, or NUL. +func is_spacez(b []byte, i int) bool { + //return is_space(b, i) || is_breakz(b, i) + return ( // is_space: + b[i] == ' ' || + // is_breakz: + b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) + b[i] == 0) +} + +// Check if the character is a line break, space, tab, or NUL. +func is_blankz(b []byte, i int) bool { + //return is_blank(b, i) || is_breakz(b, i) + return ( // is_blank: + b[i] == ' ' || b[i] == '\t' || + // is_breakz: + b[i] == '\r' || // CR (#xD) + b[i] == '\n' || // LF (#xA) + b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028) + b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029) + b[i] == 0) +} + +// Determine the width of the character. +func width(b byte) int { + // Don't replace these by a switch without first + // confirming that it is being inlined. + if b&0x80 == 0x00 { + return 1 + } + if b&0xE0 == 0xC0 { + return 2 + } + if b&0xF0 == 0xE0 { + return 3 + } + if b&0xF8 == 0xF0 { + return 4 + } + return 0 + +} diff --git a/vendor/vendor.json b/vendor/vendor.json index ff87684b6..48432de87 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -350,6 +350,12 @@ "path": "gopkg.in/olivere/elastic.v3/uritemplates", "revision": "f7ae701daf3abe5dfb99f57b3f47738ec93c9c26", "revisionTime": "2016-07-16T10:42:39Z" + }, + { + "checksumSHA1": "12GqsW8PiRPnezDDy0v4brZrndM=", + "path": "gopkg.in/yaml.v2", + "revision": "a5b47d31c556af34a302ce5d659e6fea44d90de0", + "revisionTime": "2016-09-28T15:37:09Z" } ], "rootPath": "github.com/minio/minio" From 6df7bc42b8c082b8e6033eff283a0f4aa66ed41c Mon Sep 17 00:00:00 2001 From: Aditya Manthramurthy Date: Fri, 3 Mar 2017 23:53:41 +0530 Subject: [PATCH 50/94] Fix check for bucket name: (#3832) * Do not allow bucket names with adjacent hypen and periods. * Improve performance by eliminating the usage of regular expressions. --- cmd/object-api-utils.go | 55 +++++++++++++++++++++++++++--------- cmd/object-api-utils_test.go | 11 ++++++-- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/cmd/object-api-utils.go b/cmd/object-api-utils.go index 40047657d..ce78e9265 100644 --- a/cmd/object-api-utils.go +++ b/cmd/object-api-utils.go @@ -21,7 +21,6 @@ import ( "fmt" "io" "path" - "regexp" "runtime" "strings" "unicode/utf8" @@ -38,12 +37,10 @@ const ( minioMetaMultipartBucket = minioMetaBucket + "/" + mpartMetaPrefix // Minio Tmp meta prefix. minioMetaTmpBucket = minioMetaBucket + "/tmp" + // DNS separator (period), used for bucket name validation. + dnsDelimiter = "." ) -// validBucket regexp. -var validBucket = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`) -var isIPAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`) - // isMinioBucket returns true if given bucket is a Minio internal // bucket and false otherwise. func isMinioMetaBucketName(bucket string) bool { @@ -52,10 +49,13 @@ func isMinioMetaBucketName(bucket string) bool { bucket == minioMetaTmpBucket } -// IsValidBucketName verifies a bucket name in accordance with Amazon's -// requirements. It must be 3-63 characters long, can contain dashes -// and periods, but must begin and end with a lowercase letter or a number. -// See: http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html +// IsValidBucketName verifies that a bucket name is in accordance with +// Amazon's requirements (i.e. DNS naming conventions). It must be 3-63 +// characters long, and it must be a sequence of one or more labels +// separated by periods. Each label can contain lowercase ascii +// letters, decimal digits and hyphens, but must not begin or end with +// a hyphen. See: +// http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html func IsValidBucketName(bucket string) bool { // Special case when bucket is equal to one of the meta buckets. if isMinioMetaBucketName(bucket) { @@ -64,12 +64,39 @@ func IsValidBucketName(bucket string) bool { if len(bucket) < 3 || len(bucket) > 63 { return false } - if bucket[0] == '.' || bucket[len(bucket)-1] == '.' { - return false + + // Split on dot and check each piece conforms to rules. + allNumbers := true + pieces := strings.Split(bucket, dnsDelimiter) + for _, piece := range pieces { + if len(piece) == 0 || piece[0] == '-' || + piece[len(piece)-1] == '-' { + // Current piece has 0-length or starts or + // ends with a hyphen. + return false + } + // Now only need to check if each piece is a valid + // 'label' in AWS terminology and if the bucket looks + // like an IP address. + isNotNumber := false + for i := 0; i < len(piece); i++ { + switch { + case (piece[i] >= 'a' && piece[i] <= 'z' || + piece[i] == '-'): + // Found a non-digit character, so + // this piece is not a number. + isNotNumber = true + case piece[i] >= '0' && piece[i] <= '9': + // Nothing to do. + default: + // Found invalid character. + return false + } + } + allNumbers = allNumbers && !isNotNumber } - return (validBucket.MatchString(bucket) && - !isIPAddress.MatchString(bucket) && - !strings.Contains(bucket, "..")) + // Does the bucket name look like an IP address? + return !(len(pieces) == 4 && allNumbers) } // IsValidObjectName verifies an object name in accordance with Amazon's diff --git a/cmd/object-api-utils_test.go b/cmd/object-api-utils_test.go index b93ceabb8..abf3560da 100644 --- a/cmd/object-api-utils_test.go +++ b/cmd/object-api-utils_test.go @@ -41,6 +41,8 @@ func TestIsValidBucketName(t *testing.T) { {"testbucket", true}, {"1bucket", true}, {"bucket1", true}, + {"a.b", true}, + {"ab.a.bc", true}, // cases for which test should fail. // passing invalid bucket names. {"------", false}, @@ -59,11 +61,14 @@ func TestIsValidBucketName(t *testing.T) { {"ends-with-a-dot.", false}, {"ends-with-a-dash-", false}, {"-starts-with-a-dash", false}, - {"THIS-BEINGS-WITH-UPPERCASe", false}, + {"THIS-BEGINS-WITH-UPPERCASe", false}, {"tHIS-ENDS-WITH-UPPERCASE", false}, - {"ThisBeginsAndEndsWithUpperCase", false}, + {"ThisBeginsAndEndsWithUpperCasE", false}, {"una ñina", false}, - {"lalalallalallalalalallalallalala-theString-size-is-greater-than-64", false}, + {"dash-.may-not-appear-next-to-dot", false}, + {"dash.-may-not-appear-next-to-dot", false}, + {"dash-.-may-not-appear-next-to-dot", false}, + {"lalalallalallalalalallalallalala-thestring-size-is-greater-than-63", false}, } for i, testCase := range testCases { From 0c8c463a6323d03c0d228265116458e804311550 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Sat, 4 Mar 2017 00:46:28 +0100 Subject: [PATCH 51/94] tests: Fix web handlers testing with faulty disks (#3845) --- cmd/web-handlers_test.go | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/cmd/web-handlers_test.go b/cmd/web-handlers_test.go index 5c33334ed..27d13b247 100644 --- a/cmd/web-handlers_test.go +++ b/cmd/web-handlers_test.go @@ -1422,6 +1422,12 @@ func TestWebObjectLayerFaultyDisks(t *testing.T) { // Executing the object layer tests for XL. defer removeRoots(fsDirs) + bucketName := "mybucket" + err = obj.MakeBucket(bucketName) + if err != nil { + t.Fatal("Cannot make bucket:", err) + } + // Set faulty disks to XL backend xl := obj.(*xlObjects) for i, d := range xl.storageDisks { @@ -1449,13 +1455,23 @@ func TestWebObjectLayerFaultyDisks(t *testing.T) { } // Check if web rpc calls return errors with faulty disks. ServerInfo, GenerateAuth, SetAuth, GetAuth are not concerned - webRPCs := []string{"MakeBucket", "ListBuckets", "ListObjects", "RemoveObject", - "GetBucketPolicy", "SetBucketPolicy"} + // RemoveObject is also not concerned since it always returns success. + webRPCs := []struct { + webRPCName string + ReqArgs interface{} + RepArgs interface{} + }{ + {"MakeBucket", MakeBucketArgs{BucketName: bucketName}, WebGenericRep{}}, + {"ListBuckets", AuthRPCArgs{}, ListBucketsRep{}}, + {"ListObjects", ListObjectsArgs{BucketName: bucketName, Prefix: ""}, ListObjectsRep{}}, + {"GetBucketPolicy", GetBucketPolicyArgs{BucketName: bucketName, Prefix: ""}, GetBucketPolicyRep{}}, + {"SetBucketPolicy", SetBucketPolicyArgs{BucketName: bucketName, Prefix: "", Policy: "none"}, WebGenericRep{}}, + } for _, rpcCall := range webRPCs { - args := &AuthRPCArgs{} - reply := &WebGenericRep{} - req, nerr := newTestWebRPCRequest("Web."+rpcCall, authorization, args) + args := &rpcCall.ReqArgs + reply := &rpcCall.RepArgs + req, nerr := newTestWebRPCRequest("Web."+rpcCall.webRPCName, authorization, args) if nerr != nil { t.Fatalf("Test %s: Failed to create HTTP request: %v", rpcCall, nerr) } From 05e53f1b348fb4d2f258fb6f905af5c890e7c570 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 3 Mar 2017 16:32:04 -0800 Subject: [PATCH 52/94] api: CopyObjectPart was copying wrong offsets due to shadowing. (#3838) startOffset was re-assigned to '0' so it would end up copying wrong content ignoring the requested startOffset. This also fixes the corruption issue we observed while using docker registry. Fixes https://github.com/docker/distribution/issues/2205 Also fixes #3842 - incorrect routing. --- cmd/api-errors.go | 12 +++ cmd/copy-part-range.go | 106 ++++++++++++++++++++++++++ cmd/copy-part-range_test.go | 85 +++++++++++++++++++++ cmd/fs-v1-multipart.go | 1 - cmd/object-api-errors.go | 4 - cmd/object-handlers.go | 20 ++--- cmd/object-handlers_test.go | 146 ++++++++++++++++++++++++++++++++++-- cmd/typed-errors.go | 7 ++ cmd/xl-v1-multipart.go | 1 - 9 files changed, 360 insertions(+), 22 deletions(-) create mode 100644 cmd/copy-part-range.go create mode 100644 cmd/copy-part-range_test.go diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 33cd41a75..81c69b784 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -56,6 +56,8 @@ const ( ErrInvalidBucketName ErrInvalidDigest ErrInvalidRange + ErrInvalidCopyPartRange + ErrInvalidCopyPartRangeSource ErrInvalidMaxKeys ErrInvalidMaxUploads ErrInvalidMaxParts @@ -540,6 +542,16 @@ var errorCodeResponse = map[APIErrorCode]APIError{ Description: "Configurations overlap. Configurations on the same bucket cannot share a common event type.", HTTPStatusCode: http.StatusBadRequest, }, + ErrInvalidCopyPartRange: { + Code: "InvalidArgument", + Description: "The x-amz-copy-source-range value must be of the form bytes=first-last where first and last are the zero-based offsets of the first and last bytes to copy", + HTTPStatusCode: http.StatusBadRequest, + }, + ErrInvalidCopyPartRangeSource: { + Code: "InvalidArgument", + Description: "Range specified is not valid for source object", + HTTPStatusCode: http.StatusBadRequest, + }, /// S3 extensions. ErrContentSHA256Mismatch: { diff --git a/cmd/copy-part-range.go b/cmd/copy-part-range.go new file mode 100644 index 000000000..316eebf80 --- /dev/null +++ b/cmd/copy-part-range.go @@ -0,0 +1,106 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "fmt" + "net/http" + "net/url" + "strconv" + "strings" +) + +// Writes S3 compatible copy part range error. +func writeCopyPartErr(w http.ResponseWriter, err error, url *url.URL) { + switch err { + case errInvalidRange: + writeErrorResponse(w, ErrInvalidCopyPartRange, url) + return + case errInvalidRangeSource: + writeErrorResponse(w, ErrInvalidCopyPartRangeSource, url) + return + default: + writeErrorResponse(w, ErrInternalError, url) + return + } +} + +// Parses x-amz-copy-source-range for CopyObjectPart API. Specifically written to +// differentiate the behavior between regular httpRange header v/s x-amz-copy-source-range. +// The range of bytes to copy from the source object. The range value must use the form +// bytes=first-last, where the first and last are the zero-based byte offsets to copy. +// For example, bytes=0-9 indicates that you want to copy the first ten bytes of the source. +// http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html +func parseCopyPartRange(rangeString string, resourceSize int64) (hrange *httpRange, err error) { + // Return error if given range string doesn't start with byte range prefix. + if !strings.HasPrefix(rangeString, byteRangePrefix) { + return nil, fmt.Errorf("'%s' does not start with '%s'", rangeString, byteRangePrefix) + } + + // Trim byte range prefix. + byteRangeString := strings.TrimPrefix(rangeString, byteRangePrefix) + + // Check if range string contains delimiter '-', else return error. eg. "bytes=8" + sepIndex := strings.Index(byteRangeString, "-") + if sepIndex == -1 { + return nil, errInvalidRange + } + + offsetBeginString := byteRangeString[:sepIndex] + offsetBegin := int64(-1) + // Convert offsetBeginString only if its not empty. + if len(offsetBeginString) > 0 { + if !validBytePos.MatchString(offsetBeginString) { + return nil, errInvalidRange + } + if offsetBegin, err = strconv.ParseInt(offsetBeginString, 10, 64); err != nil { + return nil, errInvalidRange + } + } + + offsetEndString := byteRangeString[sepIndex+1:] + offsetEnd := int64(-1) + // Convert offsetEndString only if its not empty. + if len(offsetEndString) > 0 { + if !validBytePos.MatchString(offsetEndString) { + return nil, errInvalidRange + } + if offsetEnd, err = strconv.ParseInt(offsetEndString, 10, 64); err != nil { + return nil, errInvalidRange + } + } + + // rangeString contains first byte positions. eg. "bytes=2-" or + // rangeString contains last bye positions. eg. "bytes=-2" + if offsetBegin == -1 || offsetEnd == -1 { + return nil, errInvalidRange + } + + // Last byte position should not be greater than first byte + // position. eg. "bytes=5-2" + if offsetBegin > offsetEnd { + return nil, errInvalidRange + } + + // First and last byte positions should not be >= resourceSize. + if offsetBegin >= resourceSize || offsetEnd >= resourceSize { + return nil, errInvalidRangeSource + } + + // Success.. + return &httpRange{offsetBegin, offsetEnd, resourceSize}, nil +} diff --git a/cmd/copy-part-range_test.go b/cmd/copy-part-range_test.go new file mode 100644 index 000000000..0c8d8f266 --- /dev/null +++ b/cmd/copy-part-range_test.go @@ -0,0 +1,85 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import "testing" + +// Test parseCopyPartRange() +func TestParseCopyPartRange(t *testing.T) { + // Test success cases. + successCases := []struct { + rangeString string + offsetBegin int64 + offsetEnd int64 + length int64 + }{ + {"bytes=2-5", 2, 5, 4}, + {"bytes=2-9", 2, 9, 8}, + {"bytes=2-2", 2, 2, 1}, + {"bytes=0000-0006", 0, 6, 7}, + } + + for _, successCase := range successCases { + hrange, err := parseCopyPartRange(successCase.rangeString, 10) + if err != nil { + t.Fatalf("expected: , got: %s", err) + } + + if hrange.offsetBegin != successCase.offsetBegin { + t.Fatalf("expected: %d, got: %d", successCase.offsetBegin, hrange.offsetBegin) + } + + if hrange.offsetEnd != successCase.offsetEnd { + t.Fatalf("expected: %d, got: %d", successCase.offsetEnd, hrange.offsetEnd) + } + if hrange.getLength() != successCase.length { + t.Fatalf("expected: %d, got: %d", successCase.length, hrange.getLength()) + } + } + + // Test invalid range strings. + invalidRangeStrings := []string{ + "bytes=8", + "bytes=5-2", + "bytes=+2-5", + "bytes=2-+5", + "bytes=2--5", + "bytes=-", + "", + "2-5", + "bytes = 2-5", + "bytes=2 - 5", + "bytes=0-0,-1", + "bytes=2-5 ", + } + for _, rangeString := range invalidRangeStrings { + if _, err := parseCopyPartRange(rangeString, 10); err == nil { + t.Fatalf("expected: an error, got: for range %s", rangeString) + } + } + + // Test error range strings. + errorRangeString := []string{ + "bytes=10-10", + "bytes=20-30", + } + for _, rangeString := range errorRangeString { + if _, err := parseCopyPartRange(rangeString, 10); err != errInvalidRangeSource { + t.Fatalf("expected: %s, got: %s", errInvalidRangeSource, err) + } + } +} diff --git a/cmd/fs-v1-multipart.go b/cmd/fs-v1-multipart.go index edde3bfe8..69ff09e1c 100644 --- a/cmd/fs-v1-multipart.go +++ b/cmd/fs-v1-multipart.go @@ -463,7 +463,6 @@ func (fs fsObjects) CopyObjectPart(srcBucket, srcObject, dstBucket, dstObject, u pipeReader, pipeWriter := io.Pipe() go func() { - var startOffset int64 // Read the whole file. if gerr := fs.GetObject(srcBucket, srcObject, startOffset, length, pipeWriter); gerr != nil { errorIf(gerr, "Unable to read %s/%s.", srcBucket, srcObject) pipeWriter.CloseWithError(gerr) diff --git a/cmd/object-api-errors.go b/cmd/object-api-errors.go index 78a62c1b2..1f9ea1561 100644 --- a/cmd/object-api-errors.go +++ b/cmd/object-api-errors.go @@ -17,7 +17,6 @@ package cmd import ( - "errors" "fmt" "io" ) @@ -252,9 +251,6 @@ func (e IncompleteBody) Error() string { return e.Bucket + "#" + e.Object + "has incomplete body" } -// errInvalidRange - returned when given range value is not valid. -var errInvalidRange = errors.New("Invalid range") - // InvalidRange - invalid range typed error. type InvalidRange struct { offsetBegin int64 diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 2e2717688..e0e6c1beb 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -601,16 +601,12 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt var hrange *httpRange rangeHeader := r.Header.Get("x-amz-copy-source-range") if rangeHeader != "" { - if hrange, err = parseRequestRange(rangeHeader, objInfo.Size); err != nil { + if hrange, err = parseCopyPartRange(rangeHeader, objInfo.Size); err != nil { // Handle only errInvalidRange // Ignore other parse error and treat it as regular Get request like Amazon S3. - if err == errInvalidRange { - writeErrorResponse(w, ErrInvalidRange, r.URL) - return - } - - // log the error. - errorIf(err, "Invalid request range") + errorIf(err, "Unable to extract range %s", rangeHeader) + writeCopyPartErr(w, err, r.URL) + return } } @@ -623,8 +619,8 @@ func (api objectAPIHandlers) CopyObjectPartHandler(w http.ResponseWriter, r *htt var startOffset int64 length := objInfo.Size if hrange != nil { - startOffset = hrange.offsetBegin length = hrange.getLength() + startOffset = hrange.offsetBegin } /// maximum copy size for multipart objects in a single operation @@ -661,6 +657,12 @@ func (api objectAPIHandlers) PutObjectPartHandler(w http.ResponseWriter, r *http return } + // X-Amz-Copy-Source shouldn't be set for this call. + if _, ok := r.Header["X-Amz-Copy-Source"]; ok { + writeErrorResponse(w, ErrInvalidCopySource, r.URL) + return + } + // get Content-Md5 sent by client and verify if valid md5Bytes, err := checkValidMD5(r.Header.Get("Content-Md5")) if err != nil { diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index 3cf72167c..591477f63 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -26,6 +26,7 @@ import ( "net/http/httptest" "net/url" "strconv" + "strings" "sync" "testing" @@ -939,6 +940,124 @@ func testAPIPutObjectHandler(obj ObjectLayer, instanceType, bucketName string, a } +// Tests sanity of attempting to copying each parts at offsets from an existing +// file and create a new object. Also validates if the written is same as what we +// expected. +func TestAPICopyObjectPartHandlerSanity(t *testing.T) { + defer DetectTestLeak(t)() + ExecObjectLayerAPITest(t, testAPICopyObjectPartHandlerSanity, []string{"CopyObjectPart"}) +} + +func testAPICopyObjectPartHandlerSanity(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler, + credentials credential, t *testing.T) { + + objectName := "test-object" + // register event notifier. + err := initEventNotifier(obj) + if err != nil { + t.Fatalf("Initializing event notifiers failed") + } + + // set of byte data for PutObject. + // object has to be created before running tests for Copy Object. + // this is required even to assert the copied object, + bytesData := []struct { + byteData []byte + }{ + {generateBytesData(6 * humanize.MiByte)}, + } + + // set of inputs for uploading the objects before tests for downloading is done. + putObjectInputs := []struct { + bucketName string + objectName string + contentLength int64 + textData []byte + metaData map[string]string + }{ + // case - 1. + {bucketName, objectName, int64(len(bytesData[0].byteData)), bytesData[0].byteData, make(map[string]string)}, + } + sha256sum := "" + // iterate through the above set of inputs and upload the object. + for i, input := range putObjectInputs { + // uploading the object. + _, err = obj.PutObject(input.bucketName, input.objectName, input.contentLength, + bytes.NewBuffer(input.textData), input.metaData, sha256sum) + // if object upload fails stop the test. + if err != nil { + t.Fatalf("Put Object case %d: Error uploading object: %v", i+1, err) + } + } + + // Initiate Multipart upload for testing PutObjectPartHandler. + testObject := "testobject" + + // PutObjectPart API HTTP Handler has to be tested in isolation, + // that is without any other handler being registered, + // That's why NewMultipartUpload is initiated using ObjectLayer. + uploadID, err := obj.NewMultipartUpload(bucketName, testObject, nil) + if err != nil { + // Failed to create NewMultipartUpload, abort. + t.Fatalf("Minio %s : %s", instanceType, err) + } + + a := 0 + b := globalMinPartSize - 1 + var parts []completePart + for partNumber := 1; partNumber <= 2; partNumber++ { + // initialize HTTP NewRecorder, this records any mutations to response writer inside the handler. + rec := httptest.NewRecorder() + cpPartURL := getCopyObjectPartURL("", bucketName, testObject, uploadID, fmt.Sprintf("%d", partNumber)) + + // construct HTTP request for copy object. + var req *http.Request + req, err = newTestSignedRequestV4("PUT", cpPartURL, 0, nil, credentials.AccessKey, credentials.SecretKey) + if err != nil { + t.Fatalf("Test failed to create HTTP request for copy object part: %v", err) + } + + // "X-Amz-Copy-Source" header contains the information about the source bucket and the object to copied. + req.Header.Set("X-Amz-Copy-Source", url.QueryEscape(pathJoin(bucketName, objectName))) + req.Header.Set("X-Amz-Copy-Source-Range", fmt.Sprintf("bytes=%d-%d", a, b)) + + // Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler. + // Call the ServeHTTP to execute the handler, `func (api objectAPIHandlers) CopyObjectHandler` handles the request. + a = globalMinPartSize + b = len(bytesData[0].byteData) - 1 + apiRouter.ServeHTTP(rec, req) + if rec.Code != http.StatusOK { + t.Fatalf("Test failed to create HTTP request for copy %d", rec.Code) + } + + resp := &CopyObjectPartResponse{} + if err = xmlDecoder(rec.Body, resp, rec.Result().ContentLength); err != nil { + t.Fatalf("Test failed to decode XML response: %v", err) + } + + parts = append(parts, completePart{ + PartNumber: partNumber, + ETag: strings.Trim(resp.ETag, "\""), + }) + } + + result, err := obj.CompleteMultipartUpload(bucketName, testObject, uploadID, parts) + if err != nil { + t.Fatalf("Test: %s complete multipart upload failed: %v", instanceType, err) + } + if result.Size != int64(len(bytesData[0].byteData)) { + t.Fatalf("Test: %s expected size not written: expected %d, got %d", instanceType, len(bytesData[0].byteData), result.Size) + } + + var buf bytes.Buffer + if err = obj.GetObject(bucketName, testObject, 0, int64(len(bytesData[0].byteData)), &buf); err != nil { + t.Fatalf("Test: %s reading completed file failed: %v", instanceType, err) + } + if !bytes.Equal(buf.Bytes(), bytesData[0].byteData) { + t.Fatalf("Test: %s returned data is not expected corruption detected:", instanceType) + } +} + // Wrapper for calling Copy Object Part API handler tests for both XL multiple disks and single node setup. func TestAPICopyObjectPartHandler(t *testing.T) { defer DetectTestLeak(t)() @@ -1069,10 +1188,23 @@ func testAPICopyObjectPartHandler(obj ObjectLayer, instanceType, bucketName stri accessKey: credentials.AccessKey, secretKey: credentials.SecretKey, - expectedRespStatus: http.StatusRequestedRangeNotSatisfiable, + expectedRespStatus: http.StatusBadRequest, }, // Test case - 6. + // Test case with ivalid byte range for exceeding source size boundaries. + { + bucketName: bucketName, + uploadID: uploadID, + copySourceHeader: url.QueryEscape("/" + bucketName + "/" + objectName), + copySourceRange: "bytes=0-6144", + accessKey: credentials.AccessKey, + secretKey: credentials.SecretKey, + + expectedRespStatus: http.StatusBadRequest, + }, + + // Test case - 7. // Test case with object name missing from source. // fail with BadRequest. { @@ -1085,7 +1217,7 @@ func testAPICopyObjectPartHandler(obj ObjectLayer, instanceType, bucketName stri expectedRespStatus: http.StatusBadRequest, }, - // Test case - 7. + // Test case - 8. // Test case with non-existent source file. // Case for the purpose of failing `api.ObjectAPI.GetObjectInfo`. // Expecting the response status code to http.StatusNotFound (404). @@ -1099,7 +1231,7 @@ func testAPICopyObjectPartHandler(obj ObjectLayer, instanceType, bucketName stri expectedRespStatus: http.StatusNotFound, }, - // Test case - 8. + // Test case - 9. // Test case with non-existent source file. // Case for the purpose of failing `api.ObjectAPI.PutObjectPart`. // Expecting the response status code to http.StatusNotFound (404). @@ -1113,7 +1245,7 @@ func testAPICopyObjectPartHandler(obj ObjectLayer, instanceType, bucketName stri expectedRespStatus: http.StatusNotFound, }, - // Test case - 9. + // Test case - 10. // Case with invalid AccessKey. { bucketName: bucketName, @@ -1125,7 +1257,7 @@ func testAPICopyObjectPartHandler(obj ObjectLayer, instanceType, bucketName stri expectedRespStatus: http.StatusForbidden, }, - // Test case - 10. + // Test case - 11. // Case with non-existent upload id. { bucketName: bucketName, @@ -1136,7 +1268,7 @@ func testAPICopyObjectPartHandler(obj ObjectLayer, instanceType, bucketName stri expectedRespStatus: http.StatusNotFound, }, - // Test case - 11. + // Test case - 12. // invalid part number. { bucketName: bucketName, @@ -1147,7 +1279,7 @@ func testAPICopyObjectPartHandler(obj ObjectLayer, instanceType, bucketName stri secretKey: credentials.SecretKey, expectedRespStatus: http.StatusOK, }, - // Test case - 12. + // Test case - 13. // maximum part number. { bucketName: bucketName, diff --git a/cmd/typed-errors.go b/cmd/typed-errors.go index 4b561bf22..ae77a611b 100644 --- a/cmd/typed-errors.go +++ b/cmd/typed-errors.go @@ -54,3 +54,10 @@ var errServerTimeMismatch = errors.New("Server times are too far apart") // errReservedBucket - bucket name is reserved for Minio, usually // returned for 'minio', '.minio.sys' var errReservedBucket = errors.New("All access to this bucket is disabled") + +// errInvalidRange - returned when given range value is not valid. +var errInvalidRange = errors.New("Invalid range") + +// errInvalidRangeSource - returned when given range value exceeds +// the source object size. +var errInvalidRangeSource = errors.New("Range specified exceeds source object size") diff --git a/cmd/xl-v1-multipart.go b/cmd/xl-v1-multipart.go index 2fa73630c..fa3187695 100644 --- a/cmd/xl-v1-multipart.go +++ b/cmd/xl-v1-multipart.go @@ -546,7 +546,6 @@ func (xl xlObjects) CopyObjectPart(srcBucket, srcObject, dstBucket, dstObject, u pipeReader, pipeWriter := io.Pipe() go func() { - var startOffset int64 // Read the whole file. if gerr := xl.GetObject(srcBucket, srcObject, startOffset, length, pipeWriter); gerr != nil { errorIf(gerr, "Unable to read %s of the object `%s/%s`.", srcBucket, srcObject) pipeWriter.CloseWithError(toObjectErr(gerr, srcBucket, srcObject)) From 0bae3330e8c8910c69e8229a3f0268e6127b6982 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Fri, 3 Mar 2017 17:07:17 -0800 Subject: [PATCH 53/94] browser: Send correct arguments for RemoveObjects web handler. (#3848) Fixes #3839 --- browser/app/js/components/Browse.js | 9 +++++---- browser/app/js/reducers.js | 1 - cmd/web-handlers.go | 8 ++++---- cmd/web-handlers_test.go | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/browser/app/js/components/Browse.js b/browser/app/js/components/Browse.js index e09540b15..0810ca149 100644 --- a/browser/app/js/components/Browse.js +++ b/browser/app/js/components/Browse.js @@ -228,12 +228,13 @@ export default class Browse extends React.Component { removeObject() { const {web, dispatch, currentPath, currentBucket, deleteConfirmation} = this.props web.RemoveObject({ - bucketName: currentBucket, - objectName: deleteConfirmation.object + bucketname: currentBucket, + objects: [deleteConfirmation.object] }) .then(() => { this.hideDeleteConfirmation() - dispatch(actions.removeObject(deleteConfirmation.object)) + let delObject = deleteConfirmation.object.replace(currentPath, '') + dispatch(actions.removeObject(delObject)) }) .catch(e => dispatch(actions.showAlert({ type: 'danger', @@ -759,4 +760,4 @@ export default class Browse extends React.Component {
    ) } -} \ No newline at end of file +} diff --git a/browser/app/js/reducers.js b/browser/app/js/reducers.js index 421d24cce..6cac5dabb 100644 --- a/browser/app/js/reducers.js +++ b/browser/app/js/reducers.js @@ -199,7 +199,6 @@ export default (state = { newState.checkedObjects = [] break } - console.log(newState.checkedObjects) return newState } diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index cfe9cbb48..c139e6f27 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -257,7 +257,7 @@ func (web *webAPIHandlers) ListObjects(r *http.Request, args *ListObjectsArgs, r // RemoveObjectArgs - args to remove an object // JSON will look like: -// '{"bucketname":"testbucket","prefix":"john/pics/","objects":["hawaii/","maldives/","sanjose.jpg"]}' +// '{"bucketname":"testbucket","objects":["photos/hawaii/","photos/maldives/","photos/sanjose.jpg"]}' type RemoveObjectArgs struct { Objects []string `json:"objects"` // can be files or sub-directories Prefix string `json:"prefix"` // current directory in the browser-ui @@ -300,8 +300,8 @@ objectLoop: return err } if !hasSuffix(object, slashSeparator) { - // If not a directory, compress the file and write it to response. - err = remove(pathJoin(args.Prefix, object)) + // If not a directory, remove the object. + err = remove(object) if err != nil { break objectLoop } @@ -311,7 +311,7 @@ objectLoop: marker := "" for { var lo ListObjectsInfo - lo, err = objectAPI.ListObjects(args.BucketName, pathJoin(args.Prefix, object), marker, "", 1000) + lo, err = objectAPI.ListObjects(args.BucketName, object, marker, "", 1000) if err != nil { break objectLoop } diff --git a/cmd/web-handlers_test.go b/cmd/web-handlers_test.go index 27d13b247..b3e4f83b5 100644 --- a/cmd/web-handlers_test.go +++ b/cmd/web-handlers_test.go @@ -477,7 +477,7 @@ func testRemoveObjectWebHandler(obj ObjectLayer, instanceType string, t TestErrH t.Fatalf("Was not able to upload an object, %v", err) } - removeObjectRequest := RemoveObjectArgs{BucketName: bucketName, Prefix: "", Objects: []string{"a/", "object"}} + removeObjectRequest := RemoveObjectArgs{BucketName: bucketName, Objects: []string{"a/", "object"}} removeObjectReply := &WebGenericRep{} req, err := newTestWebRPCRequest("Web.RemoveObject", authorization, removeObjectRequest) if err != nil { @@ -492,7 +492,7 @@ func testRemoveObjectWebHandler(obj ObjectLayer, instanceType string, t TestErrH t.Fatalf("Failed, %v", err) } - removeObjectRequest = RemoveObjectArgs{BucketName: bucketName, Prefix: "", Objects: []string{"a/", "object"}} + removeObjectRequest = RemoveObjectArgs{BucketName: bucketName, Objects: []string{"a/", "object"}} removeObjectReply = &WebGenericRep{} req, err = newTestWebRPCRequest("Web.RemoveObject", authorization, removeObjectRequest) if err != nil { From b05c1c11d40b2224406d97ef55aa95ec1e318cdc Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 3 Mar 2017 18:04:58 -0800 Subject: [PATCH 54/94] browser: Update UI assets with new changes. --- browser/ui-assets.go | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/browser/ui-assets.go b/browser/ui-assets.go index ce79853d2..81f3b8c48 100644 --- a/browser/ui-assets.go +++ b/browser/ui-assets.go @@ -4,7 +4,7 @@ // production/favicon.ico // production/firefox.png // production/index.html -// production/index_bundle-2017-02-23T00-44-42Z.js +// production/index_bundle-2017-03-04T01-07-53Z.js // production/loader.css // production/logo.svg // production/safari.png @@ -65,7 +65,7 @@ func productionChromePng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -82,7 +82,7 @@ func productionFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -99,7 +99,7 @@ func productionFirefoxPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -156,8 +156,8 @@ var _productionIndexHTML = []byte(`
    - - + + `) @@ -172,12 +172,12 @@ func productionIndexHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _productionIndex_bundle20170223t004442zJs = []byte(`!function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){A.exports=t(240)},function(A,M,t){"use strict";A.exports=t(440)},function(A,M,t){"use strict";function I(A,M,t,I,g,e,i,T){if(!A){var E;if(void 0===M)E=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var N=[t,I,g,e,i,T],o=0;E=new Error(M.replace(/%s/g,function(){return N[o++]})),E.name="Invariant Violation"}throw E.framesToPop=1,E}}A.exports=I},function(A,M,t){"use strict";var I=t(20),g=I;A.exports=g},function(A,M){"use strict";function t(A,M){if(null==A)throw new TypeError("Object.assign target cannot be null or undefined");for(var t=Object(A),I=Object.prototype.hasOwnProperty,g=1;gM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;t":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;iM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;t":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;i-1&&A%1==0&&A1)for(var t=1;tA.clientHeight}Object.defineProperty(M,"__esModule",{value:!0}),M.default=i;var T=t(57),E=I(T),N=t(39),o=I(N);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):"function"!==E&&"string"!==E?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):null}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M){"use strict";function t(A){function M(M,t,I,g,e,i){var T=g||"<>",E=i||I;if(null==t[I])return M?new Error("Required "+e+" ` + "`" + `"+E+"` + "`" + ` was not specified "+("in ` + "`" + `"+T+"` + "`" + `.")):null;for(var N=arguments.length,o=Array(N>6?N-6:0),n=6;n=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return 0===A.button}function i(A){return!!(A.metaKey||A.altKey||A.ctrlKey||A.shiftKey)}function T(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!1;return!0}function E(A,M){var t=M.query,I=M.hash,g=M.state;return t||I||g?{pathname:A,query:t,hash:I,state:g}:A}M.__esModule=!0;var N=Object.assign||function(A){for(var M=1;M=0;I--){var g=A[I],e=g.path||"";if(t=e.replace(/\/*$/,"/")+t,0===e.indexOf("/"))break}return"/"+t}},propTypes:{path:C,from:C,to:C.isRequired,query:c,state:c,onEnter:o.falsy,children:o.falsy},render:function(){(0,T.default)(!1)}});M.default=D,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0;var g=t(1),e=I(g),i=t(8),T=I(i),E=t(30),N=t(34),o=e.default.PropTypes,n=o.string,C=o.func,c=e.default.createClass({displayName:"Route",statics:{createRouteFromReactElement:E.createRouteFromReactElement},propTypes:{path:n,component:N.component,components:N.components,getComponent:C,getComponents:C},render:function(){(0,T.default)(!1)}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return!A||!A.__v2_compatible__}function i(A){return A&&A.getCurrentLocation}M.__esModule=!0;var T=Object.assign||function(A){for(var M=1;M=0&&0===window.sessionStorage.length)return;throw A}}function i(A){var M=void 0;try{M=window.sessionStorage.getItem(g(A))}catch(A){if(A.name===o)return null}if(M)try{return JSON.parse(M)}catch(A){}return null}M.__esModule=!0,M.saveState=e,M.readState=i;var T=t(23),E=(I(T),"@@History/"),N=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],o="SecurityError"},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){function M(A){return E.canUseDOM?void 0:T.default(!1),t.listen(A)}var t=n.default(e({getUserConfirmation:N.getUserConfirmation},A,{go:N.go}));return e({},t,{listen:M})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M1?M-1:0),e=1;e=A.childNodes.length?null:A.childNodes.item(t);A.insertBefore(M,I)}var g=t(434),e=t(220),i=t(17),T=t(76),E=t(121),N=t(2),o={dangerouslyReplaceNodeWithMarkup:g.dangerouslyReplaceNodeWithMarkup,updateTextContent:E,processUpdates:function(A,M){for(var t,i=null,o=null,n=0;n-1?void 0:i(!1),!N.plugins[t]){M.extractEvents?void 0:i(!1),N.plugins[t]=M;var I=M.eventTypes;for(var e in I)g(I[e],M,e)?void 0:i(!1)}}}function g(A,M,t){N.eventNameDispatchConfigs.hasOwnProperty(t)?i(!1):void 0,N.eventNameDispatchConfigs[t]=A;var I=A.phasedRegistrationNames;if(I){for(var g in I)if(I.hasOwnProperty(g)){var T=I[g];e(T,M,t)}return!0}return!!A.registrationName&&(e(A.registrationName,M,t),!0)}function e(A,M,t){N.registrationNameModules[A]?i(!1):void 0,N.registrationNameModules[A]=M,N.registrationNameDependencies[A]=M.eventTypes[t].dependencies}var i=t(2),T=null,E={},N={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(A){T?i(!1):void 0,T=Array.prototype.slice.call(A),I()},injectEventPluginsByName:function(A){var M=!1;for(var t in A)if(A.hasOwnProperty(t)){var g=A[t];E.hasOwnProperty(t)&&E[t]===g||(E[t]?i(!1):void 0,E[t]=g,M=!0)}M&&I()},getPluginModuleForEvent:function(A){var M=A.dispatchConfig;if(M.registrationName)return N.registrationNameModules[M.registrationName]||null;for(var t in M.phasedRegistrationNames)if(M.phasedRegistrationNames.hasOwnProperty(t)){var I=N.registrationNameModules[M.phasedRegistrationNames[t]];if(I)return I}return null},_resetEventPlugins:function(){T=null;for(var A in E)E.hasOwnProperty(A)&&delete E[A];N.plugins.length=0;var M=N.eventNameDispatchConfigs;for(var t in M)M.hasOwnProperty(t)&&delete M[t];var I=N.registrationNameModules;for(var g in I)I.hasOwnProperty(g)&&delete I[g]}};A.exports=N},function(A,M,t){"use strict";function I(A){return(""+A).replace(x,"//")}function g(A,M){this.func=A,this.context=M,this.count=0}function e(A,M,t){var I=A.func,g=A.context;I.call(g,M,A.count++)}function i(A,M,t){if(null==A)return A;var I=g.getPooled(M,t);Q(A,e,I),g.release(I)}function T(A,M,t,I){this.result=A,this.keyPrefix=M,this.func=t,this.context=I,this.count=0}function E(A,M,t){var g=A.result,e=A.keyPrefix,i=A.func,T=A.context,E=i.call(T,M,A.count++);Array.isArray(E)?N(E,g,t,B.thatReturnsArgument):null!=E&&(a.isValidElement(E)&&(E=a.cloneAndReplaceKey(E,e+(E!==M?I(E.key||"")+"/":"")+t)),g.push(E))}function N(A,M,t,g,e){var i="";null!=t&&(i=I(t)+"/");var N=T.getPooled(M,i,g,e);Q(A,E,N),T.release(N)}function o(A,M,t){if(null==A)return A;var I=[];return N(A,I,null,M,t),I}function n(A,M,t){return null}function C(A,M){return Q(A,n,null)}function c(A){var M=[];return N(A,M,null,B.thatReturnsArgument),M}var D=t(31),a=t(13),B=t(20),Q=t(123),r=D.twoArgumentPooler,s=D.fourArgumentPooler,x=/\/(?!\/)/g;g.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},D.addPoolingTo(g,r),T.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},D.addPoolingTo(T,s);var j={forEach:i,map:o,mapIntoWithKeyPrefixInternal:N,count:C,toArray:c};A.exports=j},function(A,M,t){"use strict";function I(A,M){var t=y.hasOwnProperty(M)?y[M]:null;w.hasOwnProperty(M)&&(t!==x.OVERRIDE_BASE?B(!1):void 0),A.hasOwnProperty(M)&&(t!==x.DEFINE_MANY&&t!==x.DEFINE_MANY_MERGED?B(!1):void 0)}function g(A,M){if(M){"function"==typeof M?B(!1):void 0,C.isValidElement(M)?B(!1):void 0;var t=A.prototype;M.hasOwnProperty(s)&&u.mixins(A,M.mixins);for(var g in M)if(M.hasOwnProperty(g)&&g!==s){var e=M[g];if(I(t,g),u.hasOwnProperty(g))u[g](A,e);else{var i=y.hasOwnProperty(g),N=t.hasOwnProperty(g),o="function"==typeof e,n=o&&!i&&!N&&M.autobind!==!1;if(n)t.__reactAutoBindMap||(t.__reactAutoBindMap={}),t.__reactAutoBindMap[g]=e,t[g]=e;else if(N){var c=y[g];!i||c!==x.DEFINE_MANY_MERGED&&c!==x.DEFINE_MANY?B(!1):void 0,c===x.DEFINE_MANY_MERGED?t[g]=T(t[g],e):c===x.DEFINE_MANY&&(t[g]=E(t[g],e))}else t[g]=e}}}}function e(A,M){if(M)for(var t in M){var I=M[t];if(M.hasOwnProperty(t)){var g=t in u;g?B(!1):void 0;var e=t in A;e?B(!1):void 0,A[t]=I}}}function i(A,M){A&&M&&"object"==typeof A&&"object"==typeof M?void 0:B(!1);for(var t in M)M.hasOwnProperty(t)&&(void 0!==A[t]?B(!1):void 0,A[t]=M[t]);return A}function T(A,M){return function(){var t=A.apply(this,arguments),I=M.apply(this,arguments);if(null==t)return I;if(null==I)return t;var g={};return i(g,t),i(g,I),g}}function E(A,M){return function(){A.apply(this,arguments),M.apply(this,arguments)}}function N(A,M){var t=M.bind(A);return t}function o(A){for(var M in A.__reactAutoBindMap)if(A.__reactAutoBindMap.hasOwnProperty(M)){var t=A.__reactAutoBindMap[M];A[M]=N(A,t)}}var n=t(207),C=t(13),c=(t(71),t(70),t(222)),D=t(4),a=t(50),B=t(2),Q=t(59),r=t(27),s=(t(3),r({mixins:null})),x=Q({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),j=[],y={mixins:x.DEFINE_MANY,statics:x.DEFINE_MANY,propTypes:x.DEFINE_MANY,contextTypes:x.DEFINE_MANY,childContextTypes:x.DEFINE_MANY,getDefaultProps:x.DEFINE_MANY_MERGED,getInitialState:x.DEFINE_MANY_MERGED,getChildContext:x.DEFINE_MANY_MERGED,render:x.DEFINE_ONCE,componentWillMount:x.DEFINE_MANY,componentDidMount:x.DEFINE_MANY,componentWillReceiveProps:x.DEFINE_MANY,shouldComponentUpdate:x.DEFINE_ONCE,componentWillUpdate:x.DEFINE_MANY,componentDidUpdate:x.DEFINE_MANY,componentWillUnmount:x.DEFINE_MANY,updateComponent:x.OVERRIDE_BASE},u={displayName:function(A,M){A.displayName=M},mixins:function(A,M){if(M)for(var t=0;t"+T+""},receiveComponent:function(A,M){if(A!==this._currentElement){this._currentElement=A;var t=""+A;if(t!==this._stringText){this._stringText=t;var g=i.getNode(this._rootNodeID);I.updateTextContent(g,t)}}},unmountComponent:function(){e.unmountIDFromEnvironment(this._rootNodeID)}}),A.exports=o},function(A,M,t){"use strict";function I(){this.reinitializeTransaction()}var g=t(18),e=t(73),i=t(4),T=t(20),E={initialize:T,close:function(){C.isBatchingUpdates=!1}},N={initialize:T,close:g.flushBatchedUpdates.bind(g)},o=[N,E];i(I.prototype,e.Mixin,{getTransactionWrappers:function(){return o}});var n=new I,C={isBatchingUpdates:!1,batchedUpdates:function(A,M,t,I,g,e){var i=C.isBatchingUpdates;C.isBatchingUpdates=!0,i?A(M,t,I,g,e):n.perform(A,null,M,t,I,g,e)}};A.exports=C},function(A,M,t){"use strict";function I(){if(!l){l=!0,Q.EventEmitter.injectReactEventListener(B),Q.EventPluginHub.injectEventPluginOrder(T),Q.EventPluginHub.injectInstanceHandle(r),Q.EventPluginHub.injectMount(s),Q.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:u,EnterLeaveEventPlugin:E,ChangeEventPlugin:e,SelectEventPlugin:j,BeforeInputEventPlugin:g}),Q.NativeComponent.injectGenericComponentClass(D),Q.NativeComponent.injectTextComponentClass(a),Q.Class.injectMixin(n),Q.DOMProperty.injectDOMPropertyConfig(o),Q.DOMProperty.injectDOMPropertyConfig(w),Q.EmptyComponent.injectEmptyComponent("noscript"),Q.Updates.injectReconcileTransaction(x),Q.Updates.injectBatchingStrategy(c),Q.RootIndex.injectCreateReactRootIndex(N.canUseDOM?i.createReactRootIndex:y.createReactRootIndex),Q.Component.injectEnvironment(C)}}var g=t(430),e=t(432),i=t(433),T=t(435),E=t(436),N=t(10),o=t(439),n=t(441),C=t(109),c=t(212),D=t(445),a=t(211),B=t(453),Q=t(454),r=t(48),s=t(12),x=t(458),j=t(464),y=t(465),u=t(466),w=t(463),l=!1;A.exports={inject:I}},function(A,M,t){"use strict";function I(){if(n.current){var A=n.current.getName();if(A)return" Check the render method of ` + "`" + `"+A+"` + "`" + `."}return""}function g(A,M){if(A._store&&!A._store.validated&&null==A.key){A._store.validated=!0;e("uniqueKey",A,M)}}function e(A,M,t){var g=I();if(!g){var e="string"==typeof t?t:t.displayName||t.name;e&&(g=" Check the top-level render call using <"+e+">.")}var i=D[A]||(D[A]={});if(i[g])return null;i[g]=!0;var T={parentOrOwner:g,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return M&&M._owner&&M._owner!==n.current&&(T.childOwner=" It was passed a child from "+M._owner.getName()+"."),T}function i(A,M){if("object"==typeof A)if(Array.isArray(A))for(var t=0;t/,e={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(A){var M=I(A);return A.replace(g," "+e.CHECKSUM_ATTR_NAME+'="'+M+'"$&')},canReuseMarkup:function(A,M){var t=M.getAttribute(e.CHECKSUM_ATTR_NAME);t=t&&parseInt(t,10);var g=I(A);return g===t}};A.exports=e},function(A,M,t){"use strict";var I=t(59),g=I({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,SET_MARKUP:null,TEXT_CONTENT:null});A.exports=g},function(A,M,t){"use strict";function I(A){if("function"==typeof A.type)return A.type;var M=A.type,t=n[M];return null==t&&(n[M]=t=N(M)),t}function g(A){return o?void 0:E(!1),new o(A.type,A.props)}function e(A){return new C(A)}function i(A){return A instanceof C}var T=t(4),E=t(2),N=null,o=null,n={},C=null,c={injectGenericComponentClass:function(A){o=A},injectTextComponentClass:function(A){C=A},injectComponentClasses:function(A){T(n,A)}},D={getComponentClassForElement:I,createInternalComponent:g,createInstanceForText:e,isTextComponent:i,injection:c};A.exports=D},function(A,M,t){"use strict";function I(A,M){}var g=(t(3),{isMounted:function(A){return!1},enqueueCallback:function(A,M){},enqueueForceUpdate:function(A){I(A,"forceUpdate")},enqueueReplaceState:function(A,M){I(A,"replaceState")},enqueueSetState:function(A,M){I(A,"setState")},enqueueSetProps:function(A,M){I(A,"setProps")},enqueueReplaceProps:function(A,M){I(A,"replaceProps")}});A.exports=g},function(A,M,t){"use strict";function I(A){function M(M,t,I,g,e,i){if(g=g||y,i=i||I,null==t[I]){var T=s[e];return M?new Error("Required "+T+" ` + "`" + `"+i+"` + "`" + ` was not specified in "+("` + "`" + `"+g+"` + "`" + `.")):null}return A(t,I,g,e,i)}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}function g(A){function M(M,t,I,g,e){var i=M[t],T=a(i);if(T!==A){var E=s[g],N=B(i);return new Error("Invalid "+E+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+N+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected ")+("` + "`" + `"+A+"` + "`" + `."))}return null}return I(M)}function e(){return I(x.thatReturns(null))}function i(A){function M(M,t,I,g,e){var i=M[t];if(!Array.isArray(i)){var T=s[g],E=a(i);return new Error("Invalid "+T+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+E+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected an array."))}for(var N=0;N>"}var r=t(13),s=t(70),x=t(20),j=t(118),y="<>",u={array:g("array"),bool:g("boolean"),func:g("function"),number:g("number"),object:g("object"),string:g("string"),any:e(),arrayOf:i,element:T(),instanceOf:E,node:C(),objectOf:o,oneOf:N,oneOfType:n,shape:c};A.exports=u},function(A,M){"use strict";var t={injectCreateReactRootIndex:function(A){I.createReactRootIndex=A}},I={createReactRootIndex:null,injection:t};A.exports=I},function(A,M){"use strict";var t={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(A){t.currentScrollLeft=A.x,t.currentScrollTop=A.y}};A.exports=t},function(A,M,t){"use strict";function I(A,M){if(null==M?g(!1):void 0,null==A)return M;var t=Array.isArray(A),I=Array.isArray(M);return t&&I?(A.push.apply(A,M),A):t?(A.push(M),A):I?[A].concat(M):[A,M]}var g=t(2);A.exports=I},function(A,M){"use strict";var t=function(A,M,t){Array.isArray(A)?A.forEach(M,t):A&&M.call(t,A)};A.exports=t},function(A,M,t){"use strict";function I(){return!e&&g.canUseDOM&&(e="textContent"in document.documentElement?"textContent":"innerText"),e}var g=t(10),e=null;A.exports=I},function(A,M){"use strict";function t(A){var M=A&&A.nodeName&&A.nodeName.toLowerCase();return M&&("input"===M&&I[A.type]||"textarea"===M)}var I={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};A.exports=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){for(var A=arguments.length,M=Array(A),t=0;t=0&&s.splice(M,1)}function T(A){var M=document.createElement("style");return M.type="text/css",e(A,M),M}function E(A){var M=document.createElement("link");return M.rel="stylesheet",e(A,M),M}function N(A,M){var t,I,g;if(M.singleton){var e=r++;t=Q||(Q=T(M)),I=o.bind(null,t,e,!1),g=o.bind(null,t,e,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=E(M),I=C.bind(null,t),g=function(){i(t),t.href&&URL.revokeObjectURL(t.href)}):(t=T(M),I=n.bind(null,t),g=function(){i(t)});return I(A),function(M){if(M){if(M.css===A.css&&M.media===A.media&&M.sourceMap===A.sourceMap)return;I(A=M)}else g()}}function o(A,M,t,I){var g=t?"":I.css;if(A.styleSheet)A.styleSheet.cssText=x(M,g);else{var e=document.createTextNode(g),i=A.childNodes;i[M]&&A.removeChild(i[M]),i.length?A.insertBefore(e,i[M]):A.appendChild(e)}}function n(A,M){var t=M.css,I=M.media;if(I&&A.setAttribute("media",I),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function C(A,M){var t=M.css,I=M.sourceMap;I&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(I))))+" */");var g=new Blob([t],{type:"text/css"}),e=A.href;A.href=URL.createObjectURL(g),e&&URL.revokeObjectURL(e)}var c={},D=function(A){var M;return function(){return"undefined"==typeof M&&(M=A.apply(this,arguments)),M}},a=D(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),B=D(function(){return document.head||document.getElementsByTagName("head")[0]}),Q=null,r=0,s=[];A.exports=function(A,M){M=M||{},"undefined"==typeof M.singleton&&(M.singleton=a()),"undefined"==typeof M.insertAt&&(M.insertAt="bottom");var t=g(A);return I(t,M),function(A){for(var e=[],i=0;i",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(360);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){var t={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,stopOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};A.exports=function(A,M){return"number"!=typeof M||t[A]?M:M+"px"}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M,t){return P.LoggedIn()?t():(location.pathname!==z.minioBrowserPrefix&&location.pathname!==z.minioBrowserPrefix+"/"||M(z.minioBrowserPrefix+"/login"),t())}function i(A,M){P.LoggedIn()&&M(""+z.minioBrowserPrefix)}function T(){q<2&&setTimeout(function(){document.querySelector(".page-load").classList.add("pl-"+q),q++,T()},K[q])}t(499);var E=t(1),N=g(E),o=t(16),n=g(o),C=t(485),c=g(C),D=t(125),a=g(D),B=t(230),Q=g(B),r=t(190),s=g(r),x=t(191),j=g(x),y=t(65),u=g(y),w=t(187),l=g(w),L=t(394),Y=g(L),d=t(22),h=g(d),S=t(42),z=(g(S),t(26)),p=t(19),U=I(p),O=t(255),m=g(O),F=t(245),f=g(F),k=t(241),R=g(k),J=t(498),G=(g(J),t(131)),H=g(G),b=t(60),v=g(b);window.Web=H.default;var X=(0,Q.default)(c.default)(a.default)(m.default),W=(0,h.default)(function(A){return A})(R.default),V=(0,h.default)(function(A){return A})(f.default),P=new H.default(window.location.protocol+"//"+window.location.host+z.minioBrowserPrefix+"/webrpc",X.dispatch);window.web=P,X.dispatch(U.setWeb(P));var Z=function(A){return N.default.createElement("div",null,A.children)};n.default.render(N.default.createElement(Y.default,{store:X,web:P},N.default.createElement(j.default,{history:u.default},N.default.createElement(s.default,{path:"/",component:Z},N.default.createElement(s.default,{path:"minio",component:Z},N.default.createElement(l.default,{component:W,onEnter:e}),N.default.createElement(s.default,{path:"login",component:V,onEnter:i}),N.default.createElement(s.default,{path:":bucket",component:W,onEnter:e}),N.default.createElement(s.default,{path:":bucket/*",component:W,onEnter:e}))))),document.getElementById("root"));var K=[0,400],q=0;T(),v.default.getItem("newlyUpdated")&&(X.dispatch(U.showAlert({type:"success",message:"Updated to the latest UI Version."})),v.default.removeItem("newlyUpdated"))},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=(M.currentPath,M.currentBucket),e=M.deleteConfirmation;t.RemoveObject({bucketName:g,objectName:e.object}).then(function(){A.hideDeleteConfirmation(),I(eA.removeObject(e.object))}).catch(function(A){return I(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideAlert",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAlert())}},{key:"showDeleteConfirmation",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.showDeleteConfirmation(M))}},{key:"hideDeleteConfirmation",value:function(){var A=this.props.dispatch;A(eA.hideDeleteConfirmation())}},{key:"shareObject",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.shareObject(M))}},{key:"hideShareObjectModal",value:function(){var A=this.props.dispatch;A(eA.hideShareObject())}},{key:"dataType",value:function(A,M){return NA.getDataType(A,M)}},{key:"sortObjectsByName",value:function(A){var M=this.props,t=M.dispatch,I=M.objects,g=M.sortNameOrder;t(eA.setObjects(TA.sortObjectsByName(I,!g))),t(eA.setSortNameOrder(!g))}},{key:"sortObjectsBySize",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortSizeOrder;M(eA.setObjects(TA.sortObjectsBySize(t,!I))),M(eA.setSortSizeOrder(!I))}},{key:"sortObjectsByDate",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortDateOrder;M(eA.setObjects(TA.sortObjectsByDate(t,!I))),M(eA.setSortDateOrder(!I))}},{key:"logout",value:function(A){var M=this.props.web;A.preventDefault(),M.Logout(),D.default.push(oA.minioBrowserPrefix+"/login")}},{key:"fullScreen",value:function(A){A.preventDefault();var M=document.documentElement;M.requestFullscreen&&M.requestFullscreen(),M.mozRequestFullScreen&&M.mozRequestFullScreen(),M.webkitRequestFullscreen&&M.webkitRequestFullscreen(),M.msRequestFullscreen&&M.msRequestFullscreen()}},{key:"toggleSidebar",value:function(A){this.props.dispatch(eA.setSidebarStatus(A))}},{key:"hideSidebar",value:function(A){var M=A||window.event,t=M.srcElement||M.target;3===t.nodeType&&(t=t.parentNode);var I=t.id;"feh-trigger"!==I&&this.props.dispatch(eA.setSidebarStatus(!1))}},{key:"showSettings",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showSettings())}},{key:"showMessage",value:function(){var A=this.props.dispatch;A(eA.showAlert({type:"success",message:"Link copied to clipboard!"})),this.hideShareObjectModal()}},{key:"selectTexts",value:function(){this.refs.copyTextInput.select()}},{key:"handleExpireValue",value:function(A,M){M===-1?this.refs[A].stepDown(1):this.refs[A].stepUp(1),7==this.refs.expireDays.value&&(this.refs.expireHours.value=0,this.refs.expireMins.value=0)}},{key:"checkObject",value:function(A,M){var t=this.props.dispatch;t(A.target.checked?eA.checkedObjectsAdd(M):eA.checkedObjectsRemove(M))}},{key:"downloadAll",value:function(){var A=this.props.dispatch,M={bucketName:this.props.currentBucket,objects:this.props.checkedObjects,prefix:this.props.currentPath},t=location.origin+"/minio/zip?token="+localStorage.token;this.xhr=new XMLHttpRequest,A(eA.downloadAllasZip(t,M,this.xhr))}},{key:"render",value:function(){var A=this.props.storageInfo,M=A.total,t=A.free,I=this.props,g=I.showMakeBucketModal,e=I.alert,i=I.sortNameOrder,T=I.sortSizeOrder,E=I.sortDateOrder,N=I.showAbout,n=I.showBucketPolicy,c=I.checkedObjects,D=this.props.serverInfo,a=D.version,Q=D.memory,r=D.platform,x=D.runtime,y=this.props.sidebarStatus,w=this.props.showSettings,L=this.props,d=L.policies,S=L.currentBucket,p=(L.currentPath,this.props.deleteConfirmation),U=this.props.shareObject,O=this.props,F=O.web,k=O.prefixWritable,J=O.istruncated,H=w?o.default.createElement(V.default,null):o.default.createElement("noscript",null),v=o.default.createElement(l.default,{className:(0,C.default)({alert:!0,animated:!0,fadeInDown:e.show,fadeOutUp:!e.show}),bsStyle:e.type,onDismiss:this.hideAlert.bind(this)},o.default.createElement("div",{className:"text-center"},e.message));e.message||(v="");var W=(o.default.createElement(h.default,{id:"tt-sign-out"},"Sign out"),o.default.createElement(h.default,{id:"tt-upload-file"},"Upload file")),P=o.default.createElement(h.default,{id:"tt-create-bucket"},"Create bucket"),K="",_="",AA="",tA=M-t,gA=tA/M*100+"%";F.LoggedIn()?_=o.default.createElement($.default,{fullScreenFunc:this.fullScreen.bind(this),aboutFunc:this.showAbout.bind(this),settingsFunc:this.showSettings.bind(this),logoutFunc:this.logout.bind(this)}):K=o.default.createElement("a",{className:"btn btn-danger",href:"/minio/login"},"Login"),F.LoggedIn()&&(AA=o.default.createElement("div",{className:"feh-usage"},o.default.createElement("div",{className:"fehu-chart"},o.default.createElement("div",{style:{width:gA}})),o.default.createElement("ul",null,o.default.createElement("li",null,"Used:",B.default.filesize(M-t)),o.default.createElement("li",{className:"pull-right"},"Free:",B.default.filesize(M-tA)))));var eA="";return F.LoggedIn()?eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," "))),o.default.createElement(Y.default,{placement:"left",overlay:P},o.default.createElement("a",{href:"#",className:"feba-btn feba-bucket",onClick:this.showMakeBucketModal.bind(this)},o.default.createElement("i",{className:"fa fa-hdd-o"}))))):k&&(eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," ")))))),o.default.createElement("div",{className:(0,C.default)({"file-explorer":!0,toggled:y})},o.default.createElement(R.default,{searchBuckets:this.searchBuckets.bind(this),selectBucket:this.selectBucket.bind(this),clickOutside:this.hideSidebar.bind(this),showPolicy:this.showBucketPolicy.bind(this)}),o.default.createElement("div",{className:"fe-body"},o.default.createElement("div",{className:"list-actions"+(0,C.default)({" list-actions-toggled":c.length>0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadAll.bind(this)}," Download all as zip "))),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:24,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:1,max:60,defaultValue:45})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{ -className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1?" fesl-row-selected":"";return e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",expiry:604800},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(t.objects),e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return console.log(t.checkedObjects),t}},function(A,M,t){A.exports={default:t(260),__esModule:!0}},function(A,M,t){t(270),A.exports=t(49).Object.assign; -},function(A,M,t){var I=t(80);A.exports=function(A,M){return I.create(A,M)}},function(A,M,t){t(271),A.exports=t(49).Object.keys},function(A,M,t){t(272),A.exports=t(49).Object.setPrototypeOf},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M,t){var I=t(136);A.exports=function(A){if(!I(A))throw TypeError(A+" is not an object!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(263);A.exports=Object("z").propertyIsEnumerable(0)?Object:function(A){return"String"==I(A)?A.split(""):Object(A)}},function(A,M,t){var I=t(80),g=t(137),e=t(266);A.exports=t(135)(function(){var A=Object.assign,M={},t={},I=Symbol(),g="abcdefghijklmnopqrst";return M[I]=7,g.split("").forEach(function(A){t[A]=A}),7!=A({},M)[I]||Object.keys(A({},t)).join("")!=g})?function(A,M){for(var t=g(A),i=arguments,T=i.length,E=1,N=I.getKeys,o=I.getSymbols,n=I.isEnum;T>E;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(135);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(136),e=t(262),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(134)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(267)})},function(A,M,t){var I=t(137);t(268)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(269).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;g",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(360);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){var t={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,stopOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};A.exports=function(A,M){return"number"!=typeof M||t[A]?M:M+"px"}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M,t){return P.LoggedIn()?t():(location.pathname!==z.minioBrowserPrefix&&location.pathname!==z.minioBrowserPrefix+"/"||M(z.minioBrowserPrefix+"/login"),t())}function i(A,M){P.LoggedIn()&&M(""+z.minioBrowserPrefix)}function T(){q<2&&setTimeout(function(){document.querySelector(".page-load").classList.add("pl-"+q),q++,T()},K[q])}t(499);var E=t(1),N=g(E),o=t(16),n=g(o),C=t(485),c=g(C),D=t(125),a=g(D),B=t(230),Q=g(B),r=t(190),s=g(r),x=t(191),j=g(x),y=t(65),u=g(y),w=t(187),l=g(w),L=t(394),Y=g(L),d=t(22),h=g(d),S=t(42),z=(g(S),t(26)),p=t(19),U=I(p),O=t(255),m=g(O),F=t(245),f=g(F),k=t(241),R=g(k),J=t(498),G=(g(J),t(131)),H=g(G),b=t(60),v=g(b);window.Web=H.default;var X=(0,Q.default)(c.default)(a.default)(m.default),W=(0,h.default)(function(A){return A})(R.default),V=(0,h.default)(function(A){return A})(f.default),P=new H.default(window.location.protocol+"//"+window.location.host+z.minioBrowserPrefix+"/webrpc",X.dispatch);window.web=P,X.dispatch(U.setWeb(P));var Z=function(A){return N.default.createElement("div",null,A.children)};n.default.render(N.default.createElement(Y.default,{store:X,web:P},N.default.createElement(j.default,{history:u.default},N.default.createElement(s.default,{path:"/",component:Z},N.default.createElement(s.default,{path:"minio",component:Z},N.default.createElement(l.default,{component:W,onEnter:e}),N.default.createElement(s.default,{path:"login",component:V,onEnter:i}),N.default.createElement(s.default,{path:":bucket",component:W,onEnter:e}),N.default.createElement(s.default,{path:":bucket/*",component:W,onEnter:e}))))),document.getElementById("root"));var K=[0,400],q=0;T(),v.default.getItem("newlyUpdated")&&(X.dispatch(U.showAlert({type:"success",message:"Updated to the latest UI Version."})),v.default.removeItem("newlyUpdated"))},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=M.currentPath,e=M.currentBucket,i=M.deleteConfirmation;t.RemoveObject({bucketname:e,objects:[i.object]}).then(function(){A.hideDeleteConfirmation();var M=i.object.replace(g,"");I(eA.removeObject(M))}).catch(function(A){return I(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideAlert",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAlert())}},{key:"showDeleteConfirmation",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.showDeleteConfirmation(M))}},{key:"hideDeleteConfirmation",value:function(){var A=this.props.dispatch;A(eA.hideDeleteConfirmation())}},{key:"shareObject",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.shareObject(M))}},{key:"hideShareObjectModal",value:function(){var A=this.props.dispatch;A(eA.hideShareObject())}},{key:"dataType",value:function(A,M){return NA.getDataType(A,M)}},{key:"sortObjectsByName",value:function(A){var M=this.props,t=M.dispatch,I=M.objects,g=M.sortNameOrder;t(eA.setObjects(TA.sortObjectsByName(I,!g))),t(eA.setSortNameOrder(!g))}},{key:"sortObjectsBySize",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortSizeOrder;M(eA.setObjects(TA.sortObjectsBySize(t,!I))),M(eA.setSortSizeOrder(!I))}},{key:"sortObjectsByDate",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortDateOrder;M(eA.setObjects(TA.sortObjectsByDate(t,!I))),M(eA.setSortDateOrder(!I))}},{key:"logout",value:function(A){var M=this.props.web;A.preventDefault(),M.Logout(),D.default.push(oA.minioBrowserPrefix+"/login")}},{key:"fullScreen",value:function(A){A.preventDefault();var M=document.documentElement;M.requestFullscreen&&M.requestFullscreen(),M.mozRequestFullScreen&&M.mozRequestFullScreen(),M.webkitRequestFullscreen&&M.webkitRequestFullscreen(),M.msRequestFullscreen&&M.msRequestFullscreen()}},{key:"toggleSidebar",value:function(A){this.props.dispatch(eA.setSidebarStatus(A))}},{key:"hideSidebar",value:function(A){var M=A||window.event,t=M.srcElement||M.target;3===t.nodeType&&(t=t.parentNode);var I=t.id;"feh-trigger"!==I&&this.props.dispatch(eA.setSidebarStatus(!1))}},{key:"showSettings",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showSettings())}},{key:"showMessage",value:function(){var A=this.props.dispatch;A(eA.showAlert({type:"success",message:"Link copied to clipboard!"})),this.hideShareObjectModal()}},{key:"selectTexts",value:function(){this.refs.copyTextInput.select()}},{key:"handleExpireValue",value:function(A,M){M===-1?this.refs[A].stepDown(1):this.refs[A].stepUp(1),7==this.refs.expireDays.value&&(this.refs.expireHours.value=0,this.refs.expireMins.value=0)}},{key:"checkObject",value:function(A,M){var t=this.props.dispatch;t(A.target.checked?eA.checkedObjectsAdd(M):eA.checkedObjectsRemove(M))}},{key:"downloadAll",value:function(){var A=this.props.dispatch,M={bucketName:this.props.currentBucket,objects:this.props.checkedObjects,prefix:this.props.currentPath},t=location.origin+"/minio/zip?token="+localStorage.token;this.xhr=new XMLHttpRequest,A(eA.downloadAllasZip(t,M,this.xhr))}},{key:"render",value:function(){var A=this.props.storageInfo,M=A.total,t=A.free,I=this.props,g=I.showMakeBucketModal,e=I.alert,i=I.sortNameOrder,T=I.sortSizeOrder,E=I.sortDateOrder,N=I.showAbout,n=I.showBucketPolicy,c=I.checkedObjects,D=this.props.serverInfo,a=D.version,Q=D.memory,r=D.platform,x=D.runtime,y=this.props.sidebarStatus,w=this.props.showSettings,L=this.props,d=L.policies,S=L.currentBucket,p=(L.currentPath,this.props.deleteConfirmation),U=this.props.shareObject,O=this.props,F=O.web,k=O.prefixWritable,J=O.istruncated,H=w?o.default.createElement(V.default,null):o.default.createElement("noscript",null),v=o.default.createElement(l.default,{className:(0,C.default)({alert:!0,animated:!0,fadeInDown:e.show,fadeOutUp:!e.show}),bsStyle:e.type,onDismiss:this.hideAlert.bind(this)},o.default.createElement("div",{className:"text-center"},e.message));e.message||(v="");var W=(o.default.createElement(h.default,{id:"tt-sign-out"},"Sign out"),o.default.createElement(h.default,{id:"tt-upload-file"},"Upload file")),P=o.default.createElement(h.default,{id:"tt-create-bucket"},"Create bucket"),K="",_="",AA="",tA=M-t,gA=tA/M*100+"%";F.LoggedIn()?_=o.default.createElement($.default,{fullScreenFunc:this.fullScreen.bind(this),aboutFunc:this.showAbout.bind(this),settingsFunc:this.showSettings.bind(this),logoutFunc:this.logout.bind(this)}):K=o.default.createElement("a",{className:"btn btn-danger",href:"/minio/login"},"Login"),F.LoggedIn()&&(AA=o.default.createElement("div",{className:"feh-usage"},o.default.createElement("div",{className:"fehu-chart"},o.default.createElement("div",{style:{width:gA}})),o.default.createElement("ul",null,o.default.createElement("li",null,"Used:",B.default.filesize(M-t)),o.default.createElement("li",{className:"pull-right"},"Free:",B.default.filesize(M-tA)))));var eA="";return F.LoggedIn()?eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," "))),o.default.createElement(Y.default,{placement:"left",overlay:P},o.default.createElement("a",{href:"#",className:"feba-btn feba-bucket",onClick:this.showMakeBucketModal.bind(this)},o.default.createElement("i",{className:"fa fa-hdd-o"}))))):k&&(eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," ")))))),o.default.createElement("div",{className:(0,C.default)({"file-explorer":!0,toggled:y})},o.default.createElement(R.default,{searchBuckets:this.searchBuckets.bind(this),selectBucket:this.selectBucket.bind(this),clickOutside:this.hideSidebar.bind(this),showPolicy:this.showBucketPolicy.bind(this)}),o.default.createElement("div",{className:"fe-body"},o.default.createElement("div",{className:"list-actions"+(0,C.default)({" list-actions-toggled":c.length>0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadAll.bind(this)}," Download all as zip "))),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:24,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:1,max:60,defaultValue:45})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{ +href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1?" fesl-row-selected":"";return e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",expiry:604800},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return t}},function(A,M,t){A.exports={default:t(260),__esModule:!0}},function(A,M,t){t(270), +A.exports=t(49).Object.assign},function(A,M,t){var I=t(80);A.exports=function(A,M){return I.create(A,M)}},function(A,M,t){t(271),A.exports=t(49).Object.keys},function(A,M,t){t(272),A.exports=t(49).Object.setPrototypeOf},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M,t){var I=t(136);A.exports=function(A){if(!I(A))throw TypeError(A+" is not an object!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(263);A.exports=Object("z").propertyIsEnumerable(0)?Object:function(A){return"String"==I(A)?A.split(""):Object(A)}},function(A,M,t){var I=t(80),g=t(137),e=t(266);A.exports=t(135)(function(){var A=Object.assign,M={},t={},I=Symbol(),g="abcdefghijklmnopqrst";return M[I]=7,g.split("").forEach(function(A){t[A]=A}),7!=A({},M)[I]||Object.keys(A({},t)).join("")!=g})?function(A,M){for(var t=g(A),i=arguments,T=i.length,E=1,N=I.getKeys,o=I.getSymbols,n=I.isEnum;T>E;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(135);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(136),e=t(262),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(134)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(267)})},function(A,M,t){var I=t(137);t(268)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(269).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;g1&&(I=t[0]+"@",A=t[1]),A=A.replace(z,".");var g=A.split("."),e=T(g,M).join(".");return I+e}function N(A){for(var M,t,I=[],g=0,e=A.length;g=55296&&M<=56319&&g65535&&(A-=65536,M+=m(A>>>10&1023|55296),A=56320|1023&A),M+=m(A)}).join("")}function n(A){return A-48<10?A-22:A-65<26?A-65:A-97<26?A-97:j}function C(A,M){return A+22+75*(A<26)-((0!=M)<<5)}function c(A,M,t){var I=0;for(A=t?O(A/l):A>>1,A+=O(A/M);A>U*u>>1;I+=j)A=O(A/U);return O(I+(U+1)*A/(A+w))}function D(A){var M,t,I,g,e,T,E,N,C,D,a=[],B=A.length,Q=0,r=Y,s=L;for(t=A.lastIndexOf(d),t<0&&(t=0),I=0;I=128&&i("not-basic"),a.push(A.charCodeAt(I));for(g=t>0?t+1:0;g=B&&i("invalid-input"),N=n(A.charCodeAt(g++)),(N>=j||N>O((x-Q)/T))&&i("overflow"),Q+=N*T,C=E<=s?y:E>=s+u?u:E-s,!(NO(x/D)&&i("overflow"),T*=D;M=a.length+1,s=c(Q-e,M,0==e),O(Q/M)>x-r&&i("overflow"),r+=O(Q/M),Q%=M,a.splice(Q++,0,r)}return o(a)}function a(A){var M,t,I,g,e,T,E,o,n,D,a,B,Q,r,s,w=[];for(A=N(A),B=A.length,M=Y,t=0,e=L,T=0;T=M&&aO((x-t)/Q)&&i("overflow"),t+=(E-M)*Q,M=E,T=0;Tx&&i("overflow"),a==M){for(o=t,n=j;D=n<=e?y:n>=e+u?u:n-e,!(o= 0x80 (not a basic code point)","invalid-input":"Invalid input"},U=j-y,O=Math.floor,m=String.fromCharCode;s={version:"1.3.2",ucs2:{decode:N,encode:o},decode:D,encode:a,toASCII:Q,toUnicode:B},I=function(){return s}.call(M,t,M,A),!(void 0!==I&&(A.exports=I))}(this)}).call(M,t(128)(A),function(){return this}())},function(A,M){"use strict";A.exports={isString:function(A){return"string"==typeof A},isObject:function(A){return"object"==typeof A&&null!==A},isNull:function(A){return null===A},isNullOrUndefined:function(A){return null==A}}}]);`) -func productionIndex_bundle20170223t004442zJsBytes() ([]byte, error) { - return _productionIndex_bundle20170223t004442zJs, nil +func productionIndex_bundle20170304t010753zJsBytes() ([]byte, error) { + return _productionIndex_bundle20170304t010753zJs, nil } -func productionIndex_bundle20170223t004442zJs() (*asset, error) { - bytes, err := productionIndex_bundle20170223t004442zJsBytes() +func productionIndex_bundle20170304t010753zJs() (*asset, error) { + bytes, err := productionIndex_bundle20170304t010753zJsBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "production/index_bundle-2017-02-23T00-44-42Z.js", size: 2282928, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/index_bundle-2017-03-04T01-07-53Z.js", size: 2282905, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -370,7 +370,7 @@ func productionLoaderCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -444,7 +444,7 @@ func productionLogoSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -461,7 +461,7 @@ func productionSafariPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1487810698, 0)} + info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -522,7 +522,7 @@ var _bindata = map[string]func() (*asset, error){ "production/favicon.ico": productionFaviconIco, "production/firefox.png": productionFirefoxPng, "production/index.html": productionIndexHTML, - "production/index_bundle-2017-02-23T00-44-42Z.js": productionIndex_bundle20170223t004442zJs, + "production/index_bundle-2017-03-04T01-07-53Z.js": productionIndex_bundle20170304t010753zJs, "production/loader.css": productionLoaderCss, "production/logo.svg": productionLogoSvg, "production/safari.png": productionSafariPng, @@ -574,7 +574,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "favicon.ico": {productionFaviconIco, map[string]*bintree{}}, "firefox.png": {productionFirefoxPng, map[string]*bintree{}}, "index.html": {productionIndexHTML, map[string]*bintree{}}, - "index_bundle-2017-02-23T00-44-42Z.js": {productionIndex_bundle20170223t004442zJs, map[string]*bintree{}}, + "index_bundle-2017-03-04T01-07-53Z.js": {productionIndex_bundle20170304t010753zJs, map[string]*bintree{}}, "loader.css": {productionLoaderCss, map[string]*bintree{}}, "logo.svg": {productionLogoSvg, map[string]*bintree{}}, "safari.png": {productionSafariPng, map[string]*bintree{}}, @@ -635,6 +635,6 @@ func assetFS() *assetfs.AssetFS { panic("unreachable") } -var UIReleaseTag = "RELEASE.2017-02-23T00-44-42Z" -var UICommitID = "52d6678bf0d1442d0ab9b7bc63b47ceda69d0e4a" -var UIVersion = "2017-02-23T00:44:42Z" +var UIReleaseTag = "RELEASE.2017-03-04T01-07-53Z" +var UICommitID = "0bae3330e8c8910c69e8229a3f0268e6127b6982" +var UIVersion = "2017-03-04T01:07:53Z" From e3fd4c0dd67562e931ac613303e70229831863ae Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Sun, 5 Mar 2017 04:23:28 +0530 Subject: [PATCH 55/94] XL: Make listOnlineDisks and outDatedDisks consistent w/ each other. (#3808) --- cmd/xl-v1-healing-common.go | 117 +++++++++++---- cmd/xl-v1-healing-common_test.go | 249 +++++++++++++++++++++++++++++++ cmd/xl-v1-healing.go | 68 ++++++--- cmd/xl-v1-object_test.go | 6 + 4 files changed, 393 insertions(+), 47 deletions(-) diff --git a/cmd/xl-v1-healing-common.go b/cmd/xl-v1-healing-common.go index d652bc462..38f79ba6a 100644 --- a/cmd/xl-v1-healing-common.go +++ b/cmd/xl-v1-healing-common.go @@ -16,7 +16,11 @@ package cmd -import "time" +import ( + "encoding/hex" + "path/filepath" + "time" +) // commonTime returns a maximally occurring time from a list of time. func commonTime(modTimes []time.Time) (modTime time.Time, count int) { @@ -59,29 +63,43 @@ func bootModtimes(diskCount int) []time.Time { } // Extracts list of times from xlMetaV1 slice and returns, skips -// slice elements which have errors. As a special error -// errFileNotFound is treated as a initial good condition. +// slice elements which have errors. func listObjectModtimes(partsMetadata []xlMetaV1, errs []error) (modTimes []time.Time) { modTimes = bootModtimes(len(partsMetadata)) - // Set a new time value, specifically set when - // error == errFileNotFound (this is needed when this is a - // fresh PutObject). - timeNow := time.Now().UTC() for index, metadata := range partsMetadata { - if errs[index] == nil { - // Once the file is found, save the uuid saved on disk. - modTimes[index] = metadata.Stat.ModTime - } else if errs[index] == errFileNotFound { - // Once the file is not found then the epoch is current time. - modTimes[index] = timeNow + if errs[index] != nil { + continue } + // Once the file is found, save the uuid saved on disk. + modTimes[index] = metadata.Stat.ModTime } return modTimes } -// Returns slice of online disks needed. -// - slice returing readable disks. -// - modTime of the Object +// Notes: +// There are 5 possible states a disk could be in, +// 1. __online__ - has the latest copy of xl.json - returned by listOnlineDisks +// +// 2. __offline__ - err == errDiskNotFound +// +// 3. __availableWithParts__ - has the latest copy of xl.json and has all +// parts with checksums matching; returned by disksWithAllParts +// +// 4. __outdated__ - returned by outDatedDisk, provided []StorageAPI +// returned by diskWithAllParts is passed for latestDisks. +// - has an old copy of xl.json +// - doesn't have xl.json (errFileNotFound) +// - has the latest xl.json but one or more parts are corrupt +// +// 5. __missingParts__ - has the latest copy of xl.json but has some parts +// missing. This is identified separately since this may need manual +// inspection to understand the root cause. E.g, this could be due to +// backend filesystem corruption. + +// listOnlineDisks - returns +// - a slice of disks where disk having 'older' xl.json (or nothing) +// are set to nil. +// - latest (in time) of the maximally occurring modTime(s). func listOnlineDisks(disks []StorageAPI, partsMetadata []xlMetaV1, errs []error) (onlineDisks []StorageAPI, modTime time.Time) { onlineDisks = make([]StorageAPI, len(disks)) @@ -102,22 +120,23 @@ func listOnlineDisks(disks []StorageAPI, partsMetadata []xlMetaV1, errs []error) return onlineDisks, modTime } -// Return disks with the outdated or missing object. -func outDatedDisks(disks []StorageAPI, partsMetadata []xlMetaV1, errs []error) (outDatedDisks []StorageAPI) { +// outDatedDisks - return disks which don't have the latest object (i.e xl.json). +// disks that are offline are not 'marked' outdated. +func outDatedDisks(disks, latestDisks []StorageAPI, errs []error, partsMetadata []xlMetaV1, + bucket, object string) (outDatedDisks []StorageAPI) { + outDatedDisks = make([]StorageAPI, len(disks)) - latestDisks, _ := listOnlineDisks(disks, partsMetadata, errs) - for index, disk := range latestDisks { - if errorCause(errs[index]) == errFileNotFound { - outDatedDisks[index] = disks[index] + for index, latestDisk := range latestDisks { + if latestDisk != nil { continue } - if errs[index] != nil { - continue - } - if disk == nil { + // disk either has an older xl.json or doesn't have one. + switch errorCause(errs[index]) { + case nil, errFileNotFound: outDatedDisks[index] = disks[index] } } + return outDatedDisks } @@ -189,3 +208,49 @@ func xlHealStat(xl xlObjects, partsMetadata []xlMetaV1, errs []error) HealObject MissingPartityCount: missingParityCount, } } + +// disksWithAllParts - This function needs to be called with +// []StorageAPI returned by listOnlineDisks. Returns, +// - disks which have all parts specified in the latest xl.json. +// - errs updated to have errFileNotFound in place of disks that had +// missing parts. +// - non-nil error if any of the online disks failed during +// calculating blake2b checksum. +func disksWithAllParts(onlineDisks []StorageAPI, partsMetadata []xlMetaV1, errs []error, bucket, object string) ([]StorageAPI, []error, error) { + availableDisks := make([]StorageAPI, len(onlineDisks)) + for index, onlineDisk := range onlineDisks { + if onlineDisk == nil { + continue + } + // disk has a valid xl.json but may not have all the + // parts. This is considered an outdated disk, since + // it needs healing too. + for pIndex, part := range partsMetadata[index].Parts { + // compute blake2b sum of part. + partPath := filepath.Join(object, part.Name) + hash := newHash(blake2bAlgo) + blakeBytes, hErr := hashSum(onlineDisk, bucket, partPath, hash) + if hErr == errFileNotFound { + errs[index] = errFileNotFound + continue + } + + if hErr != nil && hErr != errFileNotFound { + return nil, nil, traceError(hErr) + } + + partChecksum := partsMetadata[index].Erasure.Checksum[pIndex].Hash + blakeSum := hex.EncodeToString(blakeBytes) + // if blake2b sum doesn't match for a part + // then this disk is outdated and needs + // healing. + if blakeSum != partChecksum { + errs[index] = errFileNotFound + break + } + availableDisks[index] = onlineDisk + } + } + + return availableDisks, errs, nil +} diff --git a/cmd/xl-v1-healing-common_test.go b/cmd/xl-v1-healing-common_test.go index be7f200b9..7a3c63db7 100644 --- a/cmd/xl-v1-healing-common_test.go +++ b/cmd/xl-v1-healing-common_test.go @@ -17,6 +17,8 @@ package cmd import ( + "bytes" + "path/filepath" "testing" "time" ) @@ -81,3 +83,250 @@ func TestCommonTime(t *testing.T) { } } } + +// partsMetaFromModTimes - returns slice of modTimes given metadata of +// an object part. +func partsMetaFromModTimes(modTimes []time.Time, checksums []checkSumInfo) []xlMetaV1 { + var partsMetadata []xlMetaV1 + for _, modTime := range modTimes { + partsMetadata = append(partsMetadata, xlMetaV1{ + Erasure: erasureInfo{ + Checksum: checksums, + }, + Stat: statInfo{ + ModTime: modTime, + }, + Parts: []objectPartInfo{ + { + Name: "part.1", + }, + }, + }) + } + return partsMetadata +} + +// toPosix - fetches *posix object from StorageAPI. +func toPosix(disk StorageAPI) *posix { + retryDisk, ok := disk.(*retryStorage) + if !ok { + return nil + } + pDisk, ok := retryDisk.remoteStorage.(*posix) + if !ok { + return nil + } + return pDisk + +} + +// TestListOnlineDisks - checks if listOnlineDisks and outDatedDisks +// are consistent with each other. +func TestListOnlineDisks(t *testing.T) { + rootPath, err := newTestConfig(globalMinioDefaultRegion) + if err != nil { + t.Fatalf("Failed to initialize config - %v", err) + } + defer removeAll(rootPath) + + obj, disks, err := prepareXL() + if err != nil { + t.Fatalf("Prepare XL backend failed - %v", err) + } + defer removeRoots(disks) + + type tamperKind int + const ( + noTamper tamperKind = iota + deletePart tamperKind = iota + corruptPart tamperKind = iota + ) + threeNanoSecs := time.Unix(0, 3).UTC() + fourNanoSecs := time.Unix(0, 4).UTC() + modTimesThreeNone := []time.Time{ + threeNanoSecs, threeNanoSecs, threeNanoSecs, threeNanoSecs, + threeNanoSecs, threeNanoSecs, threeNanoSecs, + timeSentinel, timeSentinel, timeSentinel, timeSentinel, + timeSentinel, timeSentinel, timeSentinel, timeSentinel, + timeSentinel, + } + modTimesThreeFour := []time.Time{ + threeNanoSecs, threeNanoSecs, threeNanoSecs, threeNanoSecs, + threeNanoSecs, threeNanoSecs, threeNanoSecs, threeNanoSecs, + fourNanoSecs, fourNanoSecs, fourNanoSecs, fourNanoSecs, + fourNanoSecs, fourNanoSecs, fourNanoSecs, fourNanoSecs, + } + testCases := []struct { + modTimes []time.Time + expectedTime time.Time + errs []error + _tamperBackend tamperKind + }{ + { + modTimes: modTimesThreeFour, + expectedTime: fourNanoSecs, + errs: []error{ + nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, + }, + _tamperBackend: noTamper, + }, + { + modTimes: modTimesThreeNone, + expectedTime: threeNanoSecs, + errs: []error{ + // Disks that have a valid xl.json. + nil, nil, nil, nil, nil, nil, nil, + // Majority of disks don't have xl.json. + errFileNotFound, errFileNotFound, + errFileNotFound, errFileNotFound, + errFileNotFound, errDiskAccessDenied, + errDiskNotFound, errFileNotFound, + errFileNotFound, + }, + _tamperBackend: deletePart, + }, + { + modTimes: modTimesThreeNone, + expectedTime: threeNanoSecs, + errs: []error{ + // Disks that have a valid xl.json. + nil, nil, nil, nil, nil, nil, nil, + // Majority of disks don't have xl.json. + errFileNotFound, errFileNotFound, + errFileNotFound, errFileNotFound, + errFileNotFound, errDiskAccessDenied, + errDiskNotFound, errFileNotFound, + errFileNotFound, + }, + _tamperBackend: corruptPart, + }, + } + + bucket := "bucket" + object := "object" + data := bytes.Repeat([]byte("a"), 1024) + xlDisks := obj.(*xlObjects).storageDisks + for i, test := range testCases { + // Prepare bucket/object backend for the tests below. + + // Cleanup from previous test. + obj.DeleteObject(bucket, object) + obj.DeleteBucket(bucket) + + err = obj.MakeBucket("bucket") + if err != nil { + t.Fatalf("Failed to make a bucket %v", err) + } + + _, err = obj.PutObject(bucket, object, int64(len(data)), bytes.NewReader(data), nil, "") + if err != nil { + t.Fatalf("Failed to putObject %v", err) + } + + // Fetch xl.json from first disk to construct partsMetadata for the tests. + xlMeta, err := readXLMeta(xlDisks[0], bucket, object) + if err != nil { + t.Fatalf("Test %d: Failed to read xl.json %v", i+1, err) + } + + tamperedIndex := -1 + switch test._tamperBackend { + case deletePart: + for index, err := range test.errs { + if err != nil { + continue + } + // Remove a part from a disk + // which has a valid xl.json, + // and check if that disk + // appears in outDatedDisks. + tamperedIndex = index + dErr := xlDisks[index].DeleteFile(bucket, filepath.Join(object, "part.1")) + if dErr != nil { + t.Fatalf("Test %d: Failed to delete %s - %v", i+1, + filepath.Join(object, "part.1"), dErr) + } + break + } + case corruptPart: + for index, err := range test.errs { + if err != nil { + continue + } + // Corrupt a part from a disk + // which has a valid xl.json, + // and check if that disk + // appears in outDatedDisks. + tamperedIndex = index + dErr := xlDisks[index].AppendFile(bucket, filepath.Join(object, "part.1"), []byte("corruption")) + if dErr != nil { + t.Fatalf("Test %d: Failed to append corrupting data at the end of file %s - %v", + i+1, filepath.Join(object, "part.1"), dErr) + } + break + } + + } + + partsMetadata := partsMetaFromModTimes(test.modTimes, xlMeta.Erasure.Checksum) + + onlineDisks, modTime := listOnlineDisks(xlDisks, partsMetadata, test.errs) + availableDisks, newErrs, err := disksWithAllParts(onlineDisks, partsMetadata, test.errs, bucket, object) + test.errs = newErrs + outdatedDisks := outDatedDisks(xlDisks, availableDisks, test.errs, partsMetadata, bucket, object) + if modTime.Equal(timeSentinel) { + t.Fatalf("Test %d: modTime should never be equal to timeSentinel, but found equal", + i+1) + } + + if test._tamperBackend != noTamper { + if tamperedIndex != -1 && outdatedDisks[tamperedIndex] == nil { + t.Fatalf("Test %d: disk (%v) with part.1 missing is an outdated disk, but wasn't listed by outDatedDisks", + i+1, xlDisks[tamperedIndex]) + } + + } + + if !modTime.Equal(test.expectedTime) { + t.Fatalf("Test %d: Expected modTime to be equal to %v but was found to be %v", + i+1, test.expectedTime, modTime) + } + + // Check if a disk is considered both online and outdated, + // which is a contradiction, except if parts are missing. + overlappingDisks := make(map[string]*posix) + for _, availableDisk := range availableDisks { + if availableDisk == nil { + continue + } + pDisk := toPosix(availableDisk) + overlappingDisks[pDisk.diskPath] = pDisk + } + + for index, outdatedDisk := range outdatedDisks { + // ignore the intentionally tampered disk, + // this is expected to appear as outdated + // disk, since it doesn't have all the parts. + if index == tamperedIndex { + continue + } + + if outdatedDisk == nil { + continue + } + + pDisk := toPosix(outdatedDisk) + if _, ok := overlappingDisks[pDisk.diskPath]; ok { + t.Errorf("Test %d: Outdated disk %v was also detected as an online disk - %v %v", + i+1, pDisk, availableDisks, outdatedDisks) + } + + // errors other than errFileNotFound doesn't imply that the disk is outdated. + if test.errs[index] != nil && test.errs[index] != errFileNotFound && outdatedDisk != nil { + t.Errorf("Test %d: error (%v) other than errFileNotFound doesn't imply that the disk (%v) could be outdated", + i+1, test.errs[index], pDisk) + } + } + } +} diff --git a/cmd/xl-v1-healing.go b/cmd/xl-v1-healing.go index db8ba2fdd..c815349d7 100644 --- a/cmd/xl-v1-healing.go +++ b/cmd/xl-v1-healing.go @@ -311,6 +311,9 @@ func quickHeal(storageDisks []StorageAPI, writeQuorum int, readQuorum int) error // Heals an object only the corrupted/missing erasure blocks. func healObject(storageDisks []StorageAPI, bucket string, object string, quorum int) error { partsMetadata, errs := readAllXLMetadata(storageDisks, bucket, object) + // readQuorum suffices for xl.json since we use monotonic + // system time to break the tie when a split-brain situation + // arises. if reducedErr := reduceReadQuorumErrs(errs, nil, quorum); reducedErr != nil { return toObjectErr(reducedErr, bucket, object) } @@ -322,12 +325,35 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum // List of disks having latest version of the object. latestDisks, modTime := listOnlineDisks(storageDisks, partsMetadata, errs) + + // List of disks having all parts as per latest xl.json. + availableDisks, errs, aErr := disksWithAllParts(latestDisks, partsMetadata, errs, bucket, object) + if aErr != nil { + return toObjectErr(aErr, bucket, object) + } + + numAvailableDisks := 0 + for _, disk := range availableDisks { + if disk != nil { + numAvailableDisks++ + } + } + + // If less than read quorum number of disks have all the parts + // of the data, we can't reconstruct the erasure-coded data. + if numAvailableDisks < quorum { + return toObjectErr(errXLReadQuorum, bucket, object) + } + // List of disks having outdated version of the object or missing object. - outDatedDisks := outDatedDisks(storageDisks, partsMetadata, errs) - // Latest xlMetaV1 for reference. If a valid metadata is not present, it is as good as object not found. + outDatedDisks := outDatedDisks(storageDisks, availableDisks, errs, partsMetadata, + bucket, object) + + // Latest xlMetaV1 for reference. If a valid metadata is not + // present, it is as good as object not found. latestMeta, pErr := pickValidXLMeta(partsMetadata, modTime) if pErr != nil { - return pErr + return toObjectErr(pErr, bucket, object) } for index, disk := range outDatedDisks { @@ -357,16 +383,16 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum // Delete all the parts. Ignore if parts are not found. for _, part := range outDatedMeta.Parts { - err := disk.DeleteFile(bucket, pathJoin(object, part.Name)) - if err != nil && !isErr(err, errFileNotFound) { - return traceError(err) + dErr := disk.DeleteFile(bucket, pathJoin(object, part.Name)) + if dErr != nil && !isErr(dErr, errFileNotFound) { + return toObjectErr(traceError(dErr), bucket, object) } } // Delete xl.json file. Ignore if xl.json not found. - err := disk.DeleteFile(bucket, pathJoin(object, xlMetaJSONFile)) - if err != nil && !isErr(err, errFileNotFound) { - return traceError(err) + dErr := disk.DeleteFile(bucket, pathJoin(object, xlMetaJSONFile)) + if dErr != nil && !isErr(dErr, errFileNotFound) { + return toObjectErr(traceError(dErr), bucket, object) } } @@ -390,12 +416,12 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum erasure := latestMeta.Erasure sumInfo := latestMeta.Erasure.GetCheckSumInfo(partName) // Heal the part file. - checkSums, err := erasureHealFile(latestDisks, outDatedDisks, + checkSums, hErr := erasureHealFile(latestDisks, outDatedDisks, bucket, pathJoin(object, partName), minioMetaTmpBucket, pathJoin(tmpID, partName), partSize, erasure.BlockSize, erasure.DataBlocks, erasure.ParityBlocks, sumInfo.Algorithm) - if err != nil { - return err + if hErr != nil { + return toObjectErr(hErr, bucket, object) } for index, sum := range checkSums { if outDatedDisks[index] != nil { @@ -418,9 +444,9 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum } // Generate and write `xl.json` generated from other disks. - err := writeUniqueXLMetadata(outDatedDisks, minioMetaTmpBucket, tmpID, partsMetadata, diskCount(outDatedDisks)) - if err != nil { - return toObjectErr(err, bucket, object) + aErr = writeUniqueXLMetadata(outDatedDisks, minioMetaTmpBucket, tmpID, partsMetadata, diskCount(outDatedDisks)) + if aErr != nil { + return toObjectErr(aErr, bucket, object) } // Rename from tmp location to the actual location. @@ -429,14 +455,14 @@ func healObject(storageDisks []StorageAPI, bucket string, object string, quorum continue } // Remove any lingering partial data from current namespace. - err = disk.DeleteFile(bucket, retainSlash(object)) - if err != nil && err != errFileNotFound { - return traceError(err) + aErr = disk.DeleteFile(bucket, retainSlash(object)) + if aErr != nil && aErr != errFileNotFound { + return toObjectErr(traceError(aErr), bucket, object) } // Attempt a rename now from healed data to final location. - err = disk.RenameFile(minioMetaTmpBucket, retainSlash(tmpID), bucket, retainSlash(object)) - if err != nil { - return traceError(err) + aErr = disk.RenameFile(minioMetaTmpBucket, retainSlash(tmpID), bucket, retainSlash(object)) + if aErr != nil { + return toObjectErr(traceError(aErr), bucket, object) } } return nil diff --git a/cmd/xl-v1-object_test.go b/cmd/xl-v1-object_test.go index 1349ec985..0c30cd355 100644 --- a/cmd/xl-v1-object_test.go +++ b/cmd/xl-v1-object_test.go @@ -265,6 +265,12 @@ func TestPutObjectNoQuorum(t *testing.T) { // Tests both object and bucket healing. func TestHealing(t *testing.T) { + rootPath, err := newTestConfig(globalMinioDefaultRegion) + if err != nil { + t.Fatalf("Failed to initialize test config %v", err) + } + defer removeAll(rootPath) + obj, fsDirs, err := prepareXL() if err != nil { t.Fatal(err) From 6f931d29c44b326dba08d45b4827b3bdabb2da64 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sun, 5 Mar 2017 13:09:31 -0800 Subject: [PATCH 56/94] rpm: Add RPM spec for minio build. (#3853) Currently the package is built and hosted at https://copr.fedorainfracloud.org/coprs/minio/minio/ To enable minio repo one has to download. Fedora - 25 https://copr.fedorainfracloud.org/coprs/minio/minio/repo/fedora-25/minio-minio-fedora-25.repo Fedora - 26 https://copr.fedorainfracloud.org/coprs/minio/minio/repo/fedora-26/minio-minio-fedora-26.repo Enables for both i386 and x86_64. Fixes #3576 --- minio.spec | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 minio.spec diff --git a/minio.spec b/minio.spec new file mode 100644 index 000000000..c409f9764 --- /dev/null +++ b/minio.spec @@ -0,0 +1,83 @@ +%define tag RELEASE.2017-02-16T01-47-30Z +%define subver %(echo %{tag} | sed -e 's/[^0-9]//g') +# git fetch https://github.com/minio/minio.git refs/tags/RELEASE.2017-02-16T01-47-30Z +# git rev-list -n 1 FETCH_HEAD +%define commitid 3d98311d9f4ceb78dba996dcdc0751253241e697 +Summary: Cloud Storage Server. +Name: minio +Version: 0.0.%{subver} +Release: 1 +Vendor: Minio, Inc. +License: Apache v2.0 +Group: Applications/File +Source0: https://github.com/minio/minio/archive/%{tag}.tar.gz +URL: https://www.minio.io/ +BuildRequires: golang >= 1.7 +BuildRoot: %{tmpdir}/%{name}-%{version}-root-%(id -u -n) + +## Disable debug packages. +%define debug_package %{nil} + +## Go related tags. +%define gobuild(o:) go build -ldflags "${LDFLAGS:-}" %{?**}; +%define gopath %{_libdir}/golang +%define import_path github.com/minio/minio + +%description +Minio is an object storage server released under Apache License v2.0. +It is compatible with Amazon S3 cloud storage service. It is best +suited for storing unstructured data such as photos, videos, log +files, backups and container / VM images. Size of an object can +range from a few KBs to a maximum of 5TB. + +%prep +%setup -qc +mv %{name}-*/* . + +install -d src/$(dirname %{import_path}) +ln -s ../../.. src/%{import_path} + +%build +export GOPATH=$(pwd) + +# setup flags like 'go run buildscripts/gen-ldflags.go' would do +tag=%{tag} +version=${tag#RELEASE.} +commitid=%{commitid} +scommitid=$(echo $commitid | cut -c1-12) +prefix=%{import_path}/cmd + +LDFLAGS=" +-X $prefix.Version=$version +-X $prefix.ReleaseTag=$tag +-X $prefix.CommitID=$commitid +-X $prefix.ShortCommitID=$scommitid +" + +%gobuild -o %{name} %{import_path} + +# check that version set properly +./%{name} version | tee v + +#Version: 2016-09-11T17-42-18Z +#Release-Tag: RELEASE.2016-09-11T17-42-18Z +#Commit-ID: 85e2d886bcb005d49f3876d6849a2b5a55e03cd3 +v=$(awk '/Version:/{print $2}' v) +test "$v" = $version +v=$(awk '/Release-Tag:/{print $2}' v) +test "$v" = $tag +v=$(awk '/Commit-ID:/{print $2}' v) +test "$v" = $commitid + +%install +rm -rf $RPM_BUILD_ROOT +install -d $RPM_BUILD_ROOT%{_sbindir} +install -p %{name} $RPM_BUILD_ROOT%{_sbindir} + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(644,root,root,755) +%doc README.md README_ZH.md +%attr(755,root,root) %{_sbindir}/minio From e49efcb9d9a3a75759383b85edfe8f793ab1c44d Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 6 Mar 2017 02:00:15 -0800 Subject: [PATCH 57/94] xl: quickHeal heal bucket only when needed. (#3854) This improves the startup time significantly for clusters which have lot of buckets. Also fixes a bug where `.minio.sys` is created on disks which do not have `format.json` --- cmd/xl-v1-healing.go | 30 +++++++++++++++++------------- cmd/xl-v1.go | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/cmd/xl-v1-healing.go b/cmd/xl-v1-healing.go index c815349d7..e8d51a7e4 100644 --- a/cmd/xl-v1-healing.go +++ b/cmd/xl-v1-healing.go @@ -252,6 +252,7 @@ func (xl xlObjects) ListBucketsHeal() ([]BucketInfo, error) { if err != nil { return listBuckets, err } + // Iterate over all buckets for _, currBucket := range buckets { // Check the status of bucket metadata @@ -275,6 +276,7 @@ func (xl xlObjects) ListBucketsHeal() ([]BucketInfo, error) { } } + // Sort found buckets sort.Sort(byBucketName(listBuckets)) return listBuckets, nil @@ -284,27 +286,29 @@ func (xl xlObjects) ListBucketsHeal() ([]BucketInfo, error) { // during startup i.e healing of buckets, bucket metadata (policy.json, // notification.xml, listeners.json) etc. Currently this function // supports quick healing of buckets, bucket metadata. -// -// TODO :- -// - add support for healing dangling `uploads.json`. -// - add support for healing dangling `xl.json`. func quickHeal(storageDisks []StorageAPI, writeQuorum int, readQuorum int) error { - // List all bucket names from all disks. - bucketNames, _, err := listAllBuckets(storageDisks) + // List all bucket name occurrence from all disks. + _, bucketOcc, err := listAllBuckets(storageDisks) if err != nil { return err } - // All bucket names and bucket metadata should be healed. - for bucketName := range bucketNames { - // Heal bucket and then proceed to heal bucket metadata. - if err = healBucket(storageDisks, bucketName, writeQuorum); err == nil { - if err = healBucketMetadata(storageDisks, bucketName, readQuorum); err == nil { - continue + + // All bucket names and bucket metadata that should be healed. + for bucketName, occCount := range bucketOcc { + // Heal bucket only if healing is needed. + if occCount != len(storageDisks) { + // Heal bucket and then proceed to heal bucket metadata if any. + if err = healBucket(storageDisks, bucketName, writeQuorum); err == nil { + if err = healBucketMetadata(storageDisks, bucketName, readQuorum); err == nil { + continue + } + return err } return err } - return err } + + // Success. return nil } diff --git a/cmd/xl-v1.go b/cmd/xl-v1.go index 510662e47..afba095a6 100644 --- a/cmd/xl-v1.go +++ b/cmd/xl-v1.go @@ -151,7 +151,7 @@ func newXLObjects(storageDisks []StorageAPI) (ObjectLayer, error) { } // Initialize meta volume, if volume already exists ignores it. - if err = initMetaVolume(storageDisks); err != nil { + if err = initMetaVolume(xl.storageDisks); err != nil { return nil, fmt.Errorf("Unable to initialize '.minio.sys' meta volume, %s", err) } From 966818955eddecf19e7419637e5491068f86ae25 Mon Sep 17 00:00:00 2001 From: Rushan Date: Tue, 7 Mar 2017 05:13:43 +0530 Subject: [PATCH 58/94] Browser: Implement multiple object delete (#3859) --- browser/app/js/actions.js | 3 +- browser/app/js/components/Browse.js | 49 ++++++++++++++++++++---- browser/app/js/components/ObjectsList.js | 32 +++++++++++----- browser/app/less/inc/list.less | 3 +- 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/browser/app/js/actions.js b/browser/app/js/actions.js index cb2518f09..ebf606089 100644 --- a/browser/app/js/actions.js +++ b/browser/app/js/actions.js @@ -412,13 +412,14 @@ export const setLoginError = () => { } } -export const downloadAllasZip = (url, req, xhr) => { +export const downloadSelected = (url, req, xhr) => { return (dispatch) => { xhr.open('POST', url, true) xhr.responseType = 'blob' xhr.onload = function(e) { if (this.status == 200) { + dispatch(checkedObjectsReset()) var blob = new Blob([this.response], { type: 'application/zip' }) diff --git a/browser/app/js/components/Browse.js b/browser/app/js/components/Browse.js index 0810ca149..adf89a6a1 100644 --- a/browser/app/js/components/Browse.js +++ b/browser/app/js/components/Browse.js @@ -226,15 +226,43 @@ export default class Browse extends React.Component { } removeObject() { - const {web, dispatch, currentPath, currentBucket, deleteConfirmation} = this.props + const {web, dispatch, currentPath, currentBucket, deleteConfirmation, checkedObjects} = this.props + let objects = checkedObjects.length > 0 ? checkedObjects : [deleteConfirmation.object] + web.RemoveObject({ bucketname: currentBucket, - objects: [deleteConfirmation.object] + objects: objects }) .then(() => { this.hideDeleteConfirmation() - let delObject = deleteConfirmation.object.replace(currentPath, '') - dispatch(actions.removeObject(delObject)) + if (checkedObjects.length > 0) { + for (let i = 0; i < checkedObjects.length; i++) { + dispatch(actions.removeObject(checkedObjects[i].replace(currentPath, ''))) + } + dispatch(actions.checkedObjectsReset()) + } else { + let delObject = deleteConfirmation.object.replace(currentPath, '') + dispatch(actions.removeObject(delObject)) + } + }) + .catch(e => dispatch(actions.showAlert({ + type: 'danger', + message: e.message + }))) + } + + removeObjectSelected() { + const {web, dispatch, currentPath, currentBucket, checkedObjects} = this.props + web.RemoveObject({ + bucketname: currentBucket, + objects: checkedObjects + }) + .then(() => { + this.hideDeleteConfirmation() + for (let i = 0; i < checkedObjects.length; i++) { + dispatch(actions.removeObject(checkedObjects[i].replace(currentPath, ''))) + } + dispatch(actions.checkedObjectsReset()) }) .catch(e => dispatch(actions.showAlert({ type: 'danger', @@ -368,7 +396,7 @@ export default class Browse extends React.Component { e.target.checked ? dispatch(actions.checkedObjectsAdd(objectName)) : dispatch(actions.checkedObjectsRemove(objectName)) } - downloadAll() { + downloadSelected() { const {dispatch} = this.props let req = { bucketName: this.props.currentBucket, @@ -378,7 +406,12 @@ export default class Browse extends React.Component { let requestUrl = location.origin + "/minio/zip?token=" + localStorage.token this.xhr = new XMLHttpRequest() - dispatch(actions.downloadAllasZip(requestUrl, req, this.xhr)) + dispatch(actions.downloadSelected(requestUrl, req, this.xhr)) + } + + clearSelected() { + const {dispatch} = this.props + dispatch(actions.checkedObjectsReset()) } render() { @@ -511,7 +544,9 @@ export default class Browse extends React.Component { ' list-actions-toggled': checkedObjects.length > 0 })) }> { checkedObjects.length } Objects selected - + + +
    { alertBox } diff --git a/browser/app/js/components/ObjectsList.js b/browser/app/js/components/ObjectsList.js index 44a0ea086..acba46238 100644 --- a/browser/app/js/components/ObjectsList.js +++ b/browser/app/js/components/ObjectsList.js @@ -29,23 +29,35 @@ let ObjectsList = ({objects, currentPath, selectPrefix, dataType, showDeleteConf let deleteButton = '' if (web.LoggedIn()) deleteButton = showDeleteConfirmation(e, `${currentPath}${object.name}`) }> - if (!object.name.endsWith('/')) { - actionButtons = - - - shareObject(e, `${currentPath}${object.name}`) }> - { deleteButton } - - + + if (!checkedObjectsArray.length > 0) { + if (!object.name.endsWith('/')) { + actionButtons = + + + shareObject(e, `${currentPath}${object.name}`) }> + { deleteButton } + + + } } - let activeClass = checkedObjectsArray.indexOf(object.name) > -1 ? ' fesl-row-selected' : '' + let activeClass = '' + let isChecked = '' + + if (checkedObjectsArray.indexOf(object.name) > -1) { + activeClass = ' fesl-row-selected' + isChecked = true + } return (
    - checkObject(e, object.name) } /> + checkObject(e, object.name) } />
    diff --git a/browser/app/less/inc/list.less b/browser/app/less/inc/list.less index c38dd2c66..5cb0a9ffb 100644 --- a/browser/app/less/inc/list.less +++ b/browser/app/less/inc/list.less @@ -391,7 +391,7 @@ div.fesl-row { .opacity(0); .transition(all); .transition-duration(200ms); - padding: 20px 25px; + padding: 20px 70px 20px 25px; top: 0; left: 0; width: 100%; @@ -450,6 +450,7 @@ div.fesl-row { font-size: 13px; .transition(all); .transition-duration(300ms); + margin-left: 10px; &:hover { background-color: @white; From 436db49bf392b1d21b686abb5ee6ecad4efee953 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Mon, 6 Mar 2017 18:50:25 -0800 Subject: [PATCH 59/94] Share object expiry value modification modal was not working (#3860) --- browser/app/js/actions.js | 16 ++++++--- browser/app/js/components/Browse.js | 56 ++++++++++++----------------- browser/app/js/reducers.js | 2 +- 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/browser/app/js/actions.js b/browser/app/js/actions.js index ebf606089..5ea3afbf7 100644 --- a/browser/app/js/actions.js +++ b/browser/app/js/actions.js @@ -80,11 +80,12 @@ export const hideDeleteConfirmation = () => { } } -export const showShareObject = url => { +export const showShareObject = (object, url) => { return { type: SET_SHARE_OBJECT, shareObject: { - url: url, + object, + url, show: true } } @@ -106,9 +107,10 @@ export const shareObject = (object, expiry) => (dispatch, getState) => { let bucket = currentBucket if (!web.LoggedIn()) { - dispatch(showShareObject(`${host}/${bucket}/${object}`)) + dispatch(showShareObject(object, `${host}/${bucket}/${object}`)) return } + web.PresignedGet({ host, bucket, @@ -116,7 +118,11 @@ export const shareObject = (object, expiry) => (dispatch, getState) => { expiry }) .then(obj => { - dispatch(showShareObject(obj.url)) + dispatch(showShareObject(object, obj.url)) + dispatch(showAlert({ + type: 'success', + message: `Object shared, expires in ${expiry} seconds` + })) }) .catch(err => { dispatch(showAlert({ @@ -604,4 +610,4 @@ export const checkedObjectsReset = (objectName) => { type: CHECKED_OBJECTS_RESET, objectName } -} \ No newline at end of file +} diff --git a/browser/app/js/components/Browse.js b/browser/app/js/components/Browse.js index adf89a6a1..60daf1bf5 100644 --- a/browser/app/js/components/Browse.js +++ b/browser/app/js/components/Browse.js @@ -251,25 +251,6 @@ export default class Browse extends React.Component { }))) } - removeObjectSelected() { - const {web, dispatch, currentPath, currentBucket, checkedObjects} = this.props - web.RemoveObject({ - bucketname: currentBucket, - objects: checkedObjects - }) - .then(() => { - this.hideDeleteConfirmation() - for (let i = 0; i < checkedObjects.length; i++) { - dispatch(actions.removeObject(checkedObjects[i].replace(currentPath, ''))) - } - dispatch(actions.checkedObjectsReset()) - }) - .catch(e => dispatch(actions.showAlert({ - type: 'danger', - message: e.message - }))) - } - hideAlert(e) { e.preventDefault() const {dispatch} = this.props @@ -290,7 +271,8 @@ export default class Browse extends React.Component { shareObject(e, object) { e.preventDefault() const {dispatch} = this.props - dispatch(actions.shareObject(object)) + let expiry = 5 * 24 * 60 * 60 // 5 days expiry by default + dispatch(actions.shareObject(object, expiry)) } hideShareObjectModal() { @@ -382,13 +364,19 @@ export default class Browse extends React.Component { this.refs.copyTextInput.select() } - handleExpireValue(targetInput, inc) { + handleExpireValue(targetInput, inc, object) { inc === -1 ? this.refs[targetInput].stepDown(1) : this.refs[targetInput].stepUp(1) if (this.refs.expireDays.value == 7) { this.refs.expireHours.value = 0 this.refs.expireMins.value = 0 } + if (this.refs.expireDays.value + this.refs.expireHours.value + this.refs.expireMins.value == 0) { + this.refs.expireDays.value = 7 + } + const {dispatch} = this.props + let expiry = this.refs.expireDays.value * 24 * 60 * 60 + this.refs.expireHours.value * 60 * 60 + this.refs.expireMins.value * 60 + dispatch(actions.shareObject(object, expiry)) } checkObject(e, objectName) { @@ -734,7 +722,7 @@ export default class Browse extends React.Component {
    - +
    Days
    @@ -743,12 +731,12 @@ export default class Browse extends React.Component { type="number" min={ 0 } max={ 7 } - defaultValue={ 0 } /> + defaultValue={ 5 } />
    - +
    - +
    Hours
    @@ -756,30 +744,30 @@ export default class Browse extends React.Component {
    - +
    - +
    Minutes
    + min={ 0 } + max={ 59 } + defaultValue={ 0 } />
    - +
    -
    +
    - + diff --git a/browser/app/js/reducers.js b/browser/app/js/reducers.js index 6cac5dabb..c8c21db9b 100644 --- a/browser/app/js/reducers.js +++ b/browser/app/js/reducers.js @@ -54,7 +54,7 @@ export default (state = { shareObject: { show: false, url: '', - expiry: 604800 + object: '' }, prefixWritable: false, checkedObjects: [] From bff4d294153838b6ac0a0af105182a8b3881fec4 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Tue, 7 Mar 2017 09:05:26 +0530 Subject: [PATCH 60/94] Remove commands and commandsTree global variables. (#3855) --- cmd/commands.go | 34 --------- cmd/commands_test.go | 41 ---------- cmd/main.go | 174 ++++++++++++++----------------------------- cmd/server-main.go | 82 +++++++++++++++++++- main.go | 2 +- 5 files changed, 137 insertions(+), 196 deletions(-) delete mode 100644 cmd/commands.go delete mode 100644 cmd/commands_test.go diff --git a/cmd/commands.go b/cmd/commands.go deleted file mode 100644 index b74f33f4a..000000000 --- a/cmd/commands.go +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Minio Cloud Storage, (C) 2015 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import ( - "github.com/minio/cli" - "github.com/minio/minio/pkg/trie" -) - -// Collection of minio commands currently supported are. -var commands = []cli.Command{} - -// Collection of minio commands currently supported in a trie tree. -var commandsTree = trie.NewTrie() - -// registerCommand registers a cli command. -func registerCommand(command cli.Command) { - commands = append(commands, command) - commandsTree.Insert(command.Name) -} diff --git a/cmd/commands_test.go b/cmd/commands_test.go deleted file mode 100644 index 8f7e5cb00..000000000 --- a/cmd/commands_test.go +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Minio Cloud Storage, (C) 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import ( - "testing" - - "github.com/minio/cli" -) - -// Tests register command function. -func TestRegisterCommand(t *testing.T) { - registerCommand(cli.Command{ - Name: "test1", - }) - ccount := len(commands) - if ccount != 1 { - t.Fatalf("Unexpected number of commands found %d", ccount) - } - registerCommand(cli.Command{ - Name: "test2", - }) - ccount = len(commands) - if ccount != 2 { - t.Fatalf("Unexpected number of commands found %d", ccount) - } -} diff --git a/cmd/main.go b/cmd/main.go index d31406d36..6811a451d 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,29 +17,26 @@ package cmd import ( - "fmt" "os" "sort" - "time" "github.com/minio/cli" "github.com/minio/mc/pkg/console" + "github.com/minio/minio/pkg/trie" ) -var ( - // global flags for minio. - globalFlags = []cli.Flag{ - cli.StringFlag{ - Name: "config-dir, C", - Value: getConfigDir(), - Usage: "Path to configuration directory.", - }, - cli.BoolFlag{ - Name: "quiet", - Usage: "Disable startup information.", - }, - } -) +// global flags for minio. +var globalFlags = []cli.Flag{ + cli.StringFlag{ + Name: "config-dir, C", + Value: getConfigDir(), + Usage: "Path to configuration directory.", + }, + cli.BoolFlag{ + Name: "quiet", + Usage: "Disable startup information.", + }, +} // Help template for minio. var minioHelpTemplate = `NAME: @@ -61,43 +58,42 @@ VERSION: ` + Version + `{{ "\n"}}` -func migrate() { - // Migrate config file - err := migrateConfig() - fatalIf(err, "Config migration failed.") +func newApp() *cli.App { + // Collection of minio commands currently supported are. + commands := []cli.Command{} - // Migrate other configs here. -} + // Collection of minio commands currently supported in a trie tree. + commandsTree := trie.NewTrie() -func enableLoggers() { - // Enable all loggers here. - enableConsoleLogger() - enableFileLogger() - // Add your logger here. -} - -func findClosestCommands(command string) []string { - var closestCommands []string - for _, value := range commandsTree.PrefixMatch(command) { - closestCommands = append(closestCommands, value.(string)) + // registerCommand registers a cli command. + registerCommand := func(command cli.Command) { + commands = append(commands, command) + commandsTree.Insert(command.Name) } - sort.Strings(closestCommands) - // Suggest other close commands - allow missed, wrongly added and - // even transposed characters - for _, value := range commandsTree.Walk(commandsTree.Root()) { - if sort.SearchStrings(closestCommands, value.(string)) < len(closestCommands) { - continue - } - // 2 is arbitrary and represents the max - // allowed number of typed errors - if DamerauLevenshteinDistance(command, value.(string)) < 2 { + + findClosestCommands := func(command string) []string { + var closestCommands []string + for _, value := range commandsTree.PrefixMatch(command) { closestCommands = append(closestCommands, value.(string)) } - } - return closestCommands -} -func registerApp() *cli.App { + sort.Strings(closestCommands) + // Suggest other close commands - allow missed, wrongly added and + // even transposed characters + for _, value := range commandsTree.Walk(commandsTree.Root()) { + if sort.SearchStrings(closestCommands, value.(string)) < len(closestCommands) { + continue + } + // 2 is arbitrary and represents the max + // allowed number of typed errors + if DamerauLevenshteinDistance(command, value.(string)) < 2 { + closestCommands = append(closestCommands, value.(string)) + } + } + + return closestCommands + } + // Register all commands. registerCommand(serverCmd) registerCommand(versionCmd) @@ -108,6 +104,7 @@ func registerApp() *cli.App { Name: "help, h", Usage: "Show help.", } + app := cli.NewApp() app.Name = "Minio" app.Author = "Minio.io" @@ -120,89 +117,28 @@ func registerApp() *cli.App { app.Commands = commands app.CustomAppHelpTemplate = minioHelpTemplate app.CommandNotFound = func(ctx *cli.Context, command string) { - msg := fmt.Sprintf("‘%s’ is not a minio sub-command. See ‘minio --help’.", command) + console.Printf("‘%s’ is not a minio sub-command. See ‘minio --help’.\n", command) closestCommands := findClosestCommands(command) if len(closestCommands) > 0 { - msg += fmt.Sprintf("\n\nDid you mean one of these?\n") + console.Println() + console.Println("Did you mean one of these?") for _, cmd := range closestCommands { - msg += fmt.Sprintf(" ‘%s’\n", cmd) + console.Printf("\t‘%s’\n", cmd) } } - console.Fatalln(msg) + + os.Exit(1) } + return app } -// Check for updates and print a notification message -func checkUpdate() { - // Its OK to ignore any errors during getUpdateInfo() here. - if older, downloadURL, err := getUpdateInfo(1 * time.Second); err == nil { - if older > time.Duration(0) { - console.Println(colorizeUpdateMessage(downloadURL, older)) - } - } -} - -// envParams holds all env parameters -type envParams struct { - creds credential - browser string -} - -// Initializes a new config if it doesn't exist, else migrates any old config -// to newer config and finally loads the config to memory. -func initConfig() { - - envs := envParams{ - creds: mustGetCredentialFromEnv(), - browser: mustGetBrowserFromEnv(), - } - - // Config file does not exist, we create it fresh and return upon success. - if !isConfigFileExists() { - if err := newConfig(envs); err != nil { - console.Fatalf("Unable to initialize minio config for the first time. Err: %s.\n", err) - } - console.Println("Created minio configuration file successfully at " + getConfigDir()) - return - } - - // Migrate any old version of config / state files to newer format. - migrate() - - // Once we have migrated all the old config, now load them. - if err := loadConfig(envs); err != nil { - console.Fatalf("Unable to initialize minio config. Err: %s.\n", err) - } -} - -// Generic Minio initialization to create/load config, prepare loggers, etc.. -func minioInit(ctx *cli.Context) { - // Is TLS configured?. - globalIsSSL = isSSL() - - // Initialize minio server config. - initConfig() - - // Enable all loggers by now so we can use errorIf() and fatalIf() - enableLoggers() - - // Init the error tracing module. - initError() - -} - // Main main for minio server. -func Main(args []string, exitFn func(int)) { - app := registerApp() - - // Start profiler if env is set. - if profiler := os.Getenv("_MINIO_PROFILER"); profiler != "" { - globalProfiler = startProfiler(profiler) - } +func Main(args []string) { + app := newApp() // Run the app - exit on error. if err := app.Run(args); err != nil { - exitFn(1) + os.Exit(1) } } diff --git a/cmd/server-main.go b/cmd/server-main.go index d06765d2c..df07a3225 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -21,6 +21,7 @@ import ( "fmt" "net" "net/url" + "os" "path" "sort" "strconv" @@ -83,6 +84,80 @@ EXAMPLES: `, } +// Check for updates and print a notification message +func checkUpdate() { + // Its OK to ignore any errors during getUpdateInfo() here. + if older, downloadURL, err := getUpdateInfo(1 * time.Second); err == nil { + if older > time.Duration(0) { + console.Println(colorizeUpdateMessage(downloadURL, older)) + } + } +} + +// envParams holds all env parameters +type envParams struct { + creds credential + browser string +} + +func migrate() { + // Migrate config file + err := migrateConfig() + fatalIf(err, "Config migration failed.") + + // Migrate other configs here. +} + +func enableLoggers() { + // Enable all loggers here. + enableConsoleLogger() + enableFileLogger() + // Add your logger here. +} + +// Initializes a new config if it doesn't exist, else migrates any old config +// to newer config and finally loads the config to memory. +func initConfig() { + + envs := envParams{ + creds: mustGetCredentialFromEnv(), + browser: mustGetBrowserFromEnv(), + } + + // Config file does not exist, we create it fresh and return upon success. + if !isConfigFileExists() { + if err := newConfig(envs); err != nil { + console.Fatalf("Unable to initialize minio config for the first time. Err: %s.\n", err) + } + console.Println("Created minio configuration file successfully at " + getConfigDir()) + return + } + + // Migrate any old version of config / state files to newer format. + migrate() + + // Once we have migrated all the old config, now load them. + if err := loadConfig(envs); err != nil { + console.Fatalf("Unable to initialize minio config. Err: %s.\n", err) + } +} + +// Generic Minio initialization to create/load config, prepare loggers, etc.. +func minioInit(ctx *cli.Context) { + // Is TLS configured?. + globalIsSSL = isSSL() + + // Initialize minio server config. + initConfig() + + // Enable all loggers by now so we can use errorIf() and fatalIf() + enableLoggers() + + // Init the error tracing module. + initError() + +} + type serverCmdConfig struct { serverAddr string endpoints []*url.URL @@ -368,12 +443,17 @@ func serverMain(c *cli.Context) { configDir = c.GlobalString("config-dir") } if configDir == "" { - console.Fatalf("Configuration directory cannot be empty.") + console.Fatalln("Configuration directory cannot be empty.") } // Set configuration directory. setConfigDir(configDir) + // Start profiler if env is set. + if profiler := os.Getenv("_MINIO_PROFILER"); profiler != "" { + globalProfiler = startProfiler(profiler) + } + // Initializes server config, certs, logging and system settings. initServerConfig(c) diff --git a/main.go b/main.go index 43d2a73ed..892305e51 100644 --- a/main.go +++ b/main.go @@ -65,5 +65,5 @@ func main() { console.Fatalln("Go runtime version check failed.", err) } - minio.Main(os.Args, os.Exit) + minio.Main(os.Args) } From 29ff9674a07ff3ae74fe0343348a4e2641b6ccef Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Mon, 6 Mar 2017 20:13:52 -0800 Subject: [PATCH 61/94] browser: Humanize expiry time for Share-Object. (#3861) --- browser/app/js/actions.js | 5 +++-- browser/app/js/components/Browse.js | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/browser/app/js/actions.js b/browser/app/js/actions.js index 5ea3afbf7..2aec14a5b 100644 --- a/browser/app/js/actions.js +++ b/browser/app/js/actions.js @@ -101,7 +101,7 @@ export const hideShareObject = () => { } } -export const shareObject = (object, expiry) => (dispatch, getState) => { +export const shareObject = (object, days, hours, minutes) => (dispatch, getState) => { const {currentBucket, web} = getState() let host = location.host let bucket = currentBucket @@ -111,6 +111,7 @@ export const shareObject = (object, expiry) => (dispatch, getState) => { return } + let expiry = days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 web.PresignedGet({ host, bucket, @@ -121,7 +122,7 @@ export const shareObject = (object, expiry) => (dispatch, getState) => { dispatch(showShareObject(object, obj.url)) dispatch(showAlert({ type: 'success', - message: `Object shared, expires in ${expiry} seconds` + message: `Object shared. Expires in ${days} days ${hours} hours ${minutes} minutes.` })) }) .catch(err => { diff --git a/browser/app/js/components/Browse.js b/browser/app/js/components/Browse.js index 60daf1bf5..6a8894f11 100644 --- a/browser/app/js/components/Browse.js +++ b/browser/app/js/components/Browse.js @@ -271,8 +271,8 @@ export default class Browse extends React.Component { shareObject(e, object) { e.preventDefault() const {dispatch} = this.props - let expiry = 5 * 24 * 60 * 60 // 5 days expiry by default - dispatch(actions.shareObject(object, expiry)) + // let expiry = 5 * 24 * 60 * 60 // 5 days expiry by default + dispatch(actions.shareObject(object, 5, 0, 0)) } hideShareObjectModal() { @@ -375,8 +375,7 @@ export default class Browse extends React.Component { this.refs.expireDays.value = 7 } const {dispatch} = this.props - let expiry = this.refs.expireDays.value * 24 * 60 * 60 + this.refs.expireHours.value * 60 * 60 + this.refs.expireMins.value * 60 - dispatch(actions.shareObject(object, expiry)) + dispatch(actions.shareObject(object, this.refs.expireDays.value, this.refs.expireHours.value, this.refs.expireMins.value)) } checkObject(e, objectName) { From 79e0b9e69a7a7c90238d10429e7b4d61e5f452a2 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Tue, 7 Mar 2017 21:25:40 +0100 Subject: [PATCH 62/94] Relax minio server start when disk threshold is reached and adds space check in FS (#3865) * fs: Rename tempObjPath variable in fsCreateFile() * fs/posix: Factor checkDiskFree() function * fs: Add disk free check in fsCreateFile() * posix: Move free disk check to createFile() * xl: Relax free disk check in POSIX initialization * fs: checkDiskFree checks for space to store data --- cmd/fs-v1-helpers.go | 14 +++++++++----- cmd/fs-v1.go | 46 ++------------------------------------------ cmd/posix.go | 30 ++++++++++++++--------------- 3 files changed, 25 insertions(+), 65 deletions(-) diff --git a/cmd/fs-v1-helpers.go b/cmd/fs-v1-helpers.go index a64ad4c71..85fcce0c1 100644 --- a/cmd/fs-v1-helpers.go +++ b/cmd/fs-v1-helpers.go @@ -228,20 +228,24 @@ func fsOpenFile(readPath string, offset int64) (io.ReadCloser, int64, error) { } // Creates a file and copies data from incoming reader. Staging buffer is used by io.CopyBuffer. -func fsCreateFile(tempObjPath string, reader io.Reader, buf []byte, fallocSize int64) (int64, error) { - if tempObjPath == "" || reader == nil || buf == nil { +func fsCreateFile(filePath string, reader io.Reader, buf []byte, fallocSize int64) (int64, error) { + if filePath == "" || reader == nil || buf == nil { return 0, traceError(errInvalidArgument) } - if err := checkPathLength(tempObjPath); err != nil { + if err := checkPathLength(filePath); err != nil { return 0, traceError(err) } - if err := mkdirAll(pathutil.Dir(tempObjPath), 0777); err != nil { + if err := mkdirAll(pathutil.Dir(filePath), 0777); err != nil { return 0, traceError(err) } - writer, err := os.OpenFile(preparePath(tempObjPath), os.O_CREATE|os.O_WRONLY, 0666) + if err := checkDiskFree(pathutil.Dir(filePath), fallocSize); err != nil { + return 0, traceError(err) + } + + writer, err := os.OpenFile(preparePath(filePath), os.O_CREATE|os.O_WRONLY, 0666) if err != nil { // File path cannot be verified since one of the parents is a file. if isSysErrNotDir(err) { diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index 238720b14..924fba23d 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -24,11 +24,9 @@ import ( "io" "os" "path/filepath" - "runtime" "sort" "syscall" - "github.com/minio/minio/pkg/disk" "github.com/minio/minio/pkg/lock" "github.com/minio/sha256-simd" ) @@ -42,9 +40,6 @@ type fsObjects struct { // temporary transactions. fsUUID string - minFreeSpace int64 - minFreeInodes int64 - // FS rw pool. rwPool *fsIOPool @@ -139,10 +134,8 @@ func newFSObjectLayer(fsPath string) (ObjectLayer, error) { // Initialize fs objects. fs := &fsObjects{ - fsPath: fsPath, - fsUUID: fsUUID, - minFreeSpace: fsMinFreeSpace, - minFreeInodes: fsMinFreeInodes, + fsPath: fsPath, + fsUUID: fsUUID, rwPool: &fsIOPool{ readersMap: make(map[string]*lock.RLockedFile), }, @@ -168,41 +161,6 @@ func newFSObjectLayer(fsPath string) (ObjectLayer, error) { return fs, nil } -// checkDiskFree verifies if disk path has sufficient minimum free disk space and files. -func (fs fsObjects) checkDiskFree() (err error) { - // We don't validate disk space or inode utilization on windows. - // Each windows calls to 'GetVolumeInformationW' takes around 3-5seconds. - if runtime.GOOS == globalWindowsOSName { - return nil - } - - var di disk.Info - di, err = getDiskInfo(preparePath(fs.fsPath)) - if err != nil { - return err - } - - // Remove 5% from free space for cumulative disk space used for journalling, inodes etc. - availableDiskSpace := float64(di.Free) * 0.95 - if int64(availableDiskSpace) <= fs.minFreeSpace { - return errDiskFull - } - - // Some filesystems do not implement a way to provide total inodes available, instead inodes - // are allocated based on available disk space. For example CephFS, StoreNext CVFS, AzureFile driver. - // Allow for the available disk to be separately validate and we will validate inodes only if - // total inodes are provided by the underlying filesystem. - if di.Files != 0 && di.FSType != "NFS" { - availableFiles := int64(di.Ffree) - if availableFiles <= fs.minFreeInodes { - return errDiskFull - } - } - - // Success. - return nil -} - // Should be called when process shuts down. func (fs fsObjects) Shutdown() error { // Cleanup and delete tmp uuid. diff --git a/cmd/posix.go b/cmd/posix.go index 12d9045ae..377aef646 100644 --- a/cmd/posix.go +++ b/cmd/posix.go @@ -40,11 +40,9 @@ const ( // posix - implements StorageAPI interface. type posix struct { - ioErrCount int32 // ref: https://golang.org/pkg/sync/atomic/#pkg-note-BUG - diskPath string - minFreeSpace int64 - minFreeInodes int64 - pool sync.Pool + ioErrCount int32 // ref: https://golang.org/pkg/sync/atomic/#pkg-note-BUG + diskPath string + pool sync.Pool } // checkPathLength - returns error if given path name length more than 255 @@ -109,9 +107,7 @@ func newPosix(path string) (StorageAPI, error) { return nil, err } fs := &posix{ - diskPath: diskPath, - minFreeSpace: fsMinFreeSpace, - minFreeInodes: fsMinFreeInodes, + diskPath: diskPath, // 1MiB buffer pool for posix internal operations. pool: sync.Pool{ New: func() interface{} { @@ -133,9 +129,6 @@ func newPosix(path string) (StorageAPI, error) { return nil, err } } - if err = fs.checkDiskFree(); err != nil { - return nil, err - } return fs, nil } @@ -161,7 +154,7 @@ var ignoreDiskFreeOS = []string{ } // checkDiskFree verifies if disk path has sufficient minimum free disk space and files. -func (s *posix) checkDiskFree() (err error) { +func checkDiskFree(diskPath string, neededSpace int64) (err error) { // We don't validate disk space or inode utilization on windows. // Each windows calls to 'GetVolumeInformationW' takes around 3-5seconds. // And StatFS is not supported by Go for solaris and netbsd. @@ -170,14 +163,14 @@ func (s *posix) checkDiskFree() (err error) { } var di disk.Info - di, err = getDiskInfo(preparePath(s.diskPath)) + di, err = getDiskInfo(preparePath(diskPath)) if err != nil { return err } // Remove 5% from free space for cumulative disk space used for journalling, inodes etc. availableDiskSpace := float64(di.Free) * 0.95 - if int64(availableDiskSpace) <= s.minFreeSpace { + if int64(availableDiskSpace) <= fsMinFreeSpace { return errDiskFull } @@ -187,11 +180,16 @@ func (s *posix) checkDiskFree() (err error) { // total inodes are provided by the underlying filesystem. if di.Files != 0 && di.FSType != "NFS" { availableFiles := int64(di.Ffree) - if availableFiles <= s.minFreeInodes { + if availableFiles <= fsMinFreeInodes { return errDiskFull } } + // Check if we have enough space to store data + if neededSpace > int64(availableDiskSpace) { + return errDiskFull + } + // Success. return nil } @@ -676,7 +674,7 @@ func (s *posix) PrepareFile(volume, path string, fileSize int64) (err error) { } // Validate if disk is indeed free. - if err = s.checkDiskFree(); err != nil { + if err = checkDiskFree(s.diskPath, fileSize); err != nil { return err } From a2eae54d11e33482aa77a6652a123bedf9522d4e Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Tue, 7 Mar 2017 23:48:56 +0100 Subject: [PATCH 63/94] xl: Respect min. space by checking PrepareFile err (#3867) It was possible to upload a big file which overcomes the minimal disk space limit in XL, PrepareFile was actually checking for disk space but we weren't checking its returned error. This patch fixes this behavior. --- cmd/object-api-putobject_test.go | 4 ++-- cmd/xl-v1-multipart.go | 8 +++----- cmd/xl-v1-object.go | 28 ++++++++++++++++++++++------ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/cmd/object-api-putobject_test.go b/cmd/object-api-putobject_test.go index 3a7884e27..3e889bfb9 100644 --- a/cmd/object-api-putobject_test.go +++ b/cmd/object-api-putobject_test.go @@ -179,11 +179,11 @@ func testObjectAPIPutObject(obj ObjectLayer, instanceType string, t TestErrHandl // Wrapper for calling PutObject tests for both XL multiple disks case // when quorum is not available. func TestObjectAPIPutObjectDiskNotFound(t *testing.T) { - ExecObjectLayerDiskAlteredTest(t, testObjectAPIPutObjectDiskNotFOund) + ExecObjectLayerDiskAlteredTest(t, testObjectAPIPutObjectDiskNotFound) } // Tests validate correctness of PutObject. -func testObjectAPIPutObjectDiskNotFOund(obj ObjectLayer, instanceType string, disks []string, t *testing.T) { +func testObjectAPIPutObjectDiskNotFound(obj ObjectLayer, instanceType string, disks []string, t *testing.T) { // Generating cases for which the PutObject fails. bucket := "minio-bucket" object := "minio-object" diff --git a/cmd/xl-v1-multipart.go b/cmd/xl-v1-multipart.go index fa3187695..a6816dbe4 100644 --- a/cmd/xl-v1-multipart.go +++ b/cmd/xl-v1-multipart.go @@ -648,11 +648,9 @@ func (xl xlObjects) PutObjectPart(bucket, object, uploadID string, partID int, s defer xl.deleteObject(minioMetaTmpBucket, tmpPart) if size > 0 { - for _, disk := range onlineDisks { - if disk != nil { - actualSize := xl.sizeOnDisk(size, xlMeta.Erasure.BlockSize, xlMeta.Erasure.DataBlocks) - disk.PrepareFile(minioMetaTmpBucket, tmpPartPath, actualSize) - } + if pErr := xl.prepareFile(minioMetaTmpBucket, tmpPartPath, size, onlineDisks, xlMeta.Erasure.BlockSize, xlMeta.Erasure.DataBlocks); err != nil { + return PartInfo{}, toObjectErr(pErr, bucket, object) + } } diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index 61d582330..0c85d3980 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -36,6 +36,25 @@ import ( // list all errors which can be ignored in object operations. var objectOpIgnoredErrs = append(baseIgnoredErrs, errDiskAccessDenied) +// prepareFile hints the bottom layer to optimize the creation of a new object +func (xl xlObjects) prepareFile(bucket, object string, size int64, onlineDisks []StorageAPI, blockSize int64, dataBlocks int) error { + pErrs := make([]error, len(onlineDisks)) + // Calculate the real size of the part in one disk. + actualSize := xl.sizeOnDisk(size, blockSize, dataBlocks) + // Prepare object creation in a all disks + for index, disk := range onlineDisks { + if disk != nil { + if err := disk.PrepareFile(bucket, object, actualSize); err != nil { + // Save error to reduce it later + pErrs[index] = err + // Ignore later access to disk which generated the error + onlineDisks[index] = nil + } + } + } + return reduceWriteQuorumErrs(pErrs, objectOpIgnoredErrs, xl.writeQuorum) +} + /// Object Operations // CopyObject - copy object source object to destination object. @@ -555,12 +574,9 @@ func (xl xlObjects) PutObject(bucket string, object string, size int64, data io. // Hint the filesystem to pre-allocate one continuous large block. // This is only an optimization. if curPartSize > 0 { - // Calculate the real size of the part in the disk. - actualSize := xl.sizeOnDisk(curPartSize, xlMeta.Erasure.BlockSize, xlMeta.Erasure.DataBlocks) - for _, disk := range onlineDisks { - if disk != nil { - disk.PrepareFile(minioMetaTmpBucket, tempErasureObj, actualSize) - } + pErr := xl.prepareFile(minioMetaTmpBucket, tempErasureObj, curPartSize, onlineDisks, xlMeta.Erasure.BlockSize, xlMeta.Erasure.DataBlocks) + if pErr != nil { + return ObjectInfo{}, toObjectErr(pErr, bucket, object) } } From 3e655a2c858c3eb18a4563231b661282b9f981e9 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 7 Mar 2017 15:15:05 -0800 Subject: [PATCH 64/94] docker: Add ARM docker container dockerfile. (#3574) --- .travis.yml | 21 ++++++++++++++++++++- Dockerfile | 21 +++++++++++---------- Dockerfile.armhf | 18 ++++++++++++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 Dockerfile.armhf diff --git a/.travis.yml b/.travis.yml index d6976a5b9..9d50d7dbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ go_import_path: github.com/minio/minio sudo: required +services: + - docker + dist: trusty language: go @@ -13,12 +16,28 @@ env: - ARCH=i686 script: +# Refer https://blog.hypriot.com/post/setup-simple-ci-pipeline-for-arm-images/ +# prepare qemu +- docker run --rm --privileged multiarch/qemu-user-static:register --reset +# build image +- docker build -t minio/minio:edge-armhf . -f Dockerfile.armhf +# test image +- docker run --rm minio/minio:edge-armhf version + +## Run all the tests - make - make test GOFLAGS="-timeout 15m -race -v" - make coverage +# push image +- > + if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + docker login -u="$DOCKER_USER" -p="$DOCKER_PASS" + docker push minio/minio:edge-armhf + fi + after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.7.4 +- 1.7.5 diff --git a/Dockerfile b/Dockerfile index 80a91b589..764b99821 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,17 @@ -FROM golang:1.7-alpine +FROM alpine:3.5 -WORKDIR /go/src/app +ENV GOPATH /go +ENV PATH $PATH:$GOPATH/bin +ENV CGO_ENABLED 0 -COPY . /go/src/app +WORKDIR /go/src/github.com/minio/ -RUN \ - apk add --no-cache git && \ - go-wrapper download && \ - go-wrapper install -ldflags "$(go run buildscripts/gen-ldflags.go)" && \ - mkdir -p /export/docker && \ - rm -rf /go/pkg /go/src && \ - apk del git +RUN \ + apk add --no-cache --virtual .build-deps git go musl-dev ca-certificates && \ + go get -v -d github.com/minio/minio && \ + cd /go/src/github.com/minio/minio && \ + go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \ + rm -rf /go/pkg /go/src /usr/local/go && apk del .build-deps EXPOSE 9000 ENTRYPOINT ["minio"] diff --git a/Dockerfile.armhf b/Dockerfile.armhf new file mode 100644 index 000000000..9a59d73b4 --- /dev/null +++ b/Dockerfile.armhf @@ -0,0 +1,18 @@ +FROM resin/armhf-alpine:3.5 + +ENV GOPATH /go +ENV PATH $PATH:$GOPATH/bin +ENV CGO_ENABLED 0 + +WORKDIR /go/src/github.com/minio/ + +RUN \ + apk add --no-cache --virtual .build-deps git go musl-dev ca-certificates && \ + go get -v -d github.com/minio/minio && \ + cd /go/src/github.com/minio/minio && \ + go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \ + rm -rf /go/pkg /go/src /usr/local/go && apk del .build-deps + +EXPOSE 9000 +ENTRYPOINT ["minio"] +VOLUME ["/export"] From 433225ab0d7851c6318634550e54f8d0f82cbd0d Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 7 Mar 2017 16:30:19 -0800 Subject: [PATCH 65/94] docker: ca-certificates should not be removed. (#3868) --- .travis.yml | 2 +- Dockerfile | 3 ++- Dockerfile.armhf | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d50d7dbd..18f017918 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ script: # push image - > - if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then + if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$ARCH" == "x86_64" ]; then docker login -u="$DOCKER_USER" -p="$DOCKER_PASS" docker push minio/minio:edge-armhf fi diff --git a/Dockerfile b/Dockerfile index 764b99821..4dbfc540c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,8 @@ ENV CGO_ENABLED 0 WORKDIR /go/src/github.com/minio/ RUN \ - apk add --no-cache --virtual .build-deps git go musl-dev ca-certificates && \ + apk add --no-cache ca-certificates && \ + apk add --no-cache --virtual .build-deps git go musl-dev && \ go get -v -d github.com/minio/minio && \ cd /go/src/github.com/minio/minio && \ go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \ diff --git a/Dockerfile.armhf b/Dockerfile.armhf index 9a59d73b4..6fab9a5ce 100644 --- a/Dockerfile.armhf +++ b/Dockerfile.armhf @@ -7,7 +7,8 @@ ENV CGO_ENABLED 0 WORKDIR /go/src/github.com/minio/ RUN \ - apk add --no-cache --virtual .build-deps git go musl-dev ca-certificates && \ + apk add --no-cache ca-certificates && \ + apk add --no-cache --virtual .build-deps git go musl-dev && \ go get -v -d github.com/minio/minio && \ cd /go/src/github.com/minio/minio && \ go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \ From 47ac410ab00f8ee19ac3b146d650ee559978dd37 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 8 Mar 2017 10:00:47 -0800 Subject: [PATCH 66/94] Code cleanup - simplify server side code. (#3870) Fix all the issues reported by `gosimple` tool. --- cmd/admin-handlers_test.go | 2 +- cmd/bucket-handlers.go | 5 +---- cmd/bucket-notification-handlers.go | 5 +---- cmd/format-config-v1_test.go | 8 ++------ cmd/fs-v1-metadata.go | 7 ++----- cmd/fs-v1.go | 7 +------ cmd/notifiers.go | 5 +---- cmd/object-api-common.go | 5 +---- cmd/object_api_suite_test.go | 8 ++++---- cmd/signature-v4-parser_test.go | 2 +- cmd/test-utils_test.go | 4 +--- cmd/web-handlers_test.go | 6 +++--- cmd/xl-v1-list-objects-heal.go | 2 +- cmd/xl-v1.go | 7 +------ 14 files changed, 21 insertions(+), 52 deletions(-) diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index 7b1a20f99..b3128cfc8 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -1184,7 +1184,7 @@ func TestSetConfigHandler(t *testing.T) { t.Fatalf("Failed to decode set config result json %v", err) } - if result.Status != true { + if !result.Status { t.Error("Expected set-config to succeed, but failed") } } diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 1c6bc67c6..a1d2d4a3d 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -86,10 +86,7 @@ func isBucketActionAllowed(action, bucket, prefix string) bool { resource := bucketARNPrefix + path.Join(bucket, prefix) var conditionKeyMap map[string]set.StringSet // Validate action, resource and conditions with current policy statements. - if !bucketPolicyEvalStatements(action, resource, conditionKeyMap, policy.Statements) { - return false - } - return true + return bucketPolicyEvalStatements(action, resource, conditionKeyMap, policy.Statements) } // GetBucketLocationHandler - GET Bucket location. diff --git a/cmd/bucket-notification-handlers.go b/cmd/bucket-notification-handlers.go index ad4a6333c..96c68cf97 100644 --- a/cmd/bucket-notification-handlers.go +++ b/cmd/bucket-notification-handlers.go @@ -209,10 +209,7 @@ func writeNotification(w http.ResponseWriter, notification map[string][]Notifica _, err = w.Write(append(notificationBytes, crlf...)) // Make sure we have flushed, this would set Transfer-Encoding: chunked. w.(http.Flusher).Flush() - if err != nil { - return err - } - return nil + return err } // CRLF character used for chunked transfer in accordance with HTTP standards. diff --git a/cmd/format-config-v1_test.go b/cmd/format-config-v1_test.go index b92532b0a..b96a83ca0 100644 --- a/cmd/format-config-v1_test.go +++ b/cmd/format-config-v1_test.go @@ -213,9 +213,7 @@ func genFormatXLInvalidDisksOrder() []*formatConfigV1 { } // Re order jbod for failure case. var jbod1 = make([]string, 8) - for i, j := range jbod { - jbod1[i] = j - } + copy(jbod1, jbod) jbod1[1], jbod1[2] = jbod[2], jbod[1] formatConfigs[2].XL.JBOD = jbod1 return formatConfigs @@ -576,9 +574,7 @@ func TestSavedUUIDOrder(t *testing.T) { } // Re order jbod for failure case. var jbod1 = make([]string, 8) - for i, j := range jbod { - jbod1[i] = j - } + copy(jbod1, jbod) jbod1[1], jbod1[2] = jbod[2], jbod[1] formatConfigs[2].XL.JBOD = jbod1 uuidTestCases[1].shouldPass = false diff --git a/cmd/fs-v1-metadata.go b/cmd/fs-v1-metadata.go index f467991db..3f7f1949a 100644 --- a/cmd/fs-v1-metadata.go +++ b/cmd/fs-v1-metadata.go @@ -238,12 +238,9 @@ func saveFormatFS(formatPath string, fsFormat *formatConfigV1) error { } defer lk.Close() - if _, err = lk.Write(metadataBytes); err != nil { - return err - } - + _, err = lk.Write(metadataBytes) // Success. - return nil + return err } // Return if the part info in uploadedParts and completeParts are same. diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index 924fba23d..f651a6d52 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -67,12 +67,7 @@ func initMetaVolumeFS(fsPath, fsUUID string) error { } metaMultipartPath := pathJoin(fsPath, minioMetaMultipartBucket) - if err := mkdirAll(metaMultipartPath, 0777); err != nil { - return err - } - - // Return success here. - return nil + return mkdirAll(metaMultipartPath, 0777) } diff --git a/cmd/notifiers.go b/cmd/notifiers.go index 1d3ed1bfd..cbc31e816 100644 --- a/cmd/notifiers.go +++ b/cmd/notifiers.go @@ -98,10 +98,7 @@ func isWebhookQueue(sqsArn arnSQS) bool { return false } rNotify := serverConfig.Notify.GetWebhookByID(sqsArn.AccountID) - if !rNotify.Enable { - return false - } - return true + return rNotify.Enable } // Returns true if queueArn is for an Redis queue. diff --git a/cmd/object-api-common.go b/cmd/object-api-common.go index b5feed0fb..b2fd37af6 100644 --- a/cmd/object-api-common.go +++ b/cmd/object-api-common.go @@ -134,10 +134,7 @@ func isLocalStorage(ep *url.URL) bool { if globalMinioHost != "" && globalMinioPort != "" { // if --address host:port was specified for distXL we short // circuit only the endPoint that matches host:port - if net.JoinHostPort(globalMinioHost, globalMinioPort) == ep.Host { - return true - } - return false + return net.JoinHostPort(globalMinioHost, globalMinioPort) == ep.Host } // Split host to extract host information. host, _, err := net.SplitHostPort(ep.Host) diff --git a/cmd/object_api_suite_test.go b/cmd/object_api_suite_test.go index e3cb467ad..e382af73a 100644 --- a/cmd/object_api_suite_test.go +++ b/cmd/object_api_suite_test.go @@ -243,7 +243,7 @@ func testPaging(obj ObjectLayer, instanceType string, c TestErrHandler) { if len(result.Objects) != 0 { c.Errorf("%s: Number of objects in the result different from expected value.", instanceType) } - if result.IsTruncated != false { + if result.IsTruncated { c.Errorf("%s: Expected IsTruncated to be `false`, but instead found it to be `%v`", instanceType, result.IsTruncated) } @@ -263,7 +263,7 @@ func testPaging(obj ObjectLayer, instanceType string, c TestErrHandler) { if len(result.Objects) != i+1 { c.Errorf("%s: Expected length of objects to be %d, instead found to be %d", instanceType, len(result.Objects), i+1) } - if result.IsTruncated != false { + if result.IsTruncated { c.Errorf("%s: Expected IsTruncated to be `false`, but instead found it to be `%v`", instanceType, result.IsTruncated) } } @@ -282,7 +282,7 @@ func testPaging(obj ObjectLayer, instanceType string, c TestErrHandler) { if len(result.Objects) != 5 { c.Errorf("%s: Expected length of objects to be %d, instead found to be %d", instanceType, 5, len(result.Objects)) } - if result.IsTruncated != true { + if !result.IsTruncated { c.Errorf("%s: Expected IsTruncated to be `true`, but instead found it to be `%v`", instanceType, result.IsTruncated) } } @@ -683,7 +683,7 @@ func testListObjectsTestsForNonExistantBucket(obj ObjectLayer, instanceType stri if len(result.Objects) != 0 { c.Fatalf("%s: Expected number of objects in the result to be `%d`, but instead found `%d`", instanceType, 0, len(result.Objects)) } - if result.IsTruncated != false { + if result.IsTruncated { c.Fatalf("%s: Expected IsTruncated to be `false`, but instead found it to be `%v`", instanceType, result.IsTruncated) } if err.Error() != "Bucket not found: bucket" { diff --git a/cmd/signature-v4-parser_test.go b/cmd/signature-v4-parser_test.go index d30b8bee1..3639c093d 100644 --- a/cmd/signature-v4-parser_test.go +++ b/cmd/signature-v4-parser_test.go @@ -569,7 +569,7 @@ func TestDoesV4PresignParamsExist(t *testing.T) { func TestParsePreSignV4(t *testing.T) { // converts the duration in seconds into string format. getDurationStr := func(expires int) string { - return strconv.FormatInt(int64(expires), 10) + return strconv.Itoa(expires) } // used in expected preSignValues, preSignValues.Date is of type time.Time . queryTime := time.Now().UTC() diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index 7d518f267..efaa6dd7d 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -1690,9 +1690,7 @@ func removeDiskN(disks []string, n int) { // Makes a entire new copy of a StorageAPI slice. func deepCopyStorageDisks(storageDisks []StorageAPI) []StorageAPI { newStorageDisks := make([]StorageAPI, len(storageDisks)) - for i, disk := range storageDisks { - newStorageDisks[i] = disk - } + copy(newStorageDisks, storageDisks) return newStorageDisks } diff --git a/cmd/web-handlers_test.go b/cmd/web-handlers_test.go index b3e4f83b5..64b24fa31 100644 --- a/cmd/web-handlers_test.go +++ b/cmd/web-handlers_test.go @@ -696,7 +696,7 @@ func testUploadWebHandler(obj ObjectLayer, instanceType string, t TestErrHandler t.Fatalf("Failed, %v", err) } - if bytes.Compare(byteBuffer.Bytes(), content) != 0 { + if !bytes.Equal(byteBuffer.Bytes(), content) { t.Fatalf("The upload file is different from the download file") } @@ -782,7 +782,7 @@ func testDownloadWebHandler(obj ObjectLayer, instanceType string, t TestErrHandl t.Fatalf("Expected the response status to be 200, but instead found `%d`", code) } - if bytes.Compare(bodyContent, content) != 0 { + if !bytes.Equal(bodyContent, content) { t.Fatalf("The downloaded file is corrupted") } @@ -805,7 +805,7 @@ func testDownloadWebHandler(obj ObjectLayer, instanceType string, t TestErrHandl t.Fatalf("Expected the response status to be 200, but instead found `%d`", code) } - if bytes.Compare(bodyContent, content) != 0 { + if !bytes.Equal(bodyContent, content) { t.Fatalf("The downloaded file is corrupted") } } diff --git a/cmd/xl-v1-list-objects-heal.go b/cmd/xl-v1-list-objects-heal.go index 2fcb02c3c..d48470974 100644 --- a/cmd/xl-v1-list-objects-heal.go +++ b/cmd/xl-v1-list-objects-heal.go @@ -133,7 +133,7 @@ func (xl xlObjects) listObjectsHeal(bucket, prefix, marker, delimiter string, ma nextMarker = objInfo.Name objInfos = append(objInfos, objInfo) i++ - if walkResult.end == true { + if walkResult.end { eof = true break } diff --git a/cmd/xl-v1.go b/cmd/xl-v1.go index afba095a6..147a0411d 100644 --- a/cmd/xl-v1.go +++ b/cmd/xl-v1.go @@ -161,12 +161,7 @@ func newXLObjects(storageDisks []StorageAPI) (ObjectLayer, error) { xl.writeQuorum = writeQuorum // Do a quick heal on the buckets themselves for any discrepancies. - if err := quickHeal(xl.storageDisks, xl.writeQuorum, xl.readQuorum); err != nil { - return xl, err - } - - // Return successfully initialized object layer. - return xl, nil + return xl, quickHeal(xl.storageDisks, xl.writeQuorum, xl.readQuorum) } // Shutdown function for object storage interface. From 8a9852220d5949d307a465e87e2cb3d3f88d0d9c Mon Sep 17 00:00:00 2001 From: Bala FA Date: Thu, 9 Mar 2017 08:50:01 +0530 Subject: [PATCH 67/94] Make unit testable cert parsing functions. (#3863) --- cmd/admin-handlers.go | 2 +- cmd/certs.go | 160 ++++++++++------------- cmd/certs_test.go | 253 +++++++++++++++++++++++++++++-------- cmd/config-dir.go | 139 ++++++++++++++++++++ cmd/config-migrate_test.go | 6 +- cmd/config.go | 78 ------------ cmd/globals.go | 6 - cmd/server-main.go | 11 +- cmd/server-mux_test.go | 10 +- 9 files changed, 420 insertions(+), 245 deletions(-) create mode 100644 cmd/config-dir.go delete mode 100644 cmd/config.go diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 98ede6b53..c5231ba68 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -803,7 +803,7 @@ func (adminAPI adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http // Take a lock on minio/config.json. NB minio is a reserved // bucket name and wouldn't conflict with normal object // operations. - configLock := globalNSMutex.NewNSLock(minioReservedBucket, globalMinioConfigFile) + configLock := globalNSMutex.NewNSLock(minioReservedBucket, minioConfigFile) configLock.Lock() defer configLock.Unlock() diff --git a/cmd/certs.go b/cmd/certs.go index 4c8311122..af2696de8 100644 --- a/cmd/certs.go +++ b/cmd/certs.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,120 +19,90 @@ package cmd import ( "crypto/x509" "encoding/pem" - "errors" + "fmt" "io/ioutil" "path/filepath" ) -// getCertsPath get certs path. -func getCertsPath() string { - return filepath.Join(getConfigDir(), globalMinioCertsDir) -} - -// getCertFile must get cert file. -func getCertFile() string { - return filepath.Join(getCertsPath(), globalMinioCertFile) -} - -// getKeyFile must get key file. -func getKeyFile() string { - return filepath.Join(getCertsPath(), globalMinioKeyFile) -} - -// createCertsPath create certs path. -func createCertsPath() error { - rootCAsPath := filepath.Join(getCertsPath(), globalMinioCertsCADir) - return mkdirAll(rootCAsPath, 0700) -} - -// getCAFiles must get the list of the CA certificates stored in minio config dir -func getCAFiles() (caCerts []string) { - CAsDir := filepath.Join(getCertsPath(), globalMinioCertsCADir) - if caFiles, err := ioutil.ReadDir(CAsDir); err == nil { - // Ignore any error. - for _, cert := range caFiles { - caCerts = append(caCerts, filepath.Join(CAsDir, cert.Name())) - } - } - return caCerts -} - -// getSystemCertPool returns empty cert pool in case of error (windows) -func getSystemCertPool() *x509.CertPool { - pool, err := x509.SystemCertPool() - if err != nil { - pool = x509.NewCertPool() - } - - return pool -} - -// isCertFileExists verifies if cert file exists, returns true if -// found, false otherwise. -func isCertFileExists() bool { - return isFile(getCertFile()) -} - -// isKeyFileExists verifies if key file exists, returns true if found, -// false otherwise. -func isKeyFileExists() bool { - return isFile(getKeyFile()) -} - // isSSL - returns true with both cert and key exists. func isSSL() bool { - return isCertFileExists() && isKeyFileExists() + return isFile(getPublicCertFile()) && isFile(getPrivateKeyFile()) } -// Reads certificated file and returns a list of parsed certificates. +func parsePublicCertFile(certFile string) (certs []*x509.Certificate, err error) { + var bytes []byte + + if bytes, err = ioutil.ReadFile(certFile); err != nil { + return certs, err + } + + // Parse all certs in the chain. + var block *pem.Block + var cert *x509.Certificate + current := bytes + for len(current) > 0 { + if block, current = pem.Decode(current); block == nil { + err = fmt.Errorf("Could not read PEM block from file %s", certFile) + return certs, err + } + + if cert, err = x509.ParseCertificate(block.Bytes); err != nil { + return certs, err + } + + certs = append(certs, cert) + } + + if len(certs) == 0 { + err = fmt.Errorf("Empty public certificate file %s", certFile) + } + + return certs, err +} + +// Reads certificate file and returns a list of parsed certificates. func readCertificateChain() ([]*x509.Certificate, error) { - bytes, err := ioutil.ReadFile(getCertFile()) + return parsePublicCertFile(getPublicCertFile()) +} + +func getRootCAs(certsCAsDir string) (*x509.CertPool, error) { + // Get all CA file names. + var caFiles []string + fis, err := ioutil.ReadDir(certsCAsDir) if err != nil { return nil, err } - - // Proceed to parse the certificates. - return parseCertificateChain(bytes) -} - -// Parses certificate chain, returns a list of parsed certificates. -func parseCertificateChain(bytes []byte) ([]*x509.Certificate, error) { - var certs []*x509.Certificate - var block *pem.Block - current := bytes - - // Parse all certs in the chain. - for len(current) > 0 { - block, current = pem.Decode(current) - if block == nil { - return nil, errors.New("Could not PEM block") - } - // Parse the decoded certificate. - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return nil, err - } - certs = append(certs, cert) - + for _, fi := range fis { + caFiles = append(caFiles, filepath.Join(certsCAsDir, fi.Name())) } - return certs, nil -} -// loadRootCAs fetches CA files provided in minio config and adds them to globalRootCAs -// Currently under Windows, there is no way to load system + user CAs at the same time -func loadRootCAs() { - caFiles := getCAFiles() if len(caFiles) == 0 { - return + return nil, nil } - // Get system cert pool, and empty cert pool under Windows because it is not supported - globalRootCAs = getSystemCertPool() + + rootCAs, err := x509.SystemCertPool() + if err != nil { + // In some systems like Windows, system cert pool is not supported. + // Hence we create a new cert pool. + rootCAs = x509.NewCertPool() + } + // Load custom root CAs for client requests for _, caFile := range caFiles { caCert, err := ioutil.ReadFile(caFile) if err != nil { - fatalIf(err, "Unable to load a CA file") + return rootCAs, err } - globalRootCAs.AppendCertsFromPEM(caCert) + + rootCAs.AppendCertsFromPEM(caCert) } + + return rootCAs, nil +} + +// loadRootCAs fetches CA files provided in minio config and adds them to globalRootCAs +// Currently under Windows, there is no way to load system + user CAs at the same time +func loadRootCAs() (err error) { + globalRootCAs, err = getRootCAs(getCADir()) + return err } diff --git a/cmd/certs_test.go b/cmd/certs_test.go index 5d8c649a9..730f311ff 100644 --- a/cmd/certs_test.go +++ b/cmd/certs_test.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,49 +17,86 @@ package cmd import ( + "fmt" + "io/ioutil" "os" "path/filepath" - "strings" + "runtime" "testing" ) -// Make sure we have a valid certs path. -func TestGetCertsPath(t *testing.T) { - path := getCertsPath() - if path == "" { - t.Errorf("expected path to not be an empty string, got: '%s'", path) - } - // Ensure it contains some sort of path separator. - if !strings.ContainsRune(path, os.PathSeparator) { - t.Errorf("expected path to contain file separator") - } - // It should also be an absolute path. - if !filepath.IsAbs(path) { - t.Errorf("expected path to be an absolute path") +func createTempFile(prefix, content string) (tempFile string, err error) { + var tmpfile *os.File + + if tmpfile, err = ioutil.TempFile("", prefix); err != nil { + return tempFile, err } - // This will error if something goes wrong, so just call it. - getCertsPath() + if _, err = tmpfile.Write([]byte(content)); err != nil { + return tempFile, err + } + + if err = tmpfile.Close(); err != nil { + return tempFile, err + } + + tempFile = tmpfile.Name() + return tempFile, err } -// Ensure that the certificate and key file getters contain their respective -// file name and endings. -func TestGetFiles(t *testing.T) { - file := getCertFile() - if !strings.Contains(file, globalMinioCertFile) { - t.Errorf("CertFile does not contain %s", globalMinioCertFile) +func TestParsePublicCertFile(t *testing.T) { + tempFile1, err := createTempFile("public-cert-file", "") + if err != nil { + t.Fatalf("Unable to create temporary file. %v", err) } + defer os.Remove(tempFile1) - file = getKeyFile() - if !strings.Contains(file, globalMinioKeyFile) { - t.Errorf("KeyFile does not contain %s", globalMinioKeyFile) + tempFile2, err := createTempFile("public-cert-file", + `-----BEGIN CERTIFICATE----- +MIICdTCCAd4CCQCO5G/W1xcE9TANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJa +WTEOMAwGA1UECBMFTWluaW8xETAPBgNVBAcTCEludGVybmV0MQ4wDAYDVQQKEwVN +aW5pbzEOMAwGA1UECxMFTWluaW8xDjAMBgNVBAMTBU1pbmlvMR0wGwYJKoZIhvcN +AQkBFg50ZXN0c0BtaW5pby5pbzAeFw0xNjEwMTQxMTM0MjJaFw0xNzEwMTQxMTM0 +MjJaMH8xCzAJBgNVBAYTAlpZMQ4wDAYDVQQIEwVNaW5pbzERMA8GA1UEBxMISW50 +ZXJuZXQxDjAMBgNVBA-some-junk-Q4wDAYDVQQLEwVNaW5pbzEOMAwGA1UEAxMF +TWluaW8xHTAbBgkqhkiG9w0BCQEWDnRlc3RzQG1pbmlvLmlvMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDwNUYB/Sj79WsUE8qnXzzh2glSzWxUE79sCOpQYK83 +HWkrl5WxlG8ZxDR1IQV9Ex/lzigJu8G+KXahon6a+3n5GhNrYRe5kIXHQHz0qvv4 +aMulqlnYpvSfC83aaO9GVBtwXS/O4Nykd7QBg4nZlazVmsGk7POOjhpjGShRsqpU +JwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALqjOA6bD8BEl7hkQ8XwX/owSAL0URDe +nUfCOsXgIIAqgw4uTCLOfCJVZNKmRT+KguvPAQ6Z80vau2UxPX5Q2Q+OHXDRrEnK +FjqSBgLP06Qw7a++bshlWGTt5bHWOneW3EQikedckVuIKPkOCib9yGi4VmBBjdFE +M9ofSEt/bdRD +-----END CERTIFICATE-----`) + if err != nil { + t.Fatalf("Unable to create temporary file. %v", err) } -} + defer os.Remove(tempFile2) -// Parses .crt file contents -func TestParseCertificateChain(t *testing.T) { - // given - cert := `-----BEGIN CERTIFICATE----- + tempFile3, err := createTempFile("public-cert-file", + `-----BEGIN CERTIFICATE----- +MIICdTCCAd4CCQCO5G/W1xcE9TANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJa +WTEOMAwGA1UECBMFTWluaW8xETAPBgNVBAcTCEludGVybmV0MQ4wDAYDVQQKEwVN +aW5pbzEOMAwGA1UECxMFTWluaW8xDjAMBgNVBAMTBU1pbmlvMR0wGwYJKoZIhvcN +AQkBFg50ZXN0c0BtaW5pby5pbzAeFw0xNjEwMTQxMTM0MjJaFw0xNzEwMTQxMTM0 +MjJaMH8xCzAJBgNVBAYTAlpZMQ4wDAYDVQQIEwVNaW5pbzERMA8GA1UEBxMISW50 +ZXJuZXQxDjAMBgNVBAabababababaQ4wDAYDVQQLEwVNaW5pbzEOMAwGA1UEAxMF +TWluaW8xHTAbBgkqhkiG9w0BCQEWDnRlc3RzQG1pbmlvLmlvMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDwNUYB/Sj79WsUE8qnXzzh2glSzWxUE79sCOpQYK83 +HWkrl5WxlG8ZxDR1IQV9Ex/lzigJu8G+KXahon6a+3n5GhNrYRe5kIXHQHz0qvv4 +aMulqlnYpvSfC83aaO9GVBtwXS/O4Nykd7QBg4nZlazVmsGk7POOjhpjGShRsqpU +JwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALqjOA6bD8BEl7hkQ8XwX/owSAL0URDe +nUfCOsXgIIAqgw4uTCLOfCJVZNKmRT+KguvPAQ6Z80vau2UxPX5Q2Q+OHXDRrEnK +FjqSBgLP06Qw7a++bshlWGTt5bHWOneW3EQikedckVuIKPkOCib9yGi4VmBBjdFE +M9ofSEt/bdRD +-----END CERTIFICATE-----`) + if err != nil { + t.Fatalf("Unable to create temporary file. %v", err) + } + defer os.Remove(tempFile3) + + tempFile4, err := createTempFile("public-cert-file", + `-----BEGIN CERTIFICATE----- MIICdTCCAd4CCQCO5G/W1xcE9TANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJa WTEOMAwGA1UECBMFTWluaW8xETAPBgNVBAcTCEludGVybmV0MQ4wDAYDVQQKEwVN aW5pbzEOMAwGA1UECxMFTWluaW8xDjAMBgNVBAMTBU1pbmlvMR0wGwYJKoZIhvcN @@ -74,35 +111,149 @@ JwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALqjOA6bD8BEl7hkQ8XwX/owSAL0URDe nUfCOsXgIIAqgw4uTCLOfCJVZNKmRT+KguvPAQ6Z80vau2UxPX5Q2Q+OHXDRrEnK FjqSBgLP06Qw7a++bshlWGTt5bHWOneW3EQikedckVuIKPkOCib9yGi4VmBBjdFE M9ofSEt/bdRD ------END CERTIFICATE-----` - - // when - certs, err := parseCertificateChain([]byte(cert)) - - // then +-----END CERTIFICATE-----`) if err != nil { - t.Fatalf("Could not parse certificate: %s", err) + t.Fatalf("Unable to create temporary file. %v", err) + } + defer os.Remove(tempFile4) + + tempFile5, err := createTempFile("public-cert-file", + `-----BEGIN CERTIFICATE----- +MIICdTCCAd4CCQCO5G/W1xcE9TANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJa +WTEOMAwGA1UECBMFTWluaW8xETAPBgNVBAcTCEludGVybmV0MQ4wDAYDVQQKEwVN +aW5pbzEOMAwGA1UECxMFTWluaW8xDjAMBgNVBAMTBU1pbmlvMR0wGwYJKoZIhvcN +AQkBFg50ZXN0c0BtaW5pby5pbzAeFw0xNjEwMTQxMTM0MjJaFw0xNzEwMTQxMTM0 +MjJaMH8xCzAJBgNVBAYTAlpZMQ4wDAYDVQQIEwVNaW5pbzERMA8GA1UEBxMISW50 +ZXJuZXQxDjAMBgNVBAoTBU1pbmlvMQ4wDAYDVQQLEwVNaW5pbzEOMAwGA1UEAxMF +TWluaW8xHTAbBgkqhkiG9w0BCQEWDnRlc3RzQG1pbmlvLmlvMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDwNUYB/Sj79WsUE8qnXzzh2glSzWxUE79sCOpQYK83 +HWkrl5WxlG8ZxDR1IQV9Ex/lzigJu8G+KXahon6a+3n5GhNrYRe5kIXHQHz0qvv4 +aMulqlnYpvSfC83aaO9GVBtwXS/O4Nykd7QBg4nZlazVmsGk7POOjhpjGShRsqpU +JwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALqjOA6bD8BEl7hkQ8XwX/owSAL0URDe +nUfCOsXgIIAqgw4uTCLOfCJVZNKmRT+KguvPAQ6Z80vau2UxPX5Q2Q+OHXDRrEnK +FjqSBgLP06Qw7a++bshlWGTt5bHWOneW3EQikedckVuIKPkOCib9yGi4VmBBjdFE +M9ofSEt/bdRD +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIICdTCCAd4CCQCO5G/W1xcE9TANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJa +WTEOMAwGA1UECBMFTWluaW8xETAPBgNVBAcTCEludGVybmV0MQ4wDAYDVQQKEwVN +aW5pbzEOMAwGA1UECxMFTWluaW8xDjAMBgNVBAMTBU1pbmlvMR0wGwYJKoZIhvcN +AQkBFg50ZXN0c0BtaW5pby5pbzAeFw0xNjEwMTQxMTM0MjJaFw0xNzEwMTQxMTM0 +MjJaMH8xCzAJBgNVBAYTAlpZMQ4wDAYDVQQIEwVNaW5pbzERMA8GA1UEBxMISW50 +ZXJuZXQxDjAMBgNVBAoTBU1pbmlvMQ4wDAYDVQQLEwVNaW5pbzEOMAwGA1UEAxMF +TWluaW8xHTAbBgkqhkiG9w0BCQEWDnRlc3RzQG1pbmlvLmlvMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDwNUYB/Sj79WsUE8qnXzzh2glSzWxUE79sCOpQYK83 +HWkrl5WxlG8ZxDR1IQV9Ex/lzigJu8G+KXahon6a+3n5GhNrYRe5kIXHQHz0qvv4 +aMulqlnYpvSfC83aaO9GVBtwXS/O4Nykd7QBg4nZlazVmsGk7POOjhpjGShRsqpU +JwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBALqjOA6bD8BEl7hkQ8XwX/owSAL0URDe +nUfCOsXgIIAqgw4uTCLOfCJVZNKmRT+KguvPAQ6Z80vau2UxPX5Q2Q+OHXDRrEnK +FjqSBgLP06Qw7a++bshlWGTt5bHWOneW3EQikedckVuIKPkOCib9yGi4VmBBjdFE +M9ofSEt/bdRD +-----END CERTIFICATE-----`) + if err != nil { + t.Fatalf("Unable to create temporary file. %v", err) + } + defer os.Remove(tempFile5) + + nonexistentErr := fmt.Errorf("open nonexistent-file: no such file or directory") + if runtime.GOOS == "windows" { + // Below concatenation is done to get rid of goline error + // "error strings should not be capitalized or end with punctuation or a newline" + nonexistentErr = fmt.Errorf("open nonexistent-file:" + " The system cannot find the file specified.") } - if len(certs) != 1 { - t.Fatalf("Expected number of certificates in chain was 1, actual: %d", len(certs)) + testCases := []struct { + certFile string + expectedResultLen int + expectedErr error + }{ + {"nonexistent-file", 0, nonexistentErr}, + {tempFile1, 0, fmt.Errorf("Empty public certificate file %s", tempFile1)}, + {tempFile2, 0, fmt.Errorf("Could not read PEM block from file %s", tempFile2)}, + {tempFile3, 0, fmt.Errorf("asn1: structure error: sequence tag mismatch")}, + {tempFile4, 1, nil}, + {tempFile5, 2, nil}, } - if certs[0].Subject.CommonName != "Minio" { - t.Fatalf("Expected Subject.CommonName was Minio, actual: %s", certs[0].Subject.CommonName) + for _, testCase := range testCases { + certs, err := parsePublicCertFile(testCase.certFile) + + if testCase.expectedErr == nil { + if err != nil { + t.Fatalf("error: expected = , got = %v", err) + } + } else if err == nil { + t.Fatalf("error: expected = %v, got = ", testCase.expectedErr) + } else if testCase.expectedErr.Error() != err.Error() { + t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) + } + + if len(certs) != testCase.expectedResultLen { + t.Fatalf("certs: expected = %v, got = %v", testCase.expectedResultLen, len(certs)) + } } } -// Parses invalid .crt file contents and returns error -func TestParseInvalidCertificateChain(t *testing.T) { - // given - cert := `This is now valid certificate` +func TestGetRootCAs(t *testing.T) { + emptydir, err := ioutil.TempDir("", "test-get-root-cas") + if err != nil { + t.Fatalf("Unable create temp directory. %v", emptydir) + } + defer os.RemoveAll(emptydir) - // when - _, err := parseCertificateChain([]byte(cert)) + dir1, err := ioutil.TempDir("", "test-get-root-cas") + if err != nil { + t.Fatalf("Unable create temp directory. %v", dir1) + } + defer os.RemoveAll(dir1) + if err = os.Mkdir(filepath.Join(dir1, "empty-dir"), 0755); err != nil { + t.Fatalf("Unable create empty dir. %v", err) + } - // then - if err == nil { - t.Fatalf("Expected error but none occurred") + dir2, err := ioutil.TempDir("", "test-get-root-cas") + if err != nil { + t.Fatalf("Unable create temp directory. %v", dir2) + } + defer os.RemoveAll(dir2) + if err = ioutil.WriteFile(filepath.Join(dir2, "empty-file"), []byte{}, 0644); err != nil { + t.Fatalf("Unable create test file. %v", err) + } + + nonexistentErr := fmt.Errorf("open nonexistent-dir: no such file or directory") + if runtime.GOOS == "windows" { + // Below concatenation is done to get rid of goline error + // "error strings should not be capitalized or end with punctuation or a newline" + nonexistentErr = fmt.Errorf("open nonexistent-dir:" + " The system cannot find the file specified.") + } + + err1 := fmt.Errorf("read %s: is a directory", filepath.Join(dir1, "empty-dir")) + if runtime.GOOS == "windows" { + // Below concatenation is done to get rid of goline error + // "error strings should not be capitalized or end with punctuation or a newline" + err1 = fmt.Errorf("read %s:"+" The handle is invalid.", filepath.Join(dir1, "empty-dir")) + } + + testCases := []struct { + certCAsDir string + expectedErr error + }{ + {"nonexistent-dir", nonexistentErr}, + {dir1, err1}, + {emptydir, nil}, + {dir2, nil}, + } + + for _, testCase := range testCases { + _, err := getRootCAs(testCase.certCAsDir) + + if testCase.expectedErr == nil { + if err != nil { + t.Fatalf("error: expected = , got = %v", err) + } + } else if err == nil { + t.Fatalf("error: expected = %v, got = ", testCase.expectedErr) + } else if testCase.expectedErr.Error() != err.Error() { + t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) + } } } diff --git a/cmd/config-dir.go b/cmd/config-dir.go new file mode 100644 index 000000000..fc46a8b33 --- /dev/null +++ b/cmd/config-dir.go @@ -0,0 +1,139 @@ +/* + * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "path/filepath" + "sync" + + homedir "github.com/minio/go-homedir" + "github.com/minio/mc/pkg/console" +) + +const ( + // Default minio configuration directory where below configuration files/directories are stored. + defaultMinioConfigDir = ".minio" + + // Minio configuration file. + minioConfigFile = "config.json" + + // Directory contains below files/directories for HTTPS configuration. + certsDir = "certs" + + // Directory contains all CA certificates other than system defaults for HTTPS. + certsCADir = "CAs" + + // Public certificate file for HTTPS. + publicCertFile = "public.crt" + + // Private key file for HTTPS. + privateKeyFile = "private.key" +) + +// ConfigDir - configuration directory with locking. +type ConfigDir struct { + sync.Mutex + dir string +} + +// Set - saves given directory as configuration directory. +func (config *ConfigDir) Set(dir string) { + config.Lock() + defer config.Unlock() + + config.dir = dir +} + +// Get - returns current configuration directory. +func (config *ConfigDir) Get() string { + config.Lock() + defer config.Unlock() + + return config.dir +} + +func (config *ConfigDir) getCertsDir() string { + return filepath.Join(config.Get(), certsDir) +} + +// GetCADir - returns certificate CA directory. +func (config *ConfigDir) GetCADir() string { + return filepath.Join(config.getCertsDir(), certsCADir) +} + +// Create - creates configuration directory tree. +func (config *ConfigDir) Create() error { + return mkdirAll(config.GetCADir(), 0700) +} + +// GetMinioConfigFile - returns absolute path of config.json file. +func (config *ConfigDir) GetMinioConfigFile() string { + return filepath.Join(config.Get(), minioConfigFile) +} + +// GetPublicCertFile - returns absolute path of public.crt file. +func (config *ConfigDir) GetPublicCertFile() string { + return filepath.Join(config.getCertsDir(), publicCertFile) +} + +// GetPrivateKeyFile - returns absolute path of private.key file. +func (config *ConfigDir) GetPrivateKeyFile() string { + return filepath.Join(config.getCertsDir(), privateKeyFile) +} + +func mustGetDefaultConfigDir() string { + homeDir, err := homedir.Dir() + if err != nil { + console.Fatalln("Unable to get home directory.", err) + } + + return filepath.Join(homeDir, defaultMinioConfigDir) +} + +var configDir = &ConfigDir{dir: mustGetDefaultConfigDir()} + +func setConfigDir(dir string) { + configDir.Set(dir) +} + +func getConfigDir() string { + return configDir.Get() +} + +func getCADir() string { + return configDir.GetCADir() +} + +func createConfigDir() error { + return configDir.Create() +} + +func getConfigFile() string { + return configDir.GetMinioConfigFile() +} + +func getPublicCertFile() string { + return configDir.GetPublicCertFile() +} + +func getPrivateKeyFile() string { + return configDir.GetPrivateKeyFile() +} + +func isConfigFileExists() bool { + return isFile(getConfigFile()) +} diff --git a/cmd/config-migrate_test.go b/cmd/config-migrate_test.go index 359936be3..e30818dd5 100644 --- a/cmd/config-migrate_test.go +++ b/cmd/config-migrate_test.go @@ -66,7 +66,7 @@ func TestServerConfigMigrateInexistentConfig(t *testing.T) { defer removeAll(rootPath) setConfigDir(rootPath) - configPath := rootPath + "/" + globalMinioConfigFile + configPath := rootPath + "/" + minioConfigFile // Remove config file if err := os.Remove(configPath); err != nil { @@ -121,7 +121,7 @@ func TestServerConfigMigrateV2toV14(t *testing.T) { defer removeAll(rootPath) setConfigDir(rootPath) - configPath := rootPath + "/" + globalMinioConfigFile + configPath := rootPath + "/" + minioConfigFile // Create a corrupted config file if err := ioutil.WriteFile(configPath, []byte("{ \"version\":\"2\","), 0644); err != nil { @@ -175,7 +175,7 @@ func TestServerConfigMigrateFaultyConfig(t *testing.T) { defer removeAll(rootPath) setConfigDir(rootPath) - configPath := rootPath + "/" + globalMinioConfigFile + configPath := rootPath + "/" + minioConfigFile // Create a corrupted config file if err := ioutil.WriteFile(configPath, []byte("{ \"version\":\""), 0644); err != nil { diff --git a/cmd/config.go b/cmd/config.go deleted file mode 100644 index 59dd831ab..000000000 --- a/cmd/config.go +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import ( - "path/filepath" - "sync" - - homedir "github.com/minio/go-homedir" - "github.com/minio/mc/pkg/console" -) - -// ConfigDir - configuration directory with locking. -type ConfigDir struct { - sync.Mutex - dir string -} - -// Set - saves given directory as configuration directory. -func (config *ConfigDir) Set(dir string) { - config.Lock() - defer config.Unlock() - - config.dir = dir -} - -// Get - returns current configuration directory. -func (config *ConfigDir) Get() string { - config.Lock() - defer config.Unlock() - - return config.dir -} - -func mustGetDefaultConfigDir() string { - homeDir, err := homedir.Dir() - if err != nil { - console.Fatalln("Unable to get home directory.", err) - } - - return filepath.Join(homeDir, globalMinioConfigDir) -} - -var configDir = &ConfigDir{dir: mustGetDefaultConfigDir()} - -func setConfigDir(dir string) { - configDir.Set(dir) -} - -func getConfigDir() string { - return configDir.Get() -} - -func createConfigDir() error { - return mkdirAll(getConfigDir(), 0700) -} - -func getConfigFile() string { - return filepath.Join(getConfigDir(), globalMinioConfigFile) -} - -func isConfigFileExists() bool { - return isFile(getConfigFile()) -} diff --git a/cmd/globals.go b/cmd/globals.go index 4f04ce0e9..13f8253ec 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -28,12 +28,6 @@ import ( // minio configuration related constants. const ( - globalMinioConfigDir = ".minio" - globalMinioCertsDir = "certs" - globalMinioCertsCADir = "CAs" - globalMinioCertFile = "public.crt" - globalMinioKeyFile = "private.key" - globalMinioConfigFile = "config.json" globalMinioCertExpireWarnDays = time.Hour * 24 * 30 // 30 days. globalMinioDefaultRegion = "us-east-1" diff --git a/cmd/server-main.go b/cmd/server-main.go index df07a3225..6f44624ca 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -144,6 +144,9 @@ func initConfig() { // Generic Minio initialization to create/load config, prepare loggers, etc.. func minioInit(ctx *cli.Context) { + // Create certs path. + fatalIf(createConfigDir(), "Unable to create \"certs\" directory.") + // Is TLS configured?. globalIsSSL = isSSL() @@ -155,7 +158,6 @@ func minioInit(ctx *cli.Context) { // Init the error tracing module. initError() - } type serverCmdConfig struct { @@ -208,11 +210,8 @@ func initServerConfig(c *cli.Context) { // Initialization such as config generating/loading config, enable logging, .. minioInit(c) - // Create certs path. - fatalIf(createCertsPath(), "Unable to create \"certs\" directory.") - // Load user supplied root CAs - loadRootCAs() + fatalIf(loadRootCAs(), "Unable to load a CA files") // Set system resources to maximum. errorIf(setMaxResources(), "Unable to change resource limit") @@ -540,7 +539,7 @@ func serverMain(c *cli.Context) { go func() { cert, key := "", "" if globalIsSSL { - cert, key = getCertFile(), getKeyFile() + cert, key = getPublicCertFile(), getPrivateKeyFile() } fatalIf(apiServer.ListenAndServe(cert, key), "Failed to start minio server.") }() diff --git a/cmd/server-mux_test.go b/cmd/server-mux_test.go index c7c39278e..81985c174 100644 --- a/cmd/server-mux_test.go +++ b/cmd/server-mux_test.go @@ -354,12 +354,12 @@ func TestServerListenAndServeTLS(t *testing.T) { })) // Create a cert - err := createCertsPath() + err := createConfigDir() if err != nil { t.Fatal(err) } - certFile := getCertFile() - keyFile := getKeyFile() + certFile := getPublicCertFile() + keyFile := getPrivateKeyFile() defer os.RemoveAll(certFile) defer os.RemoveAll(keyFile) @@ -420,8 +420,8 @@ func TestServerListenAndServeTLS(t *testing.T) { // generateTestCert creates a cert and a key used for testing only func generateTestCert(host string) error { - certPath := getCertFile() - keyPath := getKeyFile() + certPath := getPublicCertFile() + keyPath := getPrivateKeyFile() priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err From 43317530d5f35278bf33321078fd91f7aed19b99 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 8 Mar 2017 20:42:45 -0800 Subject: [PATCH 68/94] Fix odd shadowing bug in XL init. (#3874) Fixes #3873 --- Makefile | 6 ++---- cmd/xl-v1.go | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index f9eb341fa..9c5127ef7 100644 --- a/Makefile +++ b/Makefile @@ -71,10 +71,8 @@ verifiers: vet fmt lint cyclo spelling vet: @echo "Running $@:" - @go tool vet -all ./cmd - @go tool vet -all ./pkg - @go tool vet -shadow=true ./cmd - @go tool vet -shadow=true ./pkg + @go vet github.com/minio/minio/cmd/... + @go vet github.com/minio/minio/pkg/... fmt: @echo "Running $@:" diff --git a/cmd/xl-v1.go b/cmd/xl-v1.go index 147a0411d..f58cb9182 100644 --- a/cmd/xl-v1.go +++ b/cmd/xl-v1.go @@ -140,9 +140,9 @@ func newXLObjects(storageDisks []StorageAPI) (ObjectLayer, error) { // Check if object cache is enabled. if xl.objCacheEnabled { // Initialize object cache. - objCache, err := objcache.New(maxCacheSize, objcache.DefaultExpiry) - if err != nil { - return nil, err + objCache, oerr := objcache.New(maxCacheSize, objcache.DefaultExpiry) + if oerr != nil { + return nil, oerr } objCache.OnEviction = func(key string) { debug.FreeOSMemory() From 85cbd875fc5cae15c8d3ae3a7d340e0a61429b5d Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 9 Mar 2017 10:13:30 -0800 Subject: [PATCH 69/94] cleanup: All conditionals simplified under pkg. (#3875) Address all the changes reported/recommended by `gosimple` tool. --- pkg/disk/type_linux.go | 2 +- pkg/madmin/api.go | 9 ++------- pkg/madmin/heal-commands.go | 5 +---- pkg/mimedb/db_test.go | 4 ++-- pkg/quick/encoding.go | 9 ++------- 5 files changed, 8 insertions(+), 21 deletions(-) diff --git a/pkg/disk/type_linux.go b/pkg/disk/type_linux.go index 98dceb66f..7de259a3c 100644 --- a/pkg/disk/type_linux.go +++ b/pkg/disk/type_linux.go @@ -40,7 +40,7 @@ var fsType2StringMap = map[string]string{ func getFSType(ftype int64) string { fsTypeHex := strconv.FormatInt(ftype, 16) fsTypeString, ok := fsType2StringMap[fsTypeHex] - if ok == false { + if !ok { return "UNKNOWN" } return fsTypeString diff --git a/pkg/madmin/api.go b/pkg/madmin/api.go index 2bf06b8b6..ef010583b 100644 --- a/pkg/madmin/api.go +++ b/pkg/madmin/api.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -276,12 +276,7 @@ func (c AdminClient) dumpHTTP(req *http.Request, resp *http.Response) error { // Ends the http dump. _, err = fmt.Fprintln(c.traceOutput, "---------END-HTTP---------") - if err != nil { - return err - } - - // Returns success. - return nil + return err } // do - execute http request. diff --git a/pkg/madmin/heal-commands.go b/pkg/madmin/heal-commands.go index 7544a8f89..3dea72ccf 100644 --- a/pkg/madmin/heal-commands.go +++ b/pkg/madmin/heal-commands.go @@ -211,10 +211,7 @@ func (adm *AdminClient) listObjectsHeal(bucket, prefix, marker, delimiter string } err = xml.NewDecoder(resp.Body).Decode(&toBeHealedObjects) - if err != nil { - return toBeHealedObjects, err - } - return toBeHealedObjects, nil + return toBeHealedObjects, err } // ListObjectsHeal - Lists upto maxKeys objects that needing heal matching bucket, prefix, marker, delimiter. diff --git a/pkg/mimedb/db_test.go b/pkg/mimedb/db_test.go index 7ef73b65c..957e558db 100644 --- a/pkg/mimedb/db_test.go +++ b/pkg/mimedb/db_test.go @@ -1,5 +1,5 @@ /* - * mime-db: Mime Database, (C) 2015, 2016 Minio, Inc. + * mime-db: Mime Database, (C) 2015, 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ func TestMimeLookup(t *testing.T) { t.Fatalf("Invalid content type are found expected \"application/x-msdownload\", got %s", contentType) } compressible := DB["txt"].Compressible - if compressible != false { + if compressible { t.Fatalf("Invalid content type are found expected \"false\", got %t", compressible) } } diff --git a/pkg/quick/encoding.go b/pkg/quick/encoding.go index c8a3a3b6d..2d2060a55 100644 --- a/pkg/quick/encoding.go +++ b/pkg/quick/encoding.go @@ -122,8 +122,7 @@ func saveFileConfig(filename string, v interface{}) error { // decoder format according to the filename extension. If no // extension is provided, json will be selected by default. func loadFileConfig(filename string, v interface{}) error { - _, err := os.Stat(filename) - if err != nil { + if _, err := os.Stat(filename); err != nil { return err } fileData, err := ioutil.ReadFile(filename) @@ -133,10 +132,6 @@ func loadFileConfig(filename string, v interface{}) error { if runtime.GOOS == "windows" { fileData = []byte(strings.Replace(string(fileData), "\r\n", "\n", -1)) } - ext := filepath.Ext(filename) // Unmarshal file's content - if err := toUnmarshaller(ext)(fileData, v); err != nil { - return err - } - return nil + return toUnmarshaller(filepath.Ext(filename))(fileData, v) } From ccc3349f0c3ef1bcf05fa9b77ff97ce99f6eafb9 Mon Sep 17 00:00:00 2001 From: Rushan Date: Fri, 10 Mar 2017 00:12:38 +0530 Subject: [PATCH 70/94] Browser: Show complete bucket name by removing the ellipsis cut off (#3877) --- browser/app/less/inc/sidebar.less | 16 ++++++++-------- browser/app/less/inc/variables.less | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/browser/app/less/inc/sidebar.less b/browser/app/less/inc/sidebar.less index c975472eb..5000cc03c 100644 --- a/browser/app/less/inc/sidebar.less +++ b/browser/app/less/inc/sidebar.less @@ -7,7 +7,7 @@ position: fixed; height: 100%; overflow: hidden; - padding: 35px; + padding: 25px; @media(min-width: @screen-md-min) { .translate3d(0, 0, 0); @@ -63,15 +63,15 @@ height: ~"calc(100vh - 260px)"; overflow: auto; padding: 0; - margin: 0 -35px; + margin: 0 -25px; & li { position: relative; & > a { display: block; - padding: 10px 40px 12px 65px; - .text-overflow(); + padding: 10px 45px 12px 55px; + word-wrap: break-word; &:before { font-family: FontAwesome; @@ -79,7 +79,7 @@ font-size: 17px; position: absolute; top: 10px; - left: 35px; + left: 25px; .opacity(0.8); } @@ -95,7 +95,7 @@ } &.active { - background-color: rgba(0, 0, 0, 0.2); + background-color: #282e32; & > a { color: @white; @@ -139,10 +139,10 @@ position: absolute; top: 0; right: 0; - width: 40px; + width: 35px; height: 100%; cursor: pointer; - background: url(../../img/more-h-light.svg) no-repeat left; + background: url(../../img/more-h-light.svg) no-repeat top 20px left; } /* Scrollbar */ diff --git a/browser/app/less/inc/variables.less b/browser/app/less/inc/variables.less index 8ad938e3d..a89008007 100644 --- a/browser/app/less/inc/variables.less +++ b/browser/app/less/inc/variables.less @@ -13,7 +13,7 @@ /*-------------------------- File Explorer ----------------------------*/ -@fe-sidebar-width : 300px; +@fe-sidebar-width : 320px; @text-muted-color : #BDBDBD; @text-strong-color : #333; From e3b627a19238fafef2d672b73d8535463531a34a Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 9 Mar 2017 13:57:27 -0800 Subject: [PATCH 71/94] docker: Add ARM64 image build support (#3876) --- .travis.yml | 13 +++++-------- Dockerfile.aarch64 | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 Dockerfile.aarch64 diff --git a/.travis.yml b/.travis.yml index 18f017918..2052a4fd6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,24 +16,21 @@ env: - ARCH=i686 script: -# Refer https://blog.hypriot.com/post/setup-simple-ci-pipeline-for-arm-images/ -# prepare qemu -- docker run --rm --privileged multiarch/qemu-user-static:register --reset -# build image -- docker build -t minio/minio:edge-armhf . -f Dockerfile.armhf -# test image -- docker run --rm minio/minio:edge-armhf version - ## Run all the tests - make - make test GOFLAGS="-timeout 15m -race -v" - make coverage +# Refer https://blog.hypriot.com/post/setup-simple-ci-pipeline-for-arm-images/ # push image - > if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$ARCH" == "x86_64" ]; then + docker run --rm --privileged multiarch/qemu-user-static:register --reset + docker build -t minio/minio:edge-armhf . -f Dockerfile.armhf + docker build -t minio/minio:edge-aarch64 . -f Dockerfile.aarch64 docker login -u="$DOCKER_USER" -p="$DOCKER_PASS" docker push minio/minio:edge-armhf + docker push minio/minio:edge-aarch64 fi after_success: diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 new file mode 100644 index 000000000..e92905ecc --- /dev/null +++ b/Dockerfile.aarch64 @@ -0,0 +1,19 @@ +FROM resin/aarch64-alpine:3.5 + +ENV GOPATH /go +ENV PATH $PATH:$GOPATH/bin +ENV CGO_ENABLED 0 + +WORKDIR /go/src/github.com/minio/ + +RUN \ + apk add --no-cache ca-certificates && \ + apk add --no-cache --virtual .build-deps git go musl-dev && \ + go get -v -d github.com/minio/minio && \ + cd /go/src/github.com/minio/minio && \ + go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \ + rm -rf /go/pkg /go/src /usr/local/go && apk del .build-deps + +EXPOSE 9000 +ENTRYPOINT ["minio"] +VOLUME ["/export"] From 03937e755471be112246e88eca8fb867fef68cba Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Fri, 10 Mar 2017 03:36:51 +0530 Subject: [PATCH 72/94] Added documentation for orchestration platforms (#3684) --- docs/orchestration/README.md | 22 +++ docs/orchestration/dcos/README.md | 43 ++++++ docs/orchestration/docker-swarm/README.md | 70 +++++++++ .../docker-swarm/docker-compose.yaml | 87 +++++++++++ docs/orchestration/kubernetes/README.md | 138 ++++++++++++++++++ docs/screenshots/Minio_Cloud_Native_Arch.png | Bin 0 -> 76212 bytes 6 files changed, 360 insertions(+) create mode 100644 docs/orchestration/README.md create mode 100644 docs/orchestration/dcos/README.md create mode 100644 docs/orchestration/docker-swarm/README.md create mode 100644 docs/orchestration/docker-swarm/docker-compose.yaml create mode 100644 docs/orchestration/kubernetes/README.md create mode 100644 docs/screenshots/Minio_Cloud_Native_Arch.png diff --git a/docs/orchestration/README.md b/docs/orchestration/README.md new file mode 100644 index 000000000..7ba563615 --- /dev/null +++ b/docs/orchestration/README.md @@ -0,0 +1,22 @@ +# Minio on orchestration platforms [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) + +Minio is a cloud-native application designed to scale in a sustainable manner in multi-tenant environments. Orchestration platforms provide perfect launchpad for Minio to scale. Below is the list of documented orchestration platforms for Minio server: + +| Orchestration platforms| +|:---| +| [`Kubernetes`](https://raw.githubusercontent.com/minio/minio/master/docs/orchestration/kubernetes/README.md) | +| [`Docker Swarm`](https://raw.githubusercontent.com/minio/minio/master/docs/orchestration/docker-swarm/README.md) | +| [`DC/OS`](https://raw.githubusercontent.com/minio/minio/master/docs/orchestration/dcos/README.md) | + +## Why is Minio cloud-native? +The term cloud-native revolves around the idea of applications deployed as micro services, that can be scaled well. Its not about just retrofitting monolithic applications onto modern container based compute environment. A cloud-native application is portable and resilient by design, and can scale horizontally by simply replicating. Modern orchestration platforms like DC/OS, Kubernetes and Swarm make replicating and managing containers in huge clusters easier than ever. + +While containers provide isolated application execution environment, orchestration platforms allow seamless scaling by helping replicate and manage containers. Minio extends this by adding isolated storage environment for each tenant. + +Minio is built ground up on the cloud-native premise. With features like erasure-coding, distributed and shared setup, it focusses only on storage and does it very well. While, it can be scaled by just replicating Minio instances per tenant via an orchestration platform. + +> In a cloud-native environment, scalability is not a function of the application but the orchestration platform. + +In a typical modern infrastructure deployment, application, Database, Key-store, etc. already live in containers and are managed by orchestration platforms. Minio brings robust, scalable, AWS S3 compatible object storage to the lot. + +![Cloud-native](https://raw.githubusercontent.com/NitishT/minio/master/docs/screenshots/Minio_Cloud_Native_Arch.png?raw=true) diff --git a/docs/orchestration/dcos/README.md b/docs/orchestration/dcos/README.md new file mode 100644 index 000000000..55d14e8a6 --- /dev/null +++ b/docs/orchestration/dcos/README.md @@ -0,0 +1,43 @@ +# Deploy Minio on DC/OS [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) + +To deploy Minio on DC/OS, you can use a Universe package, or create a customized config file. We at Minio recently released an [official universe package](https://github.com/mesosphere/universe/tree/version-3.x/repo/packages/M/minio/0) to enable single click Minio deployment on a DC/OS cluster. + +## 1. Prerequisites + +- DC/OS 1.8 or later running on your cluster. +- [Marathon-LB](https://dcos.io/docs/1.8/usage/service-discovery/marathon-lb/usage/) installed and running. +- IP address of the public agent(s) where Marathon-LB or an available hostname configured to point to the public agent(s) where Marathon-LB is running. + +## 2. Setting up Minio + +You can install Minio Universe package using the DC/OS GUI or CLI. + +### Minio installation on DC/OS GUI + +Visit the DC/OS admin page, and click on `Univers` on the left menu bar. Then click on the `Package` tab and search for Minio. Once you see the package, click the `Instal` button on the right hand side. Then, enter configuration values like the storage and service type you’d like to use with your Minio instance. Finally enter the public Marathon-LB IP address under `networking >> public-agent`, and click `Review and Install`. + +This completes the install process. Before you can access Minio server, get the access key and secret key from the Minio container logs. Click on `Services` and select Minio service in DC/OS admin page. Then go to the `logs` tab and copy the accesskey and secretkey. + +### Minio installation on DC/OS CLI + +To install Minio package via CLI, type + +```bash +$ dcos package install minio +``` + +## 3. Uninstalling Minio + +To uninstall Minio package via CLI, type + +```bash +$ dcos package uninstall minio +``` + +### Explore Further +- [Minio Erasure Code QuickStart Guide](https://docs.minio.io/docs/minio-erasure-code-quickstart-guide) +- [Use `mc` with Minio Server](https://docs.minio.io/docs/minio-client-quickstart-guide) +- [Use `aws-cli` with Minio Server](https://docs.minio.io/docs/aws-cli-with-minio) +- [Use `s3cmd` with Minio Server](https://docs.minio.io/docs/s3cmd-with-minio) +- [Use `minio-go` SDK with Minio Server](https://docs.minio.io/docs/golang-client-quickstart-guide) +- [The Minio documentation website](https://docs.minio.io) diff --git a/docs/orchestration/docker-swarm/README.md b/docs/orchestration/docker-swarm/README.md new file mode 100644 index 000000000..8d7ac385d --- /dev/null +++ b/docs/orchestration/docker-swarm/README.md @@ -0,0 +1,70 @@ +# Deploy Minio on Docker Swarm [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) + +Docker Engine provides cluster management and orchestration features in Swarm mode. Minio server can be easily deployed in distributed mode on Swarm to create a multi-tenant, highly-available and scalable object store. + +As of [Docker Engine v1.13.0](https://blog.docker.com/2017/01/whats-new-in-docker-1-13/) (Docker Compose v3.0), Docker Swarm and Compose are [cross-compatible](https://docs.docker.com/compose/compose-file/#version-3). This allows a Compose file to be used as a template to deploy services on Swarm. We have used a Docker Compose file to create distributed Minio setup. + +## 1. Prerequisites + +* Familiarity with [Swarm mode key concepts](https://docs.docker.com/engine/swarm/key-concepts/). +* Docker engine v1.13.0 running on a cluster of [networked host machines](https://docs.docker.com/engine/swarm/swarm-tutorial/#/three-networked-host-machines). + +## 2. Create a Swarm + +SSH into the machine supposed to serve as Swarm manager. If the machine is named `manager`, you can SSH by + +```shell +docker-machine ssh manager +``` +After logging in to the designated manager node, create the Swarm by + +```shell +docker swarm init --advertise-addr +``` + +After the manager is up, [add worker nodes](https://docs.docker.com/engine/swarm/swarm-tutorial/add-nodes/) to the Swarm. Find detailed steps to create the Swarm on [Docker documentation site](https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm/). + +## 3. Deploy distributed Minio services + +Download the [Docker Compose file](./docker-compose.yaml) on your Swarm master. Then execute the command + +```shell +docker stack deploy --compose-file=docker-compose.yaml minio_stack +``` +This deploys services described in the Compose file as Docker stack `minio_stack`. Look up the `docker stack` [command reference](https://docs.docker.com/engine/reference/commandline/stack/) for more info. + +After the stack is successfully deployed, you should be able to access Minio server via [Minio Client](https://docs.minio.io/docs/minio-client-complete-guide) `mc` or your browser at http://[Node_Public_IP_Address]:[Expose_Port_on_Host] + +## 4. Remove distributed Minio services + +Remove the distributed Minio services and related network by + +```shell +docker stack rm minio_stack +``` + +### Notes + +* By default the Docker Compose file uses the Docker image for latest Minio server release. You can change the image tag to pull a specific [Minio Docker image](https://hub.docker.com/r/minio/minio/). + +* There are 4 minio distributed instances created by default. You can add more Minio services (upto total 16) to your Minio Swarm deployment. To add a deployment + * Replicate a service definition and change the name of the new service appropriately. + * Add a volume in volumes section, and update volume section in the service accordingly. + * Update the command section in each service. Specifically, add the drive location to be used as storage on the new service. + * Update the port number to exposed for the new service. + + Read more about distributed Minio [here](https://docs.minio.io/docs/distributed-minio-quickstart-guide). + +* By default the services use `local` volume driver. Refer to [Docker documentation](https://docs.docker.com/compose/compose-file/#/volume-configuration-reference) to explore further options. + +* Minio services in the Docker compose file expose ports 9001 to 9004. This allows multiple services to run on a host. Explore other configuration options in [Docker documentation](https://docs.docker.com/compose/compose-file/#/ports). + +* Docker Swarm uses ingress load balancing by default. You can configure [external load balancer based](https://docs.docker.com/engine/swarm/ingress/#/configure-an-external-load-balancer) on requirements. + +### Explore Further +- [Minio Erasure Code QuickStart Guide](https://docs.minio.io/docs/minio-erasure-code-quickstart-guide) +- [Use `mc` with Minio Server](https://docs.minio.io/docs/minio-client-quickstart-guide) +- [Use `aws-cli` with Minio Server](https://docs.minio.io/docs/aws-cli-with-minio) +- [Use `s3cmd` with Minio Server](https://docs.minio.io/docs/s3cmd-with-minio) +- [Use `minio-go` SDK with Minio Server](https://docs.minio.io/docs/golang-client-quickstart-guide) +- [The Minio documentation website](https://docs.minio.io) diff --git a/docs/orchestration/docker-swarm/docker-compose.yaml b/docs/orchestration/docker-swarm/docker-compose.yaml new file mode 100644 index 000000000..f6e482b72 --- /dev/null +++ b/docs/orchestration/docker-swarm/docker-compose.yaml @@ -0,0 +1,87 @@ +version: '3' + +services: + minio1: + image: minio/minio:RELEASE.2017-01-25T03-14-52Z + volumes: + - minio1-data:/export + ports: + - "9001:9000" + networks: + - minio_distributed + environment: + MINIO_ACCESS_KEY: AKIAIOSFODNN7EXAMPLE + MINIO_SECRET_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + deploy: + restart_policy: + delay: 10s + max_attempts: 10 + window: 60s + command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + + minio2: + image: minio/minio:RELEASE.2017-01-25T03-14-52Z + volumes: + - minio2-data:/export + ports: + - "9002:9000" + networks: + - minio_distributed + environment: + MINIO_ACCESS_KEY: AKIAIOSFODNN7EXAMPLE + MINIO_SECRET_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + deploy: + restart_policy: + delay: 10s + max_attempts: 10 + window: 60s + command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + + minio3: + image: minio/minio:RELEASE.2017-01-25T03-14-52Z + volumes: + - minio3-data:/export + ports: + - "9003:9000" + networks: + - minio_distributed + environment: + MINIO_ACCESS_KEY: AKIAIOSFODNN7EXAMPLE + MINIO_SECRET_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + deploy: + restart_policy: + delay: 10s + max_attempts: 10 + window: 60s + command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + + minio4: + image: minio/minio:RELEASE.2017-01-25T03-14-52Z + volumes: + - minio4-data:/export + ports: + - "9004:9000" + networks: + - minio_distributed + environment: + MINIO_ACCESS_KEY: AKIAIOSFODNN7EXAMPLE + MINIO_SECRET_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + deploy: + restart_policy: + delay: 10s + max_attempts: 10 + window: 60s + command: server http://minio1/export http://minio2/export http://minio3/export http://minio4/export + +volumes: + minio1-data: + + minio2-data: + + minio3-data: + + minio4-data: + +networks: + minio_distributed: + driver: overlay diff --git a/docs/orchestration/kubernetes/README.md b/docs/orchestration/kubernetes/README.md new file mode 100644 index 000000000..526ade602 --- /dev/null +++ b/docs/orchestration/kubernetes/README.md @@ -0,0 +1,138 @@ +# Deploy Minio on Kubernetes [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) + +Kubernetes constructs like Deployments and StatefulSets provide perfect platform to deploy Minio server in standalone, distributed or shared mode. In addition, using Minio [Helm](https://helm.sh) Chart, you can deploy Minio server with a single command on your cluster. + +Minio Helm Chart offers great deal of [customizability](#configuration), still if you'd rather like to deploy Minio using custom config files, you can do that as well. This [blog post](https://blog.minio.io/build-aws-s3-compatible-cloud-storage-on-gcp-with-minio-and-kubernetes-159cc99caea8#.8zesfh6tc) offers an introduction to running Minio on Kubernetes using .yaml configuration files. + +## 1. Prerequisites + +* Kubernetes 1.4+ with Beta APIs enabled for default standalone mode. +* Kubernetes 1.5+ with Beta APIs enabled to run Minio in [distributed mode](#distributed-minio). +* PV provisioner support in the underlying infrastructure. +* Helm package manager [installed](https://github.com/kubernetes/helm#install) on your Kubernetes cluster. + +## 2. Deploy Minio using Helm Chart + +Install Minio chart by + +```bash +$ helm install stable/minio +``` +Above command deploys Minio on the Kubernetes cluster in the default configuration. Below section lists all the configurable parameters of the Minio chart and their default values. + +### Configuration + +| Parameter | Description | Default | +|----------------------------|-------------------------------------|---------------------------------------------------------| +| `image` | Minio image name | `minio/minio` | +| `imageTag` | Minio image tag. Possible values listed [here](https://hub.docker.com/r/minio/minio/tags/).| `RELEASE.2017-01-25T03-14-52Z`| +| `imagePullPolicy` | Image pull policy | `Always` | +| `mode` | Minio server mode (`standalone`, `shared` or `distributed`)| `standalone` | +| `numberOfNodes` | Number of nodes (applicable only for Minio distributed mode). Should be 4 <= x <= 16 | `4` | +| `accessKey` | Default access key | `AKIAIOSFODNN7EXAMPLE` | +| `secretKey` | Default secret key | `wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY` | +| `configPath` | Default config file location | `~/.minio` | +| `mountPath` | Default mount location for persistent drive| `/export` | +| `serviceType` | Kubernetes service type | `LoadBalancer` | +| `servicePort` | Kubernetes port where service is exposed| `9000` | +| `persistence.enabled` | Use persistent volume to store data | `true` | +| `persistence.size` | Size of persistent volume claim | `10Gi` | +| `persistence.storageClass` | Type of persistent volume claim | `generic` | +| `persistence.accessMode` | ReadWriteOnce or ReadOnly | `ReadWriteOnce` | +| `resources` | CPU/Memory resource requests/limits | Memory: `256Mi`, CPU: `100m` | + +You can specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```bash +$ helm install --name my-release \ + --set persistence.size=100Gi \ + stable/minio +``` + +The above command deploys Minio server with a 100Gi backing persistent volume. + +Alternately, you can provide a YAML file that specifies parameter values while installing the chart. For example, + +```bash +$ helm install --name my-release -f values.yaml stable/minio +``` + +### Distributed Minio + +This chart provisions a Minio server in standalone mode, by default. To provision Minio server in [distributed mode](https://docs.minio.io/docs/distributed-minio-quickstart-guide), set the `mode` field to `distributed`, + +```bash +$ helm install --set mode=distributed stable/minio +``` + +This provisions Minio server in distributed mode with 4 nodes. To change the number of nodes in your distributed Minio server, set the `numberOfNodes` field, + +```bash +$ helm install --set mode=distributed,numberOfNodes=8 stable/minio +``` + +This provisions Minio server in distributed mode with 8 nodes. Note that the `numberOfNodes` value should be an integer between 4 and 16 (inclusive). + +#### StatefulSet [limitations](http://kubernetes.io/docs/concepts/abstractions/controllers/statefulsets/#limitations) applicable to distributed Minio + +* StatefulSets need persistent storage, so the `persistence.enabled` flag is ignored when `mode` is set to `distributed`. +* When uninstalling a distributed Minio release, you'll need to manually delete volumes associated with the StatefulSet. + +### Shared Minio + +To provision Minio servers in [shared mode](https://github.com/minio/minio/blob/master/docs/shared-backend/README.md), set the `mode` field to `shared`, + +```bash +$ helm install --set mode=shared stable/minio +``` + +This provisions 4 Minio server nodes backed by single storage. To change the number of nodes in your shared Minio deployment, set the `numberOfNodes` field, + +```bash +$ helm install --set mode=shared,numberOfNodes=8 stable/minio +``` + +This provisions Minio server in shared mode with 8 nodes. + +### Persistence + +This chart provisions a PersistentVolumeClaim and mounts corresponding persistent volume to default location `/export`. You'll need physical storage available in the Kubernetes cluster for this to work. If you'd rather use `emptyDir`, disable PersistentVolumeClaim by: + +```bash +$ helm install --set persistence.enabled=false stable/minio +``` + +> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* + +## 3. Uninstalling the Chart + +Assuming your release is named as `my-release`, delete it using the command: + +```bash +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +### Notes + +* An instance of a chart running in a Kubernetes cluster is called a release. Helm automatically assigns a unique release name after installing the chart. You can also set your preferred name by: + +```bash +$ helm install --name my-release stable/minio +``` + +* To override the default keys, pass the access and secret keys as arguments to helm install. + +```bash +$ helm install --set accessKey=myaccesskey,secretKey=mysecretkey \ + stable/minio +``` + +### Explore Further +- [Minio Erasure Code QuickStart Guide](https://docs.minio.io/docs/minio-erasure-code-quickstart-guide) +- [Use `mc` with Minio Server](https://docs.minio.io/docs/minio-client-quickstart-guide) +- [Use `aws-cli` with Minio Server](https://docs.minio.io/docs/aws-cli-with-minio) +- [Use `s3cmd` with Minio Server](https://docs.minio.io/docs/s3cmd-with-minio) +- [Use `minio-go` SDK with Minio Server](https://docs.minio.io/docs/golang-client-quickstart-guide) +- [The Minio documentation website](https://docs.minio.io) diff --git a/docs/screenshots/Minio_Cloud_Native_Arch.png b/docs/screenshots/Minio_Cloud_Native_Arch.png new file mode 100644 index 0000000000000000000000000000000000000000..d2946f49ac82d7994ed8af1e1c28f6245e127ef5 GIT binary patch literal 76212 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

    lcq8Mb|8&hGjy44o->Yb+m5 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 b(!I=Iocf#7Kvxoc5Tc}@{-9Fc;>G^~hRIls literal 0 HcmV?d00001 From d602495600970254a1f485a99dd1516b68dbc497 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Thu, 9 Mar 2017 23:08:33 +0100 Subject: [PATCH 73/94] madmin: Do not require SSL to set credentials (#3879) We need to relax this requirement and let the client decides if it can allow to set credentials API over plain connection. --- pkg/madmin/generic-commands.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pkg/madmin/generic-commands.go b/pkg/madmin/generic-commands.go index 9cef94275..384b74ce2 100644 --- a/pkg/madmin/generic-commands.go +++ b/pkg/madmin/generic-commands.go @@ -20,7 +20,6 @@ package madmin import ( "bytes" "encoding/xml" - "errors" "net/http" "net/url" ) @@ -34,11 +33,6 @@ type setCredsReq struct { // SetCredentials - Call Set Credentials API to set new access and secret keys in the specified Minio server func (adm *AdminClient) SetCredentials(access, secret string) error { - // Disallow sending with the server if the connection is not secure - if !adm.secure { - return errors.New("setting new credentials requires HTTPS connection to the server") - } - // Setup new request reqData := requestData{} reqData.queryValues = make(url.Values) From e54025805fad9e09c88942b039f82ab5368ceb24 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 9 Mar 2017 15:26:16 -0800 Subject: [PATCH 74/94] browser: update ui-assets with new changes. --- browser/ui-assets.go | 62 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/browser/ui-assets.go b/browser/ui-assets.go index 81f3b8c48..22f565cb6 100644 --- a/browser/ui-assets.go +++ b/browser/ui-assets.go @@ -4,7 +4,7 @@ // production/favicon.ico // production/firefox.png // production/index.html -// production/index_bundle-2017-03-04T01-07-53Z.js +// production/index_bundle-2017-03-09T22-11-46Z.js // production/loader.css // production/logo.svg // production/safari.png @@ -65,7 +65,7 @@ func productionChromePng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -82,7 +82,7 @@ func productionFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -99,7 +99,7 @@ func productionFirefoxPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -156,8 +156,8 @@ var _productionIndexHTML = []byte(`

    - - + + `) @@ -172,21 +172,21 @@ func productionIndexHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _productionIndex_bundle20170304t010753zJs = []byte(`!function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){A.exports=t(240)},function(A,M,t){"use strict";A.exports=t(440)},function(A,M,t){"use strict";function I(A,M,t,I,g,e,i,T){if(!A){var E;if(void 0===M)E=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var N=[t,I,g,e,i,T],o=0;E=new Error(M.replace(/%s/g,function(){return N[o++]})),E.name="Invariant Violation"}throw E.framesToPop=1,E}}A.exports=I},function(A,M,t){"use strict";var I=t(20),g=I;A.exports=g},function(A,M){"use strict";function t(A,M){if(null==A)throw new TypeError("Object.assign target cannot be null or undefined");for(var t=Object(A),I=Object.prototype.hasOwnProperty,g=1;g2?t-2:0),g=2;g1){for(var c=Array(C),D=0;D1){for(var a=Array(D),B=0;B3&&void 0!==arguments[3]?arguments[3]:{},N=Boolean(A),C=A||w,D=void 0;D="function"==typeof M?M:M?(0,Q.default)(M):l;var B=t||L,r=I.pure,s=void 0===r||r,x=I.withRef,y=void 0!==x&&x,h=s&&B!==L,S=d++;return function(A){function M(A,M,t){var I=B(A,M,t);return I}var t="Connect("+T(A)+")",I=function(I){function T(A,M){g(this,T);var i=e(this,I.call(this,A,M));i.version=S,i.store=A.store||M.store,(0,u.default)(i.store,'Could not find "store" in either the context or '+('props of "'+t+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+t+'".'));var E=i.store.getState();return i.state={storeState:E},i.clearCache(),i}return i(T,I),T.prototype.shouldComponentUpdate=function(){return!s||this.haveOwnPropsChanged||this.hasStoreStateChanged},T.prototype.computeStateProps=function(A,M){if(!this.finalMapStateToProps)return this.configureFinalMapState(A,M);var t=A.getState(),I=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(t,M):this.finalMapStateToProps(t);return I},T.prototype.configureFinalMapState=function(A,M){var t=C(A.getState(),M),I="function"==typeof t;return this.finalMapStateToProps=I?t:C,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,I?this.computeStateProps(A,M):t},T.prototype.computeDispatchProps=function(A,M){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(A,M);var t=A.dispatch,I=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(t,M):this.finalMapDispatchToProps(t);return I},T.prototype.configureFinalMapDispatch=function(A,M){var t=D(A.dispatch,M),I="function"==typeof t;return this.finalMapDispatchToProps=I?t:D,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,I?this.computeDispatchProps(A,M):t},T.prototype.updateStatePropsIfNeeded=function(){var A=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,a.default)(A,this.stateProps))&&(this.stateProps=A,!0)},T.prototype.updateDispatchPropsIfNeeded=function(){var A=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,a.default)(A,this.dispatchProps))&&(this.dispatchProps=A,!0)},T.prototype.updateMergedPropsIfNeeded=function(){var A=M(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&h&&(0,a.default)(A,this.mergedProps))&&(this.mergedProps=A,!0)},T.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},T.prototype.trySubscribe=function(){N&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},T.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},T.prototype.componentDidMount=function(){this.trySubscribe()},T.prototype.componentWillReceiveProps=function(A){s&&(0,a.default)(A,this.props)||(this.haveOwnPropsChanged=!0)},T.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},T.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},T.prototype.handleChange=function(){if(this.unsubscribe){var A=this.store.getState(),M=this.state.storeState;if(!s||M!==A){if(s&&!this.doStatePropsDependOnOwnProps){var t=E(this.updateStatePropsIfNeeded,this);if(!t)return;t===Y&&(this.statePropsPrecalculationError=Y.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:A})}}},T.prototype.getWrappedInstance=function(){return(0,u.default)(y,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},T.prototype.render=function(){var M=this.haveOwnPropsChanged,t=this.hasStoreStateChanged,I=this.haveStatePropsBeenPrecalculated,g=this.statePropsPrecalculationError,e=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,g)throw g;var i=!0,T=!0;s&&e&&(i=t||M&&this.doStatePropsDependOnOwnProps,T=M&&this.doDispatchPropsDependOnOwnProps);var E=!1,N=!1;I?E=!0:i&&(E=this.updateStatePropsIfNeeded()),T&&(N=this.updateDispatchPropsIfNeeded());var C=!0;return C=!!(E||N||M)&&this.updateMergedPropsIfNeeded(),!C&&e?e:(y?this.renderedElement=(0,n.createElement)(A,o({},this.mergedProps,{ref:"wrappedInstance"})):this.renderedElement=(0,n.createElement)(A,this.mergedProps),this.renderedElement)},T}(n.Component);return I.displayName=t,I.WrappedComponent=A,I.contextTypes={store:c.default},I.propTypes={store:c.default},(0,j.default)(I,A)}}M.__esModule=!0;var o=Object.assign||function(A){for(var M=1;M should not have a "'+M+'" prop')}M.__esModule=!0,M.routes=M.route=M.components=M.component=M.history=void 0,M.falsy=I;var g=t(1),e=g.PropTypes.func,i=g.PropTypes.object,T=g.PropTypes.arrayOf,E=g.PropTypes.oneOfType,N=g.PropTypes.element,o=g.PropTypes.shape,n=g.PropTypes.string,C=(M.history=o({listen:e.isRequired,push:e.isRequired,replace:e.isRequired,go:e.isRequired,goBack:e.isRequired,goForward:e.isRequired}),M.component=E([e,n])),c=(M.components=E([C,i]),M.route=E([i,N]));M.routes=E([c,T(c)])},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){var M=A.match(/^https?:\/\/[^\/]*/);return null==M?A:A.substring(M[0].length)}function e(A){var M=g(A),t="",I="",e=M.indexOf("#");e!==-1&&(I=M.substring(e),M=M.substring(0,e));var i=M.indexOf("?");return i!==-1&&(t=M.substring(i),M=M.substring(0,i)),""===M&&(M="/"),{pathname:M,search:t,hash:I}}M.__esModule=!0,M.extractPath=g,M.parsePath=e;var i=t(23);I(i)},function(A,M,t){"use strict";function I(){g.attachRefs(this,this._currentElement)}var g=t(459),e={mountComponent:function(A,M,t,g){var e=A.mountComponent(M,t,g);return A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A),e},unmountComponent:function(A){g.detachRefs(A,A._currentElement),A.unmountComponent()},receiveComponent:function(A,M,t,e){var i=A._currentElement;if(M!==i||e!==A._context){var T=g.shouldUpdateRefs(i,M);T&&g.detachRefs(A,i),A.receiveComponent(M,t,e),T&&A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A)}},performUpdateIfNecessary:function(A,M){A.performUpdateIfNecessary(M)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t,I){this.dispatchConfig=A,this.dispatchMarker=M,this.nativeEvent=t;var g=this.constructor.Interface;for(var e in g)if(g.hasOwnProperty(e)){var T=g[e];T?this[e]=T(t):"target"===e?this.target=I:this[e]=t[e]}var E=null!=t.defaultPrevented?t.defaultPrevented:t.returnValue===!1;E?this.isDefaultPrevented=i.thatReturnsTrue:this.isDefaultPrevented=i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse}var g=t(31),e=t(4),i=t(20),T=(t(3),{type:null,target:null,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(A){return A.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null});e(I.prototype,{preventDefault:function(){this.defaultPrevented=!0;var A=this.nativeEvent;A&&(A.preventDefault?A.preventDefault():A.returnValue=!1,this.isDefaultPrevented=i.thatReturnsTrue)},stopPropagation:function(){var A=this.nativeEvent;A&&(A.stopPropagation?A.stopPropagation():A.cancelBubble=!0,this.isPropagationStopped=i.thatReturnsTrue)},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var A=this.constructor.Interface;for(var M in A)this[M]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),I.Interface=T,I.augmentClass=function(A,M){var t=this,I=Object.create(t.prototype);e(I,A.prototype),A.prototype=I,A.prototype.constructor=A,A.Interface=e({},t.Interface,M),A.augmentClass=t.augmentClass,g.addPoolingTo(A,g.fourArgumentPooler)},g.addPoolingTo(I,g.fourArgumentPooler),A.exports=I},function(A,M){"use strict";M.default=function(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t},M.__esModule=!0},function(A,M){"use strict";function t(A){return A&&A.ownerDocument||document}M.__esModule=!0,M.default=t,A.exports=M.default},function(A,M,t){"use strict";var I=t(32),g=function(){var A=I&&document.documentElement;return A&&A.contains?function(A,M){return A.contains(M)}:A&&A.compareDocumentPosition?function(A,M){return A===M||!!(16&A.compareDocumentPosition(M))}:function(A,M){if(M)do if(M===A)return!0;while(M=M.parentNode);return!1}}();A.exports=g},function(A,M){function t(A){return"number"==typeof A&&A>-1&&A%1==0&&A<=I}var I=9007199254740991;A.exports=t},function(A,M,t){(function(A){!function(M,t){A.exports=t()}(this,function(){"use strict";function M(){return aI.apply(null,arguments)}function t(A){aI=A}function I(A){return A instanceof Array||"[object Array]"===Object.prototype.toString.call(A)}function g(A){return null!=A&&"[object Object]"===Object.prototype.toString.call(A)}function e(A){var M;for(M in A)return!1;return!0}function i(A){return"number"==typeof A||"[object Number]"===Object.prototype.toString.call(A)}function T(A){return A instanceof Date||"[object Date]"===Object.prototype.toString.call(A)}function E(A,M){var t,I=[];for(t=0;t0)for(t in rI)I=rI[t],g=M[I],B(g)||(A[I]=g);return A}function r(A){Q(this,A),this._d=new Date(null!=A._d?A._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),sI===!1&&(sI=!0,M.updateOffset(this),sI=!1)}function s(A){return A instanceof r||null!=A&&null!=A._isAMomentObject}function x(A){return A<0?Math.ceil(A)||0:Math.floor(A)}function j(A){var M=+A,t=0;return 0!==M&&isFinite(M)&&(t=x(M)),t}function y(A,M,t){var I,g=Math.min(A.length,M.length),e=Math.abs(A.length-M.length),i=0;for(I=0;I0?"future":"past"];return L(t)?t(M):t.replace(/%s/i,M)}function F(A,M){var t=A.toLowerCase();SI[t]=SI[t+"s"]=SI[M]=A}function f(A){return"string"==typeof A?SI[A]||SI[A.toLowerCase()]:void 0}function k(A){var M,t,I={};for(t in A)N(A,t)&&(M=f(t),M&&(I[M]=A[t]));return I}function R(A,M){zI[A]=M}function J(A){var M=[];for(var t in A)M.push({unit:t,priority:zI[t]});return M.sort(function(A,M){return A.priority-M.priority}),M}function G(A,t){return function(I){return null!=I?(b(this,A,I),M.updateOffset(this,t),this):H(this,A)}}function H(A,M){return A.isValid()?A._d["get"+(A._isUTC?"UTC":"")+M]():NaN}function b(A,M,t){A.isValid()&&A._d["set"+(A._isUTC?"UTC":"")+M](t)}function v(A){return A=f(A),L(this[A])?this[A]():this}function X(A,M){if("object"==typeof A){A=k(A);for(var t=J(A),I=0;I=0;return(e?t?"+":"":"-")+Math.pow(10,Math.max(0,g)).toString().substr(1)+I}function V(A,M,t,I){var g=I;"string"==typeof I&&(g=function(){return this[I]()}),A&&(mI[A]=g),M&&(mI[M[0]]=function(){return W(g.apply(this,arguments),M[1],M[2])}),t&&(mI[t]=function(){return this.localeData().ordinal(g.apply(this,arguments),A)})}function P(A){return A.match(/\[[\s\S]/)?A.replace(/^\[|\]$/g,""):A.replace(/\\/g,"")}function Z(A){var M,t,I=A.match(pI);for(M=0,t=I.length;M=0&&UI.test(A);)A=A.replace(UI,t),UI.lastIndex=0,I-=1;return A}function _(A,M,t){$I[A]=L(M)?M:function(A,I){return A&&t?t:M}}function $(A,M){return N($I,A)?$I[A](M._strict,M._locale):new RegExp(AA(A))}function AA(A){return MA(A.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(A,M,t,I,g){return M||t||I||g}))}function MA(A){return A.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tA(A,M){var t,I=M;for("string"==typeof A&&(A=[A]),i(M)&&(I=function(A,t){t[M]=j(A)}),t=0;t=0&&isFinite(T.getFullYear())&&T.setFullYear(A),T}function xA(A){var M=new Date(Date.UTC.apply(null,arguments));return A<100&&A>=0&&isFinite(M.getUTCFullYear())&&M.setUTCFullYear(A),M}function jA(A,M,t){var I=7+M-t,g=(7+xA(A,0,I).getUTCDay()-M)%7;return-g+I-1}function yA(A,M,t,I,g){var e,i,T=(7+t-I)%7,E=jA(A,I,g),N=1+7*(M-1)+T+E;return N<=0?(e=A-1,i=BA(e)+N):N>BA(A)?(e=A+1,i=N-BA(A)):(e=A,i=N),{year:e,dayOfYear:i}}function uA(A,M,t){var I,g,e=jA(A.year(),M,t),i=Math.floor((A.dayOfYear()-e-1)/7)+1;return i<1?(g=A.year()-1,I=i+wA(g,M,t)):i>wA(A.year(),M,t)?(I=i-wA(A.year(),M,t),g=A.year()+1):(g=A.year(),I=i),{week:I,year:g}}function wA(A,M,t){var I=jA(A,M,t),g=jA(A+1,M,t);return(BA(A)-I+g)/7}function lA(A){return uA(A,this._week.dow,this._week.doy).week}function LA(){return this._week.dow}function YA(){return this._week.doy}function dA(A){var M=this.localeData().week(this);return null==A?M:this.add(7*(A-M),"d")}function hA(A){var M=uA(this,1,4).week;return null==A?M:this.add(7*(A-M),"d")}function SA(A,M){return"string"!=typeof A?A:isNaN(A)?(A=M.weekdaysParse(A),"number"==typeof A?A:null):parseInt(A,10)}function zA(A,M){return"string"==typeof A?M.weekdaysParse(A)%7||7:isNaN(A)?null:A}function pA(A,M){return A?I(this._weekdays)?this._weekdays[A.day()]:this._weekdays[this._weekdays.isFormat.test(M)?"format":"standalone"][A.day()]:this._weekdays}function UA(A){return A?this._weekdaysShort[A.day()]:this._weekdaysShort}function OA(A){return A?this._weekdaysMin[A.day()]:this._weekdaysMin}function mA(A,M,t){var I,g,e,i=A.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],I=0;I<7;++I)e=n([2e3,1]).day(I),this._minWeekdaysParse[I]=this.weekdaysMin(e,"").toLocaleLowerCase(),this._shortWeekdaysParse[I]=this.weekdaysShort(e,"").toLocaleLowerCase(),this._weekdaysParse[I]=this.weekdays(e,"").toLocaleLowerCase();return t?"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:null):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null):"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null)))}function FA(A,M,t){var I,g,e;if(this._weekdaysParseExact)return mA.call(this,A,M,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),I=0;I<7;I++){if(g=n([2e3,1]).day(I),t&&!this._fullWeekdaysParse[I]&&(this._fullWeekdaysParse[I]=new RegExp("^"+this.weekdays(g,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[I]=new RegExp("^"+this.weekdaysShort(g,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[I]=new RegExp("^"+this.weekdaysMin(g,"").replace(".",".?")+"$","i")),this._weekdaysParse[I]||(e="^"+this.weekdays(g,"")+"|^"+this.weekdaysShort(g,"")+"|^"+this.weekdaysMin(g,""),this._weekdaysParse[I]=new RegExp(e.replace(".",""),"i")),t&&"dddd"===M&&this._fullWeekdaysParse[I].test(A))return I;if(t&&"ddd"===M&&this._shortWeekdaysParse[I].test(A))return I;if(t&&"dd"===M&&this._minWeekdaysParse[I].test(A))return I;if(!t&&this._weekdaysParse[I].test(A))return I}}function fA(A){if(!this.isValid())return null!=A?this:NaN;var M=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=A?(A=SA(A,this.localeData()),this.add(A-M,"d")):M}function kA(A){if(!this.isValid())return null!=A?this:NaN;var M=(this.day()+7-this.localeData()._week.dow)%7;return null==A?M:this.add(A-M,"d")}function RA(A){if(!this.isValid())return null!=A?this:NaN;if(null!=A){var M=zA(A,this.localeData());return this.day(this.day()%7?M:M-7)}return this.day()||7}function JA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysStrictRegex:this._weekdaysRegex):(N(this,"_weekdaysRegex")||(this._weekdaysRegex=jg),this._weekdaysStrictRegex&&A?this._weekdaysStrictRegex:this._weekdaysRegex)}function GA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(N(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=yg),this._weekdaysShortStrictRegex&&A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function HA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(N(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ug),this._weekdaysMinStrictRegex&&A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function bA(){function A(A,M){return M.length-A.length}var M,t,I,g,e,i=[],T=[],E=[],N=[];for(M=0;M<7;M++)t=n([2e3,1]).day(M),I=this.weekdaysMin(t,""),g=this.weekdaysShort(t,""),e=this.weekdays(t,""),i.push(I),T.push(g),E.push(e),N.push(I),N.push(g),N.push(e);for(i.sort(A),T.sort(A),E.sort(A),N.sort(A),M=0;M<7;M++)T[M]=MA(T[M]),E[M]=MA(E[M]),N[M]=MA(N[M]);this._weekdaysRegex=new RegExp("^("+N.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+E.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+T.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function vA(){return this.hours()%12||12}function XA(){return this.hours()||24}function WA(A,M){V(A,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),M)})}function VA(A,M){return M._meridiemParse}function PA(A){return"p"===(A+"").toLowerCase().charAt(0)}function ZA(A,M,t){return A>11?t?"pm":"PM":t?"am":"AM"}function KA(A){return A?A.toLowerCase().replace("_","-"):A}function qA(A){for(var M,t,I,g,e=0;e0;){if(I=_A(g.slice(0,M).join("-")))return I;if(t&&t.length>=M&&y(g,t,!0)>=M-1)break;M--}e++}return null}function _A(M){var t=null;if(!dg[M]&&"undefined"!=typeof A&&A&&A.exports)try{t=wg._abbr,!function(){var A=new Error('Cannot find module "./locale"');throw A.code="MODULE_NOT_FOUND",A}(),$A(t)}catch(A){}return dg[M]}function $A(A,M){var t;return A&&(t=B(M)?tM(A):AM(A,M),t&&(wg=t)),wg._abbr}function AM(A,M){if(null!==M){var t=Yg;if(M.abbr=A,null!=dg[A])l("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),t=dg[A]._config;else if(null!=M.parentLocale){if(null==dg[M.parentLocale])return hg[M.parentLocale]||(hg[M.parentLocale]=[]),hg[M.parentLocale].push({name:A,config:M}),null;t=dg[M.parentLocale]._config}return dg[A]=new h(d(t,M)),hg[A]&&hg[A].forEach(function(A){AM(A.name,A.config)}),$A(A),dg[A]}return delete dg[A],null}function MM(A,M){if(null!=M){var t,I=Yg;null!=dg[A]&&(I=dg[A]._config),M=d(I,M),t=new h(M),t.parentLocale=dg[A],dg[A]=t,$A(A)}else null!=dg[A]&&(null!=dg[A].parentLocale?dg[A]=dg[A].parentLocale:null!=dg[A]&&delete dg[A]);return dg[A]}function tM(A){var M;if(A&&A._locale&&A._locale._abbr&&(A=A._locale._abbr),!A)return wg;if(!I(A)){if(M=_A(A))return M;A=[A]}return qA(A)}function IM(){return uI(dg)}function gM(A){var M,t=A._a;return t&&c(A).overflow===-2&&(M=t[tg]<0||t[tg]>11?tg:t[Ig]<1||t[Ig]>eA(t[Mg],t[tg])?Ig:t[gg]<0||t[gg]>24||24===t[gg]&&(0!==t[eg]||0!==t[ig]||0!==t[Tg])?gg:t[eg]<0||t[eg]>59?eg:t[ig]<0||t[ig]>59?ig:t[Tg]<0||t[Tg]>999?Tg:-1,c(A)._overflowDayOfYear&&(MIg)&&(M=Ig),c(A)._overflowWeeks&&M===-1&&(M=Eg),c(A)._overflowWeekday&&M===-1&&(M=Ng),c(A).overflow=M),A}function eM(A){var M,t,I,g,e,i,T=A._i,E=Sg.exec(T)||zg.exec(T);if(E){for(c(A).iso=!0,M=0,t=Ug.length;MBA(g)&&(c(A)._overflowDayOfYear=!0),t=xA(g,0,A._dayOfYear),A._a[tg]=t.getUTCMonth(),A._a[Ig]=t.getUTCDate()),M=0;M<3&&null==A._a[M];++M)A._a[M]=e[M]=I[M];for(;M<7;M++)A._a[M]=e[M]=null==A._a[M]?2===M?1:0:A._a[M];24===A._a[gg]&&0===A._a[eg]&&0===A._a[ig]&&0===A._a[Tg]&&(A._nextDay=!0,A._a[gg]=0),A._d=(A._useUTC?xA:sA).apply(null,e),null!=A._tzm&&A._d.setUTCMinutes(A._d.getUTCMinutes()-A._tzm),A._nextDay&&(A._a[gg]=24)}}function oM(A){var M,t,I,g,e,i,T,E;if(M=A._w,null!=M.GG||null!=M.W||null!=M.E)e=1,i=4,t=TM(M.GG,A._a[Mg],uA(sM(),1,4).year),I=TM(M.W,1),g=TM(M.E,1),(g<1||g>7)&&(E=!0);else{e=A._locale._week.dow,i=A._locale._week.doy;var N=uA(sM(),e,i);t=TM(M.gg,A._a[Mg],N.year),I=TM(M.w,N.week),null!=M.d?(g=M.d,(g<0||g>6)&&(E=!0)):null!=M.e?(g=M.e+e,(M.e<0||M.e>6)&&(E=!0)):g=e}I<1||I>wA(t,e,i)?c(A)._overflowWeeks=!0:null!=E?c(A)._overflowWeekday=!0:(T=yA(t,I,g,e,i),A._a[Mg]=T.year,A._dayOfYear=T.dayOfYear)}function nM(A){if(A._f===M.ISO_8601)return void eM(A);A._a=[],c(A).empty=!0;var t,I,g,e,i,T=""+A._i,E=T.length,N=0;for(g=q(A._f,A._locale).match(pI)||[],t=0;t0&&c(A).unusedInput.push(i),T=T.slice(T.indexOf(I)+I.length),N+=I.length),mI[e]?(I?c(A).empty=!1:c(A).unusedTokens.push(e),gA(e,I,A)):A._strict&&!I&&c(A).unusedTokens.push(e);c(A).charsLeftOver=E-N,T.length>0&&c(A).unusedInput.push(T),A._a[gg]<=12&&c(A).bigHour===!0&&A._a[gg]>0&&(c(A).bigHour=void 0),c(A).parsedDateParts=A._a.slice(0),c(A).meridiem=A._meridiem,A._a[gg]=CM(A._locale,A._a[gg],A._meridiem),NM(A),gM(A)}function CM(A,M,t){var I;return null==t?M:null!=A.meridiemHour?A.meridiemHour(M,t):null!=A.isPM?(I=A.isPM(t),I&&M<12&&(M+=12),I||12!==M||(M=0),M):M}function cM(A){var M,t,I,g,e;if(0===A._f.length)return c(A).invalidFormat=!0,void(A._d=new Date(NaN));for(g=0;gthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function fM(){if(!B(this._isDSTShifted))return this._isDSTShifted;var A={};if(Q(A,this),A=BM(A),A._a){var M=A._isUTC?n(A._a):sM(A._a);this._isDSTShifted=this.isValid()&&y(A._a,M.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function kM(){return!!this.isValid()&&!this._isUTC}function RM(){return!!this.isValid()&&this._isUTC}function JM(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function GM(A,M){var t,I,g,e=A,T=null;return wM(A)?e={ms:A._milliseconds,d:A._days,M:A._months}:i(A)?(e={},M?e[M]=A:e.milliseconds=A):(T=Jg.exec(A))?(t="-"===T[1]?-1:1,e={y:0,d:j(T[Ig])*t,h:j(T[gg])*t,m:j(T[eg])*t,s:j(T[ig])*t,ms:j(lM(1e3*T[Tg]))*t}):(T=Gg.exec(A))?(t="-"===T[1]?-1:1,e={y:HM(T[2],t),M:HM(T[3],t),w:HM(T[4],t),d:HM(T[5],t),h:HM(T[6],t),m:HM(T[7],t),s:HM(T[8],t)}):null==e?e={}:"object"==typeof e&&("from"in e||"to"in e)&&(g=vM(sM(e.from),sM(e.to)),e={},e.ms=g.milliseconds,e.M=g.months),I=new uM(e),wM(A)&&N(A,"_locale")&&(I._locale=A._locale),I}function HM(A,M){var t=A&&parseFloat(A.replace(",","."));return(isNaN(t)?0:t)*M}function bM(A,M){var t={milliseconds:0,months:0};return t.months=M.month()-A.month()+12*(M.year()-A.year()),A.clone().add(t.months,"M").isAfter(M)&&--t.months,t.milliseconds=+M-+A.clone().add(t.months,"M"),t}function vM(A,M){var t;return A.isValid()&&M.isValid()?(M=dM(M,A),A.isBefore(M)?t=bM(A,M):(t=bM(M,A),t.milliseconds=-t.milliseconds,t.months=-t.months),t):{milliseconds:0,months:0}}function XM(A,M){return function(t,I){var g,e;return null===I||isNaN(+I)||(l(M,"moment()."+M+"(period, number) is deprecated. Please use moment()."+M+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),e=t,t=I,I=e),t="string"==typeof t?+t:t,g=GM(t,I),WM(this,g,A),this}}function WM(A,t,I,g){var e=t._milliseconds,i=lM(t._days),T=lM(t._months);A.isValid()&&(g=null==g||g,e&&A._d.setTime(A._d.valueOf()+e*I),i&&b(A,"Date",H(A,"Date")+i*I),T&&oA(A,H(A,"Month")+T*I),g&&M.updateOffset(A,i||T))}function VM(A,M){var t=A.diff(M,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"}function PM(A,t){var I=A||sM(),g=dM(I,this).startOf("day"),e=M.calendarFormat(this,g)||"sameElse",i=t&&(L(t[e])?t[e].call(this,I):t[e]);return this.format(i||this.localeData().calendar(e,this,sM(I)))}function ZM(){return new r(this)}function KM(A,M){var t=s(A)?A:sM(A);return!(!this.isValid()||!t.isValid())&&(M=f(B(M)?"millisecond":M),"millisecond"===M?this.valueOf()>t.valueOf():t.valueOf()e&&(M=e),pt.call(this,A,M,t,I,g))}function pt(A,M,t,I,g){var e=yA(A,M,t,I,g),i=xA(e.year,0,e.dayOfYear);return this.year(i.getUTCFullYear()),this.month(i.getUTCMonth()),this.date(i.getUTCDate()),this}function Ut(A){return null==A?Math.ceil((this.month()+1)/3):this.month(3*(A-1)+this.month()%3)}function Ot(A){var M=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==A?M:this.add(A-M,"d")}function mt(A,M){M[Tg]=j(1e3*("0."+A))}function Ft(){return this._isUTC?"UTC":""}function ft(){return this._isUTC?"Coordinated Universal Time":""}function kt(A){return sM(1e3*A)}function Rt(){return sM.apply(null,arguments).parseZone()}function Jt(A){return A}function Gt(A,M,t,I){var g=tM(),e=n().set(I,M);return g[t](e,A)}function Ht(A,M,t){if(i(A)&&(M=A,A=void 0),A=A||"",null!=M)return Gt(A,M,t,"month");var I,g=[];for(I=0;I<12;I++)g[I]=Gt(A,I,t,"month");return g}function bt(A,M,t,I){"boolean"==typeof A?(i(M)&&(t=M,M=void 0),M=M||""):(M=A,t=M,A=!1,i(M)&&(t=M,M=void 0),M=M||"");var g=tM(),e=A?g._week.dow:0;if(null!=t)return Gt(M,(t+e)%7,I,"day");var T,E=[];for(T=0;T<7;T++)E[T]=Gt(M,(T+e)%7,I,"day");return E}function vt(A,M){return Ht(A,M,"months")}function Xt(A,M){return Ht(A,M,"monthsShort")}function Wt(A,M,t){return bt(A,M,t,"weekdays")}function Vt(A,M,t){return bt(A,M,t,"weekdaysShort")}function Pt(A,M,t){return bt(A,M,t,"weekdaysMin")}function Zt(){var A=this._data;return this._milliseconds=_g(this._milliseconds),this._days=_g(this._days),this._months=_g(this._months),A.milliseconds=_g(A.milliseconds),A.seconds=_g(A.seconds),A.minutes=_g(A.minutes),A.hours=_g(A.hours),A.months=_g(A.months),A.years=_g(A.years),this}function Kt(A,M,t,I){var g=GM(M,t);return A._milliseconds+=I*g._milliseconds,A._days+=I*g._days,A._months+=I*g._months,A._bubble()}function qt(A,M){return Kt(this,A,M,1)}function _t(A,M){return Kt(this,A,M,-1)}function $t(A){return A<0?Math.floor(A):Math.ceil(A)}function AI(){var A,M,t,I,g,e=this._milliseconds,i=this._days,T=this._months,E=this._data;return e>=0&&i>=0&&T>=0||e<=0&&i<=0&&T<=0||(e+=864e5*$t(tI(T)+i),i=0,T=0),E.milliseconds=e%1e3,A=x(e/1e3),E.seconds=A%60,M=x(A/60),E.minutes=M%60,t=x(M/60),E.hours=t%24,i+=x(t/24),g=x(MI(i)),T+=g,i-=$t(tI(g)),I=x(T/12),T%=12,E.days=i,E.months=T,E.years=I,this}function MI(A){return 4800*A/146097}function tI(A){return 146097*A/4800}function II(A){var M,t,I=this._milliseconds;if(A=f(A),"month"===A||"year"===A)return M=this._days+I/864e5,t=this._months+MI(M),"month"===A?t:t/12;switch(M=this._days+Math.round(tI(this._months)),A){case"week":return M/7+I/6048e5;case"day":return M+I/864e5;case"hour":return 24*M+I/36e5;case"minute":return 1440*M+I/6e4;case"second":return 86400*M+I/1e3;case"millisecond":return Math.floor(864e5*M)+I;default:throw new Error("Unknown unit "+A)}}function gI(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*j(this._months/12)}function eI(A){return function(){return this.as(A)}}function iI(A){return A=f(A),this[A+"s"]()}function TI(A){return function(){return this._data[A]}}function EI(){return x(this.days()/7)}function NI(A,M,t,I,g){return g.relativeTime(M||1,!!t,A,I)}function oI(A,M,t){var I=GM(A).abs(),g=De(I.as("s")),e=De(I.as("m")),i=De(I.as("h")),T=De(I.as("d")),E=De(I.as("M")),N=De(I.as("y")),o=g0,o[4]=t,NI.apply(null,o)}function nI(A){return void 0===A?De:"function"==typeof A&&(De=A,!0)}function CI(A,M){return void 0!==ae[A]&&(void 0===M?ae[A]:(ae[A]=M,!0))}function cI(A){var M=this.localeData(),t=oI(this,!A,M);return A&&(t=M.pastFuture(+this,t)),M.postformat(t)}function DI(){var A,M,t,I=Be(this._milliseconds)/1e3,g=Be(this._days),e=Be(this._months);A=x(I/60),M=x(A/60),I%=60,A%=60,t=x(e/12),e%=12;var i=t,T=e,E=g,N=M,o=A,n=I,C=this.asSeconds();return C?(C<0?"-":"")+"P"+(i?i+"Y":"")+(T?T+"M":"")+(E?E+"D":"")+(N||o||n?"T":"")+(N?N+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"}var aI,BI;BI=Array.prototype.some?Array.prototype.some:function(A){for(var M=Object(this),t=M.length>>>0,I=0;I68?1900:2e3)};var Bg=G("FullYear",!0);V("w",["ww",2],"wo","week"),V("W",["WW",2],"Wo","isoWeek"),F("week","w"),F("isoWeek","W"),R("week",5),R("isoWeek",5),_("w",GI),_("ww",GI,fI),_("W",GI),_("WW",GI,fI),IA(["w","ww","W","WW"],function(A,M,t,I){M[I.substr(0,1)]=j(A)});var Qg={dow:0,doy:6};V("d",0,"do","day"),V("dd",0,0,function(A){return this.localeData().weekdaysMin(this,A)}),V("ddd",0,0,function(A){return this.localeData().weekdaysShort(this,A)}),V("dddd",0,0,function(A){return this.localeData().weekdays(this,A)}),V("e",0,0,"weekday"),V("E",0,0,"isoWeekday"),F("day","d"),F("weekday","e"),F("isoWeekday","E"),R("day",11),R("weekday",11),R("isoWeekday",11),_("d",GI),_("e",GI),_("E",GI),_("dd",function(A,M){return M.weekdaysMinRegex(A)}),_("ddd",function(A,M){return M.weekdaysShortRegex(A)}),_("dddd",function(A,M){return M.weekdaysRegex(A)}),IA(["dd","ddd","dddd"],function(A,M,t,I){var g=t._locale.weekdaysParse(A,I,t._strict);null!=g?M.d=g:c(t).invalidWeekday=A}),IA(["d","e","E"],function(A,M,t,I){M[I]=j(A)});var rg="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),sg="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xg="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),jg=_I,yg=_I,ug=_I;V("H",["HH",2],0,"hour"),V("h",["hh",2],0,vA),V("k",["kk",2],0,XA),V("hmm",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)}),V("hmmss",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)+W(this.seconds(),2)}),V("Hmm",0,0,function(){return""+this.hours()+W(this.minutes(),2)}),V("Hmmss",0,0,function(){return""+this.hours()+W(this.minutes(),2)+W(this.seconds(),2)}),WA("a",!0),WA("A",!1),F("hour","h"),R("hour",13),_("a",VA),_("A",VA),_("H",GI),_("h",GI),_("HH",GI,fI),_("hh",GI,fI),_("hmm",HI),_("hmmss",bI),_("Hmm",HI),_("Hmmss",bI),tA(["H","HH"],gg),tA(["a","A"],function(A,M,t){t._isPm=t._locale.isPM(A),t._meridiem=A}),tA(["h","hh"],function(A,M,t){M[gg]=j(A),c(t).bigHour=!0}),tA("hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I)),c(t).bigHour=!0}),tA("hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g)),c(t).bigHour=!0}),tA("Hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I))}),tA("Hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g))});var wg,lg=/[ap]\.?m?\.?/i,Lg=G("Hours",!0),Yg={calendar:wI,longDateFormat:lI,invalidDate:LI,ordinal:YI,ordinalParse:dI,relativeTime:hI,months:Cg,monthsShort:cg,week:Qg,weekdays:rg,weekdaysMin:xg,weekdaysShort:sg,meridiemParse:lg},dg={},hg={},Sg=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,zg=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pg=/Z|[+-]\d\d(?::?\d\d)?/,Ug=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Og=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mg=/^\/?Date\((\-?\d+)/i;M.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(A){A._d=new Date(A._i+(A._useUTC?" UTC":""))}),M.ISO_8601=function(){};var Fg=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var A=sM.apply(null,arguments);return this.isValid()&&A.isValid()?Athis?this:A:a()}),kg=function(){return Date.now?Date.now():+new Date};LM("Z",":"),LM("ZZ",""),_("Z",KI),_("ZZ",KI),tA(["Z","ZZ"],function(A,M,t){t._useUTC=!0,t._tzm=YM(KI,A)});var Rg=/([\+\-]|\d\d)/gi;M.updateOffset=function(){};var Jg=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Gg=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;GM.fn=uM.prototype;var Hg=XM(1,"add"),bg=XM(-1,"subtract");M.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",M.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var vg=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(A){return void 0===A?this.localeData():this.locale(A)});V(0,["gg",2],0,function(){return this.weekYear()%100}),V(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Lt("gggg","weekYear"),Lt("ggggg","weekYear"),Lt("GGGG","isoWeekYear"),Lt("GGGGG","isoWeekYear"),F("weekYear","gg"),F("isoWeekYear","GG"),R("weekYear",1),R("isoWeekYear",1),_("G",PI),_("g",PI),_("GG",GI,fI),_("gg",GI,fI),_("GGGG",XI,RI),_("gggg",XI,RI),_("GGGGG",WI,JI),_("ggggg",WI,JI),IA(["gggg","ggggg","GGGG","GGGGG"],function(A,M,t,I){M[I.substr(0,2)]=j(A)}),IA(["gg","GG"],function(A,t,I,g){t[g]=M.parseTwoDigitYear(A)}),V("Q",0,"Qo","quarter"),F("quarter","Q"),R("quarter",7),_("Q",FI),tA("Q",function(A,M){M[tg]=3*(j(A)-1)}),V("D",["DD",2],"Do","date"),F("date","D"),R("date",9),_("D",GI),_("DD",GI,fI),_("Do",function(A,M){return A?M._ordinalParse:M._ordinalParseLenient}),tA(["D","DD"],Ig),tA("Do",function(A,M){M[Ig]=j(A.match(GI)[0],10)});var Xg=G("Date",!0);V("DDD",["DDDD",3],"DDDo","dayOfYear"),F("dayOfYear","DDD"),R("dayOfYear",4),_("DDD",vI),_("DDDD",kI),tA(["DDD","DDDD"],function(A,M,t){t._dayOfYear=j(A)}),V("m",["mm",2],0,"minute"),F("minute","m"),R("minute",14),_("m",GI),_("mm",GI,fI),tA(["m","mm"],eg);var Wg=G("Minutes",!1);V("s",["ss",2],0,"second"),F("second","s"),R("second",15),_("s",GI),_("ss",GI,fI),tA(["s","ss"],ig);var Vg=G("Seconds",!1);V("S",0,0,function(){return~~(this.millisecond()/100)}),V(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),V(0,["SSS",3],0,"millisecond"),V(0,["SSSS",4],0,function(){return 10*this.millisecond()}),V(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),V(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),V(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),V(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),V(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),F("millisecond","ms"),R("millisecond",16),_("S",vI,FI),_("SS",vI,fI),_("SSS",vI,kI);var Pg;for(Pg="SSSS";Pg.length<=9;Pg+="S")_(Pg,VI);for(Pg="S";Pg.length<=9;Pg+="S")tA(Pg,mt);var Zg=G("Milliseconds",!1);V("z",0,0,"zoneAbbr"),V("zz",0,0,"zoneName");var Kg=r.prototype;Kg.add=Hg,Kg.calendar=PM,Kg.clone=ZM,Kg.diff=tt,Kg.endOf=at,Kg.format=Tt,Kg.from=Et,Kg.fromNow=Nt,Kg.to=ot,Kg.toNow=nt,Kg.get=v,Kg.invalidAt=wt,Kg.isAfter=KM,Kg.isBefore=qM,Kg.isBetween=_M,Kg.isSame=$M,Kg.isSameOrAfter=At,Kg.isSameOrBefore=Mt,Kg.isValid=yt,Kg.lang=vg,Kg.locale=Ct,Kg.localeData=ct,Kg.max=fg,Kg.min=Fg,Kg.parsingFlags=ut,Kg.set=X,Kg.startOf=Dt,Kg.subtract=bg,Kg.toArray=st,Kg.toObject=xt,Kg.toDate=rt,Kg.toISOString=et,Kg.inspect=it,Kg.toJSON=jt,Kg.toString=gt,Kg.unix=Qt,Kg.valueOf=Bt,Kg.creationData=lt,Kg.year=Bg,Kg.isLeapYear=rA,Kg.weekYear=Yt,Kg.isoWeekYear=dt,Kg.quarter=Kg.quarters=Ut,Kg.month=nA,Kg.daysInMonth=CA,Kg.week=Kg.weeks=dA,Kg.isoWeek=Kg.isoWeeks=hA,Kg.weeksInYear=St,Kg.isoWeeksInYear=ht,Kg.date=Xg,Kg.day=Kg.days=fA,Kg.weekday=kA,Kg.isoWeekday=RA,Kg.dayOfYear=Ot,Kg.hour=Kg.hours=Lg,Kg.minute=Kg.minutes=Wg,Kg.second=Kg.seconds=Vg,Kg.millisecond=Kg.milliseconds=Zg,Kg.utcOffset=SM,Kg.utc=pM,Kg.local=UM,Kg.parseZone=OM,Kg.hasAlignedHourOffset=mM,Kg.isDST=FM,Kg.isLocal=kM,Kg.isUtcOffset=RM,Kg.isUtc=JM,Kg.isUTC=JM,Kg.zoneAbbr=Ft,Kg.zoneName=ft,Kg.dates=w("dates accessor is deprecated. Use date instead.",Xg),Kg.months=w("months accessor is deprecated. Use month instead",nA),Kg.years=w("years accessor is deprecated. Use year instead",Bg),Kg.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",zM),Kg.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",fM);var qg=h.prototype;qg.calendar=S,qg.longDateFormat=z,qg.invalidDate=p,qg.ordinal=U,qg.preparse=Jt,qg.postformat=Jt,qg.relativeTime=O,qg.pastFuture=m,qg.set=Y,qg.months=iA,qg.monthsShort=TA,qg.monthsParse=NA,qg.monthsRegex=DA,qg.monthsShortRegex=cA,qg.week=lA,qg.firstDayOfYear=YA,qg.firstDayOfWeek=LA,qg.weekdays=pA,qg.weekdaysMin=OA,qg.weekdaysShort=UA,qg.weekdaysParse=FA,qg.weekdaysRegex=JA,qg.weekdaysShortRegex=GA,qg.weekdaysMinRegex=HA,qg.isPM=PA,qg.meridiem=ZA,$A("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(A){var M=A%10,t=1===j(A%100/10)?"th":1===M?"st":2===M?"nd":3===M?"rd":"th";return A+t}}),M.lang=w("moment.lang is deprecated. Use moment.locale instead.",$A),M.langData=w("moment.langData is deprecated. Use moment.localeData instead.",tM);var _g=Math.abs,$g=eI("ms"),Ae=eI("s"),Me=eI("m"),te=eI("h"),Ie=eI("d"),ge=eI("w"),ee=eI("M"),ie=eI("y"),Te=TI("milliseconds"),Ee=TI("seconds"),Ne=TI("minutes"),oe=TI("hours"),ne=TI("days"),Ce=TI("months"),ce=TI("years"),De=Math.round,ae={s:45,m:45,h:22,d:26,M:11},Be=Math.abs,Qe=uM.prototype;return Qe.abs=Zt,Qe.add=qt,Qe.subtract=_t,Qe.as=II,Qe.asMilliseconds=$g,Qe.asSeconds=Ae,Qe.asMinutes=Me,Qe.asHours=te,Qe.asDays=Ie,Qe.asWeeks=ge,Qe.asMonths=ee,Qe.asYears=ie,Qe.valueOf=gI,Qe._bubble=AI,Qe.get=iI,Qe.milliseconds=Te,Qe.seconds=Ee,Qe.minutes=Ne,Qe.hours=oe,Qe.days=ne,Qe.weeks=EI,Qe.months=Ce,Qe.years=ce,Qe.humanize=cI,Qe.toISOString=DI,Qe.toString=DI,Qe.toJSON=DI,Qe.locale=Ct,Qe.localeData=ct,Qe.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",DI),Qe.lang=vg,V("X",0,0,"unix"),V("x",0,0,"valueOf"),_("x",PI),_("X",qI),tA("X",function(A,M,t){t._d=new Date(1e3*parseFloat(A,10))}),tA("x",function(A,M,t){t._d=new Date(j(A))}),M.version="2.17.1",t(sM),M.fn=Kg,M.min=jM,M.max=yM,M.now=kg,M.utc=n,M.unix=kt,M.months=vt,M.isDate=T,M.locale=$A,M.invalid=a,M.duration=GM,M.isMoment=s,M.weekdays=Wt,M.parseZone=Rt,M.localeData=tM,M.isDuration=wM,M.monthsShort=Xt,M.weekdaysMin=Pt,M.defineLocale=AM,M.updateLocale=MM,M.locales=IM,M.weekdaysShort=Vt,M.normalizeUnits=f,M.relativeTimeRounding=nI,M.relativeTimeThreshold=CI,M.calendarFormat=VM,M.prototype=Kg,M})}).call(M,t(128)(A))},function(A,M,t){"use strict";var I=t(132).default,g=t(133).default,e=t(78).default;M.__esModule=!0;var i=function(A){return I(g({values:function(){var A=this;return e(this).map(function(M){return A[M]})}}),A)},T={SIZES:{large:"lg",medium:"md",small:"sm",xsmall:"xs",lg:"lg",md:"md",sm:"sm",xs:"xs"},GRID_COLUMNS:12},E=i({LARGE:"large",MEDIUM:"medium",SMALL:"small",XSMALL:"xsmall"});M.Sizes=E;var N=i({SUCCESS:"success",WARNING:"warning",DANGER:"danger",INFO:"info"});M.State=N;var o="default";M.DEFAULT=o;var n="primary";M.PRIMARY=n;var C="link";M.LINK=C;var c="inverse";M.INVERSE=c,M.default=T},function(A,M){"use strict";function t(){for(var A=arguments.length,M=Array(A),t=0;t0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURI(o))):"("===E?g+=1:")"===E?g-=1:":"===E.charAt(0)?(N=E.substring(1),o=M[N],null!=o||g>0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURIComponent(o))):e+=E;return e.replace(/\/+/g,"/")}M.__esModule=!0,M.compilePattern=i,M.matchPattern=T,M.getParamNames=E,M.getParams=N,M.formatPattern=o;var n=t(8),C=I(n),c=Object.create(null)},function(A,M){"use strict";M.__esModule=!0;var t="PUSH";M.PUSH=t;var I="REPLACE";M.REPLACE=I;var g="POP";M.POP=g,M.default={PUSH:t,REPLACE:I,POP:g}},function(A,M,t){"use strict";function I(A,M){return(A&M)===M}var g=t(2),e={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(A){var M=e,t=A.Properties||{},i=A.DOMAttributeNamespaces||{},E=A.DOMAttributeNames||{},N=A.DOMPropertyNames||{},o=A.DOMMutationMethods||{};A.isCustomAttribute&&T._isCustomAttributeFunctions.push(A.isCustomAttribute);for(var n in t){T.properties.hasOwnProperty(n)?g(!1):void 0;var C=n.toLowerCase(),c=t[n],D={attributeName:C,attributeNamespace:null,propertyName:n,mutationMethod:null,mustUseAttribute:I(c,M.MUST_USE_ATTRIBUTE),mustUseProperty:I(c,M.MUST_USE_PROPERTY),hasSideEffects:I(c,M.HAS_SIDE_EFFECTS),hasBooleanValue:I(c,M.HAS_BOOLEAN_VALUE),hasNumericValue:I(c,M.HAS_NUMERIC_VALUE),hasPositiveNumericValue:I(c,M.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:I(c,M.HAS_OVERLOADED_BOOLEAN_VALUE)};if(D.mustUseAttribute&&D.mustUseProperty?g(!1):void 0,!D.mustUseProperty&&D.hasSideEffects?g(!1):void 0,D.hasBooleanValue+D.hasNumericValue+D.hasOverloadedBooleanValue<=1?void 0:g(!1),E.hasOwnProperty(n)){var a=E[n];D.attributeName=a}i.hasOwnProperty(n)&&(D.attributeNamespace=i[n]),N.hasOwnProperty(n)&&(D.propertyName=N[n]),o.hasOwnProperty(n)&&(D.mutationMethod=o[n]),T.properties[n]=D}}},i={},T={ID_ATTRIBUTE_NAME:"data-reactid",properties:{},getPossibleStandardName:null,_isCustomAttributeFunctions:[],isCustomAttribute:function(A){for(var M=0;M1){var M=A.indexOf(c,1);return M>-1?A.substr(0,M):A}return null},traverseEnterLeave:function(A,M,t,I,g){var e=N(A,M);e!==A&&o(A,e,t,I,!1,!0),e!==M&&o(e,M,t,g,!0,!1)},traverseTwoPhase:function(A,M,t){A&&(o("",A,M,t,!0,!1),o(A,"",M,t,!1,!0))},traverseTwoPhaseSkipTarget:function(A,M,t){A&&(o("",A,M,t,!0,!0),o(A,"",M,t,!0,!0))},traverseAncestors:function(A,M,t){o("",A,M,t,!0,!1)},getFirstCommonAncestorID:N,_getNextDescendantID:E,isAncestorIDOf:i,SEPARATOR:c};A.exports=B},function(A,M){var t=A.exports={version:"1.2.6"};"number"==typeof __e&&(__e=t)},function(A,M,t){"use strict";var I={};A.exports=I},function(A,M,t){"use strict";function I(A,M,t){var I=0;return n.default.Children.map(A,function(A){if(n.default.isValidElement(A)){var g=I;return I++,M.call(t,A,g)}return A})}function g(A,M,t){var I=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I),I++)})}function e(A){var M=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&M++}),M}function i(A){var M=!1;return n.default.Children.forEach(A,function(A){!M&&n.default.isValidElement(A)&&(M=!0)}),M}function T(A,M){var t=void 0;return g(A,function(I,g){!t&&M(I,g,A)&&(t=I)}),t}function E(A,M,t){var I=0,g=[];return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I)&&g.push(A),I++)}),g}var N=t(6).default;M.__esModule=!0;var o=t(1),n=N(o);M.default={map:I,forEach:g,numberOf:e,find:T,findValidComponents:E,hasValidComponent:i},A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=function(A){return(0,T.default)(e.default.findDOMNode(A))};var g=t(16),e=I(g),i=t(39),T=I(i);A.exports=M.default},function(A,M,t){"use strict";var I=t(204),g=t(437),e=t(217),i=t(226),T=t(227),E=t(2),N=(t(3),{}),o=null,n=function(A,M){A&&(g.executeDispatchesInOrder(A,M),A.isPersistent()||A.constructor.release(A))},C=function(A){return n(A,!0)},c=function(A){return n(A,!1)},D=null,a={injection:{injectMount:g.injection.injectMount,injectInstanceHandle:function(A){D=A},getInstanceHandle:function(){return D},injectEventPluginOrder:I.injectEventPluginOrder,injectEventPluginsByName:I.injectEventPluginsByName},eventNameDispatchConfigs:I.eventNameDispatchConfigs,registrationNameModules:I.registrationNameModules,putListener:function(A,M,t){"function"!=typeof t?E(!1):void 0;var g=N[M]||(N[M]={});g[A]=t;var e=I.registrationNameModules[M];e&&e.didPutListener&&e.didPutListener(A,M,t)},getListener:function(A,M){var t=N[M];return t&&t[A]},deleteListener:function(A,M){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M);var g=N[M];g&&delete g[A]},deleteAllListeners:function(A){for(var M in N)if(N[M][A]){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M),delete N[M][A]}},extractEvents:function(A,M,t,g,e){for(var T,E=I.plugins,N=0;N1?I-1:0),e=1;e":">","<":"<",'"':""","'":"'"},e=/[&><"']/g;A.exports=I},function(A,M,t){"use strict";var I=t(10),g=/^[ \r\n\t\f]/,e=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(A,M){A.innerHTML=M};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(A,M){MSApp.execUnsafeLocalFunction(function(){A.innerHTML=M})}),I.canUseDOM){var T=document.createElement("div");T.innerHTML=" ",""===T.innerHTML&&(i=function(A,M){if(A.parentNode&&A.parentNode.replaceChild(A,A),g.test(M)||"<"===M[0]&&e.test(M)){A.innerHTML=String.fromCharCode(65279)+M;var t=A.firstChild;1===t.data.length?A.removeChild(t):t.deleteData(0,1)}else A.innerHTML=M})}A.exports=i},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=function(A){var M=A.label,t=A.id,I=A.name,g=A.value,i=A.onChange,T=A.type,E=A.spellCheck,N=A.required,o=A.readonly,n=A.autoComplete,C=A.align,c=A.className,D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n});return o&&(D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n,disabled:!0})),e.default.createElement("div",{className:"input-group "+C+" "+c},D,e.default.createElement("i",{className:"ig-helpers"}),e.default.createElement("label",{className:"ig-label"},M))};M.default=i},function(A,M,t){A.exports={default:t(259),__esModule:!0}},function(A,M,t){var I=t(265),g=t(49),e=t(134),i="prototype",T=function(A,M,t){var E,N,o,n=A&T.F,C=A&T.G,c=A&T.S,D=A&T.P,a=A&T.B,B=A&T.W,Q=C?g:g[M]||(g[M]={}),r=C?I:c?I[M]:(I[M]||{})[i];C&&(t=M);for(E in t)N=!n&&r&&E in r,N&&E in Q||(o=N?r[E]:t[E],Q[E]=C&&"function"!=typeof r[E]?t[E]:a&&N?e(o,I):B&&r[E]==o?function(A){var M=function(M){return this instanceof A?new A(M):A(M)};return M[i]=A[i],M}(o):D&&"function"==typeof o?e(Function.call,o):o,D&&((Q[i]||(Q[i]={}))[E]=o))};T.F=1,T.G=2,T.S=4,T.P=8,T.B=16,T.W=32,A.exports=T},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M,t){"use strict";var I=t(32),g=function(){};I&&(g=function(){return document.addEventListener?function(A,M,t,I){return A.addEventListener(M,t,I||!1)}:document.attachEvent?function(A,M,t){return A.attachEvent("on"+M,t)}:void 0}()),A.exports=g},function(A,M,t){"use strict";var I=t(145),g=t(295),e=t(290),i=t(291),T=Object.prototype.hasOwnProperty;A.exports=function(A,M,t){var E="",N=M;if("string"==typeof M){if(void 0===t)return A.style[I(M)]||e(A).getPropertyValue(g(M));(N={})[M]=t}for(var o in N)T.call(N,o)&&(N[o]||0===N[o]?E+=g(o)+":"+N[o]+";":i(A,g(o)));A.style.cssText+=";"+E}},function(A,M,t){(function(){var t=this,I=t.humanize,g={};"undefined"!=typeof A&&A.exports&&(M=A.exports=g),M.humanize=g,g.noConflict=function(){return t.humanize=I,this},g.pad=function(A,M,t,I){if(A+="",t?t.length>1&&(t=t.charAt(0)):t=" ",I=void 0===I?"left":"right","right"===I)for(;A.length4&&A<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th"},w:function(){return t.getDay()},z:function(){return(o.L()?i[o.n()]:e[o.n()])+o.j()-1},W:function(){var A=o.z()-o.N()+1.5;return g.pad(1+Math.floor(Math.abs(A)/7)+(A%7>3.5?1:0),2,"0")},F:function(){return N[t.getMonth()]},m:function(){return g.pad(o.n(),2,"0")},M:function(){return o.F().slice(0,3)},n:function(){return t.getMonth()+1},t:function(){return new Date(o.Y(),o.n(),0).getDate()},L:function(){return 1===new Date(o.Y(),1,29).getMonth()?1:0},o:function(){var A=o.n(),M=o.W();return o.Y()+(12===A&&M<9?-1:1===A&&M>9)},Y:function(){return t.getFullYear()},y:function(){return String(o.Y()).slice(-2)},a:function(){return t.getHours()>11?"pm":"am"},A:function(){return o.a().toUpperCase()},B:function(){var A=t.getTime()/1e3,M=A%86400+3600;M<0&&(M+=86400);var I=M/86.4%1e3;return A<0?Math.ceil(I):Math.floor(I)},g:function(){return o.G()%12||12},G:function(){return t.getHours()},h:function(){return g.pad(o.g(),2,"0")},H:function(){return g.pad(o.G(),2,"0")},i:function(){return g.pad(t.getMinutes(),2,"0")},s:function(){return g.pad(t.getSeconds(),2,"0")},u:function(){return g.pad(1e3*t.getMilliseconds(),6,"0")},O:function(){var A=t.getTimezoneOffset(),M=Math.abs(A);return(A>0?"-":"+")+g.pad(100*Math.floor(M/60)+M%60,4,"0")},P:function(){var A=o.O();return A.substr(0,3)+":"+A.substr(3,2)},Z:function(){return 60*-t.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(I,T)},r:function(){return"D, d M Y H:i:s O".replace(I,T)},U:function(){return t.getTime()/1e3||0}};return A.replace(I,T)},g.numberFormat=function(A,M,t,I){M=isNaN(M)?2:Math.abs(M),t=void 0===t?".":t,I=void 0===I?",":I;var g=A<0?"-":"";A=Math.abs(+A||0);var e=parseInt(A.toFixed(M),10)+"",i=e.length>3?e.length%3:0;return g+(i?e.substr(0,i)+I:"")+e.substr(i).replace(/(\d{3})(?=\d)/g,"$1"+I)+(M?t+Math.abs(A-e).toFixed(M).slice(2):"")},g.naturalDay=function(A,M){A=void 0===A?g.time():A,M=void 0===M?"Y-m-d":M;var t=86400,I=new Date,e=new Date(I.getFullYear(),I.getMonth(),I.getDate()).getTime()/1e3;return A=e-t?"yesterday":A>=e&&A=e+t&&A-2)return(t>=0?"just ":"")+"now";if(t<60&&t>-60)return t>=0?Math.floor(t)+" seconds ago":"in "+Math.floor(-t)+" seconds";if(t<120&&t>-120)return t>=0?"about a minute ago":"in about a minute";if(t<3600&&t>-3600)return t>=0?Math.floor(t/60)+" minutes ago":"in "+Math.floor(-t/60)+" minutes";if(t<7200&&t>-7200)return t>=0?"about an hour ago":"in about an hour";if(t<86400&&t>-86400)return t>=0?Math.floor(t/3600)+" hours ago":"in "+Math.floor(-t/3600)+" hours";var I=172800;if(t-I)return t>=0?"1 day ago":"in 1 day";var e=2505600;if(t-e)return t>=0?Math.floor(t/86400)+" days ago":"in "+Math.floor(-t/86400)+" days";var i=5184e3;if(t-i)return t>=0?"about a month ago":"in about a month";var T=parseInt(g.date("Y",M),10),E=parseInt(g.date("Y",A),10),N=12*T+parseInt(g.date("n",M),10),o=12*E+parseInt(g.date("n",A),10),n=N-o;if(n<12&&n>-12)return n>=0?n+" months ago":"in "+-n+" months";var C=T-E;return C<2&&C>-2?C>=0?"a year ago":"in a year":C>=0?C+" years ago":"in "+-C+" years"},g.ordinal=function(A){A=parseInt(A,10),A=isNaN(A)?0:A;var M=A<0?"-":"";A=Math.abs(A);var t=A%100;return M+A+(t>4&&t<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th")},g.filesize=function(A,M,t,I,e,i){return M=void 0===M?1024:M,A<=0?"0 bytes":(A

    "),A=A.replace(/\n/g,"
    "),"

    "+A+"

    "},g.nl2br=function(A){return A.replace(/(\r\n|\n|\r)/g,"
    ")},g.truncatechars=function(A,M){return A.length<=M?A:A.substr(0,M)+"…"},g.truncatewords=function(A,M){var t=A.split(" ");return t.length0,Q=C.enumErrorProps&&(A===u||A instanceof Error),r=C.enumPrototypes&&T(A);++IM.documentElement.clientHeight;return{modalStyles:{paddingRight:I&&!g?Q.default():void 0,paddingLeft:!I&&g?Q.default():void 0}}}});v.Body=z.default,v.Header=U.default,v.Title=m.default,v.Footer=f.default,v.Dialog=h.default,v.TRANSITION_DURATION=300,v.BACKDROP_TRANSITION_DURATION=150,M.default=c.bsSizes([a.Sizes.LARGE,a.Sizes.SMALL],c.bsClass("modal",v)), -A.exports=M.default},function(A,M,t){"use strict";var I=t(15).default,g=t(14).default,e=t(38).default,i=t(7).default,T=t(6).default;M.__esModule=!0;var E=t(1),N=T(E),o=t(5),n=T(o),C=t(11),c=T(C),D=t(44),a=T(D),B=function(A){function M(){g(this,M),A.apply(this,arguments)}return I(M,A),M.prototype.render=function(){var A=this.props,M=A["aria-label"],t=e(A,["aria-label"]),I=a.default(this.context.$bs_onModalHide,this.props.onHide);return N.default.createElement("div",i({},t,{className:n.default(this.props.className,c.default.prefix(this.props,"header"))}),this.props.closeButton&&N.default.createElement("button",{type:"button",className:"close","aria-label":M,onClick:I},N.default.createElement("span",{"aria-hidden":"true"},"×")),this.props.children)},M}(N.default.Component);B.propTypes={"aria-label":N.default.PropTypes.string,bsClass:N.default.PropTypes.string,closeButton:N.default.PropTypes.bool,onHide:N.default.PropTypes.func},B.contextTypes={$bs_onModalHide:N.default.PropTypes.func},B.defaultProps={"aria-label":"Close",closeButton:!1},M.default=C.bsClass("modal",B),A.exports=M.default},function(A,M,t){"use strict";function I(A,M){return Array.isArray(M)?M.indexOf(A)>=0:A===M}var g=t(7).default,e=t(78).default,i=t(6).default;M.__esModule=!0;var T=t(40),E=i(T),N=t(170),o=i(N),n=t(1),C=i(n),c=t(16),D=i(c),a=t(127),B=(i(a),t(370)),Q=i(B),r=t(44),s=i(r),x=C.default.createClass({displayName:"OverlayTrigger",propTypes:g({},Q.default.propTypes,{trigger:C.default.PropTypes.oneOfType([C.default.PropTypes.oneOf(["click","hover","focus"]),C.default.PropTypes.arrayOf(C.default.PropTypes.oneOf(["click","hover","focus"]))]),delay:C.default.PropTypes.number,delayShow:C.default.PropTypes.number,delayHide:C.default.PropTypes.number,defaultOverlayShown:C.default.PropTypes.bool,overlay:C.default.PropTypes.node.isRequired,onBlur:C.default.PropTypes.func,onClick:C.default.PropTypes.func,onFocus:C.default.PropTypes.func,onMouseEnter:C.default.PropTypes.func,onMouseLeave:C.default.PropTypes.func,target:function(){},onHide:function(){},show:function(){}}),getDefaultProps:function(){return{defaultOverlayShown:!1,trigger:["hover","focus"]}},getInitialState:function(){return{isOverlayShown:this.props.defaultOverlayShown}},show:function(){this.setState({isOverlayShown:!0})},hide:function(){this.setState({isOverlayShown:!1})},toggle:function(){this.state.isOverlayShown?this.hide():this.show()},componentWillMount:function(){this.handleMouseOver=this.handleMouseOverOut.bind(null,this.handleDelayedShow),this.handleMouseOut=this.handleMouseOverOut.bind(null,this.handleDelayedHide)},componentDidMount:function(){this._mountNode=document.createElement("div"),this.renderOverlay()},renderOverlay:function(){D.default.unstable_renderSubtreeIntoContainer(this,this._overlay,this._mountNode)},componentWillUnmount:function(){D.default.unmountComponentAtNode(this._mountNode),this._mountNode=null,clearTimeout(this._hoverShowDelay),clearTimeout(this._hoverHideDelay)},componentDidUpdate:function(){this._mountNode&&this.renderOverlay()},getOverlayTarget:function(){return D.default.findDOMNode(this)},getOverlay:function(){var A=g({},o.default(this.props,e(Q.default.propTypes)),{show:this.state.isOverlayShown,onHide:this.hide,target:this.getOverlayTarget,onExit:this.props.onExit,onExiting:this.props.onExiting,onExited:this.props.onExited,onEnter:this.props.onEnter,onEntering:this.props.onEntering,onEntered:this.props.onEntered}),M=n.cloneElement(this.props.overlay,{placement:A.placement,container:A.container});return C.default.createElement(Q.default,A,M)},render:function(){var A=C.default.Children.only(this.props.children),M=A.props,t={"aria-describedby":this.props.overlay.props.id};return this._overlay=this.getOverlay(),t.onClick=s.default(M.onClick,this.props.onClick),I("click",this.props.trigger)&&(t.onClick=s.default(this.toggle,t.onClick)),I("hover",this.props.trigger)&&(t.onMouseOver=s.default(this.handleMouseOver,this.props.onMouseOver,M.onMouseOver),t.onMouseOut=s.default(this.handleMouseOut,this.props.onMouseOut,M.onMouseOut)),I("focus",this.props.trigger)&&(t.onFocus=s.default(this.handleDelayedShow,this.props.onFocus,M.onFocus),t.onBlur=s.default(this.handleDelayedHide,this.props.onBlur,M.onBlur)),n.cloneElement(A,t)},handleDelayedShow:function(){var A=this;if(null!=this._hoverHideDelay)return clearTimeout(this._hoverHideDelay),void(this._hoverHideDelay=null);if(!this.state.isOverlayShown&&null==this._hoverShowDelay){var M=null!=this.props.delayShow?this.props.delayShow:this.props.delay;return M?void(this._hoverShowDelay=setTimeout(function(){A._hoverShowDelay=null,A.show()},M)):void this.show()}},handleDelayedHide:function(){var A=this;if(null!=this._hoverShowDelay)return clearTimeout(this._hoverShowDelay),void(this._hoverShowDelay=null);if(this.state.isOverlayShown&&null==this._hoverHideDelay){var M=null!=this.props.delayHide?this.props.delayHide:this.props.delay;return M?void(this._hoverHideDelay=setTimeout(function(){A._hoverHideDelay=null,A.hide()},M)):void this.hide()}},handleMouseOverOut:function(A,M){var t=M.currentTarget,I=M.relatedTarget||M.nativeEvent.toElement;I&&(I===t||E.default(t,I))||A(M)}});M.default=x,A.exports=M.default},function(A,M,t){"use strict";var I=t(7).default,g=t(6).default;M.__esModule=!0;var e=t(1),i=g(e),T=t(5),E=g(T),N=t(11),o=g(N),n=t(183),C=g(n),c=i.default.createClass({displayName:"Tooltip",propTypes:{id:C.default(i.default.PropTypes.oneOfType([i.default.PropTypes.string,i.default.PropTypes.number])),placement:i.default.PropTypes.oneOf(["top","right","bottom","left"]),positionLeft:i.default.PropTypes.number,positionTop:i.default.PropTypes.number,arrowOffsetLeft:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),arrowOffsetTop:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),title:i.default.PropTypes.node},getDefaultProps:function(){return{bsClass:"tooltip",placement:"right"}},render:function(){var A,M=(A={},A[o.default.prefix(this.props)]=!0,A[this.props.placement]=!0,A),t=I({left:this.props.positionLeft,top:this.props.positionTop},this.props.style),g={left:this.props.arrowOffsetLeft,top:this.props.arrowOffsetTop};return i.default.createElement("div",I({role:"tooltip"},this.props,{className:E.default(this.props.className,M),style:t}),i.default.createElement("div",{className:o.default.prefix(this.props,"arrow"),style:g}),i.default.createElement("div",{className:o.default.prefix(this.props,"inner")},this.props.children))}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return A="function"==typeof A?A():A,i.default.findDOMNode(A)||M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=g;var e=t(16),i=I(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement. You can usually obtain a ReactComponent or DOMElement from a ReactElement by attaching a ref to it."):"object"===E&&"function"==typeof i.render||1===i.nodeType?null:new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement.")}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M,t){"use strict";function I(){function A(A,M,I){for(var g=0;g>",null!=t[I]?A(t,I,g):M?new Error("Required prop '"+I+"' was not specified in '"+g+"'."):void 0}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}M.__esModule=!0,M.errMsg=t,M.createChainableTypeChecker=I},function(A,M){"use strict";function t(A,M,t){function I(){return i=!0,T?void(N=[].concat(Array.prototype.slice.call(arguments))):void t.apply(this,arguments)}function g(){if(!i&&(E=!0,!T)){for(T=!0;!i&&e=A&&E&&(i=!0,t()))}}var e=0,i=!1,T=!1,E=!1,N=void 0;g()}function I(A,M,t){function I(A,M,I){i||(M?(i=!0,t(M)):(e[A]=I,i=++T===g,i&&t(null,e)))}var g=A.length,e=[];if(0===g)return t(null,e);var i=!1,T=0;A.forEach(function(A,t){M(A,t,function(A,M){I(t,A,M)})})}M.__esModule=!0,M.loopAsync=t,M.mapAsync=I},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0,M.router=M.routes=M.route=M.components=M.component=M.location=M.history=M.falsy=M.locationShape=M.routerShape=void 0;var e=t(1),i=t(66),T=(g(i),t(34)),E=I(T),N=t(9),o=(g(N),e.PropTypes.func),n=e.PropTypes.object,C=e.PropTypes.shape,c=e.PropTypes.string,D=M.routerShape=C({push:o.isRequired,replace:o.isRequired,go:o.isRequired,goBack:o.isRequired,goForward:o.isRequired,setRouteLeaveHook:o.isRequired,isActive:o.isRequired}),a=M.locationShape=C({pathname:c.isRequired,search:c.isRequired,state:n,action:c.isRequired,key:c}),B=M.falsy=E.falsy,Q=M.history=E.history,r=M.location=a,s=M.component=E.component,x=M.components=E.components,j=M.route=E.route,y=(M.routes=E.routes,M.router=D),u={falsy:B,history:Q,location:r,component:s,components:x,route:j,router:y};M.default=u},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!0;return!1}function e(A,M){function t(M){var t=!(arguments.length<=1||void 0===arguments[1])&&arguments[1],I=arguments.length<=2||void 0===arguments[2]?null:arguments[2],g=void 0;return t&&t!==!0||null!==I?(M={pathname:M,query:t},g=I||!1):(M=A.createLocation(M),g=t),(0,C.default)(M,g,s.location,s.routes,s.params)}function I(A,t){x&&x.location===A?e(x,t):(0,B.default)(M,A,function(M,I){M?t(M):I?e(i({},I,{location:A}),t):t()})}function e(A,M){function t(t,g){return t||g?I(t,g):void(0,D.default)(A,function(t,I){t?M(t):M(null,null,s=i({},A,{components:I}))})}function I(A,t){A?M(A):M(null,t)}var g=(0,N.default)(s,A),e=g.leaveRoutes,T=g.changeRoutes,E=g.enterRoutes;(0,o.runLeaveHooks)(e,s),e.filter(function(A){return E.indexOf(A)===-1}).forEach(a),(0,o.runChangeHooks)(T,s,A,function(M,g){return M||g?I(M,g):void(0,o.runEnterHooks)(E,A,t)})}function T(A){var M=arguments.length<=1||void 0===arguments[1]||arguments[1];return A.__id__||M&&(A.__id__=j++)}function E(A){return A.reduce(function(A,M){return A.push.apply(A,y[T(M)]),A},[])}function n(A,t){(0,B.default)(M,A,function(M,I){if(null==I)return void t();x=i({},I,{location:A});for(var g=E((0,N.default)(s,x).leaveRoutes),e=void 0,T=0,o=g.length;null==e&&T=32||13===M?M:0}A.exports=t},function(A,M){"use strict";function t(A){var M=this,t=M.nativeEvent;if(t.getModifierState)return t.getModifierState(A);var I=g[A];return!!I&&!!t[I]}function I(A){return t}var g={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};A.exports=I},function(A,M){"use strict";function t(A){var M=A.target||A.srcElement||window;return 3===M.nodeType?M.parentNode:M}A.exports=t},function(A,M){"use strict";function t(A){var M=A&&(I&&A[I]||A[g]);if("function"==typeof M)return M}var I="function"==typeof Symbol&&Symbol.iterator,g="@@iterator";A.exports=t},function(A,M,t){"use strict";function I(A){return"function"==typeof A&&"undefined"!=typeof A.prototype&&"function"==typeof A.prototype.mountComponent&&"function"==typeof A.prototype.receiveComponent}function g(A){var M;if(null===A||A===!1)M=new i(g);else if("object"==typeof A){var t=A;!t||"function"!=typeof t.type&&"string"!=typeof t.type?N(!1):void 0,M="string"==typeof t.type?T.createInternalComponent(t):I(t.type)?new t.type(t):new o}else"string"==typeof A||"number"==typeof A?M=T.createInstanceForText(A):N(!1);return M.construct(A),M._mountIndex=0,M._mountImage=null,M}var e=t(443),i=t(215),T=t(221),E=t(4),N=t(2),o=(t(3),function(){});E(o.prototype,e.Mixin,{_instantiateReactComponent:g}),A.exports=g},function(A,M,t){"use strict";/** +!function(){"use strict";function t(){for(var A=[],M=0;M2?t-2:0),g=2;g1){for(var c=Array(C),D=0;D1){for(var a=Array(D),B=0;B3&&void 0!==arguments[3]?arguments[3]:{},N=Boolean(A),C=A||w,D=void 0;D="function"==typeof M?M:M?(0,Q.default)(M):l;var B=t||L,r=I.pure,s=void 0===r||r,x=I.withRef,y=void 0!==x&&x,h=s&&B!==L,S=d++;return function(A){function M(A,M,t){var I=B(A,M,t);return I}var t="Connect("+T(A)+")",I=function(I){function T(A,M){g(this,T);var i=e(this,I.call(this,A,M));i.version=S,i.store=A.store||M.store,(0,u.default)(i.store,'Could not find "store" in either the context or '+('props of "'+t+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+t+'".'));var E=i.store.getState();return i.state={storeState:E},i.clearCache(),i}return i(T,I),T.prototype.shouldComponentUpdate=function(){return!s||this.haveOwnPropsChanged||this.hasStoreStateChanged},T.prototype.computeStateProps=function(A,M){if(!this.finalMapStateToProps)return this.configureFinalMapState(A,M);var t=A.getState(),I=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(t,M):this.finalMapStateToProps(t);return I},T.prototype.configureFinalMapState=function(A,M){var t=C(A.getState(),M),I="function"==typeof t;return this.finalMapStateToProps=I?t:C,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,I?this.computeStateProps(A,M):t},T.prototype.computeDispatchProps=function(A,M){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(A,M);var t=A.dispatch,I=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(t,M):this.finalMapDispatchToProps(t);return I},T.prototype.configureFinalMapDispatch=function(A,M){var t=D(A.dispatch,M),I="function"==typeof t;return this.finalMapDispatchToProps=I?t:D,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,I?this.computeDispatchProps(A,M):t},T.prototype.updateStatePropsIfNeeded=function(){var A=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,a.default)(A,this.stateProps))&&(this.stateProps=A,!0)},T.prototype.updateDispatchPropsIfNeeded=function(){var A=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,a.default)(A,this.dispatchProps))&&(this.dispatchProps=A,!0)},T.prototype.updateMergedPropsIfNeeded=function(){var A=M(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&h&&(0,a.default)(A,this.mergedProps))&&(this.mergedProps=A,!0)},T.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},T.prototype.trySubscribe=function(){N&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},T.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},T.prototype.componentDidMount=function(){this.trySubscribe()},T.prototype.componentWillReceiveProps=function(A){s&&(0,a.default)(A,this.props)||(this.haveOwnPropsChanged=!0)},T.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},T.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},T.prototype.handleChange=function(){if(this.unsubscribe){var A=this.store.getState(),M=this.state.storeState;if(!s||M!==A){if(s&&!this.doStatePropsDependOnOwnProps){var t=E(this.updateStatePropsIfNeeded,this);if(!t)return;t===Y&&(this.statePropsPrecalculationError=Y.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:A})}}},T.prototype.getWrappedInstance=function(){return(0,u.default)(y,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},T.prototype.render=function(){var M=this.haveOwnPropsChanged,t=this.hasStoreStateChanged,I=this.haveStatePropsBeenPrecalculated,g=this.statePropsPrecalculationError,e=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,g)throw g;var i=!0,T=!0;s&&e&&(i=t||M&&this.doStatePropsDependOnOwnProps,T=M&&this.doDispatchPropsDependOnOwnProps);var E=!1,N=!1;I?E=!0:i&&(E=this.updateStatePropsIfNeeded()),T&&(N=this.updateDispatchPropsIfNeeded());var C=!0;return C=!!(E||N||M)&&this.updateMergedPropsIfNeeded(),!C&&e?e:(y?this.renderedElement=(0,n.createElement)(A,o({},this.mergedProps,{ref:"wrappedInstance"})):this.renderedElement=(0,n.createElement)(A,this.mergedProps),this.renderedElement)},T}(n.Component);return I.displayName=t,I.WrappedComponent=A,I.contextTypes={store:c.default},I.propTypes={store:c.default},(0,j.default)(I,A)}}M.__esModule=!0;var o=Object.assign||function(A){for(var M=1;M should not have a "'+M+'" prop')}M.__esModule=!0,M.routes=M.route=M.components=M.component=M.history=void 0,M.falsy=I;var g=t(1),e=g.PropTypes.func,i=g.PropTypes.object,T=g.PropTypes.arrayOf,E=g.PropTypes.oneOfType,N=g.PropTypes.element,o=g.PropTypes.shape,n=g.PropTypes.string,C=(M.history=o({listen:e.isRequired,push:e.isRequired,replace:e.isRequired,go:e.isRequired,goBack:e.isRequired,goForward:e.isRequired}),M.component=E([e,n])),c=(M.components=E([C,i]),M.route=E([i,N]));M.routes=E([c,T(c)])},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){var M=A.match(/^https?:\/\/[^\/]*/);return null==M?A:A.substring(M[0].length)}function e(A){var M=g(A),t="",I="",e=M.indexOf("#");e!==-1&&(I=M.substring(e),M=M.substring(0,e));var i=M.indexOf("?");return i!==-1&&(t=M.substring(i),M=M.substring(0,i)),""===M&&(M="/"),{pathname:M,search:t,hash:I}}M.__esModule=!0,M.extractPath=g,M.parsePath=e;var i=t(23);I(i)},function(A,M,t){"use strict";function I(){g.attachRefs(this,this._currentElement)}var g=t(459),e={mountComponent:function(A,M,t,g){var e=A.mountComponent(M,t,g);return A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A),e},unmountComponent:function(A){g.detachRefs(A,A._currentElement),A.unmountComponent()},receiveComponent:function(A,M,t,e){var i=A._currentElement;if(M!==i||e!==A._context){var T=g.shouldUpdateRefs(i,M);T&&g.detachRefs(A,i),A.receiveComponent(M,t,e),T&&A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A)}},performUpdateIfNecessary:function(A,M){A.performUpdateIfNecessary(M)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t,I){this.dispatchConfig=A,this.dispatchMarker=M,this.nativeEvent=t;var g=this.constructor.Interface;for(var e in g)if(g.hasOwnProperty(e)){var T=g[e];T?this[e]=T(t):"target"===e?this.target=I:this[e]=t[e]}var E=null!=t.defaultPrevented?t.defaultPrevented:t.returnValue===!1;E?this.isDefaultPrevented=i.thatReturnsTrue:this.isDefaultPrevented=i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse}var g=t(31),e=t(4),i=t(20),T=(t(3),{type:null,target:null,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(A){return A.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null});e(I.prototype,{preventDefault:function(){this.defaultPrevented=!0;var A=this.nativeEvent;A&&(A.preventDefault?A.preventDefault():A.returnValue=!1,this.isDefaultPrevented=i.thatReturnsTrue)},stopPropagation:function(){var A=this.nativeEvent;A&&(A.stopPropagation?A.stopPropagation():A.cancelBubble=!0,this.isPropagationStopped=i.thatReturnsTrue)},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var A=this.constructor.Interface;for(var M in A)this[M]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),I.Interface=T,I.augmentClass=function(A,M){var t=this,I=Object.create(t.prototype);e(I,A.prototype),A.prototype=I,A.prototype.constructor=A,A.Interface=e({},t.Interface,M),A.augmentClass=t.augmentClass,g.addPoolingTo(A,g.fourArgumentPooler)},g.addPoolingTo(I,g.fourArgumentPooler),A.exports=I},function(A,M){"use strict";M.default=function(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t},M.__esModule=!0},function(A,M){"use strict";function t(A){return A&&A.ownerDocument||document}M.__esModule=!0,M.default=t,A.exports=M.default},function(A,M,t){"use strict";var I=t(32),g=function(){var A=I&&document.documentElement;return A&&A.contains?function(A,M){return A.contains(M)}:A&&A.compareDocumentPosition?function(A,M){return A===M||!!(16&A.compareDocumentPosition(M))}:function(A,M){if(M)do if(M===A)return!0;while(M=M.parentNode);return!1}}();A.exports=g},function(A,M){function t(A){return"number"==typeof A&&A>-1&&A%1==0&&A<=I}var I=9007199254740991;A.exports=t},function(A,M,t){(function(A){!function(M,t){A.exports=t()}(this,function(){"use strict";function M(){return aI.apply(null,arguments)}function t(A){aI=A}function I(A){return A instanceof Array||"[object Array]"===Object.prototype.toString.call(A)}function g(A){return null!=A&&"[object Object]"===Object.prototype.toString.call(A)}function e(A){var M;for(M in A)return!1;return!0}function i(A){return"number"==typeof A||"[object Number]"===Object.prototype.toString.call(A)}function T(A){return A instanceof Date||"[object Date]"===Object.prototype.toString.call(A)}function E(A,M){var t,I=[];for(t=0;t0)for(t in rI)I=rI[t],g=M[I],B(g)||(A[I]=g);return A}function r(A){Q(this,A),this._d=new Date(null!=A._d?A._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),sI===!1&&(sI=!0,M.updateOffset(this),sI=!1)}function s(A){return A instanceof r||null!=A&&null!=A._isAMomentObject}function x(A){return A<0?Math.ceil(A)||0:Math.floor(A)}function j(A){var M=+A,t=0;return 0!==M&&isFinite(M)&&(t=x(M)),t}function y(A,M,t){var I,g=Math.min(A.length,M.length),e=Math.abs(A.length-M.length),i=0;for(I=0;I0?"future":"past"];return L(t)?t(M):t.replace(/%s/i,M)}function F(A,M){var t=A.toLowerCase();SI[t]=SI[t+"s"]=SI[M]=A}function f(A){return"string"==typeof A?SI[A]||SI[A.toLowerCase()]:void 0}function k(A){var M,t,I={};for(t in A)N(A,t)&&(M=f(t),M&&(I[M]=A[t]));return I}function R(A,M){zI[A]=M}function J(A){var M=[];for(var t in A)M.push({unit:t,priority:zI[t]});return M.sort(function(A,M){return A.priority-M.priority}),M}function G(A,t){return function(I){return null!=I?(b(this,A,I),M.updateOffset(this,t),this):H(this,A)}}function H(A,M){return A.isValid()?A._d["get"+(A._isUTC?"UTC":"")+M]():NaN}function b(A,M,t){A.isValid()&&A._d["set"+(A._isUTC?"UTC":"")+M](t)}function v(A){return A=f(A),L(this[A])?this[A]():this}function X(A,M){if("object"==typeof A){A=k(A);for(var t=J(A),I=0;I=0;return(e?t?"+":"":"-")+Math.pow(10,Math.max(0,g)).toString().substr(1)+I}function V(A,M,t,I){var g=I;"string"==typeof I&&(g=function(){return this[I]()}),A&&(mI[A]=g),M&&(mI[M[0]]=function(){return W(g.apply(this,arguments),M[1],M[2])}),t&&(mI[t]=function(){return this.localeData().ordinal(g.apply(this,arguments),A)})}function P(A){return A.match(/\[[\s\S]/)?A.replace(/^\[|\]$/g,""):A.replace(/\\/g,"")}function Z(A){var M,t,I=A.match(pI);for(M=0,t=I.length;M=0&&UI.test(A);)A=A.replace(UI,t),UI.lastIndex=0,I-=1;return A}function _(A,M,t){$I[A]=L(M)?M:function(A,I){return A&&t?t:M}}function $(A,M){return N($I,A)?$I[A](M._strict,M._locale):new RegExp(AA(A))}function AA(A){return MA(A.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(A,M,t,I,g){return M||t||I||g}))}function MA(A){return A.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tA(A,M){var t,I=M;for("string"==typeof A&&(A=[A]),i(M)&&(I=function(A,t){t[M]=j(A)}),t=0;t=0&&isFinite(T.getFullYear())&&T.setFullYear(A),T}function xA(A){var M=new Date(Date.UTC.apply(null,arguments));return A<100&&A>=0&&isFinite(M.getUTCFullYear())&&M.setUTCFullYear(A),M}function jA(A,M,t){var I=7+M-t,g=(7+xA(A,0,I).getUTCDay()-M)%7;return-g+I-1}function yA(A,M,t,I,g){var e,i,T=(7+t-I)%7,E=jA(A,I,g),N=1+7*(M-1)+T+E;return N<=0?(e=A-1,i=BA(e)+N):N>BA(A)?(e=A+1,i=N-BA(A)):(e=A,i=N),{year:e,dayOfYear:i}}function uA(A,M,t){var I,g,e=jA(A.year(),M,t),i=Math.floor((A.dayOfYear()-e-1)/7)+1;return i<1?(g=A.year()-1,I=i+wA(g,M,t)):i>wA(A.year(),M,t)?(I=i-wA(A.year(),M,t),g=A.year()+1):(g=A.year(),I=i),{week:I,year:g}}function wA(A,M,t){var I=jA(A,M,t),g=jA(A+1,M,t);return(BA(A)-I+g)/7}function lA(A){return uA(A,this._week.dow,this._week.doy).week}function LA(){return this._week.dow}function YA(){return this._week.doy}function dA(A){var M=this.localeData().week(this);return null==A?M:this.add(7*(A-M),"d")}function hA(A){var M=uA(this,1,4).week;return null==A?M:this.add(7*(A-M),"d")}function SA(A,M){return"string"!=typeof A?A:isNaN(A)?(A=M.weekdaysParse(A),"number"==typeof A?A:null):parseInt(A,10)}function zA(A,M){return"string"==typeof A?M.weekdaysParse(A)%7||7:isNaN(A)?null:A}function pA(A,M){return A?I(this._weekdays)?this._weekdays[A.day()]:this._weekdays[this._weekdays.isFormat.test(M)?"format":"standalone"][A.day()]:this._weekdays}function UA(A){return A?this._weekdaysShort[A.day()]:this._weekdaysShort}function OA(A){return A?this._weekdaysMin[A.day()]:this._weekdaysMin}function mA(A,M,t){var I,g,e,i=A.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],I=0;I<7;++I)e=n([2e3,1]).day(I),this._minWeekdaysParse[I]=this.weekdaysMin(e,"").toLocaleLowerCase(),this._shortWeekdaysParse[I]=this.weekdaysShort(e,"").toLocaleLowerCase(),this._weekdaysParse[I]=this.weekdays(e,"").toLocaleLowerCase();return t?"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:null):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null):"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null)))}function FA(A,M,t){var I,g,e;if(this._weekdaysParseExact)return mA.call(this,A,M,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),I=0;I<7;I++){if(g=n([2e3,1]).day(I),t&&!this._fullWeekdaysParse[I]&&(this._fullWeekdaysParse[I]=new RegExp("^"+this.weekdays(g,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[I]=new RegExp("^"+this.weekdaysShort(g,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[I]=new RegExp("^"+this.weekdaysMin(g,"").replace(".",".?")+"$","i")),this._weekdaysParse[I]||(e="^"+this.weekdays(g,"")+"|^"+this.weekdaysShort(g,"")+"|^"+this.weekdaysMin(g,""),this._weekdaysParse[I]=new RegExp(e.replace(".",""),"i")),t&&"dddd"===M&&this._fullWeekdaysParse[I].test(A))return I;if(t&&"ddd"===M&&this._shortWeekdaysParse[I].test(A))return I;if(t&&"dd"===M&&this._minWeekdaysParse[I].test(A))return I;if(!t&&this._weekdaysParse[I].test(A))return I}}function fA(A){if(!this.isValid())return null!=A?this:NaN;var M=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=A?(A=SA(A,this.localeData()),this.add(A-M,"d")):M}function kA(A){if(!this.isValid())return null!=A?this:NaN;var M=(this.day()+7-this.localeData()._week.dow)%7;return null==A?M:this.add(A-M,"d")}function RA(A){if(!this.isValid())return null!=A?this:NaN;if(null!=A){var M=zA(A,this.localeData());return this.day(this.day()%7?M:M-7)}return this.day()||7}function JA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysStrictRegex:this._weekdaysRegex):(N(this,"_weekdaysRegex")||(this._weekdaysRegex=jg),this._weekdaysStrictRegex&&A?this._weekdaysStrictRegex:this._weekdaysRegex)}function GA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(N(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=yg),this._weekdaysShortStrictRegex&&A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function HA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(N(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ug),this._weekdaysMinStrictRegex&&A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function bA(){function A(A,M){return M.length-A.length}var M,t,I,g,e,i=[],T=[],E=[],N=[];for(M=0;M<7;M++)t=n([2e3,1]).day(M),I=this.weekdaysMin(t,""),g=this.weekdaysShort(t,""),e=this.weekdays(t,""),i.push(I),T.push(g),E.push(e),N.push(I),N.push(g),N.push(e);for(i.sort(A),T.sort(A),E.sort(A),N.sort(A),M=0;M<7;M++)T[M]=MA(T[M]),E[M]=MA(E[M]),N[M]=MA(N[M]);this._weekdaysRegex=new RegExp("^("+N.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+E.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+T.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function vA(){return this.hours()%12||12}function XA(){return this.hours()||24}function WA(A,M){V(A,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),M)})}function VA(A,M){return M._meridiemParse}function PA(A){return"p"===(A+"").toLowerCase().charAt(0)}function ZA(A,M,t){return A>11?t?"pm":"PM":t?"am":"AM"}function KA(A){return A?A.toLowerCase().replace("_","-"):A}function qA(A){for(var M,t,I,g,e=0;e0;){if(I=_A(g.slice(0,M).join("-")))return I;if(t&&t.length>=M&&y(g,t,!0)>=M-1)break;M--}e++}return null}function _A(M){var t=null;if(!dg[M]&&"undefined"!=typeof A&&A&&A.exports)try{t=wg._abbr,!function(){var A=new Error('Cannot find module "./locale"');throw A.code="MODULE_NOT_FOUND",A}(),$A(t)}catch(A){}return dg[M]}function $A(A,M){var t;return A&&(t=B(M)?tM(A):AM(A,M),t&&(wg=t)),wg._abbr}function AM(A,M){if(null!==M){var t=Yg;if(M.abbr=A,null!=dg[A])l("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),t=dg[A]._config;else if(null!=M.parentLocale){if(null==dg[M.parentLocale])return hg[M.parentLocale]||(hg[M.parentLocale]=[]),hg[M.parentLocale].push({name:A,config:M}),null;t=dg[M.parentLocale]._config}return dg[A]=new h(d(t,M)),hg[A]&&hg[A].forEach(function(A){AM(A.name,A.config)}),$A(A),dg[A]}return delete dg[A],null}function MM(A,M){if(null!=M){var t,I=Yg;null!=dg[A]&&(I=dg[A]._config),M=d(I,M),t=new h(M),t.parentLocale=dg[A],dg[A]=t,$A(A)}else null!=dg[A]&&(null!=dg[A].parentLocale?dg[A]=dg[A].parentLocale:null!=dg[A]&&delete dg[A]);return dg[A]}function tM(A){var M;if(A&&A._locale&&A._locale._abbr&&(A=A._locale._abbr),!A)return wg;if(!I(A)){if(M=_A(A))return M;A=[A]}return qA(A)}function IM(){return uI(dg)}function gM(A){var M,t=A._a;return t&&c(A).overflow===-2&&(M=t[tg]<0||t[tg]>11?tg:t[Ig]<1||t[Ig]>eA(t[Mg],t[tg])?Ig:t[gg]<0||t[gg]>24||24===t[gg]&&(0!==t[eg]||0!==t[ig]||0!==t[Tg])?gg:t[eg]<0||t[eg]>59?eg:t[ig]<0||t[ig]>59?ig:t[Tg]<0||t[Tg]>999?Tg:-1,c(A)._overflowDayOfYear&&(MIg)&&(M=Ig),c(A)._overflowWeeks&&M===-1&&(M=Eg),c(A)._overflowWeekday&&M===-1&&(M=Ng),c(A).overflow=M),A}function eM(A){var M,t,I,g,e,i,T=A._i,E=Sg.exec(T)||zg.exec(T);if(E){for(c(A).iso=!0,M=0,t=Ug.length;MBA(g)&&(c(A)._overflowDayOfYear=!0),t=xA(g,0,A._dayOfYear),A._a[tg]=t.getUTCMonth(),A._a[Ig]=t.getUTCDate()),M=0;M<3&&null==A._a[M];++M)A._a[M]=e[M]=I[M];for(;M<7;M++)A._a[M]=e[M]=null==A._a[M]?2===M?1:0:A._a[M];24===A._a[gg]&&0===A._a[eg]&&0===A._a[ig]&&0===A._a[Tg]&&(A._nextDay=!0,A._a[gg]=0),A._d=(A._useUTC?xA:sA).apply(null,e),null!=A._tzm&&A._d.setUTCMinutes(A._d.getUTCMinutes()-A._tzm),A._nextDay&&(A._a[gg]=24)}}function oM(A){var M,t,I,g,e,i,T,E;if(M=A._w,null!=M.GG||null!=M.W||null!=M.E)e=1,i=4,t=TM(M.GG,A._a[Mg],uA(sM(),1,4).year),I=TM(M.W,1),g=TM(M.E,1),(g<1||g>7)&&(E=!0);else{e=A._locale._week.dow,i=A._locale._week.doy;var N=uA(sM(),e,i);t=TM(M.gg,A._a[Mg],N.year),I=TM(M.w,N.week),null!=M.d?(g=M.d,(g<0||g>6)&&(E=!0)):null!=M.e?(g=M.e+e,(M.e<0||M.e>6)&&(E=!0)):g=e}I<1||I>wA(t,e,i)?c(A)._overflowWeeks=!0:null!=E?c(A)._overflowWeekday=!0:(T=yA(t,I,g,e,i),A._a[Mg]=T.year,A._dayOfYear=T.dayOfYear)}function nM(A){if(A._f===M.ISO_8601)return void eM(A);A._a=[],c(A).empty=!0;var t,I,g,e,i,T=""+A._i,E=T.length,N=0;for(g=q(A._f,A._locale).match(pI)||[],t=0;t0&&c(A).unusedInput.push(i),T=T.slice(T.indexOf(I)+I.length),N+=I.length),mI[e]?(I?c(A).empty=!1:c(A).unusedTokens.push(e),gA(e,I,A)):A._strict&&!I&&c(A).unusedTokens.push(e);c(A).charsLeftOver=E-N,T.length>0&&c(A).unusedInput.push(T),A._a[gg]<=12&&c(A).bigHour===!0&&A._a[gg]>0&&(c(A).bigHour=void 0),c(A).parsedDateParts=A._a.slice(0),c(A).meridiem=A._meridiem,A._a[gg]=CM(A._locale,A._a[gg],A._meridiem),NM(A),gM(A)}function CM(A,M,t){var I;return null==t?M:null!=A.meridiemHour?A.meridiemHour(M,t):null!=A.isPM?(I=A.isPM(t),I&&M<12&&(M+=12),I||12!==M||(M=0),M):M}function cM(A){var M,t,I,g,e;if(0===A._f.length)return c(A).invalidFormat=!0,void(A._d=new Date(NaN));for(g=0;gthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function fM(){if(!B(this._isDSTShifted))return this._isDSTShifted;var A={};if(Q(A,this),A=BM(A),A._a){var M=A._isUTC?n(A._a):sM(A._a);this._isDSTShifted=this.isValid()&&y(A._a,M.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function kM(){return!!this.isValid()&&!this._isUTC}function RM(){return!!this.isValid()&&this._isUTC}function JM(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function GM(A,M){var t,I,g,e=A,T=null;return wM(A)?e={ms:A._milliseconds,d:A._days,M:A._months}:i(A)?(e={},M?e[M]=A:e.milliseconds=A):(T=Jg.exec(A))?(t="-"===T[1]?-1:1,e={y:0,d:j(T[Ig])*t,h:j(T[gg])*t,m:j(T[eg])*t,s:j(T[ig])*t,ms:j(lM(1e3*T[Tg]))*t}):(T=Gg.exec(A))?(t="-"===T[1]?-1:1,e={y:HM(T[2],t),M:HM(T[3],t),w:HM(T[4],t),d:HM(T[5],t),h:HM(T[6],t),m:HM(T[7],t),s:HM(T[8],t)}):null==e?e={}:"object"==typeof e&&("from"in e||"to"in e)&&(g=vM(sM(e.from),sM(e.to)),e={},e.ms=g.milliseconds,e.M=g.months),I=new uM(e),wM(A)&&N(A,"_locale")&&(I._locale=A._locale),I}function HM(A,M){var t=A&&parseFloat(A.replace(",","."));return(isNaN(t)?0:t)*M}function bM(A,M){var t={milliseconds:0,months:0};return t.months=M.month()-A.month()+12*(M.year()-A.year()),A.clone().add(t.months,"M").isAfter(M)&&--t.months,t.milliseconds=+M-+A.clone().add(t.months,"M"),t}function vM(A,M){var t;return A.isValid()&&M.isValid()?(M=dM(M,A),A.isBefore(M)?t=bM(A,M):(t=bM(M,A),t.milliseconds=-t.milliseconds,t.months=-t.months),t):{milliseconds:0,months:0}}function XM(A,M){return function(t,I){var g,e;return null===I||isNaN(+I)||(l(M,"moment()."+M+"(period, number) is deprecated. Please use moment()."+M+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),e=t,t=I,I=e),t="string"==typeof t?+t:t,g=GM(t,I),WM(this,g,A),this}}function WM(A,t,I,g){var e=t._milliseconds,i=lM(t._days),T=lM(t._months);A.isValid()&&(g=null==g||g,e&&A._d.setTime(A._d.valueOf()+e*I),i&&b(A,"Date",H(A,"Date")+i*I),T&&oA(A,H(A,"Month")+T*I),g&&M.updateOffset(A,i||T))}function VM(A,M){var t=A.diff(M,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"}function PM(A,t){var I=A||sM(),g=dM(I,this).startOf("day"),e=M.calendarFormat(this,g)||"sameElse",i=t&&(L(t[e])?t[e].call(this,I):t[e]);return this.format(i||this.localeData().calendar(e,this,sM(I)))}function ZM(){return new r(this)}function KM(A,M){var t=s(A)?A:sM(A);return!(!this.isValid()||!t.isValid())&&(M=f(B(M)?"millisecond":M),"millisecond"===M?this.valueOf()>t.valueOf():t.valueOf()e&&(M=e),pt.call(this,A,M,t,I,g))}function pt(A,M,t,I,g){var e=yA(A,M,t,I,g),i=xA(e.year,0,e.dayOfYear);return this.year(i.getUTCFullYear()),this.month(i.getUTCMonth()),this.date(i.getUTCDate()),this}function Ut(A){return null==A?Math.ceil((this.month()+1)/3):this.month(3*(A-1)+this.month()%3)}function Ot(A){var M=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==A?M:this.add(A-M,"d")}function mt(A,M){M[Tg]=j(1e3*("0."+A))}function Ft(){return this._isUTC?"UTC":""}function ft(){return this._isUTC?"Coordinated Universal Time":""}function kt(A){return sM(1e3*A)}function Rt(){return sM.apply(null,arguments).parseZone()}function Jt(A){return A}function Gt(A,M,t,I){var g=tM(),e=n().set(I,M);return g[t](e,A)}function Ht(A,M,t){if(i(A)&&(M=A,A=void 0),A=A||"",null!=M)return Gt(A,M,t,"month");var I,g=[];for(I=0;I<12;I++)g[I]=Gt(A,I,t,"month");return g}function bt(A,M,t,I){"boolean"==typeof A?(i(M)&&(t=M,M=void 0),M=M||""):(M=A,t=M,A=!1,i(M)&&(t=M,M=void 0),M=M||"");var g=tM(),e=A?g._week.dow:0;if(null!=t)return Gt(M,(t+e)%7,I,"day");var T,E=[];for(T=0;T<7;T++)E[T]=Gt(M,(T+e)%7,I,"day");return E}function vt(A,M){return Ht(A,M,"months")}function Xt(A,M){return Ht(A,M,"monthsShort")}function Wt(A,M,t){return bt(A,M,t,"weekdays")}function Vt(A,M,t){return bt(A,M,t,"weekdaysShort")}function Pt(A,M,t){return bt(A,M,t,"weekdaysMin")}function Zt(){var A=this._data;return this._milliseconds=_g(this._milliseconds),this._days=_g(this._days),this._months=_g(this._months),A.milliseconds=_g(A.milliseconds),A.seconds=_g(A.seconds),A.minutes=_g(A.minutes),A.hours=_g(A.hours),A.months=_g(A.months),A.years=_g(A.years),this}function Kt(A,M,t,I){var g=GM(M,t);return A._milliseconds+=I*g._milliseconds,A._days+=I*g._days,A._months+=I*g._months,A._bubble()}function qt(A,M){return Kt(this,A,M,1)}function _t(A,M){return Kt(this,A,M,-1)}function $t(A){return A<0?Math.floor(A):Math.ceil(A)}function AI(){var A,M,t,I,g,e=this._milliseconds,i=this._days,T=this._months,E=this._data;return e>=0&&i>=0&&T>=0||e<=0&&i<=0&&T<=0||(e+=864e5*$t(tI(T)+i),i=0,T=0),E.milliseconds=e%1e3,A=x(e/1e3),E.seconds=A%60,M=x(A/60),E.minutes=M%60,t=x(M/60),E.hours=t%24,i+=x(t/24),g=x(MI(i)),T+=g,i-=$t(tI(g)),I=x(T/12),T%=12,E.days=i,E.months=T,E.years=I,this}function MI(A){return 4800*A/146097}function tI(A){return 146097*A/4800}function II(A){var M,t,I=this._milliseconds;if(A=f(A),"month"===A||"year"===A)return M=this._days+I/864e5,t=this._months+MI(M),"month"===A?t:t/12;switch(M=this._days+Math.round(tI(this._months)),A){case"week":return M/7+I/6048e5;case"day":return M+I/864e5;case"hour":return 24*M+I/36e5;case"minute":return 1440*M+I/6e4;case"second":return 86400*M+I/1e3;case"millisecond":return Math.floor(864e5*M)+I;default:throw new Error("Unknown unit "+A)}}function gI(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*j(this._months/12)}function eI(A){return function(){return this.as(A)}}function iI(A){return A=f(A),this[A+"s"]()}function TI(A){return function(){return this._data[A]}}function EI(){return x(this.days()/7)}function NI(A,M,t,I,g){return g.relativeTime(M||1,!!t,A,I)}function oI(A,M,t){var I=GM(A).abs(),g=De(I.as("s")),e=De(I.as("m")),i=De(I.as("h")),T=De(I.as("d")),E=De(I.as("M")),N=De(I.as("y")),o=g0,o[4]=t,NI.apply(null,o)}function nI(A){return void 0===A?De:"function"==typeof A&&(De=A,!0)}function CI(A,M){return void 0!==ae[A]&&(void 0===M?ae[A]:(ae[A]=M,!0))}function cI(A){var M=this.localeData(),t=oI(this,!A,M);return A&&(t=M.pastFuture(+this,t)),M.postformat(t)}function DI(){var A,M,t,I=Be(this._milliseconds)/1e3,g=Be(this._days),e=Be(this._months);A=x(I/60),M=x(A/60),I%=60,A%=60,t=x(e/12),e%=12;var i=t,T=e,E=g,N=M,o=A,n=I,C=this.asSeconds();return C?(C<0?"-":"")+"P"+(i?i+"Y":"")+(T?T+"M":"")+(E?E+"D":"")+(N||o||n?"T":"")+(N?N+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"}var aI,BI;BI=Array.prototype.some?Array.prototype.some:function(A){for(var M=Object(this),t=M.length>>>0,I=0;I68?1900:2e3)};var Bg=G("FullYear",!0);V("w",["ww",2],"wo","week"),V("W",["WW",2],"Wo","isoWeek"),F("week","w"),F("isoWeek","W"),R("week",5),R("isoWeek",5),_("w",GI),_("ww",GI,fI),_("W",GI),_("WW",GI,fI),IA(["w","ww","W","WW"],function(A,M,t,I){M[I.substr(0,1)]=j(A)});var Qg={dow:0,doy:6};V("d",0,"do","day"),V("dd",0,0,function(A){return this.localeData().weekdaysMin(this,A)}),V("ddd",0,0,function(A){return this.localeData().weekdaysShort(this,A)}),V("dddd",0,0,function(A){return this.localeData().weekdays(this,A)}),V("e",0,0,"weekday"),V("E",0,0,"isoWeekday"),F("day","d"),F("weekday","e"),F("isoWeekday","E"),R("day",11),R("weekday",11),R("isoWeekday",11),_("d",GI),_("e",GI),_("E",GI),_("dd",function(A,M){return M.weekdaysMinRegex(A)}),_("ddd",function(A,M){return M.weekdaysShortRegex(A)}),_("dddd",function(A,M){return M.weekdaysRegex(A)}),IA(["dd","ddd","dddd"],function(A,M,t,I){var g=t._locale.weekdaysParse(A,I,t._strict);null!=g?M.d=g:c(t).invalidWeekday=A}),IA(["d","e","E"],function(A,M,t,I){M[I]=j(A)});var rg="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),sg="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xg="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),jg=_I,yg=_I,ug=_I;V("H",["HH",2],0,"hour"),V("h",["hh",2],0,vA),V("k",["kk",2],0,XA),V("hmm",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)}),V("hmmss",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)+W(this.seconds(),2)}),V("Hmm",0,0,function(){return""+this.hours()+W(this.minutes(),2)}),V("Hmmss",0,0,function(){return""+this.hours()+W(this.minutes(),2)+W(this.seconds(),2)}),WA("a",!0),WA("A",!1),F("hour","h"),R("hour",13),_("a",VA),_("A",VA),_("H",GI),_("h",GI),_("HH",GI,fI),_("hh",GI,fI),_("hmm",HI),_("hmmss",bI),_("Hmm",HI),_("Hmmss",bI),tA(["H","HH"],gg),tA(["a","A"],function(A,M,t){t._isPm=t._locale.isPM(A),t._meridiem=A}),tA(["h","hh"],function(A,M,t){M[gg]=j(A),c(t).bigHour=!0}),tA("hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I)),c(t).bigHour=!0}),tA("hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g)),c(t).bigHour=!0}),tA("Hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I))}),tA("Hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g))});var wg,lg=/[ap]\.?m?\.?/i,Lg=G("Hours",!0),Yg={calendar:wI,longDateFormat:lI,invalidDate:LI,ordinal:YI,ordinalParse:dI,relativeTime:hI,months:Cg,monthsShort:cg,week:Qg,weekdays:rg,weekdaysMin:xg,weekdaysShort:sg,meridiemParse:lg},dg={},hg={},Sg=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,zg=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pg=/Z|[+-]\d\d(?::?\d\d)?/,Ug=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Og=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mg=/^\/?Date\((\-?\d+)/i;M.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(A){A._d=new Date(A._i+(A._useUTC?" UTC":""))}),M.ISO_8601=function(){};var Fg=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var A=sM.apply(null,arguments);return this.isValid()&&A.isValid()?Athis?this:A:a()}),kg=function(){return Date.now?Date.now():+new Date};LM("Z",":"),LM("ZZ",""),_("Z",KI),_("ZZ",KI),tA(["Z","ZZ"],function(A,M,t){t._useUTC=!0,t._tzm=YM(KI,A)});var Rg=/([\+\-]|\d\d)/gi;M.updateOffset=function(){};var Jg=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Gg=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;GM.fn=uM.prototype;var Hg=XM(1,"add"),bg=XM(-1,"subtract");M.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",M.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var vg=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(A){return void 0===A?this.localeData():this.locale(A)});V(0,["gg",2],0,function(){return this.weekYear()%100}),V(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Lt("gggg","weekYear"),Lt("ggggg","weekYear"),Lt("GGGG","isoWeekYear"),Lt("GGGGG","isoWeekYear"),F("weekYear","gg"),F("isoWeekYear","GG"),R("weekYear",1),R("isoWeekYear",1),_("G",PI),_("g",PI),_("GG",GI,fI),_("gg",GI,fI),_("GGGG",XI,RI),_("gggg",XI,RI),_("GGGGG",WI,JI),_("ggggg",WI,JI),IA(["gggg","ggggg","GGGG","GGGGG"],function(A,M,t,I){M[I.substr(0,2)]=j(A)}),IA(["gg","GG"],function(A,t,I,g){t[g]=M.parseTwoDigitYear(A)}),V("Q",0,"Qo","quarter"),F("quarter","Q"),R("quarter",7),_("Q",FI),tA("Q",function(A,M){M[tg]=3*(j(A)-1)}),V("D",["DD",2],"Do","date"),F("date","D"),R("date",9),_("D",GI),_("DD",GI,fI),_("Do",function(A,M){return A?M._ordinalParse:M._ordinalParseLenient}),tA(["D","DD"],Ig),tA("Do",function(A,M){M[Ig]=j(A.match(GI)[0],10)});var Xg=G("Date",!0);V("DDD",["DDDD",3],"DDDo","dayOfYear"),F("dayOfYear","DDD"),R("dayOfYear",4),_("DDD",vI),_("DDDD",kI),tA(["DDD","DDDD"],function(A,M,t){t._dayOfYear=j(A)}),V("m",["mm",2],0,"minute"),F("minute","m"),R("minute",14),_("m",GI),_("mm",GI,fI),tA(["m","mm"],eg);var Wg=G("Minutes",!1);V("s",["ss",2],0,"second"),F("second","s"),R("second",15),_("s",GI),_("ss",GI,fI),tA(["s","ss"],ig);var Vg=G("Seconds",!1);V("S",0,0,function(){return~~(this.millisecond()/100)}),V(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),V(0,["SSS",3],0,"millisecond"),V(0,["SSSS",4],0,function(){return 10*this.millisecond()}),V(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),V(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),V(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),V(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),V(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),F("millisecond","ms"),R("millisecond",16),_("S",vI,FI),_("SS",vI,fI),_("SSS",vI,kI);var Pg;for(Pg="SSSS";Pg.length<=9;Pg+="S")_(Pg,VI);for(Pg="S";Pg.length<=9;Pg+="S")tA(Pg,mt);var Zg=G("Milliseconds",!1);V("z",0,0,"zoneAbbr"),V("zz",0,0,"zoneName");var Kg=r.prototype;Kg.add=Hg,Kg.calendar=PM,Kg.clone=ZM,Kg.diff=tt,Kg.endOf=at,Kg.format=Tt,Kg.from=Et,Kg.fromNow=Nt,Kg.to=ot,Kg.toNow=nt,Kg.get=v,Kg.invalidAt=wt,Kg.isAfter=KM,Kg.isBefore=qM,Kg.isBetween=_M,Kg.isSame=$M,Kg.isSameOrAfter=At,Kg.isSameOrBefore=Mt,Kg.isValid=yt,Kg.lang=vg,Kg.locale=Ct,Kg.localeData=ct,Kg.max=fg,Kg.min=Fg,Kg.parsingFlags=ut,Kg.set=X,Kg.startOf=Dt,Kg.subtract=bg,Kg.toArray=st,Kg.toObject=xt,Kg.toDate=rt,Kg.toISOString=et,Kg.inspect=it,Kg.toJSON=jt,Kg.toString=gt,Kg.unix=Qt,Kg.valueOf=Bt,Kg.creationData=lt,Kg.year=Bg,Kg.isLeapYear=rA,Kg.weekYear=Yt,Kg.isoWeekYear=dt,Kg.quarter=Kg.quarters=Ut,Kg.month=nA,Kg.daysInMonth=CA,Kg.week=Kg.weeks=dA,Kg.isoWeek=Kg.isoWeeks=hA,Kg.weeksInYear=St,Kg.isoWeeksInYear=ht,Kg.date=Xg,Kg.day=Kg.days=fA,Kg.weekday=kA,Kg.isoWeekday=RA,Kg.dayOfYear=Ot,Kg.hour=Kg.hours=Lg,Kg.minute=Kg.minutes=Wg,Kg.second=Kg.seconds=Vg,Kg.millisecond=Kg.milliseconds=Zg,Kg.utcOffset=SM,Kg.utc=pM,Kg.local=UM,Kg.parseZone=OM,Kg.hasAlignedHourOffset=mM,Kg.isDST=FM,Kg.isLocal=kM,Kg.isUtcOffset=RM,Kg.isUtc=JM,Kg.isUTC=JM,Kg.zoneAbbr=Ft,Kg.zoneName=ft,Kg.dates=w("dates accessor is deprecated. Use date instead.",Xg),Kg.months=w("months accessor is deprecated. Use month instead",nA),Kg.years=w("years accessor is deprecated. Use year instead",Bg),Kg.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",zM),Kg.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",fM);var qg=h.prototype;qg.calendar=S,qg.longDateFormat=z,qg.invalidDate=p,qg.ordinal=U,qg.preparse=Jt,qg.postformat=Jt,qg.relativeTime=O,qg.pastFuture=m,qg.set=Y,qg.months=iA,qg.monthsShort=TA,qg.monthsParse=NA,qg.monthsRegex=DA,qg.monthsShortRegex=cA,qg.week=lA,qg.firstDayOfYear=YA,qg.firstDayOfWeek=LA,qg.weekdays=pA,qg.weekdaysMin=OA,qg.weekdaysShort=UA,qg.weekdaysParse=FA,qg.weekdaysRegex=JA,qg.weekdaysShortRegex=GA,qg.weekdaysMinRegex=HA,qg.isPM=PA,qg.meridiem=ZA,$A("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(A){var M=A%10,t=1===j(A%100/10)?"th":1===M?"st":2===M?"nd":3===M?"rd":"th";return A+t}}),M.lang=w("moment.lang is deprecated. Use moment.locale instead.",$A),M.langData=w("moment.langData is deprecated. Use moment.localeData instead.",tM);var _g=Math.abs,$g=eI("ms"),Ae=eI("s"),Me=eI("m"),te=eI("h"),Ie=eI("d"),ge=eI("w"),ee=eI("M"),ie=eI("y"),Te=TI("milliseconds"),Ee=TI("seconds"),Ne=TI("minutes"),oe=TI("hours"),ne=TI("days"),Ce=TI("months"),ce=TI("years"),De=Math.round,ae={s:45,m:45,h:22,d:26,M:11},Be=Math.abs,Qe=uM.prototype;return Qe.abs=Zt,Qe.add=qt,Qe.subtract=_t,Qe.as=II,Qe.asMilliseconds=$g,Qe.asSeconds=Ae,Qe.asMinutes=Me,Qe.asHours=te,Qe.asDays=Ie,Qe.asWeeks=ge,Qe.asMonths=ee,Qe.asYears=ie,Qe.valueOf=gI,Qe._bubble=AI,Qe.get=iI,Qe.milliseconds=Te,Qe.seconds=Ee,Qe.minutes=Ne,Qe.hours=oe,Qe.days=ne,Qe.weeks=EI,Qe.months=Ce,Qe.years=ce,Qe.humanize=cI,Qe.toISOString=DI,Qe.toString=DI,Qe.toJSON=DI,Qe.locale=Ct,Qe.localeData=ct,Qe.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",DI),Qe.lang=vg,V("X",0,0,"unix"),V("x",0,0,"valueOf"),_("x",PI),_("X",qI),tA("X",function(A,M,t){t._d=new Date(1e3*parseFloat(A,10))}),tA("x",function(A,M,t){t._d=new Date(j(A))}),M.version="2.17.1",t(sM),M.fn=Kg,M.min=jM,M.max=yM,M.now=kg,M.utc=n,M.unix=kt,M.months=vt,M.isDate=T,M.locale=$A,M.invalid=a,M.duration=GM,M.isMoment=s,M.weekdays=Wt,M.parseZone=Rt,M.localeData=tM,M.isDuration=wM,M.monthsShort=Xt,M.weekdaysMin=Pt,M.defineLocale=AM,M.updateLocale=MM,M.locales=IM,M.weekdaysShort=Vt,M.normalizeUnits=f,M.relativeTimeRounding=nI,M.relativeTimeThreshold=CI,M.calendarFormat=VM,M.prototype=Kg,M})}).call(M,t(128)(A))},function(A,M,t){"use strict";var I=t(132).default,g=t(133).default,e=t(78).default;M.__esModule=!0;var i=function(A){return I(g({values:function(){var A=this;return e(this).map(function(M){return A[M]})}}),A)},T={SIZES:{large:"lg",medium:"md",small:"sm",xsmall:"xs",lg:"lg",md:"md",sm:"sm",xs:"xs"},GRID_COLUMNS:12},E=i({LARGE:"large",MEDIUM:"medium",SMALL:"small",XSMALL:"xsmall"});M.Sizes=E;var N=i({SUCCESS:"success",WARNING:"warning",DANGER:"danger",INFO:"info"});M.State=N;var o="default";M.DEFAULT=o;var n="primary";M.PRIMARY=n;var C="link";M.LINK=C;var c="inverse";M.INVERSE=c,M.default=T},function(A,M){"use strict";function t(){for(var A=arguments.length,M=Array(A),t=0;t0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURI(o))):"("===E?g+=1:")"===E?g-=1:":"===E.charAt(0)?(N=E.substring(1),o=M[N],null!=o||g>0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURIComponent(o))):e+=E;return e.replace(/\/+/g,"/")}M.__esModule=!0,M.compilePattern=i,M.matchPattern=T,M.getParamNames=E,M.getParams=N,M.formatPattern=o;var n=t(8),C=I(n),c=Object.create(null)},function(A,M){"use strict";M.__esModule=!0;var t="PUSH";M.PUSH=t;var I="REPLACE";M.REPLACE=I;var g="POP";M.POP=g,M.default={PUSH:t,REPLACE:I,POP:g}},function(A,M,t){"use strict";function I(A,M){return(A&M)===M}var g=t(2),e={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(A){var M=e,t=A.Properties||{},i=A.DOMAttributeNamespaces||{},E=A.DOMAttributeNames||{},N=A.DOMPropertyNames||{},o=A.DOMMutationMethods||{};A.isCustomAttribute&&T._isCustomAttributeFunctions.push(A.isCustomAttribute);for(var n in t){T.properties.hasOwnProperty(n)?g(!1):void 0;var C=n.toLowerCase(),c=t[n],D={attributeName:C,attributeNamespace:null,propertyName:n,mutationMethod:null,mustUseAttribute:I(c,M.MUST_USE_ATTRIBUTE),mustUseProperty:I(c,M.MUST_USE_PROPERTY),hasSideEffects:I(c,M.HAS_SIDE_EFFECTS),hasBooleanValue:I(c,M.HAS_BOOLEAN_VALUE),hasNumericValue:I(c,M.HAS_NUMERIC_VALUE),hasPositiveNumericValue:I(c,M.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:I(c,M.HAS_OVERLOADED_BOOLEAN_VALUE)};if(D.mustUseAttribute&&D.mustUseProperty?g(!1):void 0,!D.mustUseProperty&&D.hasSideEffects?g(!1):void 0,D.hasBooleanValue+D.hasNumericValue+D.hasOverloadedBooleanValue<=1?void 0:g(!1),E.hasOwnProperty(n)){var a=E[n];D.attributeName=a}i.hasOwnProperty(n)&&(D.attributeNamespace=i[n]),N.hasOwnProperty(n)&&(D.propertyName=N[n]),o.hasOwnProperty(n)&&(D.mutationMethod=o[n]),T.properties[n]=D}}},i={},T={ID_ATTRIBUTE_NAME:"data-reactid",properties:{},getPossibleStandardName:null,_isCustomAttributeFunctions:[],isCustomAttribute:function(A){for(var M=0;M1){var M=A.indexOf(c,1);return M>-1?A.substr(0,M):A}return null},traverseEnterLeave:function(A,M,t,I,g){var e=N(A,M);e!==A&&o(A,e,t,I,!1,!0),e!==M&&o(e,M,t,g,!0,!1)},traverseTwoPhase:function(A,M,t){A&&(o("",A,M,t,!0,!1),o(A,"",M,t,!1,!0))},traverseTwoPhaseSkipTarget:function(A,M,t){A&&(o("",A,M,t,!0,!0),o(A,"",M,t,!0,!0))},traverseAncestors:function(A,M,t){o("",A,M,t,!0,!1)},getFirstCommonAncestorID:N,_getNextDescendantID:E,isAncestorIDOf:i,SEPARATOR:c};A.exports=B},function(A,M){var t=A.exports={version:"1.2.6"};"number"==typeof __e&&(__e=t)},function(A,M,t){"use strict";var I={};A.exports=I},function(A,M,t){"use strict";function I(A,M,t){var I=0;return n.default.Children.map(A,function(A){if(n.default.isValidElement(A)){var g=I;return I++,M.call(t,A,g)}return A})}function g(A,M,t){var I=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I),I++)})}function e(A){var M=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&M++}),M}function i(A){var M=!1;return n.default.Children.forEach(A,function(A){!M&&n.default.isValidElement(A)&&(M=!0)}),M}function T(A,M){var t=void 0;return g(A,function(I,g){!t&&M(I,g,A)&&(t=I)}),t}function E(A,M,t){var I=0,g=[];return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I)&&g.push(A),I++)}),g}var N=t(6).default;M.__esModule=!0;var o=t(1),n=N(o);M.default={map:I,forEach:g,numberOf:e,find:T,findValidComponents:E,hasValidComponent:i},A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=function(A){return(0,T.default)(e.default.findDOMNode(A))};var g=t(16),e=I(g),i=t(39),T=I(i);A.exports=M.default},function(A,M,t){"use strict";var I=t(204),g=t(437),e=t(217),i=t(226),T=t(227),E=t(2),N=(t(3),{}),o=null,n=function(A,M){A&&(g.executeDispatchesInOrder(A,M),A.isPersistent()||A.constructor.release(A))},C=function(A){return n(A,!0)},c=function(A){return n(A,!1)},D=null,a={injection:{injectMount:g.injection.injectMount,injectInstanceHandle:function(A){D=A},getInstanceHandle:function(){return D},injectEventPluginOrder:I.injectEventPluginOrder,injectEventPluginsByName:I.injectEventPluginsByName},eventNameDispatchConfigs:I.eventNameDispatchConfigs,registrationNameModules:I.registrationNameModules,putListener:function(A,M,t){"function"!=typeof t?E(!1):void 0;var g=N[M]||(N[M]={});g[A]=t;var e=I.registrationNameModules[M];e&&e.didPutListener&&e.didPutListener(A,M,t)},getListener:function(A,M){var t=N[M];return t&&t[A]},deleteListener:function(A,M){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M);var g=N[M];g&&delete g[A]},deleteAllListeners:function(A){for(var M in N)if(N[M][A]){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M),delete N[M][A]}},extractEvents:function(A,M,t,g,e){for(var T,E=I.plugins,N=0;N1?I-1:0),e=1;e":">","<":"<",'"':""","'":"'"},e=/[&><"']/g;A.exports=I},function(A,M,t){"use strict";var I=t(10),g=/^[ \r\n\t\f]/,e=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(A,M){A.innerHTML=M};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(A,M){MSApp.execUnsafeLocalFunction(function(){A.innerHTML=M})}),I.canUseDOM){var T=document.createElement("div");T.innerHTML=" ",""===T.innerHTML&&(i=function(A,M){if(A.parentNode&&A.parentNode.replaceChild(A,A),g.test(M)||"<"===M[0]&&e.test(M)){A.innerHTML=String.fromCharCode(65279)+M;var t=A.firstChild;1===t.data.length?A.removeChild(t):t.deleteData(0,1)}else A.innerHTML=M})}A.exports=i},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=function(A){var M=A.label,t=A.id,I=A.name,g=A.value,i=A.onChange,T=A.type,E=A.spellCheck,N=A.required,o=A.readonly,n=A.autoComplete,C=A.align,c=A.className,D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n});return o&&(D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n,disabled:!0})),e.default.createElement("div",{className:"input-group "+C+" "+c},D,e.default.createElement("i",{className:"ig-helpers"}),e.default.createElement("label",{className:"ig-label"},M))};M.default=i},function(A,M,t){A.exports={default:t(259),__esModule:!0}},function(A,M,t){var I=t(265),g=t(49),e=t(134),i="prototype",T=function(A,M,t){var E,N,o,n=A&T.F,C=A&T.G,c=A&T.S,D=A&T.P,a=A&T.B,B=A&T.W,Q=C?g:g[M]||(g[M]={}),r=C?I:c?I[M]:(I[M]||{})[i];C&&(t=M);for(E in t)N=!n&&r&&E in r,N&&E in Q||(o=N?r[E]:t[E],Q[E]=C&&"function"!=typeof r[E]?t[E]:a&&N?e(o,I):B&&r[E]==o?function(A){var M=function(M){return this instanceof A?new A(M):A(M)};return M[i]=A[i],M}(o):D&&"function"==typeof o?e(Function.call,o):o,D&&((Q[i]||(Q[i]={}))[E]=o))};T.F=1,T.G=2,T.S=4,T.P=8,T.B=16,T.W=32,A.exports=T},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M,t){"use strict";var I=t(32),g=function(){};I&&(g=function(){return document.addEventListener?function(A,M,t,I){return A.addEventListener(M,t,I||!1)}:document.attachEvent?function(A,M,t){return A.attachEvent("on"+M,t)}:void 0}()),A.exports=g},function(A,M,t){"use strict";var I=t(145),g=t(295),e=t(290),i=t(291),T=Object.prototype.hasOwnProperty;A.exports=function(A,M,t){var E="",N=M;if("string"==typeof M){if(void 0===t)return A.style[I(M)]||e(A).getPropertyValue(g(M));(N={})[M]=t}for(var o in N)T.call(N,o)&&(N[o]||0===N[o]?E+=g(o)+":"+N[o]+";":i(A,g(o)));A.style.cssText+=";"+E}},function(A,M,t){(function(){var t=this,I=t.humanize,g={};"undefined"!=typeof A&&A.exports&&(M=A.exports=g),M.humanize=g,g.noConflict=function(){return t.humanize=I,this},g.pad=function(A,M,t,I){if(A+="",t?t.length>1&&(t=t.charAt(0)):t=" ",I=void 0===I?"left":"right","right"===I)for(;A.length4&&A<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th"},w:function(){return t.getDay()},z:function(){return(o.L()?i[o.n()]:e[o.n()])+o.j()-1},W:function(){var A=o.z()-o.N()+1.5;return g.pad(1+Math.floor(Math.abs(A)/7)+(A%7>3.5?1:0),2,"0")},F:function(){return N[t.getMonth()]},m:function(){return g.pad(o.n(),2,"0")},M:function(){return o.F().slice(0,3)},n:function(){return t.getMonth()+1},t:function(){return new Date(o.Y(),o.n(),0).getDate()},L:function(){return 1===new Date(o.Y(),1,29).getMonth()?1:0},o:function(){var A=o.n(),M=o.W();return o.Y()+(12===A&&M<9?-1:1===A&&M>9)},Y:function(){return t.getFullYear()},y:function(){return String(o.Y()).slice(-2)},a:function(){return t.getHours()>11?"pm":"am"},A:function(){return o.a().toUpperCase()},B:function(){var A=t.getTime()/1e3,M=A%86400+3600;M<0&&(M+=86400);var I=M/86.4%1e3;return A<0?Math.ceil(I):Math.floor(I)},g:function(){return o.G()%12||12},G:function(){return t.getHours()},h:function(){return g.pad(o.g(),2,"0")},H:function(){return g.pad(o.G(),2,"0")},i:function(){return g.pad(t.getMinutes(),2,"0")},s:function(){return g.pad(t.getSeconds(),2,"0")},u:function(){return g.pad(1e3*t.getMilliseconds(),6,"0")},O:function(){var A=t.getTimezoneOffset(),M=Math.abs(A);return(A>0?"-":"+")+g.pad(100*Math.floor(M/60)+M%60,4,"0")},P:function(){var A=o.O();return A.substr(0,3)+":"+A.substr(3,2)},Z:function(){return 60*-t.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(I,T)},r:function(){return"D, d M Y H:i:s O".replace(I,T)},U:function(){return t.getTime()/1e3||0}};return A.replace(I,T)},g.numberFormat=function(A,M,t,I){M=isNaN(M)?2:Math.abs(M),t=void 0===t?".":t,I=void 0===I?",":I;var g=A<0?"-":"";A=Math.abs(+A||0);var e=parseInt(A.toFixed(M),10)+"",i=e.length>3?e.length%3:0;return g+(i?e.substr(0,i)+I:"")+e.substr(i).replace(/(\d{3})(?=\d)/g,"$1"+I)+(M?t+Math.abs(A-e).toFixed(M).slice(2):"")},g.naturalDay=function(A,M){A=void 0===A?g.time():A,M=void 0===M?"Y-m-d":M;var t=86400,I=new Date,e=new Date(I.getFullYear(),I.getMonth(),I.getDate()).getTime()/1e3;return A=e-t?"yesterday":A>=e&&A=e+t&&A-2)return(t>=0?"just ":"")+"now";if(t<60&&t>-60)return t>=0?Math.floor(t)+" seconds ago":"in "+Math.floor(-t)+" seconds";if(t<120&&t>-120)return t>=0?"about a minute ago":"in about a minute";if(t<3600&&t>-3600)return t>=0?Math.floor(t/60)+" minutes ago":"in "+Math.floor(-t/60)+" minutes";if(t<7200&&t>-7200)return t>=0?"about an hour ago":"in about an hour";if(t<86400&&t>-86400)return t>=0?Math.floor(t/3600)+" hours ago":"in "+Math.floor(-t/3600)+" hours";var I=172800;if(t-I)return t>=0?"1 day ago":"in 1 day";var e=2505600;if(t-e)return t>=0?Math.floor(t/86400)+" days ago":"in "+Math.floor(-t/86400)+" days";var i=5184e3;if(t-i)return t>=0?"about a month ago":"in about a month";var T=parseInt(g.date("Y",M),10),E=parseInt(g.date("Y",A),10),N=12*T+parseInt(g.date("n",M),10),o=12*E+parseInt(g.date("n",A),10),n=N-o;if(n<12&&n>-12)return n>=0?n+" months ago":"in "+-n+" months";var C=T-E;return C<2&&C>-2?C>=0?"a year ago":"in a year":C>=0?C+" years ago":"in "+-C+" years"},g.ordinal=function(A){A=parseInt(A,10),A=isNaN(A)?0:A;var M=A<0?"-":"";A=Math.abs(A);var t=A%100;return M+A+(t>4&&t<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th")},g.filesize=function(A,M,t,I,e,i){return M=void 0===M?1024:M,A<=0?"0 bytes":(A

    "),A=A.replace(/\n/g,"
    "),"

    "+A+"

    "},g.nl2br=function(A){return A.replace(/(\r\n|\n|\r)/g,"
    ")},g.truncatechars=function(A,M){return A.length<=M?A:A.substr(0,M)+"…"},g.truncatewords=function(A,M){var t=A.split(" ");return t.length0,Q=C.enumErrorProps&&(A===u||A instanceof Error),r=C.enumPrototypes&&T(A);++IM.documentElement.clientHeight;return{modalStyles:{paddingRight:I&&!g?Q.default():void 0,paddingLeft:!I&&g?Q.default():void 0}}}});v.Body=z.default,v.Header=U.default, +v.Title=m.default,v.Footer=f.default,v.Dialog=h.default,v.TRANSITION_DURATION=300,v.BACKDROP_TRANSITION_DURATION=150,M.default=c.bsSizes([a.Sizes.LARGE,a.Sizes.SMALL],c.bsClass("modal",v)),A.exports=M.default},function(A,M,t){"use strict";var I=t(15).default,g=t(14).default,e=t(38).default,i=t(7).default,T=t(6).default;M.__esModule=!0;var E=t(1),N=T(E),o=t(5),n=T(o),C=t(11),c=T(C),D=t(44),a=T(D),B=function(A){function M(){g(this,M),A.apply(this,arguments)}return I(M,A),M.prototype.render=function(){var A=this.props,M=A["aria-label"],t=e(A,["aria-label"]),I=a.default(this.context.$bs_onModalHide,this.props.onHide);return N.default.createElement("div",i({},t,{className:n.default(this.props.className,c.default.prefix(this.props,"header"))}),this.props.closeButton&&N.default.createElement("button",{type:"button",className:"close","aria-label":M,onClick:I},N.default.createElement("span",{"aria-hidden":"true"},"×")),this.props.children)},M}(N.default.Component);B.propTypes={"aria-label":N.default.PropTypes.string,bsClass:N.default.PropTypes.string,closeButton:N.default.PropTypes.bool,onHide:N.default.PropTypes.func},B.contextTypes={$bs_onModalHide:N.default.PropTypes.func},B.defaultProps={"aria-label":"Close",closeButton:!1},M.default=C.bsClass("modal",B),A.exports=M.default},function(A,M,t){"use strict";function I(A,M){return Array.isArray(M)?M.indexOf(A)>=0:A===M}var g=t(7).default,e=t(78).default,i=t(6).default;M.__esModule=!0;var T=t(40),E=i(T),N=t(170),o=i(N),n=t(1),C=i(n),c=t(16),D=i(c),a=t(127),B=(i(a),t(370)),Q=i(B),r=t(44),s=i(r),x=C.default.createClass({displayName:"OverlayTrigger",propTypes:g({},Q.default.propTypes,{trigger:C.default.PropTypes.oneOfType([C.default.PropTypes.oneOf(["click","hover","focus"]),C.default.PropTypes.arrayOf(C.default.PropTypes.oneOf(["click","hover","focus"]))]),delay:C.default.PropTypes.number,delayShow:C.default.PropTypes.number,delayHide:C.default.PropTypes.number,defaultOverlayShown:C.default.PropTypes.bool,overlay:C.default.PropTypes.node.isRequired,onBlur:C.default.PropTypes.func,onClick:C.default.PropTypes.func,onFocus:C.default.PropTypes.func,onMouseEnter:C.default.PropTypes.func,onMouseLeave:C.default.PropTypes.func,target:function(){},onHide:function(){},show:function(){}}),getDefaultProps:function(){return{defaultOverlayShown:!1,trigger:["hover","focus"]}},getInitialState:function(){return{isOverlayShown:this.props.defaultOverlayShown}},show:function(){this.setState({isOverlayShown:!0})},hide:function(){this.setState({isOverlayShown:!1})},toggle:function(){this.state.isOverlayShown?this.hide():this.show()},componentWillMount:function(){this.handleMouseOver=this.handleMouseOverOut.bind(null,this.handleDelayedShow),this.handleMouseOut=this.handleMouseOverOut.bind(null,this.handleDelayedHide)},componentDidMount:function(){this._mountNode=document.createElement("div"),this.renderOverlay()},renderOverlay:function(){D.default.unstable_renderSubtreeIntoContainer(this,this._overlay,this._mountNode)},componentWillUnmount:function(){D.default.unmountComponentAtNode(this._mountNode),this._mountNode=null,clearTimeout(this._hoverShowDelay),clearTimeout(this._hoverHideDelay)},componentDidUpdate:function(){this._mountNode&&this.renderOverlay()},getOverlayTarget:function(){return D.default.findDOMNode(this)},getOverlay:function(){var A=g({},o.default(this.props,e(Q.default.propTypes)),{show:this.state.isOverlayShown,onHide:this.hide,target:this.getOverlayTarget,onExit:this.props.onExit,onExiting:this.props.onExiting,onExited:this.props.onExited,onEnter:this.props.onEnter,onEntering:this.props.onEntering,onEntered:this.props.onEntered}),M=n.cloneElement(this.props.overlay,{placement:A.placement,container:A.container});return C.default.createElement(Q.default,A,M)},render:function(){var A=C.default.Children.only(this.props.children),M=A.props,t={"aria-describedby":this.props.overlay.props.id};return this._overlay=this.getOverlay(),t.onClick=s.default(M.onClick,this.props.onClick),I("click",this.props.trigger)&&(t.onClick=s.default(this.toggle,t.onClick)),I("hover",this.props.trigger)&&(t.onMouseOver=s.default(this.handleMouseOver,this.props.onMouseOver,M.onMouseOver),t.onMouseOut=s.default(this.handleMouseOut,this.props.onMouseOut,M.onMouseOut)),I("focus",this.props.trigger)&&(t.onFocus=s.default(this.handleDelayedShow,this.props.onFocus,M.onFocus),t.onBlur=s.default(this.handleDelayedHide,this.props.onBlur,M.onBlur)),n.cloneElement(A,t)},handleDelayedShow:function(){var A=this;if(null!=this._hoverHideDelay)return clearTimeout(this._hoverHideDelay),void(this._hoverHideDelay=null);if(!this.state.isOverlayShown&&null==this._hoverShowDelay){var M=null!=this.props.delayShow?this.props.delayShow:this.props.delay;return M?void(this._hoverShowDelay=setTimeout(function(){A._hoverShowDelay=null,A.show()},M)):void this.show()}},handleDelayedHide:function(){var A=this;if(null!=this._hoverShowDelay)return clearTimeout(this._hoverShowDelay),void(this._hoverShowDelay=null);if(this.state.isOverlayShown&&null==this._hoverHideDelay){var M=null!=this.props.delayHide?this.props.delayHide:this.props.delay;return M?void(this._hoverHideDelay=setTimeout(function(){A._hoverHideDelay=null,A.hide()},M)):void this.hide()}},handleMouseOverOut:function(A,M){var t=M.currentTarget,I=M.relatedTarget||M.nativeEvent.toElement;I&&(I===t||E.default(t,I))||A(M)}});M.default=x,A.exports=M.default},function(A,M,t){"use strict";var I=t(7).default,g=t(6).default;M.__esModule=!0;var e=t(1),i=g(e),T=t(5),E=g(T),N=t(11),o=g(N),n=t(183),C=g(n),c=i.default.createClass({displayName:"Tooltip",propTypes:{id:C.default(i.default.PropTypes.oneOfType([i.default.PropTypes.string,i.default.PropTypes.number])),placement:i.default.PropTypes.oneOf(["top","right","bottom","left"]),positionLeft:i.default.PropTypes.number,positionTop:i.default.PropTypes.number,arrowOffsetLeft:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),arrowOffsetTop:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),title:i.default.PropTypes.node},getDefaultProps:function(){return{bsClass:"tooltip",placement:"right"}},render:function(){var A,M=(A={},A[o.default.prefix(this.props)]=!0,A[this.props.placement]=!0,A),t=I({left:this.props.positionLeft,top:this.props.positionTop},this.props.style),g={left:this.props.arrowOffsetLeft,top:this.props.arrowOffsetTop};return i.default.createElement("div",I({role:"tooltip"},this.props,{className:E.default(this.props.className,M),style:t}),i.default.createElement("div",{className:o.default.prefix(this.props,"arrow"),style:g}),i.default.createElement("div",{className:o.default.prefix(this.props,"inner")},this.props.children))}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return A="function"==typeof A?A():A,i.default.findDOMNode(A)||M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=g;var e=t(16),i=I(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement. You can usually obtain a ReactComponent or DOMElement from a ReactElement by attaching a ref to it."):"object"===E&&"function"==typeof i.render||1===i.nodeType?null:new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement.")}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M,t){"use strict";function I(){function A(A,M,I){for(var g=0;g>",null!=t[I]?A(t,I,g):M?new Error("Required prop '"+I+"' was not specified in '"+g+"'."):void 0}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}M.__esModule=!0,M.errMsg=t,M.createChainableTypeChecker=I},function(A,M){"use strict";function t(A,M,t){function I(){return i=!0,T?void(N=[].concat(Array.prototype.slice.call(arguments))):void t.apply(this,arguments)}function g(){if(!i&&(E=!0,!T)){for(T=!0;!i&&e=A&&E&&(i=!0,t()))}}var e=0,i=!1,T=!1,E=!1,N=void 0;g()}function I(A,M,t){function I(A,M,I){i||(M?(i=!0,t(M)):(e[A]=I,i=++T===g,i&&t(null,e)))}var g=A.length,e=[];if(0===g)return t(null,e);var i=!1,T=0;A.forEach(function(A,t){M(A,t,function(A,M){I(t,A,M)})})}M.__esModule=!0,M.loopAsync=t,M.mapAsync=I},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0,M.router=M.routes=M.route=M.components=M.component=M.location=M.history=M.falsy=M.locationShape=M.routerShape=void 0;var e=t(1),i=t(66),T=(g(i),t(34)),E=I(T),N=t(9),o=(g(N),e.PropTypes.func),n=e.PropTypes.object,C=e.PropTypes.shape,c=e.PropTypes.string,D=M.routerShape=C({push:o.isRequired,replace:o.isRequired,go:o.isRequired,goBack:o.isRequired,goForward:o.isRequired,setRouteLeaveHook:o.isRequired,isActive:o.isRequired}),a=M.locationShape=C({pathname:c.isRequired,search:c.isRequired,state:n,action:c.isRequired,key:c}),B=M.falsy=E.falsy,Q=M.history=E.history,r=M.location=a,s=M.component=E.component,x=M.components=E.components,j=M.route=E.route,y=(M.routes=E.routes,M.router=D),u={falsy:B,history:Q,location:r,component:s,components:x,route:j,router:y};M.default=u},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!0;return!1}function e(A,M){function t(M){var t=!(arguments.length<=1||void 0===arguments[1])&&arguments[1],I=arguments.length<=2||void 0===arguments[2]?null:arguments[2],g=void 0;return t&&t!==!0||null!==I?(M={pathname:M,query:t},g=I||!1):(M=A.createLocation(M),g=t),(0,C.default)(M,g,s.location,s.routes,s.params)}function I(A,t){x&&x.location===A?e(x,t):(0,B.default)(M,A,function(M,I){M?t(M):I?e(i({},I,{location:A}),t):t()})}function e(A,M){function t(t,g){return t||g?I(t,g):void(0,D.default)(A,function(t,I){t?M(t):M(null,null,s=i({},A,{components:I}))})}function I(A,t){A?M(A):M(null,t)}var g=(0,N.default)(s,A),e=g.leaveRoutes,T=g.changeRoutes,E=g.enterRoutes;(0,o.runLeaveHooks)(e,s),e.filter(function(A){return E.indexOf(A)===-1}).forEach(a),(0,o.runChangeHooks)(T,s,A,function(M,g){return M||g?I(M,g):void(0,o.runEnterHooks)(E,A,t)})}function T(A){var M=arguments.length<=1||void 0===arguments[1]||arguments[1];return A.__id__||M&&(A.__id__=j++)}function E(A){return A.reduce(function(A,M){return A.push.apply(A,y[T(M)]),A},[])}function n(A,t){(0,B.default)(M,A,function(M,I){if(null==I)return void t();x=i({},I,{location:A});for(var g=E((0,N.default)(s,x).leaveRoutes),e=void 0,T=0,o=g.length;null==e&&T=32||13===M?M:0}A.exports=t},function(A,M){"use strict";function t(A){var M=this,t=M.nativeEvent;if(t.getModifierState)return t.getModifierState(A);var I=g[A];return!!I&&!!t[I]}function I(A){return t}var g={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};A.exports=I},function(A,M){"use strict";function t(A){var M=A.target||A.srcElement||window;return 3===M.nodeType?M.parentNode:M}A.exports=t},function(A,M){"use strict";function t(A){var M=A&&(I&&A[I]||A[g]);if("function"==typeof M)return M}var I="function"==typeof Symbol&&Symbol.iterator,g="@@iterator";A.exports=t},function(A,M,t){"use strict";function I(A){return"function"==typeof A&&"undefined"!=typeof A.prototype&&"function"==typeof A.prototype.mountComponent&&"function"==typeof A.prototype.receiveComponent}function g(A){var M;if(null===A||A===!1)M=new i(g);else if("object"==typeof A){var t=A;!t||"function"!=typeof t.type&&"string"!=typeof t.type?N(!1):void 0,M="string"==typeof t.type?T.createInternalComponent(t):I(t.type)?new t.type(t):new o}else"string"==typeof A||"number"==typeof A?M=T.createInstanceForText(A):N(!1);return M.construct(A),M._mountIndex=0,M._mountImage=null,M}var e=t(443),i=t(215),T=t(221),E=t(4),N=t(2),o=(t(3),function(){});E(o.prototype,e.Mixin,{_instantiateReactComponent:g}),A.exports=g},function(A,M,t){"use strict";/** * Checks if an event is supported in the current execution environment. * * NOTE: This will not work correctly for non-generic events such as ` + "`" + `change` + "`" + `, @@ -200,21 +200,21 @@ A.exports=M.default},function(A,M,t){"use strict";var I=t(15).default,g=t(14).de * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */ -function I(A,M){if(!e.canUseDOM||M&&!("addEventListener"in document))return!1;var t="on"+A,I=t in document;if(!I){var i=document.createElement("div");i.setAttribute(t,"return;"),I="function"==typeof i[t]}return!I&&g&&"wheel"===A&&(I=document.implementation.hasFeature("Events.wheel","3.0")),I}var g,e=t(10);e.canUseDOM&&(g=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),A.exports=I},function(A,M,t){"use strict";var I=t(10),g=t(75),e=t(76),i=function(A,M){A.textContent=M};I.canUseDOM&&("textContent"in document.documentElement||(i=function(A,M){e(A,g(M))})),A.exports=i},function(A,M){"use strict";function t(A,M){var t=null===A||A===!1,I=null===M||M===!1;if(t||I)return t===I;var g=typeof A,e=typeof M;return"string"===g||"number"===g?"string"===e||"number"===e:"object"===e&&A.type===M.type&&A.key===M.key}A.exports=t},function(A,M,t){"use strict";function I(A){return a[A]}function g(A,M){return A&&null!=A.key?i(A.key):M.toString(36)}function e(A){return(""+A).replace(B,I)}function i(A){return"$"+e(A)}function T(A,M,t,I){var e=typeof A;if("undefined"!==e&&"boolean"!==e||(A=null),null===A||"string"===e||"number"===e||N.isValidElement(A))return t(I,A,""===M?c+g(A,0):M),1;var E,o,a=0,B=""===M?c:M+D;if(Array.isArray(A))for(var Q=0;QM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;t":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;iM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;t":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;i-1&&A%1==0&&A1)for(var t=1;tA.clientHeight}Object.defineProperty(M,"__esModule",{value:!0}),M.default=i;var T=t(57),E=I(T),N=t(39),o=I(N);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):"function"!==E&&"string"!==E?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):null}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M){"use strict";function t(A){function M(M,t,I,g,e,i){var T=g||"<>",E=i||I;if(null==t[I])return M?new Error("Required "+e+" ` + "`" + `"+E+"` + "`" + ` was not specified "+("in ` + "`" + `"+T+"` + "`" + `.")):null;for(var N=arguments.length,o=Array(N>6?N-6:0),n=6;n=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return 0===A.button}function i(A){return!!(A.metaKey||A.altKey||A.ctrlKey||A.shiftKey)}function T(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!1;return!0}function E(A,M){var t=M.query,I=M.hash,g=M.state;return t||I||g?{pathname:A,query:t,hash:I,state:g}:A}M.__esModule=!0;var N=Object.assign||function(A){for(var M=1;M=0;I--){var g=A[I],e=g.path||"";if(t=e.replace(/\/*$/,"/")+t,0===e.indexOf("/"))break}return"/"+t}},propTypes:{path:C,from:C,to:C.isRequired,query:c,state:c,onEnter:o.falsy,children:o.falsy},render:function(){(0,T.default)(!1)}});M.default=D,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0;var g=t(1),e=I(g),i=t(8),T=I(i),E=t(30),N=t(34),o=e.default.PropTypes,n=o.string,C=o.func,c=e.default.createClass({displayName:"Route",statics:{createRouteFromReactElement:E.createRouteFromReactElement},propTypes:{path:n,component:N.component,components:N.components,getComponent:C,getComponents:C},render:function(){(0,T.default)(!1)}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return!A||!A.__v2_compatible__}function i(A){return A&&A.getCurrentLocation}M.__esModule=!0;var T=Object.assign||function(A){for(var M=1;M=0&&0===window.sessionStorage.length)return;throw A}}function i(A){var M=void 0;try{M=window.sessionStorage.getItem(g(A))}catch(A){if(A.name===o)return null}if(M)try{return JSON.parse(M)}catch(A){}return null}M.__esModule=!0,M.saveState=e,M.readState=i;var T=t(23),E=(I(T),"@@History/"),N=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],o="SecurityError"},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){function M(A){return E.canUseDOM?void 0:T.default(!1),t.listen(A)}var t=n.default(e({getUserConfirmation:N.getUserConfirmation},A,{go:N.go}));return e({},t,{listen:M})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M1?M-1:0),e=1;e=A.childNodes.length?null:A.childNodes.item(t);A.insertBefore(M,I)}var g=t(434),e=t(220),i=t(17),T=t(76),E=t(121),N=t(2),o={dangerouslyReplaceNodeWithMarkup:g.dangerouslyReplaceNodeWithMarkup,updateTextContent:E,processUpdates:function(A,M){for(var t,i=null,o=null,n=0;n-1?void 0:i(!1),!N.plugins[t]){M.extractEvents?void 0:i(!1),N.plugins[t]=M;var I=M.eventTypes;for(var e in I)g(I[e],M,e)?void 0:i(!1)}}}function g(A,M,t){N.eventNameDispatchConfigs.hasOwnProperty(t)?i(!1):void 0,N.eventNameDispatchConfigs[t]=A;var I=A.phasedRegistrationNames;if(I){for(var g in I)if(I.hasOwnProperty(g)){var T=I[g];e(T,M,t)}return!0}return!!A.registrationName&&(e(A.registrationName,M,t),!0)}function e(A,M,t){N.registrationNameModules[A]?i(!1):void 0,N.registrationNameModules[A]=M,N.registrationNameDependencies[A]=M.eventTypes[t].dependencies}var i=t(2),T=null,E={},N={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(A){T?i(!1):void 0,T=Array.prototype.slice.call(A),I()},injectEventPluginsByName:function(A){var M=!1;for(var t in A)if(A.hasOwnProperty(t)){var g=A[t];E.hasOwnProperty(t)&&E[t]===g||(E[t]?i(!1):void 0,E[t]=g,M=!0)}M&&I()},getPluginModuleForEvent:function(A){var M=A.dispatchConfig;if(M.registrationName)return N.registrationNameModules[M.registrationName]||null;for(var t in M.phasedRegistrationNames)if(M.phasedRegistrationNames.hasOwnProperty(t)){var I=N.registrationNameModules[M.phasedRegistrationNames[t]];if(I)return I}return null},_resetEventPlugins:function(){T=null;for(var A in E)E.hasOwnProperty(A)&&delete E[A];N.plugins.length=0;var M=N.eventNameDispatchConfigs;for(var t in M)M.hasOwnProperty(t)&&delete M[t];var I=N.registrationNameModules;for(var g in I)I.hasOwnProperty(g)&&delete I[g]}};A.exports=N},function(A,M,t){"use strict";function I(A){return(""+A).replace(x,"//")}function g(A,M){this.func=A,this.context=M,this.count=0}function e(A,M,t){var I=A.func,g=A.context;I.call(g,M,A.count++)}function i(A,M,t){if(null==A)return A;var I=g.getPooled(M,t);Q(A,e,I),g.release(I)}function T(A,M,t,I){this.result=A,this.keyPrefix=M,this.func=t,this.context=I,this.count=0}function E(A,M,t){var g=A.result,e=A.keyPrefix,i=A.func,T=A.context,E=i.call(T,M,A.count++);Array.isArray(E)?N(E,g,t,B.thatReturnsArgument):null!=E&&(a.isValidElement(E)&&(E=a.cloneAndReplaceKey(E,e+(E!==M?I(E.key||"")+"/":"")+t)),g.push(E))}function N(A,M,t,g,e){var i="";null!=t&&(i=I(t)+"/");var N=T.getPooled(M,i,g,e);Q(A,E,N),T.release(N)}function o(A,M,t){if(null==A)return A;var I=[];return N(A,I,null,M,t),I}function n(A,M,t){return null}function C(A,M){return Q(A,n,null)}function c(A){var M=[];return N(A,M,null,B.thatReturnsArgument),M}var D=t(31),a=t(13),B=t(20),Q=t(123),r=D.twoArgumentPooler,s=D.fourArgumentPooler,x=/\/(?!\/)/g;g.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},D.addPoolingTo(g,r),T.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},D.addPoolingTo(T,s);var j={forEach:i,map:o,mapIntoWithKeyPrefixInternal:N,count:C,toArray:c};A.exports=j},function(A,M,t){"use strict";function I(A,M){var t=y.hasOwnProperty(M)?y[M]:null;w.hasOwnProperty(M)&&(t!==x.OVERRIDE_BASE?B(!1):void 0),A.hasOwnProperty(M)&&(t!==x.DEFINE_MANY&&t!==x.DEFINE_MANY_MERGED?B(!1):void 0)}function g(A,M){if(M){"function"==typeof M?B(!1):void 0,C.isValidElement(M)?B(!1):void 0;var t=A.prototype;M.hasOwnProperty(s)&&u.mixins(A,M.mixins);for(var g in M)if(M.hasOwnProperty(g)&&g!==s){var e=M[g];if(I(t,g),u.hasOwnProperty(g))u[g](A,e);else{var i=y.hasOwnProperty(g),N=t.hasOwnProperty(g),o="function"==typeof e,n=o&&!i&&!N&&M.autobind!==!1;if(n)t.__reactAutoBindMap||(t.__reactAutoBindMap={}),t.__reactAutoBindMap[g]=e,t[g]=e;else if(N){var c=y[g];!i||c!==x.DEFINE_MANY_MERGED&&c!==x.DEFINE_MANY?B(!1):void 0,c===x.DEFINE_MANY_MERGED?t[g]=T(t[g],e):c===x.DEFINE_MANY&&(t[g]=E(t[g],e))}else t[g]=e}}}}function e(A,M){if(M)for(var t in M){var I=M[t];if(M.hasOwnProperty(t)){var g=t in u;g?B(!1):void 0;var e=t in A;e?B(!1):void 0,A[t]=I}}}function i(A,M){A&&M&&"object"==typeof A&&"object"==typeof M?void 0:B(!1);for(var t in M)M.hasOwnProperty(t)&&(void 0!==A[t]?B(!1):void 0,A[t]=M[t]);return A}function T(A,M){return function(){var t=A.apply(this,arguments),I=M.apply(this,arguments);if(null==t)return I;if(null==I)return t;var g={};return i(g,t),i(g,I),g}}function E(A,M){return function(){A.apply(this,arguments),M.apply(this,arguments)}}function N(A,M){var t=M.bind(A);return t}function o(A){for(var M in A.__reactAutoBindMap)if(A.__reactAutoBindMap.hasOwnProperty(M)){var t=A.__reactAutoBindMap[M];A[M]=N(A,t)}}var n=t(207),C=t(13),c=(t(71),t(70),t(222)),D=t(4),a=t(50),B=t(2),Q=t(59),r=t(27),s=(t(3),r({mixins:null})),x=Q({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),j=[],y={mixins:x.DEFINE_MANY,statics:x.DEFINE_MANY,propTypes:x.DEFINE_MANY,contextTypes:x.DEFINE_MANY,childContextTypes:x.DEFINE_MANY,getDefaultProps:x.DEFINE_MANY_MERGED,getInitialState:x.DEFINE_MANY_MERGED,getChildContext:x.DEFINE_MANY_MERGED,render:x.DEFINE_ONCE,componentWillMount:x.DEFINE_MANY,componentDidMount:x.DEFINE_MANY,componentWillReceiveProps:x.DEFINE_MANY,shouldComponentUpdate:x.DEFINE_ONCE,componentWillUpdate:x.DEFINE_MANY,componentDidUpdate:x.DEFINE_MANY,componentWillUnmount:x.DEFINE_MANY,updateComponent:x.OVERRIDE_BASE},u={displayName:function(A,M){A.displayName=M},mixins:function(A,M){if(M)for(var t=0;t"+T+""},receiveComponent:function(A,M){if(A!==this._currentElement){this._currentElement=A;var t=""+A;if(t!==this._stringText){this._stringText=t;var g=i.getNode(this._rootNodeID);I.updateTextContent(g,t)}}},unmountComponent:function(){e.unmountIDFromEnvironment(this._rootNodeID)}}),A.exports=o},function(A,M,t){"use strict";function I(){this.reinitializeTransaction()}var g=t(18),e=t(73),i=t(4),T=t(20),E={initialize:T,close:function(){C.isBatchingUpdates=!1}},N={initialize:T,close:g.flushBatchedUpdates.bind(g)},o=[N,E];i(I.prototype,e.Mixin,{getTransactionWrappers:function(){return o}});var n=new I,C={isBatchingUpdates:!1,batchedUpdates:function(A,M,t,I,g,e){var i=C.isBatchingUpdates;C.isBatchingUpdates=!0,i?A(M,t,I,g,e):n.perform(A,null,M,t,I,g,e)}};A.exports=C},function(A,M,t){"use strict";function I(){if(!l){l=!0,Q.EventEmitter.injectReactEventListener(B),Q.EventPluginHub.injectEventPluginOrder(T),Q.EventPluginHub.injectInstanceHandle(r),Q.EventPluginHub.injectMount(s),Q.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:u,EnterLeaveEventPlugin:E,ChangeEventPlugin:e,SelectEventPlugin:j,BeforeInputEventPlugin:g}),Q.NativeComponent.injectGenericComponentClass(D),Q.NativeComponent.injectTextComponentClass(a),Q.Class.injectMixin(n),Q.DOMProperty.injectDOMPropertyConfig(o),Q.DOMProperty.injectDOMPropertyConfig(w),Q.EmptyComponent.injectEmptyComponent("noscript"),Q.Updates.injectReconcileTransaction(x),Q.Updates.injectBatchingStrategy(c),Q.RootIndex.injectCreateReactRootIndex(N.canUseDOM?i.createReactRootIndex:y.createReactRootIndex),Q.Component.injectEnvironment(C)}}var g=t(430),e=t(432),i=t(433),T=t(435),E=t(436),N=t(10),o=t(439),n=t(441),C=t(109),c=t(212),D=t(445),a=t(211),B=t(453),Q=t(454),r=t(48),s=t(12),x=t(458),j=t(464),y=t(465),u=t(466),w=t(463),l=!1;A.exports={inject:I}},function(A,M,t){"use strict";function I(){if(n.current){var A=n.current.getName();if(A)return" Check the render method of ` + "`" + `"+A+"` + "`" + `."}return""}function g(A,M){if(A._store&&!A._store.validated&&null==A.key){A._store.validated=!0;e("uniqueKey",A,M)}}function e(A,M,t){var g=I();if(!g){var e="string"==typeof t?t:t.displayName||t.name;e&&(g=" Check the top-level render call using <"+e+">.")}var i=D[A]||(D[A]={});if(i[g])return null;i[g]=!0;var T={parentOrOwner:g,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return M&&M._owner&&M._owner!==n.current&&(T.childOwner=" It was passed a child from "+M._owner.getName()+"."),T}function i(A,M){if("object"==typeof A)if(Array.isArray(A))for(var t=0;t/,e={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(A){var M=I(A);return A.replace(g," "+e.CHECKSUM_ATTR_NAME+'="'+M+'"$&')},canReuseMarkup:function(A,M){var t=M.getAttribute(e.CHECKSUM_ATTR_NAME);t=t&&parseInt(t,10);var g=I(A);return g===t}};A.exports=e},function(A,M,t){"use strict";var I=t(59),g=I({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,SET_MARKUP:null,TEXT_CONTENT:null});A.exports=g},function(A,M,t){"use strict";function I(A){if("function"==typeof A.type)return A.type;var M=A.type,t=n[M];return null==t&&(n[M]=t=N(M)),t}function g(A){return o?void 0:E(!1),new o(A.type,A.props)}function e(A){return new C(A)}function i(A){return A instanceof C}var T=t(4),E=t(2),N=null,o=null,n={},C=null,c={injectGenericComponentClass:function(A){o=A},injectTextComponentClass:function(A){C=A},injectComponentClasses:function(A){T(n,A)}},D={getComponentClassForElement:I,createInternalComponent:g,createInstanceForText:e,isTextComponent:i,injection:c};A.exports=D},function(A,M,t){"use strict";function I(A,M){}var g=(t(3),{isMounted:function(A){return!1},enqueueCallback:function(A,M){},enqueueForceUpdate:function(A){I(A,"forceUpdate")},enqueueReplaceState:function(A,M){I(A,"replaceState")},enqueueSetState:function(A,M){I(A,"setState")},enqueueSetProps:function(A,M){I(A,"setProps")},enqueueReplaceProps:function(A,M){I(A,"replaceProps")}});A.exports=g},function(A,M,t){"use strict";function I(A){function M(M,t,I,g,e,i){if(g=g||y,i=i||I,null==t[I]){var T=s[e];return M?new Error("Required "+T+" ` + "`" + `"+i+"` + "`" + ` was not specified in "+("` + "`" + `"+g+"` + "`" + `.")):null}return A(t,I,g,e,i)}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}function g(A){function M(M,t,I,g,e){var i=M[t],T=a(i);if(T!==A){var E=s[g],N=B(i);return new Error("Invalid "+E+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+N+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected ")+("` + "`" + `"+A+"` + "`" + `."))}return null}return I(M)}function e(){return I(x.thatReturns(null))}function i(A){function M(M,t,I,g,e){var i=M[t];if(!Array.isArray(i)){var T=s[g],E=a(i);return new Error("Invalid "+T+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+E+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected an array."))}for(var N=0;N>"}var r=t(13),s=t(70),x=t(20),j=t(118),y="<>",u={array:g("array"),bool:g("boolean"),func:g("function"),number:g("number"),object:g("object"),string:g("string"),any:e(),arrayOf:i,element:T(),instanceOf:E,node:C(),objectOf:o,oneOf:N,oneOfType:n,shape:c};A.exports=u},function(A,M){"use strict";var t={injectCreateReactRootIndex:function(A){I.createReactRootIndex=A}},I={createReactRootIndex:null,injection:t};A.exports=I},function(A,M){"use strict";var t={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(A){t.currentScrollLeft=A.x,t.currentScrollTop=A.y}};A.exports=t},function(A,M,t){"use strict";function I(A,M){if(null==M?g(!1):void 0,null==A)return M;var t=Array.isArray(A),I=Array.isArray(M);return t&&I?(A.push.apply(A,M),A):t?(A.push(M),A):I?[A].concat(M):[A,M]}var g=t(2);A.exports=I},function(A,M){"use strict";var t=function(A,M,t){Array.isArray(A)?A.forEach(M,t):A&&M.call(t,A)};A.exports=t},function(A,M,t){"use strict";function I(){return!e&&g.canUseDOM&&(e="textContent"in document.documentElement?"textContent":"innerText"),e}var g=t(10),e=null;A.exports=I},function(A,M){"use strict";function t(A){var M=A&&A.nodeName&&A.nodeName.toLowerCase();return M&&("input"===M&&I[A.type]||"textarea"===M)}var I={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};A.exports=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){for(var A=arguments.length,M=Array(A),t=0;t=0&&s.splice(M,1)}function T(A){var M=document.createElement("style");return M.type="text/css",e(A,M),M}function E(A){var M=document.createElement("link");return M.rel="stylesheet",e(A,M),M}function N(A,M){var t,I,g;if(M.singleton){var e=r++;t=Q||(Q=T(M)),I=o.bind(null,t,e,!1),g=o.bind(null,t,e,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=E(M),I=C.bind(null,t),g=function(){i(t),t.href&&URL.revokeObjectURL(t.href)}):(t=T(M),I=n.bind(null,t),g=function(){i(t)});return I(A),function(M){if(M){if(M.css===A.css&&M.media===A.media&&M.sourceMap===A.sourceMap)return;I(A=M)}else g()}}function o(A,M,t,I){var g=t?"":I.css;if(A.styleSheet)A.styleSheet.cssText=x(M,g);else{var e=document.createTextNode(g),i=A.childNodes;i[M]&&A.removeChild(i[M]),i.length?A.insertBefore(e,i[M]):A.appendChild(e)}}function n(A,M){var t=M.css,I=M.media;if(I&&A.setAttribute("media",I),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function C(A,M){var t=M.css,I=M.sourceMap;I&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(I))))+" */");var g=new Blob([t],{type:"text/css"}),e=A.href;A.href=URL.createObjectURL(g),e&&URL.revokeObjectURL(e)}var c={},D=function(A){var M;return function(){return"undefined"==typeof M&&(M=A.apply(this,arguments)),M}},a=D(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),B=D(function(){return document.head||document.getElementsByTagName("head")[0]}),Q=null,r=0,s=[];A.exports=function(A,M){M=M||{},"undefined"==typeof M.singleton&&(M.singleton=a()),"undefined"==typeof M.insertAt&&(M.insertAt="bottom");var t=g(A);return I(t,M),function(A){for(var e=[],i=0;i",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(360);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){var t={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,stopOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};A.exports=function(A,M){return"number"!=typeof M||t[A]?M:M+"px"}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M,t){return P.LoggedIn()?t():(location.pathname!==z.minioBrowserPrefix&&location.pathname!==z.minioBrowserPrefix+"/"||M(z.minioBrowserPrefix+"/login"),t())}function i(A,M){P.LoggedIn()&&M(""+z.minioBrowserPrefix)}function T(){q<2&&setTimeout(function(){document.querySelector(".page-load").classList.add("pl-"+q),q++,T()},K[q])}t(499);var E=t(1),N=g(E),o=t(16),n=g(o),C=t(485),c=g(C),D=t(125),a=g(D),B=t(230),Q=g(B),r=t(190),s=g(r),x=t(191),j=g(x),y=t(65),u=g(y),w=t(187),l=g(w),L=t(394),Y=g(L),d=t(22),h=g(d),S=t(42),z=(g(S),t(26)),p=t(19),U=I(p),O=t(255),m=g(O),F=t(245),f=g(F),k=t(241),R=g(k),J=t(498),G=(g(J),t(131)),H=g(G),b=t(60),v=g(b);window.Web=H.default;var X=(0,Q.default)(c.default)(a.default)(m.default),W=(0,h.default)(function(A){return A})(R.default),V=(0,h.default)(function(A){return A})(f.default),P=new H.default(window.location.protocol+"//"+window.location.host+z.minioBrowserPrefix+"/webrpc",X.dispatch);window.web=P,X.dispatch(U.setWeb(P));var Z=function(A){return N.default.createElement("div",null,A.children)};n.default.render(N.default.createElement(Y.default,{store:X,web:P},N.default.createElement(j.default,{history:u.default},N.default.createElement(s.default,{path:"/",component:Z},N.default.createElement(s.default,{path:"minio",component:Z},N.default.createElement(l.default,{component:W,onEnter:e}),N.default.createElement(s.default,{path:"login",component:V,onEnter:i}),N.default.createElement(s.default,{path:":bucket",component:W,onEnter:e}),N.default.createElement(s.default,{path:":bucket/*",component:W,onEnter:e}))))),document.getElementById("root"));var K=[0,400],q=0;T(),v.default.getItem("newlyUpdated")&&(X.dispatch(U.showAlert({type:"success",message:"Updated to the latest UI Version."})),v.default.removeItem("newlyUpdated"))},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=M.currentPath,e=M.currentBucket,i=M.deleteConfirmation;t.RemoveObject({bucketname:e,objects:[i.object]}).then(function(){A.hideDeleteConfirmation();var M=i.object.replace(g,"");I(eA.removeObject(M))}).catch(function(A){return I(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideAlert",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAlert())}},{key:"showDeleteConfirmation",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.showDeleteConfirmation(M))}},{key:"hideDeleteConfirmation",value:function(){var A=this.props.dispatch;A(eA.hideDeleteConfirmation())}},{key:"shareObject",value:function(A,M){A.preventDefault();var t=this.props.dispatch;t(eA.shareObject(M))}},{key:"hideShareObjectModal",value:function(){var A=this.props.dispatch;A(eA.hideShareObject())}},{key:"dataType",value:function(A,M){return NA.getDataType(A,M)}},{key:"sortObjectsByName",value:function(A){var M=this.props,t=M.dispatch,I=M.objects,g=M.sortNameOrder;t(eA.setObjects(TA.sortObjectsByName(I,!g))),t(eA.setSortNameOrder(!g))}},{key:"sortObjectsBySize",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortSizeOrder;M(eA.setObjects(TA.sortObjectsBySize(t,!I))),M(eA.setSortSizeOrder(!I))}},{key:"sortObjectsByDate",value:function(){var A=this.props,M=A.dispatch,t=A.objects,I=A.sortDateOrder;M(eA.setObjects(TA.sortObjectsByDate(t,!I))),M(eA.setSortDateOrder(!I))}},{key:"logout",value:function(A){var M=this.props.web;A.preventDefault(),M.Logout(),D.default.push(oA.minioBrowserPrefix+"/login")}},{key:"fullScreen",value:function(A){A.preventDefault();var M=document.documentElement;M.requestFullscreen&&M.requestFullscreen(),M.mozRequestFullScreen&&M.mozRequestFullScreen(),M.webkitRequestFullscreen&&M.webkitRequestFullscreen(),M.msRequestFullscreen&&M.msRequestFullscreen()}},{key:"toggleSidebar",value:function(A){this.props.dispatch(eA.setSidebarStatus(A))}},{key:"hideSidebar",value:function(A){var M=A||window.event,t=M.srcElement||M.target;3===t.nodeType&&(t=t.parentNode);var I=t.id;"feh-trigger"!==I&&this.props.dispatch(eA.setSidebarStatus(!1))}},{key:"showSettings",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showSettings())}},{key:"showMessage",value:function(){var A=this.props.dispatch;A(eA.showAlert({type:"success",message:"Link copied to clipboard!"})),this.hideShareObjectModal()}},{key:"selectTexts",value:function(){this.refs.copyTextInput.select()}},{key:"handleExpireValue",value:function(A,M){M===-1?this.refs[A].stepDown(1):this.refs[A].stepUp(1),7==this.refs.expireDays.value&&(this.refs.expireHours.value=0,this.refs.expireMins.value=0)}},{key:"checkObject",value:function(A,M){var t=this.props.dispatch;t(A.target.checked?eA.checkedObjectsAdd(M):eA.checkedObjectsRemove(M))}},{key:"downloadAll",value:function(){var A=this.props.dispatch,M={bucketName:this.props.currentBucket,objects:this.props.checkedObjects,prefix:this.props.currentPath},t=location.origin+"/minio/zip?token="+localStorage.token;this.xhr=new XMLHttpRequest,A(eA.downloadAllasZip(t,M,this.xhr))}},{key:"render",value:function(){var A=this.props.storageInfo,M=A.total,t=A.free,I=this.props,g=I.showMakeBucketModal,e=I.alert,i=I.sortNameOrder,T=I.sortSizeOrder,E=I.sortDateOrder,N=I.showAbout,n=I.showBucketPolicy,c=I.checkedObjects,D=this.props.serverInfo,a=D.version,Q=D.memory,r=D.platform,x=D.runtime,y=this.props.sidebarStatus,w=this.props.showSettings,L=this.props,d=L.policies,S=L.currentBucket,p=(L.currentPath,this.props.deleteConfirmation),U=this.props.shareObject,O=this.props,F=O.web,k=O.prefixWritable,J=O.istruncated,H=w?o.default.createElement(V.default,null):o.default.createElement("noscript",null),v=o.default.createElement(l.default,{className:(0,C.default)({alert:!0,animated:!0,fadeInDown:e.show,fadeOutUp:!e.show}),bsStyle:e.type,onDismiss:this.hideAlert.bind(this)},o.default.createElement("div",{className:"text-center"},e.message));e.message||(v="");var W=(o.default.createElement(h.default,{id:"tt-sign-out"},"Sign out"),o.default.createElement(h.default,{id:"tt-upload-file"},"Upload file")),P=o.default.createElement(h.default,{id:"tt-create-bucket"},"Create bucket"),K="",_="",AA="",tA=M-t,gA=tA/M*100+"%";F.LoggedIn()?_=o.default.createElement($.default,{fullScreenFunc:this.fullScreen.bind(this),aboutFunc:this.showAbout.bind(this),settingsFunc:this.showSettings.bind(this),logoutFunc:this.logout.bind(this)}):K=o.default.createElement("a",{className:"btn btn-danger",href:"/minio/login"},"Login"),F.LoggedIn()&&(AA=o.default.createElement("div",{className:"feh-usage"},o.default.createElement("div",{className:"fehu-chart"},o.default.createElement("div",{style:{width:gA}})),o.default.createElement("ul",null,o.default.createElement("li",null,"Used:",B.default.filesize(M-t)),o.default.createElement("li",{className:"pull-right"},"Free:",B.default.filesize(M-tA)))));var eA="";return F.LoggedIn()?eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," "))),o.default.createElement(Y.default,{placement:"left",overlay:P},o.default.createElement("a",{href:"#",className:"feba-btn feba-bucket",onClick:this.showMakeBucketModal.bind(this)},o.default.createElement("i",{className:"fa fa-hdd-o"}))))):k&&(eA=o.default.createElement(z.default,{dropup:!0,className:"feb-actions",id:"fe-action-toggle"},o.default.createElement(z.default.Toggle,{noCaret:!0,className:"feba-toggle"},o.default.createElement("span",null,o.default.createElement("i",{className:"fa fa-plus"}))),o.default.createElement(z.default.Menu,null,o.default.createElement(Y.default,{placement:"left",overlay:W},o.default.createElement("a",{href:"#",className:"feba-btn feba-upload"},o.default.createElement("input",{type:"file",onChange:this.uploadFile.bind(this),style:{display:"none"},id:"file-input"}),o.default.createElement("label",{htmlFor:"file-input"}," ",o.default.createElement("i",{className:"fa fa-cloud-upload"})," ")))))),o.default.createElement("div",{className:(0,C.default)({"file-explorer":!0,toggled:y})},o.default.createElement(R.default,{searchBuckets:this.searchBuckets.bind(this),selectBucket:this.selectBucket.bind(this),clickOutside:this.hideSidebar.bind(this),showPolicy:this.showBucketPolicy.bind(this)}),o.default.createElement("div",{className:"fe-body"},o.default.createElement("div",{className:"list-actions"+(0,C.default)({" list-actions-toggled":c.length>0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadAll.bind(this)}," Download all as zip "))),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:24,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:1,max:60,defaultValue:45})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{ -href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1?" fesl-row-selected":"";return e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",expiry:604800},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return t}},function(A,M,t){A.exports={default:t(260),__esModule:!0}},function(A,M,t){t(270), -A.exports=t(49).Object.assign},function(A,M,t){var I=t(80);A.exports=function(A,M){return I.create(A,M)}},function(A,M,t){t(271),A.exports=t(49).Object.keys},function(A,M,t){t(272),A.exports=t(49).Object.setPrototypeOf},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M,t){var I=t(136);A.exports=function(A){if(!I(A))throw TypeError(A+" is not an object!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(263);A.exports=Object("z").propertyIsEnumerable(0)?Object:function(A){return"String"==I(A)?A.split(""):Object(A)}},function(A,M,t){var I=t(80),g=t(137),e=t(266);A.exports=t(135)(function(){var A=Object.assign,M={},t={},I=Symbol(),g="abcdefghijklmnopqrst";return M[I]=7,g.split("").forEach(function(A){t[A]=A}),7!=A({},M)[I]||Object.keys(A({},t)).join("")!=g})?function(A,M){for(var t=g(A),i=arguments,T=i.length,E=1,N=I.getKeys,o=I.getSymbols,n=I.isEnum;T>E;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(135);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(136),e=t(262),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(134)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(267)})},function(A,M,t){var I=t(137);t(268)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(269).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;g",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(360);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){var t={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,stopOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};A.exports=function(A,M){return"number"!=typeof M||t[A]?M:M+"px"}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M,t){return P.LoggedIn()?t():(location.pathname!==z.minioBrowserPrefix&&location.pathname!==z.minioBrowserPrefix+"/"||M(z.minioBrowserPrefix+"/login"),t())}function i(A,M){P.LoggedIn()&&M(""+z.minioBrowserPrefix)}function T(){q<2&&setTimeout(function(){document.querySelector(".page-load").classList.add("pl-"+q),q++,T()},K[q])}t(499);var E=t(1),N=g(E),o=t(16),n=g(o),C=t(485),c=g(C),D=t(125),a=g(D),B=t(230),Q=g(B),r=t(190),s=g(r),x=t(191),j=g(x),y=t(65),u=g(y),w=t(187),l=g(w),L=t(394),Y=g(L),d=t(22),h=g(d),S=t(42),z=(g(S),t(26)),p=t(19),U=I(p),O=t(255),m=g(O),F=t(245),f=g(F),k=t(241),R=g(k),J=t(498),G=(g(J),t(131)),H=g(G),b=t(60),v=g(b);window.Web=H.default;var X=(0,Q.default)(c.default)(a.default)(m.default),W=(0,h.default)(function(A){return A})(R.default),V=(0,h.default)(function(A){return A})(f.default),P=new H.default(window.location.protocol+"//"+window.location.host+z.minioBrowserPrefix+"/webrpc",X.dispatch);window.web=P,X.dispatch(U.setWeb(P));var Z=function(A){return N.default.createElement("div",null,A.children)};n.default.render(N.default.createElement(Y.default,{store:X,web:P},N.default.createElement(j.default,{history:u.default},N.default.createElement(s.default,{path:"/",component:Z},N.default.createElement(s.default,{path:"minio",component:Z},N.default.createElement(l.default,{component:W,onEnter:e}),N.default.createElement(s.default,{path:"login",component:V,onEnter:i}),N.default.createElement(s.default,{path:":bucket",component:W,onEnter:e}),N.default.createElement(s.default,{path:":bucket/*",component:W,onEnter:e}))))),document.getElementById("root"));var K=[0,400],q=0;T(),v.default.getItem("newlyUpdated")&&(X.dispatch(U.showAlert({type:"success",message:"Updated to the latest UI Version."})),v.default.removeItem("newlyUpdated"))},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=M.currentPath,e=M.currentBucket,i=M.deleteConfirmation,T=M.checkedObjects,E=T.length>0?T:[i.object];t.RemoveObject({bucketname:e,objects:E}).then(function(){if(A.hideDeleteConfirmation(),T.length>0){for(var M=0;M0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadSelected.bind(this)}," Download all as zip ")),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.showDeleteConfirmation.bind(this)}," Delete selected ")),o.default.createElement("i",{className:"la-close fa fa-times",onClick:this.clearSelected.bind(this)})),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:5})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:23,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:0,max:59,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1,U.object)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:window.location.protocol+"//"+U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{ +href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&(A.name.endsWith("/")||(Q=e.default.createElement(c.default,{id:"fia-dropdown-"+A.name.replace(".","-")},e.default.createElement(c.default.Toggle,{noCaret:!0,className:"fia-toggle"}),e.default.createElement(c.default.Menu,null,e.default.createElement("a",{href:"",className:"fiad-action",onClick:function(M){return E(M,""+t+A.name)}},e.default.createElement("i",{className:"fa fa-copy"})),r))));var s="",x="";return C.indexOf(A.name)>-1&&(s=" fesl-row-selected",x=!0),e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,checked:x,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",object:""},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy; +break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return t}},function(A,M,t){A.exports={default:t(260),__esModule:!0}},function(A,M,t){t(270),A.exports=t(49).Object.assign},function(A,M,t){var I=t(80);A.exports=function(A,M){return I.create(A,M)}},function(A,M,t){t(271),A.exports=t(49).Object.keys},function(A,M,t){t(272),A.exports=t(49).Object.setPrototypeOf},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M,t){var I=t(136);A.exports=function(A){if(!I(A))throw TypeError(A+" is not an object!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(263);A.exports=Object("z").propertyIsEnumerable(0)?Object:function(A){return"String"==I(A)?A.split(""):Object(A)}},function(A,M,t){var I=t(80),g=t(137),e=t(266);A.exports=t(135)(function(){var A=Object.assign,M={},t={},I=Symbol(),g="abcdefghijklmnopqrst";return M[I]=7,g.split("").forEach(function(A){t[A]=A}),7!=A({},M)[I]||Object.keys(A({},t)).join("")!=g})?function(A,M){for(var t=g(A),i=arguments,T=i.length,E=1,N=I.getKeys,o=I.getSymbols,n=I.isEnum;T>E;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(135);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(136),e=t(262),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(134)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(267)})},function(A,M,t){var I=t(137);t(268)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(269).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;gli{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\\F000"}.fa-music:before{content:"\\F001"}.fa-search:before{content:"\\F002"}.fa-envelope-o:before{content:"\\F003"}.fa-heart:before{content:"\\F004"}.fa-star:before{content:"\\F005"}.fa-star-o:before{content:"\\F006"}.fa-user:before{content:"\\F007"}.fa-film:before{content:"\\F008"}.fa-th-large:before{content:"\\F009"}.fa-th:before{content:"\\F00A"}.fa-th-list:before{content:"\\F00B"}.fa-check:before{content:"\\F00C"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\\F00D"}.fa-search-plus:before{content:"\\F00E"}.fa-search-minus:before{content:"\\F010"}.fa-power-off:before{content:"\\F011"}.fa-signal:before{content:"\\F012"}.fa-cog:before,.fa-gear:before{content:"\\F013"}.fa-trash-o:before{content:"\\F014"}.fa-home:before{content:"\\F015"}.fa-file-o:before{content:"\\F016"}.fa-clock-o:before{content:"\\F017"}.fa-road:before{content:"\\F018"}.fa-download:before{content:"\\F019"}.fa-arrow-circle-o-down:before{content:"\\F01A"}.fa-arrow-circle-o-up:before{content:"\\F01B"}.fa-inbox:before{content:"\\F01C"}.fa-play-circle-o:before{content:"\\F01D"}.fa-repeat:before,.fa-rotate-right:before{content:"\\F01E"}.fa-refresh:before{content:"\\F021"}.fa-list-alt:before{content:"\\F022"}.fa-lock:before{content:"\\F023"}.fa-flag:before{content:"\\F024"}.fa-headphones:before{content:"\\F025"}.fa-volume-off:before{content:"\\F026"}.fa-volume-down:before{content:"\\F027"}.fa-volume-up:before{content:"\\F028"}.fa-qrcode:before{content:"\\F029"}.fa-barcode:before{content:"\\F02A"}.fa-tag:before{content:"\\F02B"}.fa-tags:before{content:"\\F02C"}.fa-book:before{content:"\\F02D"}.fa-bookmark:before{content:"\\F02E"}.fa-print:before{content:"\\F02F"}.fa-camera:before{content:"\\F030"}.fa-font:before{content:"\\F031"}.fa-bold:before{content:"\\F032"}.fa-italic:before{content:"\\F033"}.fa-text-height:before{content:"\\F034"}.fa-text-width:before{content:"\\F035"}.fa-align-left:before{content:"\\F036"}.fa-align-center:before{content:"\\F037"}.fa-align-right:before{content:"\\F038"}.fa-align-justify:before{content:"\\F039"}.fa-list:before{content:"\\F03A"}.fa-dedent:before,.fa-outdent:before{content:"\\F03B"}.fa-indent:before{content:"\\F03C"}.fa-video-camera:before{content:"\\F03D"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\\F03E"}.fa-pencil:before{content:"\\F040"}.fa-map-marker:before{content:"\\F041"}.fa-adjust:before{content:"\\F042"}.fa-tint:before{content:"\\F043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\\F044"}.fa-share-square-o:before{content:"\\F045"}.fa-check-square-o:before{content:"\\F046"}.fa-arrows:before{content:"\\F047"}.fa-step-backward:before{content:"\\F048"}.fa-fast-backward:before{content:"\\F049"}.fa-backward:before{content:"\\F04A"}.fa-play:before{content:"\\F04B"}.fa-pause:before{content:"\\F04C"}.fa-stop:before{content:"\\F04D"}.fa-forward:before{content:"\\F04E"}.fa-fast-forward:before{content:"\\F050"}.fa-step-forward:before{content:"\\F051"}.fa-eject:before{content:"\\F052"}.fa-chevron-left:before{content:"\\F053"}.fa-chevron-right:before{content:"\\F054"}.fa-plus-circle:before{content:"\\F055"}.fa-minus-circle:before{content:"\\F056"}.fa-times-circle:before{content:"\\F057"}.fa-check-circle:before{content:"\\F058"}.fa-question-circle:before{content:"\\F059"}.fa-info-circle:before{content:"\\F05A"}.fa-crosshairs:before{content:"\\F05B"}.fa-times-circle-o:before{content:"\\F05C"}.fa-check-circle-o:before{content:"\\F05D"}.fa-ban:before{content:"\\F05E"}.fa-arrow-left:before{content:"\\F060"}.fa-arrow-right:before{content:"\\F061"}.fa-arrow-up:before{content:"\\F062"}.fa-arrow-down:before{content:"\\F063"}.fa-mail-forward:before,.fa-share:before{content:"\\F064"}.fa-expand:before{content:"\\F065"}.fa-compress:before{content:"\\F066"}.fa-plus:before{content:"\\F067"}.fa-minus:before{content:"\\F068"}.fa-asterisk:before{content:"\\F069"}.fa-exclamation-circle:before{content:"\\F06A"}.fa-gift:before{content:"\\F06B"}.fa-leaf:before{content:"\\F06C"}.fa-fire:before{content:"\\F06D"}.fa-eye:before{content:"\\F06E"}.fa-eye-slash:before{content:"\\F070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\\F071"}.fa-plane:before{content:"\\F072"}.fa-calendar:before{content:"\\F073"}.fa-random:before{content:"\\F074"}.fa-comment:before{content:"\\F075"}.fa-magnet:before{content:"\\F076"}.fa-chevron-up:before{content:"\\F077"}.fa-chevron-down:before{content:"\\F078"}.fa-retweet:before{content:"\\F079"}.fa-shopping-cart:before{content:"\\F07A"}.fa-folder:before{content:"\\F07B"}.fa-folder-open:before{content:"\\F07C"}.fa-arrows-v:before{content:"\\F07D"}.fa-arrows-h:before{content:"\\F07E"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\\F080"}.fa-twitter-square:before{content:"\\F081"}.fa-facebook-square:before{content:"\\F082"}.fa-camera-retro:before{content:"\\F083"}.fa-key:before{content:"\\F084"}.fa-cogs:before,.fa-gears:before{content:"\\F085"}.fa-comments:before{content:"\\F086"}.fa-thumbs-o-up:before{content:"\\F087"}.fa-thumbs-o-down:before{content:"\\F088"}.fa-star-half:before{content:"\\F089"}.fa-heart-o:before{content:"\\F08A"}.fa-sign-out:before{content:"\\F08B"}.fa-linkedin-square:before{content:"\\F08C"}.fa-thumb-tack:before{content:"\\F08D"}.fa-external-link:before{content:"\\F08E"}.fa-sign-in:before{content:"\\F090"}.fa-trophy:before{content:"\\F091"}.fa-github-square:before{content:"\\F092"}.fa-upload:before{content:"\\F093"}.fa-lemon-o:before{content:"\\F094"}.fa-phone:before{content:"\\F095"}.fa-square-o:before{content:"\\F096"}.fa-bookmark-o:before{content:"\\F097"}.fa-phone-square:before{content:"\\F098"}.fa-twitter:before{content:"\\F099"}.fa-facebook-f:before,.fa-facebook:before{content:"\\F09A"}.fa-github:before{content:"\\F09B"}.fa-unlock:before{content:"\\F09C"}.fa-credit-card:before{content:"\\F09D"}.fa-feed:before,.fa-rss:before{content:"\\F09E"}.fa-hdd-o:before{content:"\\F0A0"}.fa-bullhorn:before{content:"\\F0A1"}.fa-bell:before{content:"\\F0F3"}.fa-certificate:before{content:"\\F0A3"}.fa-hand-o-right:before{content:"\\F0A4"}.fa-hand-o-left:before{content:"\\F0A5"}.fa-hand-o-up:before{content:"\\F0A6"}.fa-hand-o-down:before{content:"\\F0A7"}.fa-arrow-circle-left:before{content:"\\F0A8"}.fa-arrow-circle-right:before{content:"\\F0A9"}.fa-arrow-circle-up:before{content:"\\F0AA"}.fa-arrow-circle-down:before{content:"\\F0AB"}.fa-globe:before{content:"\\F0AC"}.fa-wrench:before{content:"\\F0AD"}.fa-tasks:before{content:"\\F0AE"}.fa-filter:before{content:"\\F0B0"}.fa-briefcase:before{content:"\\F0B1"}.fa-arrows-alt:before{content:"\\F0B2"}.fa-group:before,.fa-users:before{content:"\\F0C0"}.fa-chain:before,.fa-link:before{content:"\\F0C1"}.fa-cloud:before{content:"\\F0C2"}.fa-flask:before{content:"\\F0C3"}.fa-cut:before,.fa-scissors:before{content:"\\F0C4"}.fa-copy:before,.fa-files-o:before{content:"\\F0C5"}.fa-paperclip:before{content:"\\F0C6"}.fa-floppy-o:before,.fa-save:before{content:"\\F0C7"}.fa-square:before{content:"\\F0C8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\\F0C9"}.fa-list-ul:before{content:"\\F0CA"}.fa-list-ol:before{content:"\\F0CB"}.fa-strikethrough:before{content:"\\F0CC"}.fa-underline:before{content:"\\F0CD"}.fa-table:before{content:"\\F0CE"}.fa-magic:before{content:"\\F0D0"}.fa-truck:before{content:"\\F0D1"}.fa-pinterest:before{content:"\\F0D2"}.fa-pinterest-square:before{content:"\\F0D3"}.fa-google-plus-square:before{content:"\\F0D4"}.fa-google-plus:before{content:"\\F0D5"}.fa-money:before{content:"\\F0D6"}.fa-caret-down:before{content:"\\F0D7"}.fa-caret-up:before{content:"\\F0D8"}.fa-caret-left:before{content:"\\F0D9"}.fa-caret-right:before{content:"\\F0DA"}.fa-columns:before{content:"\\F0DB"}.fa-sort:before,.fa-unsorted:before{content:"\\F0DC"}.fa-sort-desc:before,.fa-sort-down:before{content:"\\F0DD"}.fa-sort-asc:before,.fa-sort-up:before{content:"\\F0DE"}.fa-envelope:before{content:"\\F0E0"}.fa-linkedin:before{content:"\\F0E1"}.fa-rotate-left:before,.fa-undo:before{content:"\\F0E2"}.fa-gavel:before,.fa-legal:before{content:"\\F0E3"}.fa-dashboard:before,.fa-tachometer:before{content:"\\F0E4"}.fa-comment-o:before{content:"\\F0E5"}.fa-comments-o:before{content:"\\F0E6"}.fa-bolt:before,.fa-flash:before{content:"\\F0E7"}.fa-sitemap:before{content:"\\F0E8"}.fa-umbrella:before{content:"\\F0E9"}.fa-clipboard:before,.fa-paste:before{content:"\\F0EA"}.fa-lightbulb-o:before{content:"\\F0EB"}.fa-exchange:before{content:"\\F0EC"}.fa-cloud-download:before{content:"\\F0ED"}.fa-cloud-upload:before{content:"\\F0EE"}.fa-user-md:before{content:"\\F0F0"}.fa-stethoscope:before{content:"\\F0F1"}.fa-suitcase:before{content:"\\F0F2"}.fa-bell-o:before{content:"\\F0A2"}.fa-coffee:before{content:"\\F0F4"}.fa-cutlery:before{content:"\\F0F5"}.fa-file-text-o:before{content:"\\F0F6"}.fa-building-o:before{content:"\\F0F7"}.fa-hospital-o:before{content:"\\F0F8"}.fa-ambulance:before{content:"\\F0F9"}.fa-medkit:before{content:"\\F0FA"}.fa-fighter-jet:before{content:"\\F0FB"}.fa-beer:before{content:"\\F0FC"}.fa-h-square:before{content:"\\F0FD"}.fa-plus-square:before{content:"\\F0FE"}.fa-angle-double-left:before{content:"\\F100"}.fa-angle-double-right:before{content:"\\F101"}.fa-angle-double-up:before{content:"\\F102"}.fa-angle-double-down:before{content:"\\F103"}.fa-angle-left:before{content:"\\F104"}.fa-angle-right:before{content:"\\F105"}.fa-angle-up:before{content:"\\F106"}.fa-angle-down:before{content:"\\F107"}.fa-desktop:before{content:"\\F108"}.fa-laptop:before{content:"\\F109"}.fa-tablet:before{content:"\\F10A"}.fa-mobile-phone:before,.fa-mobile:before{content:"\\F10B"}.fa-circle-o:before{content:"\\F10C"}.fa-quote-left:before{content:"\\F10D"}.fa-quote-right:before{content:"\\F10E"}.fa-spinner:before{content:"\\F110"}.fa-circle:before{content:"\\F111"}.fa-mail-reply:before,.fa-reply:before{content:"\\F112"}.fa-github-alt:before{content:"\\F113"}.fa-folder-o:before{content:"\\F114"}.fa-folder-open-o:before{content:"\\F115"}.fa-smile-o:before{content:"\\F118"}.fa-frown-o:before{content:"\\F119"}.fa-meh-o:before{content:"\\F11A"}.fa-gamepad:before{content:"\\F11B"}.fa-keyboard-o:before{content:"\\F11C"}.fa-flag-o:before{content:"\\F11D"}.fa-flag-checkered:before{content:"\\F11E"}.fa-terminal:before{content:"\\F120"}.fa-code:before{content:"\\F121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\\F122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\\F123"}.fa-location-arrow:before{content:"\\F124"}.fa-crop:before{content:"\\F125"}.fa-code-fork:before{content:"\\F126"}.fa-chain-broken:before,.fa-unlink:before{content:"\\F127"}.fa-question:before{content:"\\F128"}.fa-info:before{content:"\\F129"}.fa-exclamation:before{content:"\\F12A"}.fa-superscript:before{content:"\\F12B"}.fa-subscript:before{content:"\\F12C"}.fa-eraser:before{content:"\\F12D"}.fa-puzzle-piece:before{content:"\\F12E"}.fa-microphone:before{content:"\\F130"}.fa-microphone-slash:before{content:"\\F131"}.fa-shield:before{content:"\\F132"}.fa-calendar-o:before{content:"\\F133"}.fa-fire-extinguisher:before{content:"\\F134"}.fa-rocket:before{content:"\\F135"}.fa-maxcdn:before{content:"\\F136"}.fa-chevron-circle-left:before{content:"\\F137"}.fa-chevron-circle-right:before{content:"\\F138"}.fa-chevron-circle-up:before{content:"\\F139"}.fa-chevron-circle-down:before{content:"\\F13A"}.fa-html5:before{content:"\\F13B"}.fa-css3:before{content:"\\F13C"}.fa-anchor:before{content:"\\F13D"}.fa-unlock-alt:before{content:"\\F13E"}.fa-bullseye:before{content:"\\F140"}.fa-ellipsis-h:before{content:"\\F141"}.fa-ellipsis-v:before{content:"\\F142"}.fa-rss-square:before{content:"\\F143"}.fa-play-circle:before{content:"\\F144"}.fa-ticket:before{content:"\\F145"}.fa-minus-square:before{content:"\\F146"}.fa-minus-square-o:before{content:"\\F147"}.fa-level-up:before{content:"\\F148"}.fa-level-down:before{content:"\\F149"}.fa-check-square:before{content:"\\F14A"}.fa-pencil-square:before{content:"\\F14B"}.fa-external-link-square:before{content:"\\F14C"}.fa-share-square:before{content:"\\F14D"}.fa-compass:before{content:"\\F14E"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\\F150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\\F151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\\F152"}.fa-eur:before,.fa-euro:before{content:"\\F153"}.fa-gbp:before{content:"\\F154"}.fa-dollar:before,.fa-usd:before{content:"\\F155"}.fa-inr:before,.fa-rupee:before{content:"\\F156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\\F157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\\F158"}.fa-krw:before,.fa-won:before{content:"\\F159"}.fa-bitcoin:before,.fa-btc:before{content:"\\F15A"}.fa-file:before{content:"\\F15B"}.fa-file-text:before{content:"\\F15C"}.fa-sort-alpha-asc:before{content:"\\F15D"}.fa-sort-alpha-desc:before{content:"\\F15E"}.fa-sort-amount-asc:before{content:"\\F160"}.fa-sort-amount-desc:before{content:"\\F161"}.fa-sort-numeric-asc:before{content:"\\F162"}.fa-sort-numeric-desc:before{content:"\\F163"}.fa-thumbs-up:before{content:"\\F164"}.fa-thumbs-down:before{content:"\\F165"}.fa-youtube-square:before{content:"\\F166"}.fa-youtube:before{content:"\\F167"}.fa-xing:before{content:"\\F168"}.fa-xing-square:before{content:"\\F169"}.fa-youtube-play:before{content:"\\F16A"}.fa-dropbox:before{content:"\\F16B"}.fa-stack-overflow:before{content:"\\F16C"}.fa-instagram:before{content:"\\F16D"}.fa-flickr:before{content:"\\F16E"}.fa-adn:before{content:"\\F170"}.fa-bitbucket:before{content:"\\F171"}.fa-bitbucket-square:before{content:"\\F172"}.fa-tumblr:before{content:"\\F173"}.fa-tumblr-square:before{content:"\\F174"}.fa-long-arrow-down:before{content:"\\F175"}.fa-long-arrow-up:before{content:"\\F176"}.fa-long-arrow-left:before{content:"\\F177"}.fa-long-arrow-right:before{content:"\\F178"}.fa-apple:before{content:"\\F179"}.fa-windows:before{content:"\\F17A"}.fa-android:before{content:"\\F17B"}.fa-linux:before{content:"\\F17C"}.fa-dribbble:before{content:"\\F17D"}.fa-skype:before{content:"\\F17E"}.fa-foursquare:before{content:"\\F180"}.fa-trello:before{content:"\\F181"}.fa-female:before{content:"\\F182"}.fa-male:before{content:"\\F183"}.fa-gittip:before,.fa-gratipay:before{content:"\\F184"}.fa-sun-o:before{content:"\\F185"}.fa-moon-o:before{content:"\\F186"}.fa-archive:before{content:"\\F187"}.fa-bug:before{content:"\\F188"}.fa-vk:before{content:"\\F189"}.fa-weibo:before{content:"\\F18A"}.fa-renren:before{content:"\\F18B"}.fa-pagelines:before{content:"\\F18C"}.fa-stack-exchange:before{content:"\\F18D"}.fa-arrow-circle-o-right:before{content:"\\F18E"}.fa-arrow-circle-o-left:before{content:"\\F190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\\F191"}.fa-dot-circle-o:before{content:"\\F192"}.fa-wheelchair:before{content:"\\F193"}.fa-vimeo-square:before{content:"\\F194"}.fa-try:before,.fa-turkish-lira:before{content:"\\F195"}.fa-plus-square-o:before{content:"\\F196"}.fa-space-shuttle:before{content:"\\F197"}.fa-slack:before{content:"\\F198"}.fa-envelope-square:before{content:"\\F199"}.fa-wordpress:before{content:"\\F19A"}.fa-openid:before{content:"\\F19B"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\\F19C"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\\F19D"}.fa-yahoo:before{content:"\\F19E"}.fa-google:before{content:"\\F1A0"}.fa-reddit:before{content:"\\F1A1"}.fa-reddit-square:before{content:"\\F1A2"}.fa-stumbleupon-circle:before{content:"\\F1A3"}.fa-stumbleupon:before{content:"\\F1A4"}.fa-delicious:before{content:"\\F1A5"}.fa-digg:before{content:"\\F1A6"}.fa-pied-piper-pp:before{content:"\\F1A7"}.fa-pied-piper-alt:before{content:"\\F1A8"}.fa-drupal:before{content:"\\F1A9"}.fa-joomla:before{content:"\\F1AA"}.fa-language:before{content:"\\F1AB"}.fa-fax:before{content:"\\F1AC"}.fa-building:before{content:"\\F1AD"}.fa-child:before{content:"\\F1AE"}.fa-paw:before{content:"\\F1B0"}.fa-spoon:before{content:"\\F1B1"}.fa-cube:before{content:"\\F1B2"}.fa-cubes:before{content:"\\F1B3"}.fa-behance:before{content:"\\F1B4"}.fa-behance-square:before{content:"\\F1B5"}.fa-steam:before{content:"\\F1B6"}.fa-steam-square:before{content:"\\F1B7"}.fa-recycle:before{content:"\\F1B8"}.fa-automobile:before,.fa-car:before{content:"\\F1B9"}.fa-cab:before,.fa-taxi:before{content:"\\F1BA"}.fa-tree:before{content:"\\F1BB"}.fa-spotify:before{content:"\\F1BC"}.fa-deviantart:before{content:"\\F1BD"}.fa-soundcloud:before{content:"\\F1BE"}.fa-database:before{content:"\\F1C0"}.fa-file-pdf-o:before{content:"\\F1C1"}.fa-file-word-o:before{content:"\\F1C2"}.fa-file-excel-o:before{content:"\\F1C3"}.fa-file-powerpoint-o:before{content:"\\F1C4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\\F1C5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\\F1C6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\\F1C7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\\F1C8"}.fa-file-code-o:before{content:"\\F1C9"}.fa-vine:before{content:"\\F1CA"}.fa-codepen:before{content:"\\F1CB"}.fa-jsfiddle:before{content:"\\F1CC"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\\F1CD"}.fa-circle-o-notch:before{content:"\\F1CE"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\\F1D0"}.fa-empire:before,.fa-ge:before{content:"\\F1D1"}.fa-git-square:before{content:"\\F1D2"}.fa-git:before{content:"\\F1D3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\\F1D4"}.fa-tencent-weibo:before{content:"\\F1D5"}.fa-qq:before{content:"\\F1D6"}.fa-wechat:before,.fa-weixin:before{content:"\\F1D7"}.fa-paper-plane:before,.fa-send:before{content:"\\F1D8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\\F1D9"}.fa-history:before{content:"\\F1DA"}.fa-circle-thin:before{content:"\\F1DB"}.fa-header:before{content:"\\F1DC"}.fa-paragraph:before{content:"\\F1DD"}.fa-sliders:before{content:"\\F1DE"}.fa-share-alt:before{content:"\\F1E0"}.fa-share-alt-square:before{content:"\\F1E1"}.fa-bomb:before{content:"\\F1E2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\\F1E3"}.fa-tty:before{content:"\\F1E4"}.fa-binoculars:before{content:"\\F1E5"}.fa-plug:before{content:"\\F1E6"}.fa-slideshare:before{content:"\\F1E7"}.fa-twitch:before{content:"\\F1E8"}.fa-yelp:before{content:"\\F1E9"}.fa-newspaper-o:before{content:"\\F1EA"}.fa-wifi:before{content:"\\F1EB"}.fa-calculator:before{content:"\\F1EC"}.fa-paypal:before{content:"\\F1ED"}.fa-google-wallet:before{content:"\\F1EE"}.fa-cc-visa:before{content:"\\F1F0"}.fa-cc-mastercard:before{content:"\\F1F1"}.fa-cc-discover:before{content:"\\F1F2"}.fa-cc-amex:before{content:"\\F1F3"}.fa-cc-paypal:before{content:"\\F1F4"}.fa-cc-stripe:before{content:"\\F1F5"}.fa-bell-slash:before{content:"\\F1F6"}.fa-bell-slash-o:before{content:"\\F1F7"}.fa-trash:before{content:"\\F1F8"}.fa-copyright:before{content:"\\F1F9"}.fa-at:before{content:"\\F1FA"}.fa-eyedropper:before{content:"\\F1FB"}.fa-paint-brush:before{content:"\\F1FC"}.fa-birthday-cake:before{content:"\\F1FD"}.fa-area-chart:before{content:"\\F1FE"}.fa-pie-chart:before{content:"\\F200"}.fa-line-chart:before{content:"\\F201"}.fa-lastfm:before{content:"\\F202"}.fa-lastfm-square:before{content:"\\F203"}.fa-toggle-off:before{content:"\\F204"}.fa-toggle-on:before{content:"\\F205"}.fa-bicycle:before{content:"\\F206"}.fa-bus:before{content:"\\F207"}.fa-ioxhost:before{content:"\\F208"}.fa-angellist:before{content:"\\F209"}.fa-cc:before{content:"\\F20A"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\\F20B"}.fa-meanpath:before{content:"\\F20C"}.fa-buysellads:before{content:"\\F20D"}.fa-connectdevelop:before{content:"\\F20E"}.fa-dashcube:before{content:"\\F210"}.fa-forumbee:before{content:"\\F211"}.fa-leanpub:before{content:"\\F212"}.fa-sellsy:before{content:"\\F213"}.fa-shirtsinbulk:before{content:"\\F214"}.fa-simplybuilt:before{content:"\\F215"}.fa-skyatlas:before{content:"\\F216"}.fa-cart-plus:before{content:"\\F217"}.fa-cart-arrow-down:before{content:"\\F218"}.fa-diamond:before{content:"\\F219"}.fa-ship:before{content:"\\F21A"}.fa-user-secret:before{content:"\\F21B"}.fa-motorcycle:before{content:"\\F21C"}.fa-street-view:before{content:"\\F21D"}.fa-heartbeat:before{content:"\\F21E"}.fa-venus:before{content:"\\F221"}.fa-mars:before{content:"\\F222"}.fa-mercury:before{content:"\\F223"}.fa-intersex:before,.fa-transgender:before{content:"\\F224"}.fa-transgender-alt:before{content:"\\F225"}.fa-venus-double:before{content:"\\F226"}.fa-mars-double:before{content:"\\F227"}.fa-venus-mars:before{content:"\\F228"}.fa-mars-stroke:before{content:"\\F229"}.fa-mars-stroke-v:before{content:"\\F22A"}.fa-mars-stroke-h:before{content:"\\F22B"}.fa-neuter:before{content:"\\F22C"}.fa-genderless:before{content:"\\F22D"}.fa-facebook-official:before{content:"\\F230"}.fa-pinterest-p:before{content:"\\F231"}.fa-whatsapp:before{content:"\\F232"}.fa-server:before{content:"\\F233"}.fa-user-plus:before{content:"\\F234"}.fa-user-times:before{content:"\\F235"}.fa-bed:before,.fa-hotel:before{content:"\\F236"}.fa-viacoin:before{content:"\\F237"}.fa-train:before{content:"\\F238"}.fa-subway:before{content:"\\F239"}.fa-medium:before{content:"\\F23A"}.fa-y-combinator:before,.fa-yc:before{content:"\\F23B"}.fa-optin-monster:before{content:"\\F23C"}.fa-opencart:before{content:"\\F23D"}.fa-expeditedssl:before{content:"\\F23E"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:"\\F240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\\F241"}.fa-battery-2:before,.fa-battery-half:before{content:"\\F242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\\F243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\\F244"}.fa-mouse-pointer:before{content:"\\F245"}.fa-i-cursor:before{content:"\\F246"}.fa-object-group:before{content:"\\F247"}.fa-object-ungroup:before{content:"\\F248"}.fa-sticky-note:before{content:"\\F249"}.fa-sticky-note-o:before{content:"\\F24A"}.fa-cc-jcb:before{content:"\\F24B"}.fa-cc-diners-club:before{content:"\\F24C"}.fa-clone:before{content:"\\F24D"}.fa-balance-scale:before{content:"\\F24E"}.fa-hourglass-o:before{content:"\\F250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\\F251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\\F252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\\F253"}.fa-hourglass:before{content:"\\F254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\\F255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\\F256"}.fa-hand-scissors-o:before{content:"\\F257"}.fa-hand-lizard-o:before{content:"\\F258"}.fa-hand-spock-o:before{content:"\\F259"}.fa-hand-pointer-o:before{content:"\\F25A"}.fa-hand-peace-o:before{content:"\\F25B"}.fa-trademark:before{content:"\\F25C"}.fa-registered:before{content:"\\F25D"}.fa-creative-commons:before{content:"\\F25E"}.fa-gg:before{content:"\\F260"}.fa-gg-circle:before{content:"\\F261"}.fa-tripadvisor:before{content:"\\F262"}.fa-odnoklassniki:before{content:"\\F263"}.fa-odnoklassniki-square:before{content:"\\F264"}.fa-get-pocket:before{content:"\\F265"}.fa-wikipedia-w:before{content:"\\F266"}.fa-safari:before{content:"\\F267"}.fa-chrome:before{content:"\\F268"}.fa-firefox:before{content:"\\F269"}.fa-opera:before{content:"\\F26A"}.fa-internet-explorer:before{content:"\\F26B"}.fa-television:before,.fa-tv:before{content:"\\F26C"}.fa-contao:before{content:"\\F26D"}.fa-500px:before{content:"\\F26E"}.fa-amazon:before{content:"\\F270"}.fa-calendar-plus-o:before{content:"\\F271"}.fa-calendar-minus-o:before{content:"\\F272"}.fa-calendar-times-o:before{content:"\\F273"}.fa-calendar-check-o:before{content:"\\F274"}.fa-industry:before{content:"\\F275"}.fa-map-pin:before{content:"\\F276"}.fa-map-signs:before{content:"\\F277"}.fa-map-o:before{content:"\\F278"}.fa-map:before{content:"\\F279"}.fa-commenting:before{content:"\\F27A"}.fa-commenting-o:before{content:"\\F27B"}.fa-houzz:before{content:"\\F27C"}.fa-vimeo:before{content:"\\F27D"}.fa-black-tie:before{content:"\\F27E"}.fa-fonticons:before{content:"\\F280"}.fa-reddit-alien:before{content:"\\F281"}.fa-edge:before{content:"\\F282"}.fa-credit-card-alt:before{content:"\\F283"}.fa-codiepie:before{content:"\\F284"}.fa-modx:before{content:"\\F285"}.fa-fort-awesome:before{content:"\\F286"}.fa-usb:before{content:"\\F287"}.fa-product-hunt:before{content:"\\F288"}.fa-mixcloud:before{content:"\\F289"}.fa-scribd:before{content:"\\F28A"}.fa-pause-circle:before{content:"\\F28B"}.fa-pause-circle-o:before{content:"\\F28C"}.fa-stop-circle:before{content:"\\F28D"}.fa-stop-circle-o:before{content:"\\F28E"}.fa-shopping-bag:before{content:"\\F290"}.fa-shopping-basket:before{content:"\\F291"}.fa-hashtag:before{content:"\\F292"}.fa-bluetooth:before{content:"\\F293"}.fa-bluetooth-b:before{content:"\\F294"}.fa-percent:before{content:"\\F295"}.fa-gitlab:before{content:"\\F296"}.fa-wpbeginner:before{content:"\\F297"}.fa-wpforms:before{content:"\\F298"}.fa-envira:before{content:"\\F299"}.fa-universal-access:before{content:"\\F29A"}.fa-wheelchair-alt:before{content:"\\F29B"}.fa-question-circle-o:before{content:"\\F29C"}.fa-blind:before{content:"\\F29D"}.fa-audio-description:before{content:"\\F29E"}.fa-volume-control-phone:before{content:"\\F2A0"}.fa-braille:before{content:"\\F2A1"}.fa-assistive-listening-systems:before{content:"\\F2A2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\\F2A3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\\F2A4"}.fa-glide:before{content:"\\F2A5"}.fa-glide-g:before{content:"\\F2A6"}.fa-sign-language:before,.fa-signing:before{content:"\\F2A7"}.fa-low-vision:before{content:"\\F2A8"}.fa-viadeo:before{content:"\\F2A9"}.fa-viadeo-square:before{content:"\\F2AA"}.fa-snapchat:before{content:"\\F2AB"}.fa-snapchat-ghost:before{content:"\\F2AC"}.fa-snapchat-square:before{content:"\\F2AD"}.fa-pied-piper:before{content:"\\F2AE"}.fa-first-order:before{content:"\\F2B0"}.fa-yoast:before{content:"\\F2B1"}.fa-themeisle:before{content:"\\F2B2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\\F2B3"}.fa-fa:before,.fa-font-awesome:before{content:"\\F2B4"}.fa-handshake-o:before{content:"\\F2B5"}.fa-envelope-open:before{content:"\\F2B6"}.fa-envelope-open-o:before{content:"\\F2B7"}.fa-linode:before{content:"\\F2B8"}.fa-address-book:before{content:"\\F2B9"}.fa-address-book-o:before{content:"\\F2BA"}.fa-address-card:before,.fa-vcard:before{content:"\\F2BB"}.fa-address-card-o:before,.fa-vcard-o:before{content:"\\F2BC"}.fa-user-circle:before{content:"\\F2BD"}.fa-user-circle-o:before{content:"\\F2BE"}.fa-user-o:before{content:"\\F2C0"}.fa-id-badge:before{content:"\\F2C1"}.fa-drivers-license:before,.fa-id-card:before{content:"\\F2C2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\\F2C3"}.fa-quora:before{content:"\\F2C4"}.fa-free-code-camp:before{content:"\\F2C5"}.fa-telegram:before{content:"\\F2C6"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:"\\F2C7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\\F2C8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\\F2C9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\\F2CA"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\\F2CB"}.fa-shower:before{content:"\\F2CC"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:"\\F2CD"}.fa-podcast:before{content:"\\F2CE"}.fa-window-maximize:before{content:"\\F2D0"}.fa-window-minimize:before{content:"\\F2D1"}.fa-window-restore:before{content:"\\F2D2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\\F2D3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\\F2D4"}.fa-bandcamp:before{content:"\\F2D5"}.fa-grav:before{content:"\\F2D6"}.fa-etsy:before{content:"\\F2D7"}.fa-imdb:before{content:"\\F2D8"}.fa-ravelry:before{content:"\\F2D9"}.fa-eercast:before{content:"\\F2DA"}.fa-microchip:before{content:"\\F2DB"}.fa-snowflake-o:before{content:"\\F2DC"}.fa-superpowers:before{content:"\\F2DD"}.fa-wpexplorer:before{content:"\\F2DE"}.fa-meetup:before{content:"\\F2E0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}',""]); -},function(A,M,t){M=A.exports=t(138)(),M.push([A.id,'*,:after,:before{box-sizing:border-box}body{font-family:Lato,sans-serif;font-size:15px;line-height:1.42857143;color:#8e8e8e;background-color:#edecec}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#46a5e0}a,a:focus,a:hover{text-decoration:none}a:focus,a:hover{color:#1f7fba}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#edecec;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,.08)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#8e8e8e;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#333;background-color:rgba(0,0,0,.05)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#333;text-decoration:none;outline:0;background-color:rgba(0,0,0,.075)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#e4e4e4}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:13px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu>li>a{text-align:right}.navbar-right .dropdown-menu-left{left:0;right:auto}}.modal,.modal-open{overflow:hidden}.modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid transparent;border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:rgba(0,0,0,.1)}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:30px 35px 0;border-bottom:1px solid transparent}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:transparent}.modal-body{position:relative;padding:30px 35px}.modal-footer{padding:30px 35px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:400px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Lato,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:13px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:active,:focus{outline:0}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{min-height:100%}a{-webkit-transition:color;transition:color;-webkit-transition-duration:.3s;transition-duration:.3s}button{border:0}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.text-center{text-align:center!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.modal-footer:after,.modal-header:after,.row:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.p-relative{position:relative}.m-0{margin:0!important}.m-t-0{margin-top:0!important}.m-b-0{margin-bottom:0!important}.m-l-0{margin-left:0!important}.m-r-0{margin-right:0!important}.m-5{margin:5px!important}.m-t-5{margin-top:5px!important}.m-b-5{margin-bottom:5px!important}.m-l-5{margin-left:5px!important}.m-r-5{margin-right:5px!important}.m-10{margin:10px!important}.m-t-10{margin-top:10px!important}.m-b-10{margin-bottom:10px!important}.m-l-10{margin-left:10px!important}.m-r-10{margin-right:10px!important}.m-15{margin:15px!important}.m-t-15{margin-top:15px!important}.m-b-15{margin-bottom:15px!important}.m-l-15{margin-left:15px!important}.m-r-15{margin-right:15px!important}.m-20{margin:20px!important}.m-t-20{margin-top:20px!important}.m-b-20{margin-bottom:20px!important}.m-l-20{margin-left:20px!important}.m-r-20{margin-right:20px!important}.m-25{margin:25px!important}.m-t-25{margin-top:25px!important}.m-b-25{margin-bottom:25px!important}.m-l-25{margin-left:25px!important}.m-r-25{margin-right:25px!important}.m-30{margin:30px!important}.m-t-30{margin-top:30px!important}.m-b-30{margin-bottom:30px!important}.m-l-30{margin-left:30px!important}.m-r-30{margin-right:30px!important}.p-0{padding:0!important}.p-t-0{padding-top:0!important}.p-b-0{padding-bottom:0!important}.p-l-0{padding-left:0!important}.p-r-0{padding-right:0!important}.p-5{padding:5px!important}.p-t-5{padding-top:5px!important}.p-b-5{padding-bottom:5px!important}.p-l-5{padding-left:5px!important}.p-r-5{padding-right:5px!important}.p-10{padding:10px!important}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.p-l-10{padding-left:10px!important}.p-r-10{padding-right:10px!important}.p-15{padding:15px!important}.p-t-15{padding-top:15px!important}.p-b-15{padding-bottom:15px!important}.p-l-15{padding-left:15px!important}.p-r-15{padding-right:15px!important}.p-20{padding:20px!important}.p-t-20{padding-top:20px!important}.p-b-20{padding-bottom:20px!important}.p-l-20{padding-left:20px!important}.p-r-20{padding-right:20px!important}.p-25{padding:25px!important}.p-t-25{padding-top:25px!important}.p-b-25{padding-bottom:25px!important}.p-l-25{padding-left:25px!important}.p-r-25{padding-right:25px!important}.p-30{padding:30px!important}.p-t-30{padding-top:30px!important}.p-b-30{padding-bottom:30px!important}.p-l-30{padding-left:30px!important}.p-r-30{padding-right:30px!important}@font-face{font-family:Lato;src:url('+t(515)+') format("woff2"),url('+t(514)+') format("woff");font-weight:400;font-style:normal}.form-control{border:0;border-bottom:1px solid #eee;color:#32393f;padding:5px;width:100%;font-size:13px;background-color:transparent}select.form-control{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background:url('+t(518)+') no-repeat bottom 7px right}.input-group{position:relative}.input-group:not(:last-child){margin-bottom:25px}.input-group label:not(.ig-label){font-size:13px;display:block;margin-bottom:10px}.ig-label{position:absolute;text-align:center;bottom:7px;left:0;width:100%;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;padding:2px 0 3px;border-radius:2px;font-weight:400}.ig-helpers{z-index:1;width:100%;left:0}.ig-helpers,.ig-helpers:after,.ig-helpers:before{position:absolute;height:2px;bottom:0}.ig-helpers:after,.ig-helpers:before{content:"";width:0;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;background-color:#03a9f4}.ig-helpers:before{left:50%}.ig-helpers:after{right:50%}.ig-text{width:100%;height:40px;border:0;background:transparent;text-align:center;position:relative;z-index:1;border-bottom:1px solid #eee;color:#32393f;font-size:13px}.ig-text:focus+.ig-helpers:after,.ig-text:focus+.ig-helpers:before{width:50%}.ig-text:disabled~.ig-label,.ig-text:focus~.ig-label,.ig-text:valid~.ig-label{bottom:35px;font-size:13px;z-index:1}.ig-text:disabled{opacity:.5;filter:alpha(opacity=50)}.ig-dark .ig-text{color:#fff;border-color:hsla(0,0%,100%,.1)}.ig-dark .ig-helpers:after,.ig-dark .ig-helpers:before{background-color:#dfdfdf;height:1px}.ig-left .ig-label,.ig-left .ig-text{text-align:left}.ig-error .ig-label{color:#e23f3f}.ig-error .ig-helpers i:first-child,.ig-error .ig-helpers i:first-child:after,.ig-error .ig-helpers i:first-child:before{background:rgba(226,63,63,.43)}.ig-error .ig-helpers i:last-child,.ig-error .ig-helpers i:last-child:after,.ig-error .ig-helpers i:last-child:before{background:#e23f3f!important}.ig-error:after{content:"\\F05A";font-family:FontAwesome;position:absolute;top:17px;right:9px;font-size:20px;color:#d33d3e}.ig-search:before{font-family:fontAwesome;content:"\\F002";font-size:15px;position:absolute;left:2px;top:8px}.ig-search .ig-text{padding-left:25px}.set-expire{border:1px solid #eee;margin:35px 0 30px}.set-expire-item{padding:9px 5px 3px;position:relative;display:table-cell;width:1%;text-align:center}.set-expire-item:not(:last-child){border-right:1px solid #eee}.set-expire-title{font-size:10px;text-transform:uppercase}.set-expire-value{display:inline-block;overflow:hidden;position:relative;left:-8px}.set-expire-value input{font-size:20px;text-align:center;position:relative;right:-15px;border:0;color:#333;padding:0;height:25px;width:100%;font-weight:400}.set-expire-decrease,.set-expire-increase{position:absolute;width:20px;height:20px;background:url('+t(516)+') no-repeat 50%;background-size:85%;left:50%;margin-left:-10px;opacity:.2;filter:alpha(opacity=20);cursor:pointer}.set-expire-decrease:hover,.set-expire-increase:hover{opacity:.5;filter:alpha(opacity=50)}.set-expire-increase{top:-25px}.set-expire-decrease{bottom:-27px;-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.btn{border:0;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:2px;text-align:center;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.btn:focus,.btn:hover{opacity:.9;filter:alpha(opacity=90)}.btn-block{display:block;width:100%}.btn-white{color:#5b5b5b;background-color:#fff}.btn-white:focus,.btn-white:hover{color:#5b5b5b;background-color:#f0f0f0}.btn-link{color:#545454;background-color:#eee}.btn-link:focus,.btn-link:hover{color:#545454;background-color:#dfdfdf}.btn-danger{color:#fff;background-color:#ff726f}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff5450}.btn-primary{color:#fff;background-color:#50b2ff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#31a5ff}.btn-success{color:#fff;background-color:#33d46f}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#28c061}.close{right:15px;font-weight:400;opacity:1;font-size:18px;position:absolute;text-align:center;top:16px;z-index:1;padding:0;border:0;background-color:transparent}.close span{width:25px;height:25px;display:block;border-radius:50%;line-height:24px;text-shadow:none}.close:not(.close-alt) span{background-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.close:not(.close-alt):focus span,.close:not(.close-alt):hover span{background-color:hsla(0,0%,100%,.2);color:#fff}.close-alt span{background-color:#efefef;color:#989898}.close-alt:focus span,.close-alt:hover span{background-color:#e8e8e8;color:#7b7b7b}.hidden{display:none!important}.copy-text input{width:100%;border-radius:1px;border:1px solid #eee;padding:7px 12px;font-size:13px;line-height:100%;cursor:text;-webkit-transition:border-color;transition:border-color;-webkit-transition-duration:.3s;transition-duration:.3s}.copy-text input:hover{border-color:#e1e1e1}.share-availability{margin-bottom:40px}.share-availability:after,.share-availability:before{position:absolute;bottom:-30px;font-size:10px}.share-availability:before{content:"01 Sec";left:0}.share-availability:after{content:"7 days";right:0}.modal-aheader{height:100px}.modal-aheader:before{height:0!important}.modal-aheader .modal-dialog{margin:0;vertical-align:top}.login{height:100vh;min-height:500px;background:#32393f;text-align:center}.login:before{height:calc(100% - 110px);width:1px;content:""}.l-wrap,.login:before{display:inline-block;vertical-align:middle}.l-wrap{width:80%;max-width:500px;margin-top:-50px}.l-wrap.toggled{display:inline-block}.l-wrap .input-group:not(:last-child){margin-bottom:40px}.l-footer{height:110px;padding:0 50px}.lf-logo{float:right}.lf-logo img{width:40px}.lf-server{float:left;color:hsla(0,0%,100%,.4);font-size:20px;font-weight:400;padding-top:40px}@media (max-width:768px){.lf-logo,.lf-server{float:none;display:block;text-align:center;width:100%}.lf-logo{margin-bottom:5px}.lf-server{font-size:15px}}.lw-btn{width:50px;height:50px;border:1px solid #fff;display:inline-block;border-radius:50%;font-size:22px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;opacity:.3;background-color:transparent;line-height:45px;padding:0}.lw-btn:hover{color:#fff;opacity:.8;border-color:#fff}.lw-btn i{display:block;width:100%;padding-left:3px}input:-webkit-autofill{-webkit-box-shadow:0 0 0 50px #32393f inset!important;-webkit-text-fill-color:#fff!important}@media (min-width:668px){.fe-header{position:relative;padding:40px 40px 20px 45px}}@media (max-width:667px){.fe-header{padding:20px}}.fe-header h2{font-size:16px;font-weight:400;margin:0}.fe-header h2>span{margin-bottom:7px;display:inline-block}.fe-header h2>span:not(:first-child):before{content:"/";margin:0 4px;color:#8e8e8e}.fe-header p{margin-top:7px}.feh-usage{margin-top:12px;max-width:285px}@media (max-width:667px){.feh-usage{max-width:100%;font-size:12px}}.feh-usage>ul{margin-top:7px;list-style:none;padding:0}.feh-usage>ul>li{padding-right:0;display:inline-block}.fehu-chart{height:5px;background:#eee;position:relative;border-radius:2px;overflow:hidden}.fehu-chart>div{position:absolute;left:0;height:100%;background:#46a5e0}.feh-actions{list-style:none;padding:0;margin:0;position:absolute;right:35px;top:30px;z-index:11}@media (max-width:991px){.feh-actions{top:7px;right:10px;position:fixed}}.feh-actions>li{display:inline-block;text-align:right;vertical-align:top;line-height:100%}.feh-actions>li>.btn-group>button,.feh-actions>li>a{display:block;height:45px;min-width:45px;text-align:center;border-radius:50%;padding:0;border:0;background:none}@media (min-width:992px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{color:#7b7b7b;font-size:21px;line-height:45px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feh-actions>li>.btn-group>button:hover,.feh-actions>li>a:hover{background:rgba(0,0,0,.09)}}@media (max-width:991px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{background:url('+t(237)+') no-repeat 50%}.feh-actions>li>.btn-group>button .fa-reorder,.feh-actions>li>a .fa-reorder{display:none}}@media (max-width:991px){.fe-header-mobile{background-color:#32393f;padding:10px 50px 9px 12px;text-align:center;position:fixed;z-index:10;box-shadow:0 0 10px rgba(0,0,0,.3);left:0;top:0;width:100%}.fe-header-mobile .mh-logo{height:35px;position:relative;top:4px}.feh-trigger{width:41px;height:41px;cursor:pointer;float:left;position:relative;text-align:center}.feh-trigger:after,.feh-trigger:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.feh-trigger:after{z-index:1}.feh-trigger:before{background:hsla(0,0%,100%,.1);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:scale(0);transform:scale(0)}.feht-toggled:before{-webkit-transform:scale(1);transform:scale(1)}.feht-toggled .feht-lines{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.feht-toggled .feht-lines>div.top{width:12px;transform:translateX(8px) translateY(1px) rotate(45deg);-webkit-transform:translateX(8px) translateY(1px) rotate(45deg)}.feht-toggled .feht-lines>div.bottom{width:12px;transform:translateX(8px) translateY(-1px) rotate(-45deg);-webkit-transform:translateX(8px) translateY(-1px) rotate(-45deg)}.feht-lines,.feht-lines>div{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feht-lines{width:18px;height:12px;display:inline-block;margin-top:14px}.feht-lines>div{background-color:#eaeaea;width:18px;height:2px}.feht-lines>div.center{margin:3px 0}}.fe-sidebar{width:300px;background-color:#32393f;position:fixed;height:100%;overflow:hidden;padding:35px}@media (min-width:992px){.fe-sidebar{-webkit-transform:translateZ(0);transform:translateZ(0)}}@media (max-width:991px){.fe-sidebar{padding-top:85px;z-index:9;box-shadow:0 0 10px rgba(0,0,0,.65);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:translate3d(-315px,0,0);transform:translate3d(-315px,0,0)}.fe-sidebar.toggled{-webkit-transform:translateZ(0);transform:translateZ(0)}}.fe-sidebar a{color:hsla(0,0%,100%,.58)}.fe-sidebar a:hover{color:#fff}.fes-header{margin-bottom:40px}.fes-header h2,.fes-header img{float:left}.fes-header h2{margin:13px 0 0 10px;font-weight:400}.fes-header img{width:32px}.fesl-inner{height:calc(100vh - 260px);overflow:auto;padding:0;margin:0 -35px}.fesl-inner li{position:relative}.fesl-inner li>a{display:block;padding:10px 40px 12px 65px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fesl-inner li>a:before{font-family:FontAwesome;content:"\\F0A0";font-size:17px;position:absolute;top:10px;left:35px;opacity:.8;filter:alpha(opacity=80)}.fesl-inner li>a.fesli-loading:before{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.1);border-bottom-color:hsla(0,0%,100%,.5);position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:32px;top:0;bottom:0;margin:auto}.fesl-inner li.active{background-color:rgba(0,0,0,.2)}.fesl-inner li.active>a{color:#fff}.fesl-inner li:not(.active):hover{background-color:rgba(0,0,0,.1)}.fesl-inner li:not(.active):hover>a{color:#fff}.fesl-inner li:hover .fesli-trigger{opacity:.6;filter:alpha(opacity=60)}.fesl-inner li:hover .fesli-trigger:hover{opacity:1;filter:alpha(opacity=100)}.fesl-inner ul{list-style:none;padding:0;margin:0}.fesl-inner:hover .scrollbar-vertical{opacity:1}.fesli-trigger{filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;top:0;right:0;width:40px;cursor:pointer;background:url('+t(237)+') no-repeat 0}.fesli-trigger,.scrollbar-vertical{opacity:0;position:absolute;height:100%}.scrollbar-vertical{right:5px;width:4px;-webkit-transition:opacity;transition:opacity;-webkit-transition-duration:.3s;transition-duration:.3s}.scrollbar-vertical div{border-radius:1px!important;background-color:#6a6a6a!important}.fes-host{position:fixed;left:0;bottom:0;z-index:1;background:#32393f;color:hsla(0,0%,100%,.4);font-size:15px;font-weight:400;width:300px;padding:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fes-host>i{margin-right:10px}.fesl-row{position:relative}@media (min-width:668px){.fesl-row{padding:5px 20px 5px 40px;display:flex;flex-flow:row nowrap;justify-content:space-between}}@media (max-width:667px){.fesl-row{padding:5px 20px}}.fesl-row:after,.fesl-row:before{content:" ";display:table}.fesl-row:after{clear:both}@media (min-width:668px){header.fesl-row{margin-bottom:20px;border-bottom:1px solid #f0f0f0;padding-left:30px}header.fesl-row .fesl-item,header.fesl-row .fesli-sort{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}header.fesl-row .fesl-item{cursor:pointer;color:#8e8e8e;font-weight:500;margin-bottom:-5px}header.fesl-row .fesl-item>.fesli-sort{float:right;margin:4px 0 0;opacity:0;filter:alpha(opacity=0);color:#32393f;font-size:14px}header.fesl-row .fesl-item:hover:not(.fesl-item-actions){background:#f5f5f5;color:#32393f}header.fesl-row .fesl-item:hover:not(.fesl-item-actions)>.fesli-sort{opacity:.5;filter:alpha(opacity=50)}}@media (max-width:667px){header.fesl-row{display:none}}div.fesl-row{border-bottom:1px solid transparent;cursor:default;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.5s;transition-duration:.5s}@media (max-width:667px){div.fesl-row{padding:5px 20px}}div.fesl-row:not(.fesl-row-selected):nth-child(2n){background-color:#fafafa}div.fesl-row:hover .fis-icon:before{opacity:0;filter:alpha(opacity=0)}div.fesl-row:hover .fis-helper:before{opacity:1;filter:alpha(opacity=100)}div.fesl-row[data-type=folder] .fis-icon{background-color:#a1d6dd}div.fesl-row[data-type=folder] .fis-icon:before{content:"\\F114"}div.fesl-row[data-type=pdf] .fis-icon{background-color:#fa7775}div.fesl-row[data-type=pdf] .fis-icon:before{content:"\\F1C1"}div.fesl-row[data-type=zip] .fis-icon{background-color:#427089}div.fesl-row[data-type=zip] .fis-icon:before{content:"\\F1C6"}div.fesl-row[data-type=audio] .fis-icon{background-color:#009688}div.fesl-row[data-type=audio] .fis-icon:before{content:"\\F1C7"}div.fesl-row[data-type=code] .fis-icon{background-color:#997867}div.fesl-row[data-type=code] .fis-icon:before{content:"\\F1C9"}div.fesl-row[data-type=excel] .fis-icon{background-color:#f1c3 3}div.fesl-row[data-type=excel] .fis-icon:before{content:"\\F1C3"}div.fesl-row[data-type=image] .fis-icon{background-color:#f06292}div.fesl-row[data-type=image] .fis-icon:before{content:"\\F1C5"}div.fesl-row[data-type=video] .fis-icon{background-color:#f8c363}div.fesl-row[data-type=video] .fis-icon:before{content:"\\F1C8"}div.fesl-row[data-type=other] .fis-icon{background-color:#afafaf}div.fesl-row[data-type=other] .fis-icon:before{content:"\\F016"}div.fesl-row[data-type=text] .fis-icon{background-color:#8a8a8a}div.fesl-row[data-type=text] .fis-icon:before{content:"\\F0F6"}div.fesl-row[data-type=doc] .fis-icon{background-color:#2196f5}div.fesl-row[data-type=doc] .fis-icon:before{content:"\\F1C2"}div.fesl-row[data-type=presentation] .fis-icon{background-color:#896ea6}div.fesl-row[data-type=presentation] .fis-icon:before{content:"\\F1C4"}div.fesl-row.fesl-loading:before{content:""}div.fesl-row.fesl-loading:after{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.5);border-bottom-color:#fff;position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:57px;top:17px}@media (max-width:667px){div.fesl-row.fesl-loading:after{left:27px}}.fesl-row-selected{background-color:#fbf2bf}.fesl-row-selected,.fesl-row-selected .fesl-item a{color:#757575}.fi-select{float:left;position:relative;width:35px;height:35px;margin:3px 0}@media (max-width:667px){.fi-select{margin-right:15px}}.fi-select input{position:absolute;left:0;top:0;width:35px;height:35px;z-index:20;opacity:0;cursor:pointer}.fi-select input:checked~.fis-icon{background-color:#32393f}.fi-select input:checked~.fis-icon:before{opacity:0}.fi-select input:checked~.fis-helper:before{-webkit-transform:scale(0);transform:scale(0)}.fi-select input:checked~.fis-helper:after{-webkit-transform:scale(1);transform:scale(1)}.fis-icon{display:inline-block;vertical-align:top;border-radius:50%;width:35px;height:35px;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-icon:before{width:100%;height:100%;text-align:center;position:absolute;border-radius:50%;font-family:fontAwesome;line-height:35px;font-size:16px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;font-style:normal}.fis-helper:after,.fis-helper:before{position:absolute;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-helper:before{content:"";width:15px;height:15px;border:2px solid #fff;z-index:10;border-radius:2px;top:10px;left:10px;opacity:0}.fis-helper:after{font-family:fontAwesome;content:"\\F00C";top:8px;left:9px;color:#fff;font-size:14px;-webkit-transform:scale(0);transform:scale(0)}.fesl-item{display:block}.fesl-item a{color:#818181}@media (min-width:668px){.fesl-item:not(.fesl-item-actions):not(.fesl-item-icon){text-overflow:ellipsis;padding:10px 15px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-name{flex:3}.fesl-item.fesl-item-size{width:140px}.fesl-item.fesl-item-modified{width:190px}.fesl-item.fesl-item-actions{width:40px}}@media (max-width:667px){.fesl-item{padding:0}.fesl-item.fesl-item-name{width:100%;margin-bottom:3px}.fesl-item.fesl-item-modified,.fesl-item.fesl-item-size{font-size:12px;color:#b5b5b5;float:left}.fesl-item.fesl-item-modified{max-width:72px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-size{margin-right:10px}.fesl-item.fesl-item-actions{position:absolute;top:5px;right:10px}}.fia-toggle{height:36px;width:36px;background:transparent url('+t(517)+') no-repeat 50%;position:relative;top:3px;opacity:.4;filter:alpha(opacity=40)}.fia-toggle:hover{opacity:.7;filter:alpha(opacity=70)}.fesl-item-actions .dropdown-menu{background-color:transparent;box-shadow:none;padding:0;right:38px;left:auto;margin:0;height:100%;text-align:right}.fesl-item-actions .dropdown.open .dropdown-menu .fiad-action{right:0}.fiad-action{height:35px;width:35px;background:#ffc107;display:inline-block;border-radius:50%;text-align:center;line-height:35px;font-weight:400;position:relative;top:4px;margin-left:5px;-webkit-animation-name:fiad-action-anim;animation-name:fiad-action-anim;-webkit-transform-origin:center center;transform-origin:center center;-webkit-backface-visibility:none;backface-visibility:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.fiad-action:nth-child(2){-webkit-animation-duration:.1s;animation-duration:.1s}.fiad-action:first-child{-webkit-animation-duration:.25s;animation-duration:.25s}.fiad-action>i{font-size:14px;color:#fff}.fiad-action:hover{background-color:#f7b900}.list-actions{position:fixed;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);opacity:0;filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;padding:20px 25px;top:0;left:0;width:100%;background-color:#2298f7;z-index:20;box-shadow:0 0 10px rgba(0,0,0,.3);text-align:center}.list-actions.list-actions-toggled{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1;filter:alpha(opacity=100)}.la-close{position:absolute;right:20px;top:0;color:#fff;width:30px;height:30px;border-radius:50%;text-align:center;line-height:30px!important;background:hsla(0,0%,100%,.1);font-weight:400;bottom:0;margin:auto;cursor:pointer}.la-close:hover{background-color:hsla(0,0%,100%,.2)}.la-label{color:#fff;float:left;padding:4px 0}.la-label .fa{font-size:22px;vertical-align:top;margin-right:10px;margin-top:-1px}.la-actions button{background-color:transparent;border:2px solid hsla(0,0%,100%,.9);color:#fff;border-radius:2px;padding:5px 10px;font-size:13px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.la-actions button:hover{background-color:#fff;color:#2298f7}@-webkit-keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}@keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}.file-explorer{background-color:#fff;position:relative;height:100%}.file-explorer.toggled{height:100vh;overflow:hidden}.fe-body{min-height:100vh;overflow:auto}@media (min-width:992px){.fe-body{padding:0 0 40px 300px}}@media (max-width:991px){.fe-body{padding:75px 0 80px}}.feb-actions{position:fixed;bottom:30px;right:30px}.feb-actions .dropdown-menu{min-width:55px;width:55px;text-align:center;background:transparent;box-shadow:none;margin:0}.feb-actions.open .feba-btn{-webkit-transform:scale(1);transform:scale(1)}.feb-actions.open .feba-btn:first-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.3s;animation-duration:.3s}.feb-actions.open .feba-btn:last-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.1s;animation-duration:.1s}.feb-actions.open .feba-toggle{background:#ff403c}.feb-actions.open .feba-toggle>span{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.feba-toggle{width:55px;height:55px;line-height:55px;border-radius:50%;background:#ff726f;box-shadow:0 2px 3px rgba(0,0,0,.15);display:inline-block;text-align:center;border:0;padding:0}.feba-toggle span{display:inline-block;height:100%;width:100%}.feba-toggle i{color:#fff;font-size:17px;line-height:58px}.feba-toggle,.feba-toggle>span{-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;-webkit-backface-visibility:hidden;backface-visibility:hidden}.feba-btn{width:40px;margin-top:10px;height:40px;border-radius:50%;text-align:center;display:inline-block;line-height:40px;box-shadow:0 2px 3px rgba(0,0,0,.15);-webkit-transform:scale(0);transform:scale(0);position:relative}.feba-btn,.feba-btn:focus,.feba-btn:hover{color:#fff}.feba-btn label{width:100%;height:100%;position:absolute;left:0;top:0;cursor:pointer}.feba-bucket{background:#ffc155}.feba-upload{background:#ffc107}@-webkit-keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}@keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}.ie-warning{background-color:#ff5252;width:100%;height:100%;position:fixed;left:0;top:0;text-align:center}.ie-warning:before{width:1px;content:"";height:100%}.ie-warning .iw-inner,.ie-warning:before{display:inline-block;vertical-align:middle}.iw-inner{width:470px;height:300px;background-color:#fff;border-radius:5px;padding:40px;position:relative}.iw-inner ul{list-style:none;padding:0;margin:0;width:230px;margin-left:80px;margin-top:16px}.iw-inner ul>li{float:left}.iw-inner ul>li>a{display:block;padding:10px 15px 7px;font-size:14px;margin:0 1px;border-radius:3px}.iw-inner ul>li>a:hover{background:#eee}.iw-inner ul>li>a img{height:40px;margin-bottom:5px}.iwi-icon{color:#ff5252;font-size:40px;display:block;line-height:100%;margin-bottom:15px}.iwi-skip{position:absolute;left:0;bottom:-35px;width:100%;color:hsla(0,0%,100%,.6);cursor:pointer}.iwi-skip:hover{color:#fff}.dropdown-menu{padding:15px 0;top:0;margin-top:-1px}.dropdown-menu>li>a{padding:8px 20px;font-size:15px}.dropdown-menu>li>a>i{width:20px;position:relative;top:1px}.dropdown-menu-right>li>a{text-align:right}.alert{border:0;position:fixed;max-width:500px;margin:0;box-shadow:0 4px 5px rgba(0,0,0,.1);color:#fff;width:100%;right:20px;border-radius:3px;padding:17px 50px 17px 17px;z-index:10010;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.alert:not(.progress){top:20px}@media (min-width:768px){.alert:not(.progress){left:50%;margin-left:-250px}}.alert.progress{bottom:20px;right:20px}.alert.alert-danger{background:#ff726f}.alert.alert-success{background:#33d46f}.alert.alert-info{background:#50b2ff}@media (max-width:767px){.alert{left:20px;width:calc(100% - 40px);max-width:100%}}.alert .progress{margin:10px 10px 8px 0;height:5px;box-shadow:none;border-radius:1px;background-color:#50b2ff;border-radius:2px;overflow:hidden}.alert .progress-bar{box-shadow:none;background-color:#fff;height:100%}.alert .close{position:absolute;top:15px}@media (min-width:768px){.modal{text-align:center}.modal:before{content:"";height:100%;width:1px}.modal .modal-dialog,.modal:before{display:inline-block;vertical-align:middle}.modal .modal-dialog{text-align:left;margin:10px auto}}.modal-dark .modal-header{color:hsla(0,0%,100%,.4)}.modal-dark .modal-header small{color:hsla(0,0%,100%,.2)}.modal-dark .modal-content{background-color:#32393f}.modal-backdrop{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-backdrop,.modal-dialog{-webkit-animation-duration:.2s;animation-duration:.2s}.modal-dialog{-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-header{color:#333;position:relative}.modal-header small{display:block;text-transform:none;font-size:12px;margin-top:5px;color:#a8a8a8}.modal-content{border-radius:3px;box-shadow:none}.modal-footer{padding:0 30px 30px}.modal-confirm .modal-dialog,.modal-footer{text-align:center}.mc-icon{margin:0 0 10px}.mc-icon>i{font-size:60px}.mci-red{color:#ff8f8f}.mci-amber{color:#ffc107}.mci-green{color:#64e096}.mc-text{color:#333}.mc-sub{color:#bdbdbd;margin-top:5px;font-size:13px}@media (max-width:767px){.modal-about{text-align:center}.modal-about .modal-dialog{max-width:400px;width:90%;margin:20px auto 0}}.ma-inner{display:flex;flex-direction:row;align-items:center;min-height:350px;position:relative}@media (min-width:768px){.ma-inner:before{content:"";width:150px;height:100%;top:0;left:0;position:absolute;border-radius:3px 0 0 3px;background-color:#23282c}}.mai-item:first-child{width:150px;text-align:center}.mai-item:last-child{flex:4;padding:30px}.maii-logo{width:70px;position:relative}.maii-list{list-style:none;padding:0}.maii-list>li{margin-bottom:15px}.maii-list>li div{color:hsla(0,0%,100%,.8);text-transform:uppercase;font-size:14px}.maii-list>li small{font-size:13px;color:hsla(0,0%,100%,.4)}.toggle-password{position:absolute;bottom:30px;right:35px;width:30px;height:30px;border:1px solid #eee;border-radius:0;text-align:center;cursor:pointer;z-index:10;background-color:#fff;padding-top:5px}.toggle-password.toggled{background:#eee}.pm-body{padding-bottom:30px}.pmb-header{margin-bottom:35px}.pmb-list{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;padding:10px 35px}.pmb-list:nth-child(2n){background-color:#f7f7f7}.pmb-list .form-control{padding-left:0;padding-right:0}header.pmb-list{margin:20px 0 10px}.pmbl-item{display:block;font-size:13px}.pmbl-item:first-child{flex:2}.pmbl-item:nth-child(2){margin:0 25px;width:150px}.pmbl-item:nth-child(3){width:70px}div.pmb-list select{border:0}div.pmb-list .pml-item:not(:last-child){padding:0 5px}.modal-create-bucket .modal-dialog{position:fixed;right:25px;bottom:95px;margin:0;height:110px}.modal-create-bucket .modal-content{width:100%;height:100%}',""]); +},function(A,M,t){M=A.exports=t(138)(),M.push([A.id,'*,:after,:before{box-sizing:border-box}body{font-family:Lato,sans-serif;font-size:15px;line-height:1.42857143;color:#8e8e8e;background-color:#edecec}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#46a5e0}a,a:focus,a:hover{text-decoration:none}a:focus,a:hover{color:#1f7fba}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#edecec;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,.08)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#8e8e8e;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#333;background-color:rgba(0,0,0,.05)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#333;text-decoration:none;outline:0;background-color:rgba(0,0,0,.075)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#e4e4e4}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:13px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu>li>a{text-align:right}.navbar-right .dropdown-menu-left{left:0;right:auto}}.modal,.modal-open{overflow:hidden}.modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid transparent;border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:rgba(0,0,0,.1)}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:30px 35px 0;border-bottom:1px solid transparent}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:transparent}.modal-body{position:relative;padding:30px 35px}.modal-footer{padding:30px 35px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:400px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Lato,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:13px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:active,:focus{outline:0}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{min-height:100%}a{-webkit-transition:color;transition:color;-webkit-transition-duration:.3s;transition-duration:.3s}button{border:0}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.text-center{text-align:center!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.modal-footer:after,.modal-header:after,.row:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.p-relative{position:relative}.m-0{margin:0!important}.m-t-0{margin-top:0!important}.m-b-0{margin-bottom:0!important}.m-l-0{margin-left:0!important}.m-r-0{margin-right:0!important}.m-5{margin:5px!important}.m-t-5{margin-top:5px!important}.m-b-5{margin-bottom:5px!important}.m-l-5{margin-left:5px!important}.m-r-5{margin-right:5px!important}.m-10{margin:10px!important}.m-t-10{margin-top:10px!important}.m-b-10{margin-bottom:10px!important}.m-l-10{margin-left:10px!important}.m-r-10{margin-right:10px!important}.m-15{margin:15px!important}.m-t-15{margin-top:15px!important}.m-b-15{margin-bottom:15px!important}.m-l-15{margin-left:15px!important}.m-r-15{margin-right:15px!important}.m-20{margin:20px!important}.m-t-20{margin-top:20px!important}.m-b-20{margin-bottom:20px!important}.m-l-20{margin-left:20px!important}.m-r-20{margin-right:20px!important}.m-25{margin:25px!important}.m-t-25{margin-top:25px!important}.m-b-25{margin-bottom:25px!important}.m-l-25{margin-left:25px!important}.m-r-25{margin-right:25px!important}.m-30{margin:30px!important}.m-t-30{margin-top:30px!important}.m-b-30{margin-bottom:30px!important}.m-l-30{margin-left:30px!important}.m-r-30{margin-right:30px!important}.p-0{padding:0!important}.p-t-0{padding-top:0!important}.p-b-0{padding-bottom:0!important}.p-l-0{padding-left:0!important}.p-r-0{padding-right:0!important}.p-5{padding:5px!important}.p-t-5{padding-top:5px!important}.p-b-5{padding-bottom:5px!important}.p-l-5{padding-left:5px!important}.p-r-5{padding-right:5px!important}.p-10{padding:10px!important}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.p-l-10{padding-left:10px!important}.p-r-10{padding-right:10px!important}.p-15{padding:15px!important}.p-t-15{padding-top:15px!important}.p-b-15{padding-bottom:15px!important}.p-l-15{padding-left:15px!important}.p-r-15{padding-right:15px!important}.p-20{padding:20px!important}.p-t-20{padding-top:20px!important}.p-b-20{padding-bottom:20px!important}.p-l-20{padding-left:20px!important}.p-r-20{padding-right:20px!important}.p-25{padding:25px!important}.p-t-25{padding-top:25px!important}.p-b-25{padding-bottom:25px!important}.p-l-25{padding-left:25px!important}.p-r-25{padding-right:25px!important}.p-30{padding:30px!important}.p-t-30{padding-top:30px!important}.p-b-30{padding-bottom:30px!important}.p-l-30{padding-left:30px!important}.p-r-30{padding-right:30px!important}@font-face{font-family:Lato;src:url('+t(515)+') format("woff2"),url('+t(514)+') format("woff");font-weight:400;font-style:normal}.form-control{border:0;border-bottom:1px solid #eee;color:#32393f;padding:5px;width:100%;font-size:13px;background-color:transparent}select.form-control{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background:url('+t(518)+') no-repeat bottom 7px right}.input-group{position:relative}.input-group:not(:last-child){margin-bottom:25px}.input-group label:not(.ig-label){font-size:13px;display:block;margin-bottom:10px}.ig-label{position:absolute;text-align:center;bottom:7px;left:0;width:100%;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;padding:2px 0 3px;border-radius:2px;font-weight:400}.ig-helpers{z-index:1;width:100%;left:0}.ig-helpers,.ig-helpers:after,.ig-helpers:before{position:absolute;height:2px;bottom:0}.ig-helpers:after,.ig-helpers:before{content:"";width:0;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;background-color:#03a9f4}.ig-helpers:before{left:50%}.ig-helpers:after{right:50%}.ig-text{width:100%;height:40px;border:0;background:transparent;text-align:center;position:relative;z-index:1;border-bottom:1px solid #eee;color:#32393f;font-size:13px}.ig-text:focus+.ig-helpers:after,.ig-text:focus+.ig-helpers:before{width:50%}.ig-text:disabled~.ig-label,.ig-text:focus~.ig-label,.ig-text:valid~.ig-label{bottom:35px;font-size:13px;z-index:1}.ig-text:disabled{opacity:.5;filter:alpha(opacity=50)}.ig-dark .ig-text{color:#fff;border-color:hsla(0,0%,100%,.1)}.ig-dark .ig-helpers:after,.ig-dark .ig-helpers:before{background-color:#dfdfdf;height:1px}.ig-left .ig-label,.ig-left .ig-text{text-align:left}.ig-error .ig-label{color:#e23f3f}.ig-error .ig-helpers i:first-child,.ig-error .ig-helpers i:first-child:after,.ig-error .ig-helpers i:first-child:before{background:rgba(226,63,63,.43)}.ig-error .ig-helpers i:last-child,.ig-error .ig-helpers i:last-child:after,.ig-error .ig-helpers i:last-child:before{background:#e23f3f!important}.ig-error:after{content:"\\F05A";font-family:FontAwesome;position:absolute;top:17px;right:9px;font-size:20px;color:#d33d3e}.ig-search:before{font-family:fontAwesome;content:"\\F002";font-size:15px;position:absolute;left:2px;top:8px}.ig-search .ig-text{padding-left:25px}.set-expire{border:1px solid #eee;margin:35px 0 30px}.set-expire-item{padding:9px 5px 3px;position:relative;display:table-cell;width:1%;text-align:center}.set-expire-item:not(:last-child){border-right:1px solid #eee}.set-expire-title{font-size:10px;text-transform:uppercase}.set-expire-value{display:inline-block;overflow:hidden;position:relative;left:-8px}.set-expire-value input{font-size:20px;text-align:center;position:relative;right:-15px;border:0;color:#333;padding:0;height:25px;width:100%;font-weight:400}.set-expire-decrease,.set-expire-increase{position:absolute;width:20px;height:20px;background:url('+t(516)+') no-repeat 50%;background-size:85%;left:50%;margin-left:-10px;opacity:.2;filter:alpha(opacity=20);cursor:pointer}.set-expire-decrease:hover,.set-expire-increase:hover{opacity:.5;filter:alpha(opacity=50)}.set-expire-increase{top:-25px}.set-expire-decrease{bottom:-27px;-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.btn{border:0;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:2px;text-align:center;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.btn:focus,.btn:hover{opacity:.9;filter:alpha(opacity=90)}.btn-block{display:block;width:100%}.btn-white{color:#5b5b5b;background-color:#fff}.btn-white:focus,.btn-white:hover{color:#5b5b5b;background-color:#f0f0f0}.btn-link{color:#545454;background-color:#eee}.btn-link:focus,.btn-link:hover{color:#545454;background-color:#dfdfdf}.btn-danger{color:#fff;background-color:#ff726f}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff5450}.btn-primary{color:#fff;background-color:#50b2ff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#31a5ff}.btn-success{color:#fff;background-color:#33d46f}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#28c061}.close{right:15px;font-weight:400;opacity:1;font-size:18px;position:absolute;text-align:center;top:16px;z-index:1;padding:0;border:0;background-color:transparent}.close span{width:25px;height:25px;display:block;border-radius:50%;line-height:24px;text-shadow:none}.close:not(.close-alt) span{background-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.close:not(.close-alt):focus span,.close:not(.close-alt):hover span{background-color:hsla(0,0%,100%,.2);color:#fff}.close-alt span{background-color:#efefef;color:#989898}.close-alt:focus span,.close-alt:hover span{background-color:#e8e8e8;color:#7b7b7b}.hidden{display:none!important}.copy-text input{width:100%;border-radius:1px;border:1px solid #eee;padding:7px 12px;font-size:13px;line-height:100%;cursor:text;-webkit-transition:border-color;transition:border-color;-webkit-transition-duration:.3s;transition-duration:.3s}.copy-text input:hover{border-color:#e1e1e1}.share-availability{margin-bottom:40px}.share-availability:after,.share-availability:before{position:absolute;bottom:-30px;font-size:10px}.share-availability:before{content:"01 Sec";left:0}.share-availability:after{content:"7 days";right:0}.modal-aheader{height:100px}.modal-aheader:before{height:0!important}.modal-aheader .modal-dialog{margin:0;vertical-align:top}.login{height:100vh;min-height:500px;background:#32393f;text-align:center}.login:before{height:calc(100% - 110px);width:1px;content:""}.l-wrap,.login:before{display:inline-block;vertical-align:middle}.l-wrap{width:80%;max-width:500px;margin-top:-50px}.l-wrap.toggled{display:inline-block}.l-wrap .input-group:not(:last-child){margin-bottom:40px}.l-footer{height:110px;padding:0 50px}.lf-logo{float:right}.lf-logo img{width:40px}.lf-server{float:left;color:hsla(0,0%,100%,.4);font-size:20px;font-weight:400;padding-top:40px}@media (max-width:768px){.lf-logo,.lf-server{float:none;display:block;text-align:center;width:100%}.lf-logo{margin-bottom:5px}.lf-server{font-size:15px}}.lw-btn{width:50px;height:50px;border:1px solid #fff;display:inline-block;border-radius:50%;font-size:22px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;opacity:.3;background-color:transparent;line-height:45px;padding:0}.lw-btn:hover{color:#fff;opacity:.8;border-color:#fff}.lw-btn i{display:block;width:100%;padding-left:3px}input:-webkit-autofill{-webkit-box-shadow:0 0 0 50px #32393f inset!important;-webkit-text-fill-color:#fff!important}@media (min-width:668px){.fe-header{position:relative;padding:40px 40px 20px 45px}}@media (max-width:667px){.fe-header{padding:20px}}.fe-header h2{font-size:16px;font-weight:400;margin:0}.fe-header h2>span{margin-bottom:7px;display:inline-block}.fe-header h2>span:not(:first-child):before{content:"/";margin:0 4px;color:#8e8e8e}.fe-header p{margin-top:7px}.feh-usage{margin-top:12px;max-width:285px}@media (max-width:667px){.feh-usage{max-width:100%;font-size:12px}}.feh-usage>ul{margin-top:7px;list-style:none;padding:0}.feh-usage>ul>li{padding-right:0;display:inline-block}.fehu-chart{height:5px;background:#eee;position:relative;border-radius:2px;overflow:hidden}.fehu-chart>div{position:absolute;left:0;height:100%;background:#46a5e0}.feh-actions{list-style:none;padding:0;margin:0;position:absolute;right:35px;top:30px;z-index:11}@media (max-width:991px){.feh-actions{top:7px;right:10px;position:fixed}}.feh-actions>li{display:inline-block;text-align:right;vertical-align:top;line-height:100%}.feh-actions>li>.btn-group>button,.feh-actions>li>a{display:block;height:45px;min-width:45px;text-align:center;border-radius:50%;padding:0;border:0;background:none}@media (min-width:992px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{color:#7b7b7b;font-size:21px;line-height:45px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feh-actions>li>.btn-group>button:hover,.feh-actions>li>a:hover{background:rgba(0,0,0,.09)}}@media (max-width:991px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{background:url('+t(237)+') no-repeat 50%}.feh-actions>li>.btn-group>button .fa-reorder,.feh-actions>li>a .fa-reorder{display:none}}@media (max-width:991px){.fe-header-mobile{background-color:#32393f;padding:10px 50px 9px 12px;text-align:center;position:fixed;z-index:10;box-shadow:0 0 10px rgba(0,0,0,.3);left:0;top:0;width:100%}.fe-header-mobile .mh-logo{height:35px;position:relative;top:4px}.feh-trigger{width:41px;height:41px;cursor:pointer;float:left;position:relative;text-align:center}.feh-trigger:after,.feh-trigger:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.feh-trigger:after{z-index:1}.feh-trigger:before{background:hsla(0,0%,100%,.1);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:scale(0);transform:scale(0)}.feht-toggled:before{-webkit-transform:scale(1);transform:scale(1)}.feht-toggled .feht-lines{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.feht-toggled .feht-lines>div.top{width:12px;transform:translateX(8px) translateY(1px) rotate(45deg);-webkit-transform:translateX(8px) translateY(1px) rotate(45deg)}.feht-toggled .feht-lines>div.bottom{width:12px;transform:translateX(8px) translateY(-1px) rotate(-45deg);-webkit-transform:translateX(8px) translateY(-1px) rotate(-45deg)}.feht-lines,.feht-lines>div{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feht-lines{width:18px;height:12px;display:inline-block;margin-top:14px}.feht-lines>div{background-color:#eaeaea;width:18px;height:2px}.feht-lines>div.center{margin:3px 0}}.fe-sidebar{width:320px;background-color:#32393f;position:fixed;height:100%;overflow:hidden;padding:25px}@media (min-width:992px){.fe-sidebar{-webkit-transform:translateZ(0);transform:translateZ(0)}}@media (max-width:991px){.fe-sidebar{padding-top:85px;z-index:9;box-shadow:0 0 10px rgba(0,0,0,.65);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:translate3d(-335px,0,0);transform:translate3d(-335px,0,0)}.fe-sidebar.toggled{-webkit-transform:translateZ(0);transform:translateZ(0)}}.fe-sidebar a{color:hsla(0,0%,100%,.58)}.fe-sidebar a:hover{color:#fff}.fes-header{margin-bottom:40px}.fes-header h2,.fes-header img{float:left}.fes-header h2{margin:13px 0 0 10px;font-weight:400}.fes-header img{width:32px}.fesl-inner{height:calc(100vh - 260px);overflow:auto;padding:0;margin:0 -25px}.fesl-inner li{position:relative}.fesl-inner li>a{display:block;padding:10px 45px 12px 55px;word-wrap:break-word}.fesl-inner li>a:before{font-family:FontAwesome;content:"\\F0A0";font-size:17px;position:absolute;top:10px;left:25px;opacity:.8;filter:alpha(opacity=80)}.fesl-inner li>a.fesli-loading:before{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.1);border-bottom-color:hsla(0,0%,100%,.5);position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:32px;top:0;bottom:0;margin:auto}.fesl-inner li.active{background-color:#282e32}.fesl-inner li.active>a{color:#fff}.fesl-inner li:not(.active):hover{background-color:rgba(0,0,0,.1)}.fesl-inner li:not(.active):hover>a{color:#fff}.fesl-inner li:hover .fesli-trigger{opacity:.6;filter:alpha(opacity=60)}.fesl-inner li:hover .fesli-trigger:hover{opacity:1;filter:alpha(opacity=100)}.fesl-inner ul{list-style:none;padding:0;margin:0}.fesl-inner:hover .scrollbar-vertical{opacity:1}.fesli-trigger{filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;top:0;right:0;width:35px;cursor:pointer;background:url('+t(237)+') no-repeat top 20px left}.fesli-trigger,.scrollbar-vertical{opacity:0;position:absolute;height:100%}.scrollbar-vertical{right:5px;width:4px;-webkit-transition:opacity;transition:opacity;-webkit-transition-duration:.3s;transition-duration:.3s}.scrollbar-vertical div{border-radius:1px!important;background-color:#6a6a6a!important}.fes-host{position:fixed;left:0;bottom:0;z-index:1;background:#32393f;color:hsla(0,0%,100%,.4);font-size:15px;font-weight:400;width:320px;padding:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fes-host>i{margin-right:10px}.fesl-row{position:relative}@media (min-width:668px){.fesl-row{padding:5px 20px 5px 40px;display:flex;flex-flow:row nowrap;justify-content:space-between}}@media (max-width:667px){.fesl-row{padding:5px 20px}}.fesl-row:after,.fesl-row:before{content:" ";display:table}.fesl-row:after{clear:both}@media (min-width:668px){header.fesl-row{margin-bottom:20px;border-bottom:1px solid #f0f0f0;padding-left:30px}header.fesl-row .fesl-item,header.fesl-row .fesli-sort{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}header.fesl-row .fesl-item{cursor:pointer;color:#8e8e8e;font-weight:500;margin-bottom:-5px}header.fesl-row .fesl-item>.fesli-sort{float:right;margin:4px 0 0;opacity:0;filter:alpha(opacity=0);color:#32393f;font-size:14px}header.fesl-row .fesl-item:hover:not(.fesl-item-actions){background:#f5f5f5;color:#32393f}header.fesl-row .fesl-item:hover:not(.fesl-item-actions)>.fesli-sort{opacity:.5;filter:alpha(opacity=50)}}@media (max-width:667px){header.fesl-row{display:none}}div.fesl-row{border-bottom:1px solid transparent;cursor:default;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.5s;transition-duration:.5s}@media (max-width:667px){div.fesl-row{padding:5px 20px}}div.fesl-row:not(.fesl-row-selected):nth-child(2n){background-color:#fafafa}div.fesl-row:hover .fis-icon:before{opacity:0;filter:alpha(opacity=0)}div.fesl-row:hover .fis-helper:before{opacity:1;filter:alpha(opacity=100)}div.fesl-row[data-type=folder] .fis-icon{background-color:#a1d6dd}div.fesl-row[data-type=folder] .fis-icon:before{content:"\\F114"}div.fesl-row[data-type=pdf] .fis-icon{background-color:#fa7775}div.fesl-row[data-type=pdf] .fis-icon:before{content:"\\F1C1"}div.fesl-row[data-type=zip] .fis-icon{background-color:#427089}div.fesl-row[data-type=zip] .fis-icon:before{content:"\\F1C6"}div.fesl-row[data-type=audio] .fis-icon{background-color:#009688}div.fesl-row[data-type=audio] .fis-icon:before{content:"\\F1C7"}div.fesl-row[data-type=code] .fis-icon{background-color:#997867}div.fesl-row[data-type=code] .fis-icon:before{content:"\\F1C9"}div.fesl-row[data-type=excel] .fis-icon{background-color:#f1c3 3}div.fesl-row[data-type=excel] .fis-icon:before{content:"\\F1C3"}div.fesl-row[data-type=image] .fis-icon{background-color:#f06292}div.fesl-row[data-type=image] .fis-icon:before{content:"\\F1C5"}div.fesl-row[data-type=video] .fis-icon{background-color:#f8c363}div.fesl-row[data-type=video] .fis-icon:before{content:"\\F1C8"}div.fesl-row[data-type=other] .fis-icon{background-color:#afafaf}div.fesl-row[data-type=other] .fis-icon:before{content:"\\F016"}div.fesl-row[data-type=text] .fis-icon{background-color:#8a8a8a}div.fesl-row[data-type=text] .fis-icon:before{content:"\\F0F6"}div.fesl-row[data-type=doc] .fis-icon{background-color:#2196f5}div.fesl-row[data-type=doc] .fis-icon:before{content:"\\F1C2"}div.fesl-row[data-type=presentation] .fis-icon{background-color:#896ea6}div.fesl-row[data-type=presentation] .fis-icon:before{content:"\\F1C4"}div.fesl-row.fesl-loading:before{content:""}div.fesl-row.fesl-loading:after{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.5);border-bottom-color:#fff;position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:57px;top:17px}@media (max-width:667px){div.fesl-row.fesl-loading:after{left:27px}}.fesl-row-selected{background-color:#fbf2bf}.fesl-row-selected,.fesl-row-selected .fesl-item a{color:#757575}.fi-select{float:left;position:relative;width:35px;height:35px;margin:3px 0}@media (max-width:667px){.fi-select{margin-right:15px}}.fi-select input{position:absolute;left:0;top:0;width:35px;height:35px;z-index:20;opacity:0;cursor:pointer}.fi-select input:checked~.fis-icon{background-color:#32393f}.fi-select input:checked~.fis-icon:before{opacity:0}.fi-select input:checked~.fis-helper:before{-webkit-transform:scale(0);transform:scale(0)}.fi-select input:checked~.fis-helper:after{-webkit-transform:scale(1);transform:scale(1)}.fis-icon{display:inline-block;vertical-align:top;border-radius:50%;width:35px;height:35px;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-icon:before{width:100%;height:100%;text-align:center;position:absolute;border-radius:50%;font-family:fontAwesome;line-height:35px;font-size:16px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;font-style:normal}.fis-helper:after,.fis-helper:before{position:absolute;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-helper:before{content:"";width:15px;height:15px;border:2px solid #fff;z-index:10;border-radius:2px;top:10px;left:10px;opacity:0}.fis-helper:after{font-family:fontAwesome;content:"\\F00C";top:8px;left:9px;color:#fff;font-size:14px;-webkit-transform:scale(0);transform:scale(0)}.fesl-item{display:block}.fesl-item a{color:#818181}@media (min-width:668px){.fesl-item:not(.fesl-item-actions):not(.fesl-item-icon){text-overflow:ellipsis;padding:10px 15px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-name{flex:3}.fesl-item.fesl-item-size{width:140px}.fesl-item.fesl-item-modified{width:190px}.fesl-item.fesl-item-actions{width:40px}}@media (max-width:667px){.fesl-item{padding:0}.fesl-item.fesl-item-name{width:100%;margin-bottom:3px}.fesl-item.fesl-item-modified,.fesl-item.fesl-item-size{font-size:12px;color:#b5b5b5;float:left}.fesl-item.fesl-item-modified{max-width:72px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-size{margin-right:10px}.fesl-item.fesl-item-actions{position:absolute;top:5px;right:10px}}.fia-toggle{height:36px;width:36px;background:transparent url('+t(517)+') no-repeat 50%;position:relative;top:3px;opacity:.4;filter:alpha(opacity=40)}.fia-toggle:hover{opacity:.7;filter:alpha(opacity=70)}.fesl-item-actions .dropdown-menu{background-color:transparent;box-shadow:none;padding:0;right:38px;left:auto;margin:0;height:100%;text-align:right}.fesl-item-actions .dropdown.open .dropdown-menu .fiad-action{right:0}.fiad-action{height:35px;width:35px;background:#ffc107;display:inline-block;border-radius:50%;text-align:center;line-height:35px;font-weight:400;position:relative;top:4px;margin-left:5px;-webkit-animation-name:fiad-action-anim;animation-name:fiad-action-anim;-webkit-transform-origin:center center;transform-origin:center center;-webkit-backface-visibility:none;backface-visibility:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.fiad-action:nth-child(2){-webkit-animation-duration:.1s;animation-duration:.1s}.fiad-action:first-child{-webkit-animation-duration:.25s;animation-duration:.25s}.fiad-action>i{font-size:14px;color:#fff}.fiad-action:hover{background-color:#f7b900}.list-actions{position:fixed;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);opacity:0;filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;padding:20px 70px 20px 25px;top:0;left:0;width:100%;background-color:#2298f7;z-index:20;box-shadow:0 0 10px rgba(0,0,0,.3);text-align:center}.list-actions.list-actions-toggled{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1;filter:alpha(opacity=100)}.la-close{position:absolute;right:20px;top:0;color:#fff;width:30px;height:30px;border-radius:50%;text-align:center;line-height:30px!important;background:hsla(0,0%,100%,.1);font-weight:400;bottom:0;margin:auto;cursor:pointer}.la-close:hover{background-color:hsla(0,0%,100%,.2)}.la-label{color:#fff;float:left;padding:4px 0}.la-label .fa{font-size:22px;vertical-align:top;margin-right:10px;margin-top:-1px}.la-actions button{background-color:transparent;border:2px solid hsla(0,0%,100%,.9);color:#fff;border-radius:2px;padding:5px 10px;font-size:13px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;margin-left:10px}.la-actions button:hover{background-color:#fff;color:#2298f7}@-webkit-keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}@keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}.file-explorer{background-color:#fff;position:relative;height:100%}.file-explorer.toggled{height:100vh;overflow:hidden}.fe-body{min-height:100vh;overflow:auto}@media (min-width:992px){.fe-body{padding:0 0 40px 320px}}@media (max-width:991px){.fe-body{padding:75px 0 80px}}.feb-actions{position:fixed;bottom:30px;right:30px}.feb-actions .dropdown-menu{min-width:55px;width:55px;text-align:center;background:transparent;box-shadow:none;margin:0}.feb-actions.open .feba-btn{-webkit-transform:scale(1);transform:scale(1)}.feb-actions.open .feba-btn:first-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.3s;animation-duration:.3s}.feb-actions.open .feba-btn:last-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.1s;animation-duration:.1s}.feb-actions.open .feba-toggle{background:#ff403c}.feb-actions.open .feba-toggle>span{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.feba-toggle{width:55px;height:55px;line-height:55px;border-radius:50%;background:#ff726f;box-shadow:0 2px 3px rgba(0,0,0,.15);display:inline-block;text-align:center;border:0;padding:0}.feba-toggle span{display:inline-block;height:100%;width:100%}.feba-toggle i{color:#fff;font-size:17px;line-height:58px}.feba-toggle,.feba-toggle>span{-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;-webkit-backface-visibility:hidden;backface-visibility:hidden}.feba-btn{width:40px;margin-top:10px;height:40px;border-radius:50%;text-align:center;display:inline-block;line-height:40px;box-shadow:0 2px 3px rgba(0,0,0,.15);-webkit-transform:scale(0);transform:scale(0);position:relative}.feba-btn,.feba-btn:focus,.feba-btn:hover{color:#fff}.feba-btn label{width:100%;height:100%;position:absolute;left:0;top:0;cursor:pointer}.feba-bucket{background:#ffc155}.feba-upload{background:#ffc107}@-webkit-keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}@keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}.ie-warning{background-color:#ff5252;width:100%;height:100%;position:fixed;left:0;top:0;text-align:center}.ie-warning:before{width:1px;content:"";height:100%}.ie-warning .iw-inner,.ie-warning:before{display:inline-block;vertical-align:middle}.iw-inner{width:470px;height:300px;background-color:#fff;border-radius:5px;padding:40px;position:relative}.iw-inner ul{list-style:none;padding:0;margin:0;width:230px;margin-left:80px;margin-top:16px}.iw-inner ul>li{float:left}.iw-inner ul>li>a{display:block;padding:10px 15px 7px;font-size:14px;margin:0 1px;border-radius:3px}.iw-inner ul>li>a:hover{background:#eee}.iw-inner ul>li>a img{height:40px;margin-bottom:5px}.iwi-icon{color:#ff5252;font-size:40px;display:block;line-height:100%;margin-bottom:15px}.iwi-skip{position:absolute;left:0;bottom:-35px;width:100%;color:hsla(0,0%,100%,.6);cursor:pointer}.iwi-skip:hover{color:#fff}.dropdown-menu{padding:15px 0;top:0;margin-top:-1px}.dropdown-menu>li>a{padding:8px 20px;font-size:15px}.dropdown-menu>li>a>i{width:20px;position:relative;top:1px}.dropdown-menu-right>li>a{text-align:right}.alert{border:0;position:fixed;max-width:500px;margin:0;box-shadow:0 4px 5px rgba(0,0,0,.1);color:#fff;width:100%;right:20px;border-radius:3px;padding:17px 50px 17px 17px;z-index:10010;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.alert:not(.progress){top:20px}@media (min-width:768px){.alert:not(.progress){left:50%;margin-left:-250px}}.alert.progress{bottom:20px;right:20px}.alert.alert-danger{background:#ff726f}.alert.alert-success{background:#33d46f}.alert.alert-info{background:#50b2ff}@media (max-width:767px){.alert{left:20px;width:calc(100% - 40px);max-width:100%}}.alert .progress{margin:10px 10px 8px 0;height:5px;box-shadow:none;border-radius:1px;background-color:#50b2ff;border-radius:2px;overflow:hidden}.alert .progress-bar{box-shadow:none;background-color:#fff;height:100%}.alert .close{position:absolute;top:15px}@media (min-width:768px){.modal{text-align:center}.modal:before{content:"";height:100%;width:1px}.modal .modal-dialog,.modal:before{display:inline-block;vertical-align:middle}.modal .modal-dialog{text-align:left;margin:10px auto}}.modal-dark .modal-header{color:hsla(0,0%,100%,.4)}.modal-dark .modal-header small{color:hsla(0,0%,100%,.2)}.modal-dark .modal-content{background-color:#32393f}.modal-backdrop{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-backdrop,.modal-dialog{-webkit-animation-duration:.2s;animation-duration:.2s}.modal-dialog{-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-header{color:#333;position:relative}.modal-header small{display:block;text-transform:none;font-size:12px;margin-top:5px;color:#a8a8a8}.modal-content{border-radius:3px;box-shadow:none}.modal-footer{padding:0 30px 30px}.modal-confirm .modal-dialog,.modal-footer{text-align:center}.mc-icon{margin:0 0 10px}.mc-icon>i{font-size:60px}.mci-red{color:#ff8f8f}.mci-amber{color:#ffc107}.mci-green{color:#64e096}.mc-text{color:#333}.mc-sub{color:#bdbdbd;margin-top:5px;font-size:13px}@media (max-width:767px){.modal-about{text-align:center}.modal-about .modal-dialog{max-width:400px;width:90%;margin:20px auto 0}}.ma-inner{display:flex;flex-direction:row;align-items:center;min-height:350px;position:relative}@media (min-width:768px){.ma-inner:before{content:"";width:150px;height:100%;top:0;left:0;position:absolute;border-radius:3px 0 0 3px;background-color:#23282c}}.mai-item:first-child{width:150px;text-align:center}.mai-item:last-child{flex:4;padding:30px}.maii-logo{width:70px;position:relative}.maii-list{list-style:none;padding:0}.maii-list>li{margin-bottom:15px}.maii-list>li div{color:hsla(0,0%,100%,.8);text-transform:uppercase;font-size:14px}.maii-list>li small{font-size:13px;color:hsla(0,0%,100%,.4)}.toggle-password{position:absolute;bottom:30px;right:35px;width:30px;height:30px;border:1px solid #eee;border-radius:0;text-align:center;cursor:pointer;z-index:10;background-color:#fff;padding-top:5px}.toggle-password.toggled{background:#eee}.pm-body{padding-bottom:30px}.pmb-header{margin-bottom:35px}.pmb-list{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;padding:10px 35px}.pmb-list:nth-child(2n){background-color:#f7f7f7}.pmb-list .form-control{padding-left:0;padding-right:0}header.pmb-list{margin:20px 0 10px}.pmbl-item{display:block;font-size:13px}.pmbl-item:first-child{flex:2}.pmbl-item:nth-child(2){margin:0 25px;width:150px}.pmbl-item:nth-child(3){width:70px}div.pmb-list select{border:0}div.pmb-list .pml-item:not(:last-child){padding:0 5px}.modal-create-bucket .modal-dialog{position:fixed;right:25px;bottom:95px;margin:0;height:110px}.modal-create-bucket .modal-content{width:100%;height:100%}',""]); },function(A,M,t){function I(A){return null===A||void 0===A}function g(A){return!(!A||"object"!=typeof A||"number"!=typeof A.length)&&("function"==typeof A.copy&&"function"==typeof A.slice&&!(A.length>0&&"number"!=typeof A[0]))}function e(A,M,t){var e,o;if(I(A)||I(M))return!1;if(A.prototype!==M.prototype)return!1;if(E(A))return!!E(M)&&(A=i.call(A),M=i.call(M),N(A,M,t));if(g(A)){if(!g(M))return!1;if(A.length!==M.length)return!1;for(e=0;e=0;e--)if(n[e]!=C[e])return!1;for(e=n.length-1;e>=0;e--)if(o=n[e],!N(A[o],M[o],t))return!1;return typeof A==typeof M}var i=Array.prototype.slice,T=t(280),E=t(279),N=A.exports=function(A,M,t){return t||(t={}),A===M||(A instanceof Date&&M instanceof Date?A.getTime()===M.getTime():!A||!M||"object"!=typeof A&&"object"!=typeof M?t.strict?A===M:A==M:e(A,M,t))}},function(A,M){function t(A){return"[object Arguments]"==Object.prototype.toString.call(A)}function I(A){return A&&"object"==typeof A&&"number"==typeof A.length&&Object.prototype.hasOwnProperty.call(A,"callee")&&!Object.prototype.propertyIsEnumerable.call(A,"callee")||!1}var g="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();M=A.exports=g?t:I,M.supported=t,M.unsupported=I},function(A,M){function t(A){var M=[];for(var t in A)M.push(t);return M}M=A.exports="function"==typeof Object.keys?Object.keys:t,M.shim=t},function(A,M,t){"use strict";var I=t(141);A.exports=function(A,M){A.classList?A.classList.add(M):I(A)||(A.className=A.className+" "+M)}},function(A,M,t){"use strict";A.exports={addClass:t(281),removeClass:t(283),hasClass:t(141)}},function(A,M){"use strict";A.exports=function(A,M){A.classList?A.classList.remove(M):A.className=A.className.replace(new RegExp("(^|\\s)"+M+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}},function(A,M,t){"use strict";var I=t(40),g=t(288);A.exports=function(A,M){return function(t){var e=t.currentTarget,i=t.target,T=g(e,A);T.some(function(A){return I(A,i)})&&M.call(this,t)}}},function(A,M,t){"use strict";var I=t(81),g=t(142),e=t(284);A.exports={on:I,off:g,filter:e}},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A){for(var M=(0,T.default)(A),t=A&&A.offsetParent;t&&"html"!==I(A)&&"static"===(0,N.default)(t,"position");)t=t.offsetParent;return t||M.documentElement}var e=t(58);M.__esModule=!0,M.default=g;var i=t(39),T=e.interopRequireDefault(i),E=t(82),N=e.interopRequireDefault(E);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A,M){var t,g={top:0,left:0};return"fixed"===(0,a.default)(A,"position")?t=A.getBoundingClientRect():(M=M||(0,N.default)(A),t=(0,T.default)(A),"html"!==I(M)&&(g=(0,T.default)(M)),g.top+=parseInt((0,a.default)(M,"borderTopWidth"),10)-(0,n.default)(M)||0,g.left+=parseInt((0,a.default)(M,"borderLeftWidth"),10)-(0,c.default)(M)||0),e._extends({},t,{top:t.top-g.top-(parseInt((0,a.default)(A,"marginTop"),10)||0),left:t.left-g.left-(parseInt((0,a.default)(A,"marginLeft"),10)||0)})}var e=t(58);M.__esModule=!0,M.default=g;var i=t(143),T=e.interopRequireDefault(i),E=t(286),N=e.interopRequireDefault(E),o=t(144),n=e.interopRequireDefault(o),C=t(289),c=e.interopRequireDefault(C),D=t(82),a=e.interopRequireDefault(D);A.exports=M.default},function(A,M){"use strict";var t=/^[\w-]*$/,I=Function.prototype.bind.call(Function.prototype.call,[].slice);A.exports=function(A,M){var g,e="#"===M[0],i="."===M[0],T=e||i?M.slice(1):M,E=t.test(T);return E?e?(A=A.getElementById?A:document,(g=A.getElementById(T))?[g]:[]):I(A.getElementsByClassName&&i?A.getElementsByClassName(T):A.getElementsByTagName(M)):I(A.querySelectorAll(M))}},function(A,M,t){"use strict";var I=t(57);A.exports=function(A,M){var t=I(A);return void 0===M?t?"pageXOffset"in t?t.pageXOffset:t.document.documentElement.scrollLeft:A.scrollLeft:void(t?t.scrollTo(M,"pageYOffset"in t?t.pageYOffset:t.document.documentElement.scrollTop):A.scrollLeft=M)}},function(A,M,t){"use strict";var I=t(58),g=t(145),e=I.interopRequireDefault(g),i=/^(top|right|bottom|left)$/,T=/^([+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/i;A.exports=function(A){if(!A)throw new TypeError("No Element passed to ` + "`" + `getComputedStyle()` + "`" + `");var M=A.ownerDocument;return"defaultView"in M?M.defaultView.opener?A.ownerDocument.defaultView.getComputedStyle(A,null):window.getComputedStyle(A,null):{getPropertyValue:function(M){var t=A.style;M=(0,e.default)(M),"float"==M&&(M="styleFloat");var I=A.currentStyle[M]||null;if(null==I&&t&&t[M]&&(I=t[M]),T.test(I)&&!i.test(M)){var g=t.left,E=A.runtimeStyle,N=E&&E.left;N&&(E.left=A.currentStyle.left),t.left="fontSize"===M?"1em":I,I=t.pixelLeft+"px",t.left=g,N&&(E.left=N)}return I}}}},function(A,M){"use strict";A.exports=function(A,M){return"removeProperty"in A.style?A.style.removeProperty(M):A.style.removeAttribute(M)}},function(A,M,t){"use strict";function I(){var A,M="",t={O:"otransitionend",Moz:"transitionend",Webkit:"webkitTransitionEnd",ms:"MSTransitionEnd"},I=document.createElement("div");for(var g in t)if(N.call(t,g)&&void 0!==I.style[g+"TransitionProperty"]){M="-"+g.toLowerCase()+"-",A=t[g];break}return A||void 0===I.style.transitionProperty||(A="transitionend"),{end:A,prefix:M}}var g,e,i,T,E=t(32),N=Object.prototype.hasOwnProperty,o="transform",n={};E&&(n=I(),o=n.prefix+o,i=n.prefix+"transition-property",e=n.prefix+"transition-duration",T=n.prefix+"transition-delay",g=n.prefix+"transition-timing-function"),A.exports={transform:o,end:n.end,property:i,timing:g,delay:T,duration:e}},function(A,M){"use strict";var t=/-(.)/g;A.exports=function(A){return A.replace(t,function(A,M){return M.toUpperCase()})}},function(A,M){"use strict";var t=/([A-Z])/g;A.exports=function(A){return A.replace(t,"-$1").toLowerCase()}},function(A,M,t){"use strict";var I=t(294),g=/^ms-/;A.exports=function(A){return I(A).replace(g,"-ms-")}},function(A,M){"use strict";function t(A){return A.replace(I,function(A,M){return M.toUpperCase()})}var I=/-(.)/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A.replace(e,"ms-"))}var g=t(296),e=/^-ms-/;A.exports=I},function(A,M,t){"use strict";function I(A){return!!A&&("object"==typeof A||"function"==typeof A)&&"length"in A&&!("setInterval"in A)&&"number"!=typeof A.nodeType&&(Array.isArray(A)||"callee"in A||"item"in A)}function g(A){return I(A)?Array.isArray(A)?A.slice():e(A):[A]}var e=t(307);A.exports=g},function(A,M,t){"use strict";function I(A){var M=A.match(o);return M&&M[1].toLowerCase()}function g(A,M){var t=N;N?void 0:E(!1);var g=I(A),e=g&&T(g);if(e){t.innerHTML=e[1]+A+e[2];for(var o=e[0];o--;)t=t.lastChild}else t.innerHTML=A;var n=t.getElementsByTagName("script");n.length&&(M?void 0:E(!1),i(n).forEach(M));for(var C=i(t.childNodes);t.lastChild;)t.removeChild(t.lastChild);return C}var e=t(10),i=t(298),T=t(151),E=t(2),N=e.canUseDOM?document.createElement("div"):null,o=/^\s*<(\w+)/;A.exports=g},function(A,M){"use strict";function t(A){return A===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:A.scrollLeft,y:A.scrollTop}}A.exports=t},function(A,M){"use strict";function t(A){return A.replace(I,"-$1").toLowerCase()}var I=/([A-Z])/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A).replace(e,"-ms-")}var g=t(301),e=/^ms-/;A.exports=I},function(A,M){"use strict";function t(A){return!(!A||!("function"==typeof Node?A instanceof Node:"object"==typeof A&&"number"==typeof A.nodeType&&"string"==typeof A.nodeName))}A.exports=t},function(A,M,t){"use strict";function I(A){return g(A)&&3==A.nodeType}var g=t(303);A.exports=I},function(A,M){"use strict";function t(A,M,t){if(!A)return null;var g={};for(var e in A)I.call(A,e)&&(g[e]=M.call(t,A[e],e,A));return g}var I=Object.prototype.hasOwnProperty;A.exports=t},function(A,M){"use strict";function t(A){var M={};return function(t){return M.hasOwnProperty(t)||(M[t]=A.call(this,t)),M[t]}}A.exports=t},function(A,M,t){"use strict";function I(A){var M=A.length;if(Array.isArray(A)||"object"!=typeof A&&"function"!=typeof A?g(!1):void 0,"number"!=typeof M?g(!1):void 0,0===M||M-1 in A?void 0:g(!1),A.hasOwnProperty)try{return Array.prototype.slice.call(A)}catch(A){}for(var t=Array(M),I=0;I1&&(I=t[0]+"@",A=t[1]),A=A.replace(z,".");var g=A.split("."),e=T(g,M).join(".");return I+e}function N(A){for(var M,t,I=[],g=0,e=A.length;g=55296&&M<=56319&&g65535&&(A-=65536,M+=m(A>>>10&1023|55296),A=56320|1023&A),M+=m(A)}).join("")}function n(A){return A-48<10?A-22:A-65<26?A-65:A-97<26?A-97:j}function C(A,M){return A+22+75*(A<26)-((0!=M)<<5)}function c(A,M,t){var I=0;for(A=t?O(A/l):A>>1,A+=O(A/M);A>U*u>>1;I+=j)A=O(A/U);return O(I+(U+1)*A/(A+w))}function D(A){var M,t,I,g,e,T,E,N,C,D,a=[],B=A.length,Q=0,r=Y,s=L;for(t=A.lastIndexOf(d),t<0&&(t=0),I=0;I=128&&i("not-basic"),a.push(A.charCodeAt(I));for(g=t>0?t+1:0;g=B&&i("invalid-input"),N=n(A.charCodeAt(g++)),(N>=j||N>O((x-Q)/T))&&i("overflow"),Q+=N*T,C=E<=s?y:E>=s+u?u:E-s,!(NO(x/D)&&i("overflow"),T*=D;M=a.length+1,s=c(Q-e,M,0==e),O(Q/M)>x-r&&i("overflow"),r+=O(Q/M),Q%=M,a.splice(Q++,0,r)}return o(a)}function a(A){var M,t,I,g,e,T,E,o,n,D,a,B,Q,r,s,w=[];for(A=N(A),B=A.length,M=Y,t=0,e=L,T=0;T=M&&aO((x-t)/Q)&&i("overflow"),t+=(E-M)*Q,M=E,T=0;Tx&&i("overflow"),a==M){for(o=t,n=j;D=n<=e?y:n>=e+u?u:n-e,!(o= 0x80 (not a basic code point)","invalid-input":"Invalid input"},U=j-y,O=Math.floor,m=String.fromCharCode;s={version:"1.3.2",ucs2:{decode:N,encode:o},decode:D,encode:a,toASCII:Q,toUnicode:B},I=function(){return s}.call(M,t,M,A),!(void 0!==I&&(A.exports=I))}(this)}).call(M,t(128)(A),function(){return this}())},function(A,M){"use strict";A.exports={isString:function(A){return"string"==typeof A},isObject:function(A){return"object"==typeof A&&null!==A},isNull:function(A){return null===A},isNullOrUndefined:function(A){return null==A}}}]);`) -func productionIndex_bundle20170304t010753zJsBytes() ([]byte, error) { - return _productionIndex_bundle20170304t010753zJs, nil +func productionIndex_bundle20170309t221146zJsBytes() ([]byte, error) { + return _productionIndex_bundle20170309t221146zJs, nil } -func productionIndex_bundle20170304t010753zJs() (*asset, error) { - bytes, err := productionIndex_bundle20170304t010753zJsBytes() +func productionIndex_bundle20170309t221146zJs() (*asset, error) { + bytes, err := productionIndex_bundle20170309t221146zJsBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "production/index_bundle-2017-03-04T01-07-53Z.js", size: 2282905, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/index_bundle-2017-03-09T22-11-46Z.js", size: 2283985, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -370,7 +370,7 @@ func productionLoaderCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -444,7 +444,7 @@ func productionLogoSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -461,7 +461,7 @@ func productionSafariPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1488589689, 0)} + info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -522,7 +522,7 @@ var _bindata = map[string]func() (*asset, error){ "production/favicon.ico": productionFaviconIco, "production/firefox.png": productionFirefoxPng, "production/index.html": productionIndexHTML, - "production/index_bundle-2017-03-04T01-07-53Z.js": productionIndex_bundle20170304t010753zJs, + "production/index_bundle-2017-03-09T22-11-46Z.js": productionIndex_bundle20170309t221146zJs, "production/loader.css": productionLoaderCss, "production/logo.svg": productionLogoSvg, "production/safari.png": productionSafariPng, @@ -574,7 +574,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "favicon.ico": {productionFaviconIco, map[string]*bintree{}}, "firefox.png": {productionFirefoxPng, map[string]*bintree{}}, "index.html": {productionIndexHTML, map[string]*bintree{}}, - "index_bundle-2017-03-04T01-07-53Z.js": {productionIndex_bundle20170304t010753zJs, map[string]*bintree{}}, + "index_bundle-2017-03-09T22-11-46Z.js": {productionIndex_bundle20170309t221146zJs, map[string]*bintree{}}, "loader.css": {productionLoaderCss, map[string]*bintree{}}, "logo.svg": {productionLogoSvg, map[string]*bintree{}}, "safari.png": {productionSafariPng, map[string]*bintree{}}, @@ -635,6 +635,6 @@ func assetFS() *assetfs.AssetFS { panic("unreachable") } -var UIReleaseTag = "RELEASE.2017-03-04T01-07-53Z" -var UICommitID = "0bae3330e8c8910c69e8229a3f0268e6127b6982" -var UIVersion = "2017-03-04T01:07:53Z" +var UIReleaseTag = "RELEASE.2017-03-09T22-11-46Z" +var UICommitID = "d602495600970254a1f485a99dd1516b68dbc497" +var UIVersion = "2017-03-09T22:11:46Z" From 2410eb281e85be1470068b16d4d67b7ee04cbf47 Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Fri, 10 Mar 2017 22:31:59 +0530 Subject: [PATCH 75/94] Update kafkacat command with consumer flag (#3882) --- docs/bucket/notifications/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/bucket/notifications/README.md b/docs/bucket/notifications/README.md index 59cdeefc9..27d5fd43f 100644 --- a/docs/bucket/notifications/README.md +++ b/docs/bucket/notifications/README.md @@ -461,7 +461,7 @@ arn:minio:sqs:us-east-1:1:kafka s3:ObjectCreated:*,s3:ObjectRemoved:* Filter: su We used [kafkacat](https://github.com/edenhill/kafkacat) to print all notifications on the console. ``` -kafkacat -b localhost:9092 -t bucketevents +kafkacat -C -b localhost:9092 -t bucketevents ``` Open another terminal and upload a JPEG image into ``images`` bucket. From e77885d671070805edad89e0cc1d60525dc9a51c Mon Sep 17 00:00:00 2001 From: Rushan Date: Sat, 11 Mar 2017 04:00:23 +0530 Subject: [PATCH 76/94] Browser: Add Object.assign polyfill to support older browsers (#3884) --- browser/app/index.js | 2 ++ browser/app/js/actions.js | 4 ---- browser/package.json | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/browser/app/index.js b/browser/app/index.js index 26a1cc1d3..5c2a33749 100644 --- a/browser/app/index.js +++ b/browser/app/index.js @@ -44,6 +44,8 @@ import Web from './js/web' window.Web = Web import storage from 'local-storage-fallback' +import objectAssign from 'es6-object-assign' +objectAssign.polyfill() const store = applyMiddleware(thunkMiddleware)(createStore)(reducer) const Browse = connect(state => state)(_Browse) diff --git a/browser/app/js/actions.js b/browser/app/js/actions.js index 2aec14a5b..a39113dc6 100644 --- a/browser/app/js/actions.js +++ b/browser/app/js/actions.js @@ -14,13 +14,9 @@ * limitations under the License. */ -import url from 'url' import Moment from 'moment' import browserHistory from 'react-router/lib/browserHistory' -import web from './web' -import * as utils from './utils' import storage from 'local-storage-fallback' - import { minioBrowserPrefix } from './constants' export const SET_WEB = 'SET_WEB' diff --git a/browser/package.json b/browser/package.json index 9f792974d..a60f80759 100644 --- a/browser/package.json +++ b/browser/package.json @@ -67,6 +67,7 @@ "dependencies": { "bootstrap": "^3.3.6", "classnames": "^2.2.3", + "es6-object-assign": "^1.0.3", "font-awesome": "^4.7.0", "humanize": "0.0.9", "json-loader": "^0.5.4", From 305952d734e868c79b32560866c2edbd4aa0578f Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 10 Mar 2017 15:13:26 -0800 Subject: [PATCH 77/94] browser: Update ui-assets with new changes. --- browser/ui-assets.go | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/browser/ui-assets.go b/browser/ui-assets.go index 22f565cb6..c0f13d848 100644 --- a/browser/ui-assets.go +++ b/browser/ui-assets.go @@ -4,7 +4,7 @@ // production/favicon.ico // production/firefox.png // production/index.html -// production/index_bundle-2017-03-09T22-11-46Z.js +// production/index_bundle-2017-03-10T23-12-26Z.js // production/loader.css // production/logo.svg // production/safari.png @@ -65,7 +65,7 @@ func productionChromePng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -82,7 +82,7 @@ func productionFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -99,7 +99,7 @@ func productionFirefoxPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -156,8 +156,8 @@ var _productionIndexHTML = []byte(`
    - - + + `) @@ -172,21 +172,21 @@ func productionIndexHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _productionIndex_bundle20170309t221146zJs = []byte(`!function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){A.exports=t(240)},function(A,M,t){"use strict";A.exports=t(440)},function(A,M,t){"use strict";function I(A,M,t,I,g,e,i,T){if(!A){var E;if(void 0===M)E=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var N=[t,I,g,e,i,T],o=0;E=new Error(M.replace(/%s/g,function(){return N[o++]})),E.name="Invariant Violation"}throw E.framesToPop=1,E}}A.exports=I},function(A,M,t){"use strict";var I=t(20),g=I;A.exports=g},function(A,M){"use strict";function t(A,M){if(null==A)throw new TypeError("Object.assign target cannot be null or undefined");for(var t=Object(A),I=Object.prototype.hasOwnProperty,g=1;g2?t-2:0),g=2;g1){for(var c=Array(C),D=0;D1){for(var a=Array(D),B=0;B3&&void 0!==arguments[3]?arguments[3]:{},N=Boolean(A),C=A||w,D=void 0;D="function"==typeof M?M:M?(0,Q.default)(M):l;var B=t||L,r=I.pure,s=void 0===r||r,x=I.withRef,y=void 0!==x&&x,h=s&&B!==L,S=d++;return function(A){function M(A,M,t){var I=B(A,M,t);return I}var t="Connect("+T(A)+")",I=function(I){function T(A,M){g(this,T);var i=e(this,I.call(this,A,M));i.version=S,i.store=A.store||M.store,(0,u.default)(i.store,'Could not find "store" in either the context or '+('props of "'+t+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+t+'".'));var E=i.store.getState();return i.state={storeState:E},i.clearCache(),i}return i(T,I),T.prototype.shouldComponentUpdate=function(){return!s||this.haveOwnPropsChanged||this.hasStoreStateChanged},T.prototype.computeStateProps=function(A,M){if(!this.finalMapStateToProps)return this.configureFinalMapState(A,M);var t=A.getState(),I=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(t,M):this.finalMapStateToProps(t);return I},T.prototype.configureFinalMapState=function(A,M){var t=C(A.getState(),M),I="function"==typeof t;return this.finalMapStateToProps=I?t:C,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,I?this.computeStateProps(A,M):t},T.prototype.computeDispatchProps=function(A,M){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(A,M);var t=A.dispatch,I=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(t,M):this.finalMapDispatchToProps(t);return I},T.prototype.configureFinalMapDispatch=function(A,M){var t=D(A.dispatch,M),I="function"==typeof t;return this.finalMapDispatchToProps=I?t:D,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,I?this.computeDispatchProps(A,M):t},T.prototype.updateStatePropsIfNeeded=function(){var A=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,a.default)(A,this.stateProps))&&(this.stateProps=A,!0)},T.prototype.updateDispatchPropsIfNeeded=function(){var A=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,a.default)(A,this.dispatchProps))&&(this.dispatchProps=A,!0)},T.prototype.updateMergedPropsIfNeeded=function(){var A=M(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&h&&(0,a.default)(A,this.mergedProps))&&(this.mergedProps=A,!0)},T.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},T.prototype.trySubscribe=function(){N&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},T.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},T.prototype.componentDidMount=function(){this.trySubscribe()},T.prototype.componentWillReceiveProps=function(A){s&&(0,a.default)(A,this.props)||(this.haveOwnPropsChanged=!0)},T.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},T.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},T.prototype.handleChange=function(){if(this.unsubscribe){var A=this.store.getState(),M=this.state.storeState;if(!s||M!==A){if(s&&!this.doStatePropsDependOnOwnProps){var t=E(this.updateStatePropsIfNeeded,this);if(!t)return;t===Y&&(this.statePropsPrecalculationError=Y.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:A})}}},T.prototype.getWrappedInstance=function(){return(0,u.default)(y,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},T.prototype.render=function(){var M=this.haveOwnPropsChanged,t=this.hasStoreStateChanged,I=this.haveStatePropsBeenPrecalculated,g=this.statePropsPrecalculationError,e=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,g)throw g;var i=!0,T=!0;s&&e&&(i=t||M&&this.doStatePropsDependOnOwnProps,T=M&&this.doDispatchPropsDependOnOwnProps);var E=!1,N=!1;I?E=!0:i&&(E=this.updateStatePropsIfNeeded()),T&&(N=this.updateDispatchPropsIfNeeded());var C=!0;return C=!!(E||N||M)&&this.updateMergedPropsIfNeeded(),!C&&e?e:(y?this.renderedElement=(0,n.createElement)(A,o({},this.mergedProps,{ref:"wrappedInstance"})):this.renderedElement=(0,n.createElement)(A,this.mergedProps),this.renderedElement)},T}(n.Component);return I.displayName=t,I.WrappedComponent=A,I.contextTypes={store:c.default},I.propTypes={store:c.default},(0,j.default)(I,A)}}M.__esModule=!0;var o=Object.assign||function(A){for(var M=1;M should not have a "'+M+'" prop')}M.__esModule=!0,M.routes=M.route=M.components=M.component=M.history=void 0,M.falsy=I;var g=t(1),e=g.PropTypes.func,i=g.PropTypes.object,T=g.PropTypes.arrayOf,E=g.PropTypes.oneOfType,N=g.PropTypes.element,o=g.PropTypes.shape,n=g.PropTypes.string,C=(M.history=o({listen:e.isRequired,push:e.isRequired,replace:e.isRequired,go:e.isRequired,goBack:e.isRequired,goForward:e.isRequired}),M.component=E([e,n])),c=(M.components=E([C,i]),M.route=E([i,N]));M.routes=E([c,T(c)])},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){var M=A.match(/^https?:\/\/[^\/]*/);return null==M?A:A.substring(M[0].length)}function e(A){var M=g(A),t="",I="",e=M.indexOf("#");e!==-1&&(I=M.substring(e),M=M.substring(0,e));var i=M.indexOf("?");return i!==-1&&(t=M.substring(i),M=M.substring(0,i)),""===M&&(M="/"),{pathname:M,search:t,hash:I}}M.__esModule=!0,M.extractPath=g,M.parsePath=e;var i=t(23);I(i)},function(A,M,t){"use strict";function I(){g.attachRefs(this,this._currentElement)}var g=t(459),e={mountComponent:function(A,M,t,g){var e=A.mountComponent(M,t,g);return A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A),e},unmountComponent:function(A){g.detachRefs(A,A._currentElement),A.unmountComponent()},receiveComponent:function(A,M,t,e){var i=A._currentElement;if(M!==i||e!==A._context){var T=g.shouldUpdateRefs(i,M);T&&g.detachRefs(A,i),A.receiveComponent(M,t,e),T&&A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A)}},performUpdateIfNecessary:function(A,M){A.performUpdateIfNecessary(M)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t,I){this.dispatchConfig=A,this.dispatchMarker=M,this.nativeEvent=t;var g=this.constructor.Interface;for(var e in g)if(g.hasOwnProperty(e)){var T=g[e];T?this[e]=T(t):"target"===e?this.target=I:this[e]=t[e]}var E=null!=t.defaultPrevented?t.defaultPrevented:t.returnValue===!1;E?this.isDefaultPrevented=i.thatReturnsTrue:this.isDefaultPrevented=i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse}var g=t(31),e=t(4),i=t(20),T=(t(3),{type:null,target:null,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(A){return A.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null});e(I.prototype,{preventDefault:function(){this.defaultPrevented=!0;var A=this.nativeEvent;A&&(A.preventDefault?A.preventDefault():A.returnValue=!1,this.isDefaultPrevented=i.thatReturnsTrue)},stopPropagation:function(){var A=this.nativeEvent;A&&(A.stopPropagation?A.stopPropagation():A.cancelBubble=!0,this.isPropagationStopped=i.thatReturnsTrue)},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var A=this.constructor.Interface;for(var M in A)this[M]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),I.Interface=T,I.augmentClass=function(A,M){var t=this,I=Object.create(t.prototype);e(I,A.prototype),A.prototype=I,A.prototype.constructor=A,A.Interface=e({},t.Interface,M),A.augmentClass=t.augmentClass,g.addPoolingTo(A,g.fourArgumentPooler)},g.addPoolingTo(I,g.fourArgumentPooler),A.exports=I},function(A,M){"use strict";M.default=function(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t},M.__esModule=!0},function(A,M){"use strict";function t(A){return A&&A.ownerDocument||document}M.__esModule=!0,M.default=t,A.exports=M.default},function(A,M,t){"use strict";var I=t(32),g=function(){var A=I&&document.documentElement;return A&&A.contains?function(A,M){return A.contains(M)}:A&&A.compareDocumentPosition?function(A,M){return A===M||!!(16&A.compareDocumentPosition(M))}:function(A,M){if(M)do if(M===A)return!0;while(M=M.parentNode);return!1}}();A.exports=g},function(A,M){function t(A){return"number"==typeof A&&A>-1&&A%1==0&&A<=I}var I=9007199254740991;A.exports=t},function(A,M,t){(function(A){!function(M,t){A.exports=t()}(this,function(){"use strict";function M(){return aI.apply(null,arguments)}function t(A){aI=A}function I(A){return A instanceof Array||"[object Array]"===Object.prototype.toString.call(A)}function g(A){return null!=A&&"[object Object]"===Object.prototype.toString.call(A)}function e(A){var M;for(M in A)return!1;return!0}function i(A){return"number"==typeof A||"[object Number]"===Object.prototype.toString.call(A)}function T(A){return A instanceof Date||"[object Date]"===Object.prototype.toString.call(A)}function E(A,M){var t,I=[];for(t=0;t0)for(t in rI)I=rI[t],g=M[I],B(g)||(A[I]=g);return A}function r(A){Q(this,A),this._d=new Date(null!=A._d?A._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),sI===!1&&(sI=!0,M.updateOffset(this),sI=!1)}function s(A){return A instanceof r||null!=A&&null!=A._isAMomentObject}function x(A){return A<0?Math.ceil(A)||0:Math.floor(A)}function j(A){var M=+A,t=0;return 0!==M&&isFinite(M)&&(t=x(M)),t}function y(A,M,t){var I,g=Math.min(A.length,M.length),e=Math.abs(A.length-M.length),i=0;for(I=0;I0?"future":"past"];return L(t)?t(M):t.replace(/%s/i,M)}function F(A,M){var t=A.toLowerCase();SI[t]=SI[t+"s"]=SI[M]=A}function f(A){return"string"==typeof A?SI[A]||SI[A.toLowerCase()]:void 0}function k(A){var M,t,I={};for(t in A)N(A,t)&&(M=f(t),M&&(I[M]=A[t]));return I}function R(A,M){zI[A]=M}function J(A){var M=[];for(var t in A)M.push({unit:t,priority:zI[t]});return M.sort(function(A,M){return A.priority-M.priority}),M}function G(A,t){return function(I){return null!=I?(b(this,A,I),M.updateOffset(this,t),this):H(this,A)}}function H(A,M){return A.isValid()?A._d["get"+(A._isUTC?"UTC":"")+M]():NaN}function b(A,M,t){A.isValid()&&A._d["set"+(A._isUTC?"UTC":"")+M](t)}function v(A){return A=f(A),L(this[A])?this[A]():this}function X(A,M){if("object"==typeof A){A=k(A);for(var t=J(A),I=0;I=0;return(e?t?"+":"":"-")+Math.pow(10,Math.max(0,g)).toString().substr(1)+I}function V(A,M,t,I){var g=I;"string"==typeof I&&(g=function(){return this[I]()}),A&&(mI[A]=g),M&&(mI[M[0]]=function(){return W(g.apply(this,arguments),M[1],M[2])}),t&&(mI[t]=function(){return this.localeData().ordinal(g.apply(this,arguments),A)})}function P(A){return A.match(/\[[\s\S]/)?A.replace(/^\[|\]$/g,""):A.replace(/\\/g,"")}function Z(A){var M,t,I=A.match(pI);for(M=0,t=I.length;M=0&&UI.test(A);)A=A.replace(UI,t),UI.lastIndex=0,I-=1;return A}function _(A,M,t){$I[A]=L(M)?M:function(A,I){return A&&t?t:M}}function $(A,M){return N($I,A)?$I[A](M._strict,M._locale):new RegExp(AA(A))}function AA(A){return MA(A.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(A,M,t,I,g){return M||t||I||g}))}function MA(A){return A.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tA(A,M){var t,I=M;for("string"==typeof A&&(A=[A]),i(M)&&(I=function(A,t){t[M]=j(A)}),t=0;t=0&&isFinite(T.getFullYear())&&T.setFullYear(A),T}function xA(A){var M=new Date(Date.UTC.apply(null,arguments));return A<100&&A>=0&&isFinite(M.getUTCFullYear())&&M.setUTCFullYear(A),M}function jA(A,M,t){var I=7+M-t,g=(7+xA(A,0,I).getUTCDay()-M)%7;return-g+I-1}function yA(A,M,t,I,g){var e,i,T=(7+t-I)%7,E=jA(A,I,g),N=1+7*(M-1)+T+E;return N<=0?(e=A-1,i=BA(e)+N):N>BA(A)?(e=A+1,i=N-BA(A)):(e=A,i=N),{year:e,dayOfYear:i}}function uA(A,M,t){var I,g,e=jA(A.year(),M,t),i=Math.floor((A.dayOfYear()-e-1)/7)+1;return i<1?(g=A.year()-1,I=i+wA(g,M,t)):i>wA(A.year(),M,t)?(I=i-wA(A.year(),M,t),g=A.year()+1):(g=A.year(),I=i),{week:I,year:g}}function wA(A,M,t){var I=jA(A,M,t),g=jA(A+1,M,t);return(BA(A)-I+g)/7}function lA(A){return uA(A,this._week.dow,this._week.doy).week}function LA(){return this._week.dow}function YA(){return this._week.doy}function dA(A){var M=this.localeData().week(this);return null==A?M:this.add(7*(A-M),"d")}function hA(A){var M=uA(this,1,4).week;return null==A?M:this.add(7*(A-M),"d")}function SA(A,M){return"string"!=typeof A?A:isNaN(A)?(A=M.weekdaysParse(A),"number"==typeof A?A:null):parseInt(A,10)}function zA(A,M){return"string"==typeof A?M.weekdaysParse(A)%7||7:isNaN(A)?null:A}function pA(A,M){return A?I(this._weekdays)?this._weekdays[A.day()]:this._weekdays[this._weekdays.isFormat.test(M)?"format":"standalone"][A.day()]:this._weekdays}function UA(A){return A?this._weekdaysShort[A.day()]:this._weekdaysShort}function OA(A){return A?this._weekdaysMin[A.day()]:this._weekdaysMin}function mA(A,M,t){var I,g,e,i=A.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],I=0;I<7;++I)e=n([2e3,1]).day(I),this._minWeekdaysParse[I]=this.weekdaysMin(e,"").toLocaleLowerCase(),this._shortWeekdaysParse[I]=this.weekdaysShort(e,"").toLocaleLowerCase(),this._weekdaysParse[I]=this.weekdays(e,"").toLocaleLowerCase();return t?"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:null):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null):"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null)))}function FA(A,M,t){var I,g,e;if(this._weekdaysParseExact)return mA.call(this,A,M,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),I=0;I<7;I++){if(g=n([2e3,1]).day(I),t&&!this._fullWeekdaysParse[I]&&(this._fullWeekdaysParse[I]=new RegExp("^"+this.weekdays(g,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[I]=new RegExp("^"+this.weekdaysShort(g,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[I]=new RegExp("^"+this.weekdaysMin(g,"").replace(".",".?")+"$","i")),this._weekdaysParse[I]||(e="^"+this.weekdays(g,"")+"|^"+this.weekdaysShort(g,"")+"|^"+this.weekdaysMin(g,""),this._weekdaysParse[I]=new RegExp(e.replace(".",""),"i")),t&&"dddd"===M&&this._fullWeekdaysParse[I].test(A))return I;if(t&&"ddd"===M&&this._shortWeekdaysParse[I].test(A))return I;if(t&&"dd"===M&&this._minWeekdaysParse[I].test(A))return I;if(!t&&this._weekdaysParse[I].test(A))return I}}function fA(A){if(!this.isValid())return null!=A?this:NaN;var M=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=A?(A=SA(A,this.localeData()),this.add(A-M,"d")):M}function kA(A){if(!this.isValid())return null!=A?this:NaN;var M=(this.day()+7-this.localeData()._week.dow)%7;return null==A?M:this.add(A-M,"d")}function RA(A){if(!this.isValid())return null!=A?this:NaN;if(null!=A){var M=zA(A,this.localeData());return this.day(this.day()%7?M:M-7)}return this.day()||7}function JA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysStrictRegex:this._weekdaysRegex):(N(this,"_weekdaysRegex")||(this._weekdaysRegex=jg),this._weekdaysStrictRegex&&A?this._weekdaysStrictRegex:this._weekdaysRegex)}function GA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(N(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=yg),this._weekdaysShortStrictRegex&&A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function HA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(N(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ug),this._weekdaysMinStrictRegex&&A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function bA(){function A(A,M){return M.length-A.length}var M,t,I,g,e,i=[],T=[],E=[],N=[];for(M=0;M<7;M++)t=n([2e3,1]).day(M),I=this.weekdaysMin(t,""),g=this.weekdaysShort(t,""),e=this.weekdays(t,""),i.push(I),T.push(g),E.push(e),N.push(I),N.push(g),N.push(e);for(i.sort(A),T.sort(A),E.sort(A),N.sort(A),M=0;M<7;M++)T[M]=MA(T[M]),E[M]=MA(E[M]),N[M]=MA(N[M]);this._weekdaysRegex=new RegExp("^("+N.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+E.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+T.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function vA(){return this.hours()%12||12}function XA(){return this.hours()||24}function WA(A,M){V(A,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),M)})}function VA(A,M){return M._meridiemParse}function PA(A){return"p"===(A+"").toLowerCase().charAt(0)}function ZA(A,M,t){return A>11?t?"pm":"PM":t?"am":"AM"}function KA(A){return A?A.toLowerCase().replace("_","-"):A}function qA(A){for(var M,t,I,g,e=0;e0;){if(I=_A(g.slice(0,M).join("-")))return I;if(t&&t.length>=M&&y(g,t,!0)>=M-1)break;M--}e++}return null}function _A(M){var t=null;if(!dg[M]&&"undefined"!=typeof A&&A&&A.exports)try{t=wg._abbr,!function(){var A=new Error('Cannot find module "./locale"');throw A.code="MODULE_NOT_FOUND",A}(),$A(t)}catch(A){}return dg[M]}function $A(A,M){var t;return A&&(t=B(M)?tM(A):AM(A,M),t&&(wg=t)),wg._abbr}function AM(A,M){if(null!==M){var t=Yg;if(M.abbr=A,null!=dg[A])l("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),t=dg[A]._config;else if(null!=M.parentLocale){if(null==dg[M.parentLocale])return hg[M.parentLocale]||(hg[M.parentLocale]=[]),hg[M.parentLocale].push({name:A,config:M}),null;t=dg[M.parentLocale]._config}return dg[A]=new h(d(t,M)),hg[A]&&hg[A].forEach(function(A){AM(A.name,A.config)}),$A(A),dg[A]}return delete dg[A],null}function MM(A,M){if(null!=M){var t,I=Yg;null!=dg[A]&&(I=dg[A]._config),M=d(I,M),t=new h(M),t.parentLocale=dg[A],dg[A]=t,$A(A)}else null!=dg[A]&&(null!=dg[A].parentLocale?dg[A]=dg[A].parentLocale:null!=dg[A]&&delete dg[A]);return dg[A]}function tM(A){var M;if(A&&A._locale&&A._locale._abbr&&(A=A._locale._abbr),!A)return wg;if(!I(A)){if(M=_A(A))return M;A=[A]}return qA(A)}function IM(){return uI(dg)}function gM(A){var M,t=A._a;return t&&c(A).overflow===-2&&(M=t[tg]<0||t[tg]>11?tg:t[Ig]<1||t[Ig]>eA(t[Mg],t[tg])?Ig:t[gg]<0||t[gg]>24||24===t[gg]&&(0!==t[eg]||0!==t[ig]||0!==t[Tg])?gg:t[eg]<0||t[eg]>59?eg:t[ig]<0||t[ig]>59?ig:t[Tg]<0||t[Tg]>999?Tg:-1,c(A)._overflowDayOfYear&&(MIg)&&(M=Ig),c(A)._overflowWeeks&&M===-1&&(M=Eg),c(A)._overflowWeekday&&M===-1&&(M=Ng),c(A).overflow=M),A}function eM(A){var M,t,I,g,e,i,T=A._i,E=Sg.exec(T)||zg.exec(T);if(E){for(c(A).iso=!0,M=0,t=Ug.length;MBA(g)&&(c(A)._overflowDayOfYear=!0),t=xA(g,0,A._dayOfYear),A._a[tg]=t.getUTCMonth(),A._a[Ig]=t.getUTCDate()),M=0;M<3&&null==A._a[M];++M)A._a[M]=e[M]=I[M];for(;M<7;M++)A._a[M]=e[M]=null==A._a[M]?2===M?1:0:A._a[M];24===A._a[gg]&&0===A._a[eg]&&0===A._a[ig]&&0===A._a[Tg]&&(A._nextDay=!0,A._a[gg]=0),A._d=(A._useUTC?xA:sA).apply(null,e),null!=A._tzm&&A._d.setUTCMinutes(A._d.getUTCMinutes()-A._tzm),A._nextDay&&(A._a[gg]=24)}}function oM(A){var M,t,I,g,e,i,T,E;if(M=A._w,null!=M.GG||null!=M.W||null!=M.E)e=1,i=4,t=TM(M.GG,A._a[Mg],uA(sM(),1,4).year),I=TM(M.W,1),g=TM(M.E,1),(g<1||g>7)&&(E=!0);else{e=A._locale._week.dow,i=A._locale._week.doy;var N=uA(sM(),e,i);t=TM(M.gg,A._a[Mg],N.year),I=TM(M.w,N.week),null!=M.d?(g=M.d,(g<0||g>6)&&(E=!0)):null!=M.e?(g=M.e+e,(M.e<0||M.e>6)&&(E=!0)):g=e}I<1||I>wA(t,e,i)?c(A)._overflowWeeks=!0:null!=E?c(A)._overflowWeekday=!0:(T=yA(t,I,g,e,i),A._a[Mg]=T.year,A._dayOfYear=T.dayOfYear)}function nM(A){if(A._f===M.ISO_8601)return void eM(A);A._a=[],c(A).empty=!0;var t,I,g,e,i,T=""+A._i,E=T.length,N=0;for(g=q(A._f,A._locale).match(pI)||[],t=0;t0&&c(A).unusedInput.push(i),T=T.slice(T.indexOf(I)+I.length),N+=I.length),mI[e]?(I?c(A).empty=!1:c(A).unusedTokens.push(e),gA(e,I,A)):A._strict&&!I&&c(A).unusedTokens.push(e);c(A).charsLeftOver=E-N,T.length>0&&c(A).unusedInput.push(T),A._a[gg]<=12&&c(A).bigHour===!0&&A._a[gg]>0&&(c(A).bigHour=void 0),c(A).parsedDateParts=A._a.slice(0),c(A).meridiem=A._meridiem,A._a[gg]=CM(A._locale,A._a[gg],A._meridiem),NM(A),gM(A)}function CM(A,M,t){var I;return null==t?M:null!=A.meridiemHour?A.meridiemHour(M,t):null!=A.isPM?(I=A.isPM(t),I&&M<12&&(M+=12),I||12!==M||(M=0),M):M}function cM(A){var M,t,I,g,e;if(0===A._f.length)return c(A).invalidFormat=!0,void(A._d=new Date(NaN));for(g=0;gthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function fM(){if(!B(this._isDSTShifted))return this._isDSTShifted;var A={};if(Q(A,this),A=BM(A),A._a){var M=A._isUTC?n(A._a):sM(A._a);this._isDSTShifted=this.isValid()&&y(A._a,M.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function kM(){return!!this.isValid()&&!this._isUTC}function RM(){return!!this.isValid()&&this._isUTC}function JM(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function GM(A,M){var t,I,g,e=A,T=null;return wM(A)?e={ms:A._milliseconds,d:A._days,M:A._months}:i(A)?(e={},M?e[M]=A:e.milliseconds=A):(T=Jg.exec(A))?(t="-"===T[1]?-1:1,e={y:0,d:j(T[Ig])*t,h:j(T[gg])*t,m:j(T[eg])*t,s:j(T[ig])*t,ms:j(lM(1e3*T[Tg]))*t}):(T=Gg.exec(A))?(t="-"===T[1]?-1:1,e={y:HM(T[2],t),M:HM(T[3],t),w:HM(T[4],t),d:HM(T[5],t),h:HM(T[6],t),m:HM(T[7],t),s:HM(T[8],t)}):null==e?e={}:"object"==typeof e&&("from"in e||"to"in e)&&(g=vM(sM(e.from),sM(e.to)),e={},e.ms=g.milliseconds,e.M=g.months),I=new uM(e),wM(A)&&N(A,"_locale")&&(I._locale=A._locale),I}function HM(A,M){var t=A&&parseFloat(A.replace(",","."));return(isNaN(t)?0:t)*M}function bM(A,M){var t={milliseconds:0,months:0};return t.months=M.month()-A.month()+12*(M.year()-A.year()),A.clone().add(t.months,"M").isAfter(M)&&--t.months,t.milliseconds=+M-+A.clone().add(t.months,"M"),t}function vM(A,M){var t;return A.isValid()&&M.isValid()?(M=dM(M,A),A.isBefore(M)?t=bM(A,M):(t=bM(M,A),t.milliseconds=-t.milliseconds,t.months=-t.months),t):{milliseconds:0,months:0}}function XM(A,M){return function(t,I){var g,e;return null===I||isNaN(+I)||(l(M,"moment()."+M+"(period, number) is deprecated. Please use moment()."+M+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),e=t,t=I,I=e),t="string"==typeof t?+t:t,g=GM(t,I),WM(this,g,A),this}}function WM(A,t,I,g){var e=t._milliseconds,i=lM(t._days),T=lM(t._months);A.isValid()&&(g=null==g||g,e&&A._d.setTime(A._d.valueOf()+e*I),i&&b(A,"Date",H(A,"Date")+i*I),T&&oA(A,H(A,"Month")+T*I),g&&M.updateOffset(A,i||T))}function VM(A,M){var t=A.diff(M,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"}function PM(A,t){var I=A||sM(),g=dM(I,this).startOf("day"),e=M.calendarFormat(this,g)||"sameElse",i=t&&(L(t[e])?t[e].call(this,I):t[e]);return this.format(i||this.localeData().calendar(e,this,sM(I)))}function ZM(){return new r(this)}function KM(A,M){var t=s(A)?A:sM(A);return!(!this.isValid()||!t.isValid())&&(M=f(B(M)?"millisecond":M),"millisecond"===M?this.valueOf()>t.valueOf():t.valueOf()e&&(M=e),pt.call(this,A,M,t,I,g))}function pt(A,M,t,I,g){var e=yA(A,M,t,I,g),i=xA(e.year,0,e.dayOfYear);return this.year(i.getUTCFullYear()),this.month(i.getUTCMonth()),this.date(i.getUTCDate()),this}function Ut(A){return null==A?Math.ceil((this.month()+1)/3):this.month(3*(A-1)+this.month()%3)}function Ot(A){var M=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==A?M:this.add(A-M,"d")}function mt(A,M){M[Tg]=j(1e3*("0."+A))}function Ft(){return this._isUTC?"UTC":""}function ft(){return this._isUTC?"Coordinated Universal Time":""}function kt(A){return sM(1e3*A)}function Rt(){return sM.apply(null,arguments).parseZone()}function Jt(A){return A}function Gt(A,M,t,I){var g=tM(),e=n().set(I,M);return g[t](e,A)}function Ht(A,M,t){if(i(A)&&(M=A,A=void 0),A=A||"",null!=M)return Gt(A,M,t,"month");var I,g=[];for(I=0;I<12;I++)g[I]=Gt(A,I,t,"month");return g}function bt(A,M,t,I){"boolean"==typeof A?(i(M)&&(t=M,M=void 0),M=M||""):(M=A,t=M,A=!1,i(M)&&(t=M,M=void 0),M=M||"");var g=tM(),e=A?g._week.dow:0;if(null!=t)return Gt(M,(t+e)%7,I,"day");var T,E=[];for(T=0;T<7;T++)E[T]=Gt(M,(T+e)%7,I,"day");return E}function vt(A,M){return Ht(A,M,"months")}function Xt(A,M){return Ht(A,M,"monthsShort")}function Wt(A,M,t){return bt(A,M,t,"weekdays")}function Vt(A,M,t){return bt(A,M,t,"weekdaysShort")}function Pt(A,M,t){return bt(A,M,t,"weekdaysMin")}function Zt(){var A=this._data;return this._milliseconds=_g(this._milliseconds),this._days=_g(this._days),this._months=_g(this._months),A.milliseconds=_g(A.milliseconds),A.seconds=_g(A.seconds),A.minutes=_g(A.minutes),A.hours=_g(A.hours),A.months=_g(A.months),A.years=_g(A.years),this}function Kt(A,M,t,I){var g=GM(M,t);return A._milliseconds+=I*g._milliseconds,A._days+=I*g._days,A._months+=I*g._months,A._bubble()}function qt(A,M){return Kt(this,A,M,1)}function _t(A,M){return Kt(this,A,M,-1)}function $t(A){return A<0?Math.floor(A):Math.ceil(A)}function AI(){var A,M,t,I,g,e=this._milliseconds,i=this._days,T=this._months,E=this._data;return e>=0&&i>=0&&T>=0||e<=0&&i<=0&&T<=0||(e+=864e5*$t(tI(T)+i),i=0,T=0),E.milliseconds=e%1e3,A=x(e/1e3),E.seconds=A%60,M=x(A/60),E.minutes=M%60,t=x(M/60),E.hours=t%24,i+=x(t/24),g=x(MI(i)),T+=g,i-=$t(tI(g)),I=x(T/12),T%=12,E.days=i,E.months=T,E.years=I,this}function MI(A){return 4800*A/146097}function tI(A){return 146097*A/4800}function II(A){var M,t,I=this._milliseconds;if(A=f(A),"month"===A||"year"===A)return M=this._days+I/864e5,t=this._months+MI(M),"month"===A?t:t/12;switch(M=this._days+Math.round(tI(this._months)),A){case"week":return M/7+I/6048e5;case"day":return M+I/864e5;case"hour":return 24*M+I/36e5;case"minute":return 1440*M+I/6e4;case"second":return 86400*M+I/1e3;case"millisecond":return Math.floor(864e5*M)+I;default:throw new Error("Unknown unit "+A)}}function gI(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*j(this._months/12)}function eI(A){return function(){return this.as(A)}}function iI(A){return A=f(A),this[A+"s"]()}function TI(A){return function(){return this._data[A]}}function EI(){return x(this.days()/7)}function NI(A,M,t,I,g){return g.relativeTime(M||1,!!t,A,I)}function oI(A,M,t){var I=GM(A).abs(),g=De(I.as("s")),e=De(I.as("m")),i=De(I.as("h")),T=De(I.as("d")),E=De(I.as("M")),N=De(I.as("y")),o=g0,o[4]=t,NI.apply(null,o)}function nI(A){return void 0===A?De:"function"==typeof A&&(De=A,!0)}function CI(A,M){return void 0!==ae[A]&&(void 0===M?ae[A]:(ae[A]=M,!0))}function cI(A){var M=this.localeData(),t=oI(this,!A,M);return A&&(t=M.pastFuture(+this,t)),M.postformat(t)}function DI(){var A,M,t,I=Be(this._milliseconds)/1e3,g=Be(this._days),e=Be(this._months);A=x(I/60),M=x(A/60),I%=60,A%=60,t=x(e/12),e%=12;var i=t,T=e,E=g,N=M,o=A,n=I,C=this.asSeconds();return C?(C<0?"-":"")+"P"+(i?i+"Y":"")+(T?T+"M":"")+(E?E+"D":"")+(N||o||n?"T":"")+(N?N+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"}var aI,BI;BI=Array.prototype.some?Array.prototype.some:function(A){for(var M=Object(this),t=M.length>>>0,I=0;I68?1900:2e3)};var Bg=G("FullYear",!0);V("w",["ww",2],"wo","week"),V("W",["WW",2],"Wo","isoWeek"),F("week","w"),F("isoWeek","W"),R("week",5),R("isoWeek",5),_("w",GI),_("ww",GI,fI),_("W",GI),_("WW",GI,fI),IA(["w","ww","W","WW"],function(A,M,t,I){M[I.substr(0,1)]=j(A)});var Qg={dow:0,doy:6};V("d",0,"do","day"),V("dd",0,0,function(A){return this.localeData().weekdaysMin(this,A)}),V("ddd",0,0,function(A){return this.localeData().weekdaysShort(this,A)}),V("dddd",0,0,function(A){return this.localeData().weekdays(this,A)}),V("e",0,0,"weekday"),V("E",0,0,"isoWeekday"),F("day","d"),F("weekday","e"),F("isoWeekday","E"),R("day",11),R("weekday",11),R("isoWeekday",11),_("d",GI),_("e",GI),_("E",GI),_("dd",function(A,M){return M.weekdaysMinRegex(A)}),_("ddd",function(A,M){return M.weekdaysShortRegex(A)}),_("dddd",function(A,M){return M.weekdaysRegex(A)}),IA(["dd","ddd","dddd"],function(A,M,t,I){var g=t._locale.weekdaysParse(A,I,t._strict);null!=g?M.d=g:c(t).invalidWeekday=A}),IA(["d","e","E"],function(A,M,t,I){M[I]=j(A)});var rg="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),sg="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xg="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),jg=_I,yg=_I,ug=_I;V("H",["HH",2],0,"hour"),V("h",["hh",2],0,vA),V("k",["kk",2],0,XA),V("hmm",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)}),V("hmmss",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)+W(this.seconds(),2)}),V("Hmm",0,0,function(){return""+this.hours()+W(this.minutes(),2)}),V("Hmmss",0,0,function(){return""+this.hours()+W(this.minutes(),2)+W(this.seconds(),2)}),WA("a",!0),WA("A",!1),F("hour","h"),R("hour",13),_("a",VA),_("A",VA),_("H",GI),_("h",GI),_("HH",GI,fI),_("hh",GI,fI),_("hmm",HI),_("hmmss",bI),_("Hmm",HI),_("Hmmss",bI),tA(["H","HH"],gg),tA(["a","A"],function(A,M,t){t._isPm=t._locale.isPM(A),t._meridiem=A}),tA(["h","hh"],function(A,M,t){M[gg]=j(A),c(t).bigHour=!0}),tA("hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I)),c(t).bigHour=!0}),tA("hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g)),c(t).bigHour=!0}),tA("Hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I))}),tA("Hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g))});var wg,lg=/[ap]\.?m?\.?/i,Lg=G("Hours",!0),Yg={calendar:wI,longDateFormat:lI,invalidDate:LI,ordinal:YI,ordinalParse:dI,relativeTime:hI,months:Cg,monthsShort:cg,week:Qg,weekdays:rg,weekdaysMin:xg,weekdaysShort:sg,meridiemParse:lg},dg={},hg={},Sg=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,zg=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pg=/Z|[+-]\d\d(?::?\d\d)?/,Ug=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Og=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mg=/^\/?Date\((\-?\d+)/i;M.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(A){A._d=new Date(A._i+(A._useUTC?" UTC":""))}),M.ISO_8601=function(){};var Fg=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var A=sM.apply(null,arguments);return this.isValid()&&A.isValid()?Athis?this:A:a()}),kg=function(){return Date.now?Date.now():+new Date};LM("Z",":"),LM("ZZ",""),_("Z",KI),_("ZZ",KI),tA(["Z","ZZ"],function(A,M,t){t._useUTC=!0,t._tzm=YM(KI,A)});var Rg=/([\+\-]|\d\d)/gi;M.updateOffset=function(){};var Jg=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Gg=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;GM.fn=uM.prototype;var Hg=XM(1,"add"),bg=XM(-1,"subtract");M.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",M.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var vg=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(A){return void 0===A?this.localeData():this.locale(A)});V(0,["gg",2],0,function(){return this.weekYear()%100}),V(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Lt("gggg","weekYear"),Lt("ggggg","weekYear"),Lt("GGGG","isoWeekYear"),Lt("GGGGG","isoWeekYear"),F("weekYear","gg"),F("isoWeekYear","GG"),R("weekYear",1),R("isoWeekYear",1),_("G",PI),_("g",PI),_("GG",GI,fI),_("gg",GI,fI),_("GGGG",XI,RI),_("gggg",XI,RI),_("GGGGG",WI,JI),_("ggggg",WI,JI),IA(["gggg","ggggg","GGGG","GGGGG"],function(A,M,t,I){M[I.substr(0,2)]=j(A)}),IA(["gg","GG"],function(A,t,I,g){t[g]=M.parseTwoDigitYear(A)}),V("Q",0,"Qo","quarter"),F("quarter","Q"),R("quarter",7),_("Q",FI),tA("Q",function(A,M){M[tg]=3*(j(A)-1)}),V("D",["DD",2],"Do","date"),F("date","D"),R("date",9),_("D",GI),_("DD",GI,fI),_("Do",function(A,M){return A?M._ordinalParse:M._ordinalParseLenient}),tA(["D","DD"],Ig),tA("Do",function(A,M){M[Ig]=j(A.match(GI)[0],10)});var Xg=G("Date",!0);V("DDD",["DDDD",3],"DDDo","dayOfYear"),F("dayOfYear","DDD"),R("dayOfYear",4),_("DDD",vI),_("DDDD",kI),tA(["DDD","DDDD"],function(A,M,t){t._dayOfYear=j(A)}),V("m",["mm",2],0,"minute"),F("minute","m"),R("minute",14),_("m",GI),_("mm",GI,fI),tA(["m","mm"],eg);var Wg=G("Minutes",!1);V("s",["ss",2],0,"second"),F("second","s"),R("second",15),_("s",GI),_("ss",GI,fI),tA(["s","ss"],ig);var Vg=G("Seconds",!1);V("S",0,0,function(){return~~(this.millisecond()/100)}),V(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),V(0,["SSS",3],0,"millisecond"),V(0,["SSSS",4],0,function(){return 10*this.millisecond()}),V(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),V(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),V(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),V(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),V(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),F("millisecond","ms"),R("millisecond",16),_("S",vI,FI),_("SS",vI,fI),_("SSS",vI,kI);var Pg;for(Pg="SSSS";Pg.length<=9;Pg+="S")_(Pg,VI);for(Pg="S";Pg.length<=9;Pg+="S")tA(Pg,mt);var Zg=G("Milliseconds",!1);V("z",0,0,"zoneAbbr"),V("zz",0,0,"zoneName");var Kg=r.prototype;Kg.add=Hg,Kg.calendar=PM,Kg.clone=ZM,Kg.diff=tt,Kg.endOf=at,Kg.format=Tt,Kg.from=Et,Kg.fromNow=Nt,Kg.to=ot,Kg.toNow=nt,Kg.get=v,Kg.invalidAt=wt,Kg.isAfter=KM,Kg.isBefore=qM,Kg.isBetween=_M,Kg.isSame=$M,Kg.isSameOrAfter=At,Kg.isSameOrBefore=Mt,Kg.isValid=yt,Kg.lang=vg,Kg.locale=Ct,Kg.localeData=ct,Kg.max=fg,Kg.min=Fg,Kg.parsingFlags=ut,Kg.set=X,Kg.startOf=Dt,Kg.subtract=bg,Kg.toArray=st,Kg.toObject=xt,Kg.toDate=rt,Kg.toISOString=et,Kg.inspect=it,Kg.toJSON=jt,Kg.toString=gt,Kg.unix=Qt,Kg.valueOf=Bt,Kg.creationData=lt,Kg.year=Bg,Kg.isLeapYear=rA,Kg.weekYear=Yt,Kg.isoWeekYear=dt,Kg.quarter=Kg.quarters=Ut,Kg.month=nA,Kg.daysInMonth=CA,Kg.week=Kg.weeks=dA,Kg.isoWeek=Kg.isoWeeks=hA,Kg.weeksInYear=St,Kg.isoWeeksInYear=ht,Kg.date=Xg,Kg.day=Kg.days=fA,Kg.weekday=kA,Kg.isoWeekday=RA,Kg.dayOfYear=Ot,Kg.hour=Kg.hours=Lg,Kg.minute=Kg.minutes=Wg,Kg.second=Kg.seconds=Vg,Kg.millisecond=Kg.milliseconds=Zg,Kg.utcOffset=SM,Kg.utc=pM,Kg.local=UM,Kg.parseZone=OM,Kg.hasAlignedHourOffset=mM,Kg.isDST=FM,Kg.isLocal=kM,Kg.isUtcOffset=RM,Kg.isUtc=JM,Kg.isUTC=JM,Kg.zoneAbbr=Ft,Kg.zoneName=ft,Kg.dates=w("dates accessor is deprecated. Use date instead.",Xg),Kg.months=w("months accessor is deprecated. Use month instead",nA),Kg.years=w("years accessor is deprecated. Use year instead",Bg),Kg.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",zM),Kg.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",fM);var qg=h.prototype;qg.calendar=S,qg.longDateFormat=z,qg.invalidDate=p,qg.ordinal=U,qg.preparse=Jt,qg.postformat=Jt,qg.relativeTime=O,qg.pastFuture=m,qg.set=Y,qg.months=iA,qg.monthsShort=TA,qg.monthsParse=NA,qg.monthsRegex=DA,qg.monthsShortRegex=cA,qg.week=lA,qg.firstDayOfYear=YA,qg.firstDayOfWeek=LA,qg.weekdays=pA,qg.weekdaysMin=OA,qg.weekdaysShort=UA,qg.weekdaysParse=FA,qg.weekdaysRegex=JA,qg.weekdaysShortRegex=GA,qg.weekdaysMinRegex=HA,qg.isPM=PA,qg.meridiem=ZA,$A("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(A){var M=A%10,t=1===j(A%100/10)?"th":1===M?"st":2===M?"nd":3===M?"rd":"th";return A+t}}),M.lang=w("moment.lang is deprecated. Use moment.locale instead.",$A),M.langData=w("moment.langData is deprecated. Use moment.localeData instead.",tM);var _g=Math.abs,$g=eI("ms"),Ae=eI("s"),Me=eI("m"),te=eI("h"),Ie=eI("d"),ge=eI("w"),ee=eI("M"),ie=eI("y"),Te=TI("milliseconds"),Ee=TI("seconds"),Ne=TI("minutes"),oe=TI("hours"),ne=TI("days"),Ce=TI("months"),ce=TI("years"),De=Math.round,ae={s:45,m:45,h:22,d:26,M:11},Be=Math.abs,Qe=uM.prototype;return Qe.abs=Zt,Qe.add=qt,Qe.subtract=_t,Qe.as=II,Qe.asMilliseconds=$g,Qe.asSeconds=Ae,Qe.asMinutes=Me,Qe.asHours=te,Qe.asDays=Ie,Qe.asWeeks=ge,Qe.asMonths=ee,Qe.asYears=ie,Qe.valueOf=gI,Qe._bubble=AI,Qe.get=iI,Qe.milliseconds=Te,Qe.seconds=Ee,Qe.minutes=Ne,Qe.hours=oe,Qe.days=ne,Qe.weeks=EI,Qe.months=Ce,Qe.years=ce,Qe.humanize=cI,Qe.toISOString=DI,Qe.toString=DI,Qe.toJSON=DI,Qe.locale=Ct,Qe.localeData=ct,Qe.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",DI),Qe.lang=vg,V("X",0,0,"unix"),V("x",0,0,"valueOf"),_("x",PI),_("X",qI),tA("X",function(A,M,t){t._d=new Date(1e3*parseFloat(A,10))}),tA("x",function(A,M,t){t._d=new Date(j(A))}),M.version="2.17.1",t(sM),M.fn=Kg,M.min=jM,M.max=yM,M.now=kg,M.utc=n,M.unix=kt,M.months=vt,M.isDate=T,M.locale=$A,M.invalid=a,M.duration=GM,M.isMoment=s,M.weekdays=Wt,M.parseZone=Rt,M.localeData=tM,M.isDuration=wM,M.monthsShort=Xt,M.weekdaysMin=Pt,M.defineLocale=AM,M.updateLocale=MM,M.locales=IM,M.weekdaysShort=Vt,M.normalizeUnits=f,M.relativeTimeRounding=nI,M.relativeTimeThreshold=CI,M.calendarFormat=VM,M.prototype=Kg,M})}).call(M,t(128)(A))},function(A,M,t){"use strict";var I=t(132).default,g=t(133).default,e=t(78).default;M.__esModule=!0;var i=function(A){return I(g({values:function(){var A=this;return e(this).map(function(M){return A[M]})}}),A)},T={SIZES:{large:"lg",medium:"md",small:"sm",xsmall:"xs",lg:"lg",md:"md",sm:"sm",xs:"xs"},GRID_COLUMNS:12},E=i({LARGE:"large",MEDIUM:"medium",SMALL:"small",XSMALL:"xsmall"});M.Sizes=E;var N=i({SUCCESS:"success",WARNING:"warning",DANGER:"danger",INFO:"info"});M.State=N;var o="default";M.DEFAULT=o;var n="primary";M.PRIMARY=n;var C="link";M.LINK=C;var c="inverse";M.INVERSE=c,M.default=T},function(A,M){"use strict";function t(){for(var A=arguments.length,M=Array(A),t=0;t0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURI(o))):"("===E?g+=1:")"===E?g-=1:":"===E.charAt(0)?(N=E.substring(1),o=M[N],null!=o||g>0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURIComponent(o))):e+=E;return e.replace(/\/+/g,"/")}M.__esModule=!0,M.compilePattern=i,M.matchPattern=T,M.getParamNames=E,M.getParams=N,M.formatPattern=o;var n=t(8),C=I(n),c=Object.create(null)},function(A,M){"use strict";M.__esModule=!0;var t="PUSH";M.PUSH=t;var I="REPLACE";M.REPLACE=I;var g="POP";M.POP=g,M.default={PUSH:t,REPLACE:I,POP:g}},function(A,M,t){"use strict";function I(A,M){return(A&M)===M}var g=t(2),e={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(A){var M=e,t=A.Properties||{},i=A.DOMAttributeNamespaces||{},E=A.DOMAttributeNames||{},N=A.DOMPropertyNames||{},o=A.DOMMutationMethods||{};A.isCustomAttribute&&T._isCustomAttributeFunctions.push(A.isCustomAttribute);for(var n in t){T.properties.hasOwnProperty(n)?g(!1):void 0;var C=n.toLowerCase(),c=t[n],D={attributeName:C,attributeNamespace:null,propertyName:n,mutationMethod:null,mustUseAttribute:I(c,M.MUST_USE_ATTRIBUTE),mustUseProperty:I(c,M.MUST_USE_PROPERTY),hasSideEffects:I(c,M.HAS_SIDE_EFFECTS),hasBooleanValue:I(c,M.HAS_BOOLEAN_VALUE),hasNumericValue:I(c,M.HAS_NUMERIC_VALUE),hasPositiveNumericValue:I(c,M.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:I(c,M.HAS_OVERLOADED_BOOLEAN_VALUE)};if(D.mustUseAttribute&&D.mustUseProperty?g(!1):void 0,!D.mustUseProperty&&D.hasSideEffects?g(!1):void 0,D.hasBooleanValue+D.hasNumericValue+D.hasOverloadedBooleanValue<=1?void 0:g(!1),E.hasOwnProperty(n)){var a=E[n];D.attributeName=a}i.hasOwnProperty(n)&&(D.attributeNamespace=i[n]),N.hasOwnProperty(n)&&(D.propertyName=N[n]),o.hasOwnProperty(n)&&(D.mutationMethod=o[n]),T.properties[n]=D}}},i={},T={ID_ATTRIBUTE_NAME:"data-reactid",properties:{},getPossibleStandardName:null,_isCustomAttributeFunctions:[],isCustomAttribute:function(A){for(var M=0;M1){var M=A.indexOf(c,1);return M>-1?A.substr(0,M):A}return null},traverseEnterLeave:function(A,M,t,I,g){var e=N(A,M);e!==A&&o(A,e,t,I,!1,!0),e!==M&&o(e,M,t,g,!0,!1)},traverseTwoPhase:function(A,M,t){A&&(o("",A,M,t,!0,!1),o(A,"",M,t,!1,!0))},traverseTwoPhaseSkipTarget:function(A,M,t){A&&(o("",A,M,t,!0,!0),o(A,"",M,t,!0,!0))},traverseAncestors:function(A,M,t){o("",A,M,t,!0,!1)},getFirstCommonAncestorID:N,_getNextDescendantID:E,isAncestorIDOf:i,SEPARATOR:c};A.exports=B},function(A,M){var t=A.exports={version:"1.2.6"};"number"==typeof __e&&(__e=t)},function(A,M,t){"use strict";var I={};A.exports=I},function(A,M,t){"use strict";function I(A,M,t){var I=0;return n.default.Children.map(A,function(A){if(n.default.isValidElement(A)){var g=I;return I++,M.call(t,A,g)}return A})}function g(A,M,t){var I=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I),I++)})}function e(A){var M=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&M++}),M}function i(A){var M=!1;return n.default.Children.forEach(A,function(A){!M&&n.default.isValidElement(A)&&(M=!0)}),M}function T(A,M){var t=void 0;return g(A,function(I,g){!t&&M(I,g,A)&&(t=I)}),t}function E(A,M,t){var I=0,g=[];return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I)&&g.push(A),I++)}),g}var N=t(6).default;M.__esModule=!0;var o=t(1),n=N(o);M.default={map:I,forEach:g,numberOf:e,find:T,findValidComponents:E,hasValidComponent:i},A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=function(A){return(0,T.default)(e.default.findDOMNode(A))};var g=t(16),e=I(g),i=t(39),T=I(i);A.exports=M.default},function(A,M,t){"use strict";var I=t(204),g=t(437),e=t(217),i=t(226),T=t(227),E=t(2),N=(t(3),{}),o=null,n=function(A,M){A&&(g.executeDispatchesInOrder(A,M),A.isPersistent()||A.constructor.release(A))},C=function(A){return n(A,!0)},c=function(A){return n(A,!1)},D=null,a={injection:{injectMount:g.injection.injectMount,injectInstanceHandle:function(A){D=A},getInstanceHandle:function(){return D},injectEventPluginOrder:I.injectEventPluginOrder,injectEventPluginsByName:I.injectEventPluginsByName},eventNameDispatchConfigs:I.eventNameDispatchConfigs,registrationNameModules:I.registrationNameModules,putListener:function(A,M,t){"function"!=typeof t?E(!1):void 0;var g=N[M]||(N[M]={});g[A]=t;var e=I.registrationNameModules[M];e&&e.didPutListener&&e.didPutListener(A,M,t)},getListener:function(A,M){var t=N[M];return t&&t[A]},deleteListener:function(A,M){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M);var g=N[M];g&&delete g[A]},deleteAllListeners:function(A){for(var M in N)if(N[M][A]){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M),delete N[M][A]}},extractEvents:function(A,M,t,g,e){for(var T,E=I.plugins,N=0;N1?I-1:0),e=1;e":">","<":"<",'"':""","'":"'"},e=/[&><"']/g;A.exports=I},function(A,M,t){"use strict";var I=t(10),g=/^[ \r\n\t\f]/,e=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(A,M){A.innerHTML=M};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(A,M){MSApp.execUnsafeLocalFunction(function(){A.innerHTML=M})}),I.canUseDOM){var T=document.createElement("div");T.innerHTML=" ",""===T.innerHTML&&(i=function(A,M){if(A.parentNode&&A.parentNode.replaceChild(A,A),g.test(M)||"<"===M[0]&&e.test(M)){A.innerHTML=String.fromCharCode(65279)+M;var t=A.firstChild;1===t.data.length?A.removeChild(t):t.deleteData(0,1)}else A.innerHTML=M})}A.exports=i},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=function(A){var M=A.label,t=A.id,I=A.name,g=A.value,i=A.onChange,T=A.type,E=A.spellCheck,N=A.required,o=A.readonly,n=A.autoComplete,C=A.align,c=A.className,D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n});return o&&(D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n,disabled:!0})),e.default.createElement("div",{className:"input-group "+C+" "+c},D,e.default.createElement("i",{className:"ig-helpers"}),e.default.createElement("label",{className:"ig-label"},M))};M.default=i},function(A,M,t){A.exports={default:t(259),__esModule:!0}},function(A,M,t){var I=t(265),g=t(49),e=t(134),i="prototype",T=function(A,M,t){var E,N,o,n=A&T.F,C=A&T.G,c=A&T.S,D=A&T.P,a=A&T.B,B=A&T.W,Q=C?g:g[M]||(g[M]={}),r=C?I:c?I[M]:(I[M]||{})[i];C&&(t=M);for(E in t)N=!n&&r&&E in r,N&&E in Q||(o=N?r[E]:t[E],Q[E]=C&&"function"!=typeof r[E]?t[E]:a&&N?e(o,I):B&&r[E]==o?function(A){var M=function(M){return this instanceof A?new A(M):A(M)};return M[i]=A[i],M}(o):D&&"function"==typeof o?e(Function.call,o):o,D&&((Q[i]||(Q[i]={}))[E]=o))};T.F=1,T.G=2,T.S=4,T.P=8,T.B=16,T.W=32,A.exports=T},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M,t){"use strict";var I=t(32),g=function(){};I&&(g=function(){return document.addEventListener?function(A,M,t,I){return A.addEventListener(M,t,I||!1)}:document.attachEvent?function(A,M,t){return A.attachEvent("on"+M,t)}:void 0}()),A.exports=g},function(A,M,t){"use strict";var I=t(145),g=t(295),e=t(290),i=t(291),T=Object.prototype.hasOwnProperty;A.exports=function(A,M,t){var E="",N=M;if("string"==typeof M){if(void 0===t)return A.style[I(M)]||e(A).getPropertyValue(g(M));(N={})[M]=t}for(var o in N)T.call(N,o)&&(N[o]||0===N[o]?E+=g(o)+":"+N[o]+";":i(A,g(o)));A.style.cssText+=";"+E}},function(A,M,t){(function(){var t=this,I=t.humanize,g={};"undefined"!=typeof A&&A.exports&&(M=A.exports=g),M.humanize=g,g.noConflict=function(){return t.humanize=I,this},g.pad=function(A,M,t,I){if(A+="",t?t.length>1&&(t=t.charAt(0)):t=" ",I=void 0===I?"left":"right","right"===I)for(;A.length4&&A<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th"},w:function(){return t.getDay()},z:function(){return(o.L()?i[o.n()]:e[o.n()])+o.j()-1},W:function(){var A=o.z()-o.N()+1.5;return g.pad(1+Math.floor(Math.abs(A)/7)+(A%7>3.5?1:0),2,"0")},F:function(){return N[t.getMonth()]},m:function(){return g.pad(o.n(),2,"0")},M:function(){return o.F().slice(0,3)},n:function(){return t.getMonth()+1},t:function(){return new Date(o.Y(),o.n(),0).getDate()},L:function(){return 1===new Date(o.Y(),1,29).getMonth()?1:0},o:function(){var A=o.n(),M=o.W();return o.Y()+(12===A&&M<9?-1:1===A&&M>9)},Y:function(){return t.getFullYear()},y:function(){return String(o.Y()).slice(-2)},a:function(){return t.getHours()>11?"pm":"am"},A:function(){return o.a().toUpperCase()},B:function(){var A=t.getTime()/1e3,M=A%86400+3600;M<0&&(M+=86400);var I=M/86.4%1e3;return A<0?Math.ceil(I):Math.floor(I)},g:function(){return o.G()%12||12},G:function(){return t.getHours()},h:function(){return g.pad(o.g(),2,"0")},H:function(){return g.pad(o.G(),2,"0")},i:function(){return g.pad(t.getMinutes(),2,"0")},s:function(){return g.pad(t.getSeconds(),2,"0")},u:function(){return g.pad(1e3*t.getMilliseconds(),6,"0")},O:function(){var A=t.getTimezoneOffset(),M=Math.abs(A);return(A>0?"-":"+")+g.pad(100*Math.floor(M/60)+M%60,4,"0")},P:function(){var A=o.O();return A.substr(0,3)+":"+A.substr(3,2)},Z:function(){return 60*-t.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(I,T)},r:function(){return"D, d M Y H:i:s O".replace(I,T)},U:function(){return t.getTime()/1e3||0}};return A.replace(I,T)},g.numberFormat=function(A,M,t,I){M=isNaN(M)?2:Math.abs(M),t=void 0===t?".":t,I=void 0===I?",":I;var g=A<0?"-":"";A=Math.abs(+A||0);var e=parseInt(A.toFixed(M),10)+"",i=e.length>3?e.length%3:0;return g+(i?e.substr(0,i)+I:"")+e.substr(i).replace(/(\d{3})(?=\d)/g,"$1"+I)+(M?t+Math.abs(A-e).toFixed(M).slice(2):"")},g.naturalDay=function(A,M){A=void 0===A?g.time():A,M=void 0===M?"Y-m-d":M;var t=86400,I=new Date,e=new Date(I.getFullYear(),I.getMonth(),I.getDate()).getTime()/1e3;return A=e-t?"yesterday":A>=e&&A=e+t&&A-2)return(t>=0?"just ":"")+"now";if(t<60&&t>-60)return t>=0?Math.floor(t)+" seconds ago":"in "+Math.floor(-t)+" seconds";if(t<120&&t>-120)return t>=0?"about a minute ago":"in about a minute";if(t<3600&&t>-3600)return t>=0?Math.floor(t/60)+" minutes ago":"in "+Math.floor(-t/60)+" minutes";if(t<7200&&t>-7200)return t>=0?"about an hour ago":"in about an hour";if(t<86400&&t>-86400)return t>=0?Math.floor(t/3600)+" hours ago":"in "+Math.floor(-t/3600)+" hours";var I=172800;if(t-I)return t>=0?"1 day ago":"in 1 day";var e=2505600;if(t-e)return t>=0?Math.floor(t/86400)+" days ago":"in "+Math.floor(-t/86400)+" days";var i=5184e3;if(t-i)return t>=0?"about a month ago":"in about a month";var T=parseInt(g.date("Y",M),10),E=parseInt(g.date("Y",A),10),N=12*T+parseInt(g.date("n",M),10),o=12*E+parseInt(g.date("n",A),10),n=N-o;if(n<12&&n>-12)return n>=0?n+" months ago":"in "+-n+" months";var C=T-E;return C<2&&C>-2?C>=0?"a year ago":"in a year":C>=0?C+" years ago":"in "+-C+" years"},g.ordinal=function(A){A=parseInt(A,10),A=isNaN(A)?0:A;var M=A<0?"-":"";A=Math.abs(A);var t=A%100;return M+A+(t>4&&t<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th")},g.filesize=function(A,M,t,I,e,i){return M=void 0===M?1024:M,A<=0?"0 bytes":(A

    "),A=A.replace(/\n/g,"
    "),"

    "+A+"

    "},g.nl2br=function(A){return A.replace(/(\r\n|\n|\r)/g,"
    ")},g.truncatechars=function(A,M){return A.length<=M?A:A.substr(0,M)+"…"},g.truncatewords=function(A,M){var t=A.split(" ");return t.length0,Q=C.enumErrorProps&&(A===u||A instanceof Error),r=C.enumPrototypes&&T(A);++IM.documentElement.clientHeight;return{modalStyles:{paddingRight:I&&!g?Q.default():void 0,paddingLeft:!I&&g?Q.default():void 0}}}});v.Body=z.default,v.Header=U.default, -v.Title=m.default,v.Footer=f.default,v.Dialog=h.default,v.TRANSITION_DURATION=300,v.BACKDROP_TRANSITION_DURATION=150,M.default=c.bsSizes([a.Sizes.LARGE,a.Sizes.SMALL],c.bsClass("modal",v)),A.exports=M.default},function(A,M,t){"use strict";var I=t(15).default,g=t(14).default,e=t(38).default,i=t(7).default,T=t(6).default;M.__esModule=!0;var E=t(1),N=T(E),o=t(5),n=T(o),C=t(11),c=T(C),D=t(44),a=T(D),B=function(A){function M(){g(this,M),A.apply(this,arguments)}return I(M,A),M.prototype.render=function(){var A=this.props,M=A["aria-label"],t=e(A,["aria-label"]),I=a.default(this.context.$bs_onModalHide,this.props.onHide);return N.default.createElement("div",i({},t,{className:n.default(this.props.className,c.default.prefix(this.props,"header"))}),this.props.closeButton&&N.default.createElement("button",{type:"button",className:"close","aria-label":M,onClick:I},N.default.createElement("span",{"aria-hidden":"true"},"×")),this.props.children)},M}(N.default.Component);B.propTypes={"aria-label":N.default.PropTypes.string,bsClass:N.default.PropTypes.string,closeButton:N.default.PropTypes.bool,onHide:N.default.PropTypes.func},B.contextTypes={$bs_onModalHide:N.default.PropTypes.func},B.defaultProps={"aria-label":"Close",closeButton:!1},M.default=C.bsClass("modal",B),A.exports=M.default},function(A,M,t){"use strict";function I(A,M){return Array.isArray(M)?M.indexOf(A)>=0:A===M}var g=t(7).default,e=t(78).default,i=t(6).default;M.__esModule=!0;var T=t(40),E=i(T),N=t(170),o=i(N),n=t(1),C=i(n),c=t(16),D=i(c),a=t(127),B=(i(a),t(370)),Q=i(B),r=t(44),s=i(r),x=C.default.createClass({displayName:"OverlayTrigger",propTypes:g({},Q.default.propTypes,{trigger:C.default.PropTypes.oneOfType([C.default.PropTypes.oneOf(["click","hover","focus"]),C.default.PropTypes.arrayOf(C.default.PropTypes.oneOf(["click","hover","focus"]))]),delay:C.default.PropTypes.number,delayShow:C.default.PropTypes.number,delayHide:C.default.PropTypes.number,defaultOverlayShown:C.default.PropTypes.bool,overlay:C.default.PropTypes.node.isRequired,onBlur:C.default.PropTypes.func,onClick:C.default.PropTypes.func,onFocus:C.default.PropTypes.func,onMouseEnter:C.default.PropTypes.func,onMouseLeave:C.default.PropTypes.func,target:function(){},onHide:function(){},show:function(){}}),getDefaultProps:function(){return{defaultOverlayShown:!1,trigger:["hover","focus"]}},getInitialState:function(){return{isOverlayShown:this.props.defaultOverlayShown}},show:function(){this.setState({isOverlayShown:!0})},hide:function(){this.setState({isOverlayShown:!1})},toggle:function(){this.state.isOverlayShown?this.hide():this.show()},componentWillMount:function(){this.handleMouseOver=this.handleMouseOverOut.bind(null,this.handleDelayedShow),this.handleMouseOut=this.handleMouseOverOut.bind(null,this.handleDelayedHide)},componentDidMount:function(){this._mountNode=document.createElement("div"),this.renderOverlay()},renderOverlay:function(){D.default.unstable_renderSubtreeIntoContainer(this,this._overlay,this._mountNode)},componentWillUnmount:function(){D.default.unmountComponentAtNode(this._mountNode),this._mountNode=null,clearTimeout(this._hoverShowDelay),clearTimeout(this._hoverHideDelay)},componentDidUpdate:function(){this._mountNode&&this.renderOverlay()},getOverlayTarget:function(){return D.default.findDOMNode(this)},getOverlay:function(){var A=g({},o.default(this.props,e(Q.default.propTypes)),{show:this.state.isOverlayShown,onHide:this.hide,target:this.getOverlayTarget,onExit:this.props.onExit,onExiting:this.props.onExiting,onExited:this.props.onExited,onEnter:this.props.onEnter,onEntering:this.props.onEntering,onEntered:this.props.onEntered}),M=n.cloneElement(this.props.overlay,{placement:A.placement,container:A.container});return C.default.createElement(Q.default,A,M)},render:function(){var A=C.default.Children.only(this.props.children),M=A.props,t={"aria-describedby":this.props.overlay.props.id};return this._overlay=this.getOverlay(),t.onClick=s.default(M.onClick,this.props.onClick),I("click",this.props.trigger)&&(t.onClick=s.default(this.toggle,t.onClick)),I("hover",this.props.trigger)&&(t.onMouseOver=s.default(this.handleMouseOver,this.props.onMouseOver,M.onMouseOver),t.onMouseOut=s.default(this.handleMouseOut,this.props.onMouseOut,M.onMouseOut)),I("focus",this.props.trigger)&&(t.onFocus=s.default(this.handleDelayedShow,this.props.onFocus,M.onFocus),t.onBlur=s.default(this.handleDelayedHide,this.props.onBlur,M.onBlur)),n.cloneElement(A,t)},handleDelayedShow:function(){var A=this;if(null!=this._hoverHideDelay)return clearTimeout(this._hoverHideDelay),void(this._hoverHideDelay=null);if(!this.state.isOverlayShown&&null==this._hoverShowDelay){var M=null!=this.props.delayShow?this.props.delayShow:this.props.delay;return M?void(this._hoverShowDelay=setTimeout(function(){A._hoverShowDelay=null,A.show()},M)):void this.show()}},handleDelayedHide:function(){var A=this;if(null!=this._hoverShowDelay)return clearTimeout(this._hoverShowDelay),void(this._hoverShowDelay=null);if(this.state.isOverlayShown&&null==this._hoverHideDelay){var M=null!=this.props.delayHide?this.props.delayHide:this.props.delay;return M?void(this._hoverHideDelay=setTimeout(function(){A._hoverHideDelay=null,A.hide()},M)):void this.hide()}},handleMouseOverOut:function(A,M){var t=M.currentTarget,I=M.relatedTarget||M.nativeEvent.toElement;I&&(I===t||E.default(t,I))||A(M)}});M.default=x,A.exports=M.default},function(A,M,t){"use strict";var I=t(7).default,g=t(6).default;M.__esModule=!0;var e=t(1),i=g(e),T=t(5),E=g(T),N=t(11),o=g(N),n=t(183),C=g(n),c=i.default.createClass({displayName:"Tooltip",propTypes:{id:C.default(i.default.PropTypes.oneOfType([i.default.PropTypes.string,i.default.PropTypes.number])),placement:i.default.PropTypes.oneOf(["top","right","bottom","left"]),positionLeft:i.default.PropTypes.number,positionTop:i.default.PropTypes.number,arrowOffsetLeft:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),arrowOffsetTop:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),title:i.default.PropTypes.node},getDefaultProps:function(){return{bsClass:"tooltip",placement:"right"}},render:function(){var A,M=(A={},A[o.default.prefix(this.props)]=!0,A[this.props.placement]=!0,A),t=I({left:this.props.positionLeft,top:this.props.positionTop},this.props.style),g={left:this.props.arrowOffsetLeft,top:this.props.arrowOffsetTop};return i.default.createElement("div",I({role:"tooltip"},this.props,{className:E.default(this.props.className,M),style:t}),i.default.createElement("div",{className:o.default.prefix(this.props,"arrow"),style:g}),i.default.createElement("div",{className:o.default.prefix(this.props,"inner")},this.props.children))}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return A="function"==typeof A?A():A,i.default.findDOMNode(A)||M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=g;var e=t(16),i=I(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement. You can usually obtain a ReactComponent or DOMElement from a ReactElement by attaching a ref to it."):"object"===E&&"function"==typeof i.render||1===i.nodeType?null:new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement.")}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M,t){"use strict";function I(){function A(A,M,I){for(var g=0;g>",null!=t[I]?A(t,I,g):M?new Error("Required prop '"+I+"' was not specified in '"+g+"'."):void 0}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}M.__esModule=!0,M.errMsg=t,M.createChainableTypeChecker=I},function(A,M){"use strict";function t(A,M,t){function I(){return i=!0,T?void(N=[].concat(Array.prototype.slice.call(arguments))):void t.apply(this,arguments)}function g(){if(!i&&(E=!0,!T)){for(T=!0;!i&&e=A&&E&&(i=!0,t()))}}var e=0,i=!1,T=!1,E=!1,N=void 0;g()}function I(A,M,t){function I(A,M,I){i||(M?(i=!0,t(M)):(e[A]=I,i=++T===g,i&&t(null,e)))}var g=A.length,e=[];if(0===g)return t(null,e);var i=!1,T=0;A.forEach(function(A,t){M(A,t,function(A,M){I(t,A,M)})})}M.__esModule=!0,M.loopAsync=t,M.mapAsync=I},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0,M.router=M.routes=M.route=M.components=M.component=M.location=M.history=M.falsy=M.locationShape=M.routerShape=void 0;var e=t(1),i=t(66),T=(g(i),t(34)),E=I(T),N=t(9),o=(g(N),e.PropTypes.func),n=e.PropTypes.object,C=e.PropTypes.shape,c=e.PropTypes.string,D=M.routerShape=C({push:o.isRequired,replace:o.isRequired,go:o.isRequired,goBack:o.isRequired,goForward:o.isRequired,setRouteLeaveHook:o.isRequired,isActive:o.isRequired}),a=M.locationShape=C({pathname:c.isRequired,search:c.isRequired,state:n,action:c.isRequired,key:c}),B=M.falsy=E.falsy,Q=M.history=E.history,r=M.location=a,s=M.component=E.component,x=M.components=E.components,j=M.route=E.route,y=(M.routes=E.routes,M.router=D),u={falsy:B,history:Q,location:r,component:s,components:x,route:j,router:y};M.default=u},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!0;return!1}function e(A,M){function t(M){var t=!(arguments.length<=1||void 0===arguments[1])&&arguments[1],I=arguments.length<=2||void 0===arguments[2]?null:arguments[2],g=void 0;return t&&t!==!0||null!==I?(M={pathname:M,query:t},g=I||!1):(M=A.createLocation(M),g=t),(0,C.default)(M,g,s.location,s.routes,s.params)}function I(A,t){x&&x.location===A?e(x,t):(0,B.default)(M,A,function(M,I){M?t(M):I?e(i({},I,{location:A}),t):t()})}function e(A,M){function t(t,g){return t||g?I(t,g):void(0,D.default)(A,function(t,I){t?M(t):M(null,null,s=i({},A,{components:I}))})}function I(A,t){A?M(A):M(null,t)}var g=(0,N.default)(s,A),e=g.leaveRoutes,T=g.changeRoutes,E=g.enterRoutes;(0,o.runLeaveHooks)(e,s),e.filter(function(A){return E.indexOf(A)===-1}).forEach(a),(0,o.runChangeHooks)(T,s,A,function(M,g){return M||g?I(M,g):void(0,o.runEnterHooks)(E,A,t)})}function T(A){var M=arguments.length<=1||void 0===arguments[1]||arguments[1];return A.__id__||M&&(A.__id__=j++)}function E(A){return A.reduce(function(A,M){return A.push.apply(A,y[T(M)]),A},[])}function n(A,t){(0,B.default)(M,A,function(M,I){if(null==I)return void t();x=i({},I,{location:A});for(var g=E((0,N.default)(s,x).leaveRoutes),e=void 0,T=0,o=g.length;null==e&&T=32||13===M?M:0}A.exports=t},function(A,M){"use strict";function t(A){var M=this,t=M.nativeEvent;if(t.getModifierState)return t.getModifierState(A);var I=g[A];return!!I&&!!t[I]}function I(A){return t}var g={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};A.exports=I},function(A,M){"use strict";function t(A){var M=A.target||A.srcElement||window;return 3===M.nodeType?M.parentNode:M}A.exports=t},function(A,M){"use strict";function t(A){var M=A&&(I&&A[I]||A[g]);if("function"==typeof M)return M}var I="function"==typeof Symbol&&Symbol.iterator,g="@@iterator";A.exports=t},function(A,M,t){"use strict";function I(A){return"function"==typeof A&&"undefined"!=typeof A.prototype&&"function"==typeof A.prototype.mountComponent&&"function"==typeof A.prototype.receiveComponent}function g(A){var M;if(null===A||A===!1)M=new i(g);else if("object"==typeof A){var t=A;!t||"function"!=typeof t.type&&"string"!=typeof t.type?N(!1):void 0,M="string"==typeof t.type?T.createInternalComponent(t):I(t.type)?new t.type(t):new o}else"string"==typeof A||"number"==typeof A?M=T.createInstanceForText(A):N(!1);return M.construct(A),M._mountIndex=0,M._mountImage=null,M}var e=t(443),i=t(215),T=t(221),E=t(4),N=t(2),o=(t(3),function(){});E(o.prototype,e.Mixin,{_instantiateReactComponent:g}),A.exports=g},function(A,M,t){"use strict";/** +!function(){"use strict";function t(){for(var A=[],M=0;M2?t-2:0),g=2;g1){for(var c=Array(C),D=0;D1){for(var a=Array(D),B=0;B3&&void 0!==arguments[3]?arguments[3]:{},N=Boolean(A),C=A||w,D=void 0;D="function"==typeof M?M:M?(0,Q.default)(M):l;var B=t||L,r=I.pure,s=void 0===r||r,x=I.withRef,y=void 0!==x&&x,h=s&&B!==L,S=d++;return function(A){function M(A,M,t){var I=B(A,M,t);return I}var t="Connect("+T(A)+")",I=function(I){function T(A,M){g(this,T);var i=e(this,I.call(this,A,M));i.version=S,i.store=A.store||M.store,(0,u.default)(i.store,'Could not find "store" in either the context or '+('props of "'+t+'". ')+"Either wrap the root component in a , "+('or explicitly pass "store" as a prop to "'+t+'".'));var E=i.store.getState();return i.state={storeState:E},i.clearCache(),i}return i(T,I),T.prototype.shouldComponentUpdate=function(){return!s||this.haveOwnPropsChanged||this.hasStoreStateChanged},T.prototype.computeStateProps=function(A,M){if(!this.finalMapStateToProps)return this.configureFinalMapState(A,M);var t=A.getState(),I=this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(t,M):this.finalMapStateToProps(t);return I},T.prototype.configureFinalMapState=function(A,M){var t=C(A.getState(),M),I="function"==typeof t;return this.finalMapStateToProps=I?t:C,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,I?this.computeStateProps(A,M):t},T.prototype.computeDispatchProps=function(A,M){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(A,M);var t=A.dispatch,I=this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(t,M):this.finalMapDispatchToProps(t);return I},T.prototype.configureFinalMapDispatch=function(A,M){var t=D(A.dispatch,M),I="function"==typeof t;return this.finalMapDispatchToProps=I?t:D,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,I?this.computeDispatchProps(A,M):t},T.prototype.updateStatePropsIfNeeded=function(){var A=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,a.default)(A,this.stateProps))&&(this.stateProps=A,!0)},T.prototype.updateDispatchPropsIfNeeded=function(){var A=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,a.default)(A,this.dispatchProps))&&(this.dispatchProps=A,!0)},T.prototype.updateMergedPropsIfNeeded=function(){var A=M(this.stateProps,this.dispatchProps,this.props);return!(this.mergedProps&&h&&(0,a.default)(A,this.mergedProps))&&(this.mergedProps=A,!0)},T.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},T.prototype.trySubscribe=function(){N&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},T.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},T.prototype.componentDidMount=function(){this.trySubscribe()},T.prototype.componentWillReceiveProps=function(A){s&&(0,a.default)(A,this.props)||(this.haveOwnPropsChanged=!0)},T.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},T.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},T.prototype.handleChange=function(){if(this.unsubscribe){var A=this.store.getState(),M=this.state.storeState;if(!s||M!==A){if(s&&!this.doStatePropsDependOnOwnProps){var t=E(this.updateStatePropsIfNeeded,this);if(!t)return;t===Y&&(this.statePropsPrecalculationError=Y.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:A})}}},T.prototype.getWrappedInstance=function(){return(0,u.default)(y,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},T.prototype.render=function(){var M=this.haveOwnPropsChanged,t=this.hasStoreStateChanged,I=this.haveStatePropsBeenPrecalculated,g=this.statePropsPrecalculationError,e=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,g)throw g;var i=!0,T=!0;s&&e&&(i=t||M&&this.doStatePropsDependOnOwnProps,T=M&&this.doDispatchPropsDependOnOwnProps);var E=!1,N=!1;I?E=!0:i&&(E=this.updateStatePropsIfNeeded()),T&&(N=this.updateDispatchPropsIfNeeded());var C=!0;return C=!!(E||N||M)&&this.updateMergedPropsIfNeeded(),!C&&e?e:(y?this.renderedElement=(0,n.createElement)(A,o({},this.mergedProps,{ref:"wrappedInstance"})):this.renderedElement=(0,n.createElement)(A,this.mergedProps),this.renderedElement)},T}(n.Component);return I.displayName=t,I.WrappedComponent=A,I.contextTypes={store:c.default},I.propTypes={store:c.default},(0,j.default)(I,A)}}M.__esModule=!0;var o=Object.assign||function(A){for(var M=1;M should not have a "'+M+'" prop')}M.__esModule=!0,M.routes=M.route=M.components=M.component=M.history=void 0,M.falsy=I;var g=t(1),e=g.PropTypes.func,i=g.PropTypes.object,T=g.PropTypes.arrayOf,E=g.PropTypes.oneOfType,N=g.PropTypes.element,o=g.PropTypes.shape,n=g.PropTypes.string,C=(M.history=o({listen:e.isRequired,push:e.isRequired,replace:e.isRequired,go:e.isRequired,goBack:e.isRequired,goForward:e.isRequired}),M.component=E([e,n])),c=(M.components=E([C,i]),M.route=E([i,N]));M.routes=E([c,T(c)])},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){var M=A.match(/^https?:\/\/[^\/]*/);return null==M?A:A.substring(M[0].length)}function e(A){var M=g(A),t="",I="",e=M.indexOf("#");e!==-1&&(I=M.substring(e),M=M.substring(0,e));var i=M.indexOf("?");return i!==-1&&(t=M.substring(i),M=M.substring(0,i)),""===M&&(M="/"),{pathname:M,search:t,hash:I}}M.__esModule=!0,M.extractPath=g,M.parsePath=e;var i=t(23);I(i)},function(A,M,t){"use strict";function I(){g.attachRefs(this,this._currentElement)}var g=t(458),e={mountComponent:function(A,M,t,g){var e=A.mountComponent(M,t,g);return A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A),e},unmountComponent:function(A){g.detachRefs(A,A._currentElement),A.unmountComponent()},receiveComponent:function(A,M,t,e){var i=A._currentElement;if(M!==i||e!==A._context){var T=g.shouldUpdateRefs(i,M);T&&g.detachRefs(A,i),A.receiveComponent(M,t,e),T&&A._currentElement&&null!=A._currentElement.ref&&t.getReactMountReady().enqueue(I,A)}},performUpdateIfNecessary:function(A,M){A.performUpdateIfNecessary(M)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t,I){this.dispatchConfig=A,this.dispatchMarker=M,this.nativeEvent=t;var g=this.constructor.Interface;for(var e in g)if(g.hasOwnProperty(e)){var T=g[e];T?this[e]=T(t):"target"===e?this.target=I:this[e]=t[e]}var E=null!=t.defaultPrevented?t.defaultPrevented:t.returnValue===!1;E?this.isDefaultPrevented=i.thatReturnsTrue:this.isDefaultPrevented=i.thatReturnsFalse,this.isPropagationStopped=i.thatReturnsFalse}var g=t(31),e=t(4),i=t(20),T=(t(3),{type:null,target:null,currentTarget:i.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(A){return A.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null});e(I.prototype,{preventDefault:function(){this.defaultPrevented=!0;var A=this.nativeEvent;A&&(A.preventDefault?A.preventDefault():A.returnValue=!1,this.isDefaultPrevented=i.thatReturnsTrue)},stopPropagation:function(){var A=this.nativeEvent;A&&(A.stopPropagation?A.stopPropagation():A.cancelBubble=!0,this.isPropagationStopped=i.thatReturnsTrue)},persist:function(){this.isPersistent=i.thatReturnsTrue},isPersistent:i.thatReturnsFalse,destructor:function(){var A=this.constructor.Interface;for(var M in A)this[M]=null;this.dispatchConfig=null,this.dispatchMarker=null,this.nativeEvent=null}}),I.Interface=T,I.augmentClass=function(A,M){var t=this,I=Object.create(t.prototype);e(I,A.prototype),A.prototype=I,A.prototype.constructor=A,A.Interface=e({},t.Interface,M),A.augmentClass=t.augmentClass,g.addPoolingTo(A,g.fourArgumentPooler)},g.addPoolingTo(I,g.fourArgumentPooler),A.exports=I},function(A,M){"use strict";M.default=function(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t},M.__esModule=!0},function(A,M){"use strict";function t(A){return A&&A.ownerDocument||document}M.__esModule=!0,M.default=t,A.exports=M.default},function(A,M,t){"use strict";var I=t(32),g=function(){var A=I&&document.documentElement;return A&&A.contains?function(A,M){return A.contains(M)}:A&&A.compareDocumentPosition?function(A,M){return A===M||!!(16&A.compareDocumentPosition(M))}:function(A,M){if(M)do if(M===A)return!0;while(M=M.parentNode);return!1}}();A.exports=g},function(A,M){function t(A){return"number"==typeof A&&A>-1&&A%1==0&&A<=I}var I=9007199254740991;A.exports=t},function(A,M,t){(function(A){!function(M,t){A.exports=t()}(this,function(){"use strict";function M(){return aI.apply(null,arguments)}function t(A){aI=A}function I(A){return A instanceof Array||"[object Array]"===Object.prototype.toString.call(A)}function g(A){return null!=A&&"[object Object]"===Object.prototype.toString.call(A)}function e(A){var M;for(M in A)return!1;return!0}function i(A){return"number"==typeof A||"[object Number]"===Object.prototype.toString.call(A)}function T(A){return A instanceof Date||"[object Date]"===Object.prototype.toString.call(A)}function E(A,M){var t,I=[];for(t=0;t0)for(t in rI)I=rI[t],g=M[I],B(g)||(A[I]=g);return A}function r(A){Q(this,A),this._d=new Date(null!=A._d?A._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),sI===!1&&(sI=!0,M.updateOffset(this),sI=!1)}function s(A){return A instanceof r||null!=A&&null!=A._isAMomentObject}function x(A){return A<0?Math.ceil(A)||0:Math.floor(A)}function j(A){var M=+A,t=0;return 0!==M&&isFinite(M)&&(t=x(M)),t}function y(A,M,t){var I,g=Math.min(A.length,M.length),e=Math.abs(A.length-M.length),i=0;for(I=0;I0?"future":"past"];return L(t)?t(M):t.replace(/%s/i,M)}function F(A,M){var t=A.toLowerCase();SI[t]=SI[t+"s"]=SI[M]=A}function f(A){return"string"==typeof A?SI[A]||SI[A.toLowerCase()]:void 0}function k(A){var M,t,I={};for(t in A)N(A,t)&&(M=f(t),M&&(I[M]=A[t]));return I}function R(A,M){zI[A]=M}function J(A){var M=[];for(var t in A)M.push({unit:t,priority:zI[t]});return M.sort(function(A,M){return A.priority-M.priority}),M}function G(A,t){return function(I){return null!=I?(b(this,A,I),M.updateOffset(this,t),this):H(this,A)}}function H(A,M){return A.isValid()?A._d["get"+(A._isUTC?"UTC":"")+M]():NaN}function b(A,M,t){A.isValid()&&A._d["set"+(A._isUTC?"UTC":"")+M](t)}function v(A){return A=f(A),L(this[A])?this[A]():this}function X(A,M){if("object"==typeof A){A=k(A);for(var t=J(A),I=0;I=0;return(e?t?"+":"":"-")+Math.pow(10,Math.max(0,g)).toString().substr(1)+I}function V(A,M,t,I){var g=I;"string"==typeof I&&(g=function(){return this[I]()}),A&&(mI[A]=g),M&&(mI[M[0]]=function(){return W(g.apply(this,arguments),M[1],M[2])}),t&&(mI[t]=function(){return this.localeData().ordinal(g.apply(this,arguments),A)})}function P(A){return A.match(/\[[\s\S]/)?A.replace(/^\[|\]$/g,""):A.replace(/\\/g,"")}function Z(A){var M,t,I=A.match(pI);for(M=0,t=I.length;M=0&&UI.test(A);)A=A.replace(UI,t),UI.lastIndex=0,I-=1;return A}function _(A,M,t){$I[A]=L(M)?M:function(A,I){return A&&t?t:M}}function $(A,M){return N($I,A)?$I[A](M._strict,M._locale):new RegExp(AA(A))}function AA(A){return MA(A.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(A,M,t,I,g){return M||t||I||g}))}function MA(A){return A.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function tA(A,M){var t,I=M;for("string"==typeof A&&(A=[A]),i(M)&&(I=function(A,t){t[M]=j(A)}),t=0;t=0&&isFinite(T.getFullYear())&&T.setFullYear(A),T}function xA(A){var M=new Date(Date.UTC.apply(null,arguments));return A<100&&A>=0&&isFinite(M.getUTCFullYear())&&M.setUTCFullYear(A),M}function jA(A,M,t){var I=7+M-t,g=(7+xA(A,0,I).getUTCDay()-M)%7;return-g+I-1}function yA(A,M,t,I,g){var e,i,T=(7+t-I)%7,E=jA(A,I,g),N=1+7*(M-1)+T+E;return N<=0?(e=A-1,i=BA(e)+N):N>BA(A)?(e=A+1,i=N-BA(A)):(e=A,i=N),{year:e,dayOfYear:i}}function uA(A,M,t){var I,g,e=jA(A.year(),M,t),i=Math.floor((A.dayOfYear()-e-1)/7)+1;return i<1?(g=A.year()-1,I=i+wA(g,M,t)):i>wA(A.year(),M,t)?(I=i-wA(A.year(),M,t),g=A.year()+1):(g=A.year(),I=i),{week:I,year:g}}function wA(A,M,t){var I=jA(A,M,t),g=jA(A+1,M,t);return(BA(A)-I+g)/7}function lA(A){return uA(A,this._week.dow,this._week.doy).week}function LA(){return this._week.dow}function YA(){return this._week.doy}function dA(A){var M=this.localeData().week(this);return null==A?M:this.add(7*(A-M),"d")}function hA(A){var M=uA(this,1,4).week;return null==A?M:this.add(7*(A-M),"d")}function SA(A,M){return"string"!=typeof A?A:isNaN(A)?(A=M.weekdaysParse(A),"number"==typeof A?A:null):parseInt(A,10)}function zA(A,M){return"string"==typeof A?M.weekdaysParse(A)%7||7:isNaN(A)?null:A}function pA(A,M){return A?I(this._weekdays)?this._weekdays[A.day()]:this._weekdays[this._weekdays.isFormat.test(M)?"format":"standalone"][A.day()]:this._weekdays}function UA(A){return A?this._weekdaysShort[A.day()]:this._weekdaysShort}function OA(A){return A?this._weekdaysMin[A.day()]:this._weekdaysMin}function mA(A,M,t){var I,g,e,i=A.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],I=0;I<7;++I)e=n([2e3,1]).day(I),this._minWeekdaysParse[I]=this.weekdaysMin(e,"").toLocaleLowerCase(),this._shortWeekdaysParse[I]=this.weekdaysShort(e,"").toLocaleLowerCase(),this._weekdaysParse[I]=this.weekdays(e,"").toLocaleLowerCase();return t?"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:null):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null):"dddd"===M?(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):"ddd"===M?(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._minWeekdaysParse,i),g!==-1?g:null))):(g=og.call(this._minWeekdaysParse,i),g!==-1?g:(g=og.call(this._weekdaysParse,i),g!==-1?g:(g=og.call(this._shortWeekdaysParse,i),g!==-1?g:null)))}function FA(A,M,t){var I,g,e;if(this._weekdaysParseExact)return mA.call(this,A,M,t);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),I=0;I<7;I++){if(g=n([2e3,1]).day(I),t&&!this._fullWeekdaysParse[I]&&(this._fullWeekdaysParse[I]=new RegExp("^"+this.weekdays(g,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[I]=new RegExp("^"+this.weekdaysShort(g,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[I]=new RegExp("^"+this.weekdaysMin(g,"").replace(".",".?")+"$","i")),this._weekdaysParse[I]||(e="^"+this.weekdays(g,"")+"|^"+this.weekdaysShort(g,"")+"|^"+this.weekdaysMin(g,""),this._weekdaysParse[I]=new RegExp(e.replace(".",""),"i")),t&&"dddd"===M&&this._fullWeekdaysParse[I].test(A))return I;if(t&&"ddd"===M&&this._shortWeekdaysParse[I].test(A))return I;if(t&&"dd"===M&&this._minWeekdaysParse[I].test(A))return I;if(!t&&this._weekdaysParse[I].test(A))return I}}function fA(A){if(!this.isValid())return null!=A?this:NaN;var M=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=A?(A=SA(A,this.localeData()),this.add(A-M,"d")):M}function kA(A){if(!this.isValid())return null!=A?this:NaN;var M=(this.day()+7-this.localeData()._week.dow)%7;return null==A?M:this.add(A-M,"d")}function RA(A){if(!this.isValid())return null!=A?this:NaN;if(null!=A){var M=zA(A,this.localeData());return this.day(this.day()%7?M:M-7)}return this.day()||7}function JA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysStrictRegex:this._weekdaysRegex):(N(this,"_weekdaysRegex")||(this._weekdaysRegex=jg),this._weekdaysStrictRegex&&A?this._weekdaysStrictRegex:this._weekdaysRegex)}function GA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(N(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=yg),this._weekdaysShortStrictRegex&&A?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function HA(A){return this._weekdaysParseExact?(N(this,"_weekdaysRegex")||bA.call(this),A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(N(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ug),this._weekdaysMinStrictRegex&&A?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function bA(){function A(A,M){return M.length-A.length}var M,t,I,g,e,i=[],T=[],E=[],N=[];for(M=0;M<7;M++)t=n([2e3,1]).day(M),I=this.weekdaysMin(t,""),g=this.weekdaysShort(t,""),e=this.weekdays(t,""),i.push(I),T.push(g),E.push(e),N.push(I),N.push(g),N.push(e);for(i.sort(A),T.sort(A),E.sort(A),N.sort(A),M=0;M<7;M++)T[M]=MA(T[M]),E[M]=MA(E[M]),N[M]=MA(N[M]);this._weekdaysRegex=new RegExp("^("+N.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+E.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+T.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function vA(){return this.hours()%12||12}function XA(){return this.hours()||24}function WA(A,M){V(A,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),M)})}function VA(A,M){return M._meridiemParse}function PA(A){return"p"===(A+"").toLowerCase().charAt(0)}function ZA(A,M,t){return A>11?t?"pm":"PM":t?"am":"AM"}function KA(A){return A?A.toLowerCase().replace("_","-"):A}function qA(A){for(var M,t,I,g,e=0;e0;){if(I=_A(g.slice(0,M).join("-")))return I;if(t&&t.length>=M&&y(g,t,!0)>=M-1)break;M--}e++}return null}function _A(M){var t=null;if(!dg[M]&&"undefined"!=typeof A&&A&&A.exports)try{t=wg._abbr,!function(){var A=new Error('Cannot find module "./locale"');throw A.code="MODULE_NOT_FOUND",A}(),$A(t)}catch(A){}return dg[M]}function $A(A,M){var t;return A&&(t=B(M)?tM(A):AM(A,M),t&&(wg=t)),wg._abbr}function AM(A,M){if(null!==M){var t=Yg;if(M.abbr=A,null!=dg[A])l("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),t=dg[A]._config;else if(null!=M.parentLocale){if(null==dg[M.parentLocale])return hg[M.parentLocale]||(hg[M.parentLocale]=[]),hg[M.parentLocale].push({name:A,config:M}),null;t=dg[M.parentLocale]._config}return dg[A]=new h(d(t,M)),hg[A]&&hg[A].forEach(function(A){AM(A.name,A.config)}),$A(A),dg[A]}return delete dg[A],null}function MM(A,M){if(null!=M){var t,I=Yg;null!=dg[A]&&(I=dg[A]._config),M=d(I,M),t=new h(M),t.parentLocale=dg[A],dg[A]=t,$A(A)}else null!=dg[A]&&(null!=dg[A].parentLocale?dg[A]=dg[A].parentLocale:null!=dg[A]&&delete dg[A]);return dg[A]}function tM(A){var M;if(A&&A._locale&&A._locale._abbr&&(A=A._locale._abbr),!A)return wg;if(!I(A)){if(M=_A(A))return M;A=[A]}return qA(A)}function IM(){return uI(dg)}function gM(A){var M,t=A._a;return t&&c(A).overflow===-2&&(M=t[tg]<0||t[tg]>11?tg:t[Ig]<1||t[Ig]>eA(t[Mg],t[tg])?Ig:t[gg]<0||t[gg]>24||24===t[gg]&&(0!==t[eg]||0!==t[ig]||0!==t[Tg])?gg:t[eg]<0||t[eg]>59?eg:t[ig]<0||t[ig]>59?ig:t[Tg]<0||t[Tg]>999?Tg:-1,c(A)._overflowDayOfYear&&(MIg)&&(M=Ig),c(A)._overflowWeeks&&M===-1&&(M=Eg),c(A)._overflowWeekday&&M===-1&&(M=Ng),c(A).overflow=M),A}function eM(A){var M,t,I,g,e,i,T=A._i,E=Sg.exec(T)||zg.exec(T);if(E){for(c(A).iso=!0,M=0,t=Ug.length;MBA(g)&&(c(A)._overflowDayOfYear=!0),t=xA(g,0,A._dayOfYear),A._a[tg]=t.getUTCMonth(),A._a[Ig]=t.getUTCDate()),M=0;M<3&&null==A._a[M];++M)A._a[M]=e[M]=I[M];for(;M<7;M++)A._a[M]=e[M]=null==A._a[M]?2===M?1:0:A._a[M];24===A._a[gg]&&0===A._a[eg]&&0===A._a[ig]&&0===A._a[Tg]&&(A._nextDay=!0,A._a[gg]=0),A._d=(A._useUTC?xA:sA).apply(null,e),null!=A._tzm&&A._d.setUTCMinutes(A._d.getUTCMinutes()-A._tzm),A._nextDay&&(A._a[gg]=24)}}function oM(A){var M,t,I,g,e,i,T,E;if(M=A._w,null!=M.GG||null!=M.W||null!=M.E)e=1,i=4,t=TM(M.GG,A._a[Mg],uA(sM(),1,4).year),I=TM(M.W,1),g=TM(M.E,1),(g<1||g>7)&&(E=!0);else{e=A._locale._week.dow,i=A._locale._week.doy;var N=uA(sM(),e,i);t=TM(M.gg,A._a[Mg],N.year),I=TM(M.w,N.week),null!=M.d?(g=M.d,(g<0||g>6)&&(E=!0)):null!=M.e?(g=M.e+e,(M.e<0||M.e>6)&&(E=!0)):g=e}I<1||I>wA(t,e,i)?c(A)._overflowWeeks=!0:null!=E?c(A)._overflowWeekday=!0:(T=yA(t,I,g,e,i),A._a[Mg]=T.year,A._dayOfYear=T.dayOfYear)}function nM(A){if(A._f===M.ISO_8601)return void eM(A);A._a=[],c(A).empty=!0;var t,I,g,e,i,T=""+A._i,E=T.length,N=0;for(g=q(A._f,A._locale).match(pI)||[],t=0;t0&&c(A).unusedInput.push(i),T=T.slice(T.indexOf(I)+I.length),N+=I.length),mI[e]?(I?c(A).empty=!1:c(A).unusedTokens.push(e),gA(e,I,A)):A._strict&&!I&&c(A).unusedTokens.push(e);c(A).charsLeftOver=E-N,T.length>0&&c(A).unusedInput.push(T),A._a[gg]<=12&&c(A).bigHour===!0&&A._a[gg]>0&&(c(A).bigHour=void 0),c(A).parsedDateParts=A._a.slice(0),c(A).meridiem=A._meridiem,A._a[gg]=CM(A._locale,A._a[gg],A._meridiem),NM(A),gM(A)}function CM(A,M,t){var I;return null==t?M:null!=A.meridiemHour?A.meridiemHour(M,t):null!=A.isPM?(I=A.isPM(t),I&&M<12&&(M+=12),I||12!==M||(M=0),M):M}function cM(A){var M,t,I,g,e;if(0===A._f.length)return c(A).invalidFormat=!0,void(A._d=new Date(NaN));for(g=0;gthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function fM(){if(!B(this._isDSTShifted))return this._isDSTShifted;var A={};if(Q(A,this),A=BM(A),A._a){var M=A._isUTC?n(A._a):sM(A._a);this._isDSTShifted=this.isValid()&&y(A._a,M.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function kM(){return!!this.isValid()&&!this._isUTC}function RM(){return!!this.isValid()&&this._isUTC}function JM(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function GM(A,M){var t,I,g,e=A,T=null;return wM(A)?e={ms:A._milliseconds,d:A._days,M:A._months}:i(A)?(e={},M?e[M]=A:e.milliseconds=A):(T=Jg.exec(A))?(t="-"===T[1]?-1:1,e={y:0,d:j(T[Ig])*t,h:j(T[gg])*t,m:j(T[eg])*t,s:j(T[ig])*t,ms:j(lM(1e3*T[Tg]))*t}):(T=Gg.exec(A))?(t="-"===T[1]?-1:1,e={y:HM(T[2],t),M:HM(T[3],t),w:HM(T[4],t),d:HM(T[5],t),h:HM(T[6],t),m:HM(T[7],t),s:HM(T[8],t)}):null==e?e={}:"object"==typeof e&&("from"in e||"to"in e)&&(g=vM(sM(e.from),sM(e.to)),e={},e.ms=g.milliseconds,e.M=g.months),I=new uM(e),wM(A)&&N(A,"_locale")&&(I._locale=A._locale),I}function HM(A,M){var t=A&&parseFloat(A.replace(",","."));return(isNaN(t)?0:t)*M}function bM(A,M){var t={milliseconds:0,months:0};return t.months=M.month()-A.month()+12*(M.year()-A.year()),A.clone().add(t.months,"M").isAfter(M)&&--t.months,t.milliseconds=+M-+A.clone().add(t.months,"M"),t}function vM(A,M){var t;return A.isValid()&&M.isValid()?(M=dM(M,A),A.isBefore(M)?t=bM(A,M):(t=bM(M,A),t.milliseconds=-t.milliseconds,t.months=-t.months),t):{milliseconds:0,months:0}}function XM(A,M){return function(t,I){var g,e;return null===I||isNaN(+I)||(l(M,"moment()."+M+"(period, number) is deprecated. Please use moment()."+M+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),e=t,t=I,I=e),t="string"==typeof t?+t:t,g=GM(t,I),WM(this,g,A),this}}function WM(A,t,I,g){var e=t._milliseconds,i=lM(t._days),T=lM(t._months);A.isValid()&&(g=null==g||g,e&&A._d.setTime(A._d.valueOf()+e*I),i&&b(A,"Date",H(A,"Date")+i*I),T&&oA(A,H(A,"Month")+T*I),g&&M.updateOffset(A,i||T))}function VM(A,M){var t=A.diff(M,"days",!0);return t<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"}function PM(A,t){var I=A||sM(),g=dM(I,this).startOf("day"),e=M.calendarFormat(this,g)||"sameElse",i=t&&(L(t[e])?t[e].call(this,I):t[e]);return this.format(i||this.localeData().calendar(e,this,sM(I)))}function ZM(){return new r(this)}function KM(A,M){var t=s(A)?A:sM(A);return!(!this.isValid()||!t.isValid())&&(M=f(B(M)?"millisecond":M),"millisecond"===M?this.valueOf()>t.valueOf():t.valueOf()e&&(M=e),pt.call(this,A,M,t,I,g))}function pt(A,M,t,I,g){var e=yA(A,M,t,I,g),i=xA(e.year,0,e.dayOfYear);return this.year(i.getUTCFullYear()),this.month(i.getUTCMonth()),this.date(i.getUTCDate()),this}function Ut(A){return null==A?Math.ceil((this.month()+1)/3):this.month(3*(A-1)+this.month()%3)}function Ot(A){var M=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==A?M:this.add(A-M,"d")}function mt(A,M){M[Tg]=j(1e3*("0."+A))}function Ft(){return this._isUTC?"UTC":""}function ft(){return this._isUTC?"Coordinated Universal Time":""}function kt(A){return sM(1e3*A)}function Rt(){return sM.apply(null,arguments).parseZone()}function Jt(A){return A}function Gt(A,M,t,I){var g=tM(),e=n().set(I,M);return g[t](e,A)}function Ht(A,M,t){if(i(A)&&(M=A,A=void 0),A=A||"",null!=M)return Gt(A,M,t,"month");var I,g=[];for(I=0;I<12;I++)g[I]=Gt(A,I,t,"month");return g}function bt(A,M,t,I){"boolean"==typeof A?(i(M)&&(t=M,M=void 0),M=M||""):(M=A,t=M,A=!1,i(M)&&(t=M,M=void 0),M=M||"");var g=tM(),e=A?g._week.dow:0;if(null!=t)return Gt(M,(t+e)%7,I,"day");var T,E=[];for(T=0;T<7;T++)E[T]=Gt(M,(T+e)%7,I,"day");return E}function vt(A,M){return Ht(A,M,"months")}function Xt(A,M){return Ht(A,M,"monthsShort")}function Wt(A,M,t){return bt(A,M,t,"weekdays")}function Vt(A,M,t){return bt(A,M,t,"weekdaysShort")}function Pt(A,M,t){return bt(A,M,t,"weekdaysMin")}function Zt(){var A=this._data;return this._milliseconds=_g(this._milliseconds),this._days=_g(this._days),this._months=_g(this._months),A.milliseconds=_g(A.milliseconds),A.seconds=_g(A.seconds),A.minutes=_g(A.minutes),A.hours=_g(A.hours),A.months=_g(A.months),A.years=_g(A.years),this}function Kt(A,M,t,I){var g=GM(M,t);return A._milliseconds+=I*g._milliseconds,A._days+=I*g._days,A._months+=I*g._months,A._bubble()}function qt(A,M){return Kt(this,A,M,1)}function _t(A,M){return Kt(this,A,M,-1)}function $t(A){return A<0?Math.floor(A):Math.ceil(A)}function AI(){var A,M,t,I,g,e=this._milliseconds,i=this._days,T=this._months,E=this._data;return e>=0&&i>=0&&T>=0||e<=0&&i<=0&&T<=0||(e+=864e5*$t(tI(T)+i),i=0,T=0),E.milliseconds=e%1e3,A=x(e/1e3),E.seconds=A%60,M=x(A/60),E.minutes=M%60,t=x(M/60),E.hours=t%24,i+=x(t/24),g=x(MI(i)),T+=g,i-=$t(tI(g)),I=x(T/12),T%=12,E.days=i,E.months=T,E.years=I,this}function MI(A){return 4800*A/146097}function tI(A){return 146097*A/4800}function II(A){var M,t,I=this._milliseconds;if(A=f(A),"month"===A||"year"===A)return M=this._days+I/864e5,t=this._months+MI(M),"month"===A?t:t/12;switch(M=this._days+Math.round(tI(this._months)),A){case"week":return M/7+I/6048e5;case"day":return M+I/864e5;case"hour":return 24*M+I/36e5;case"minute":return 1440*M+I/6e4;case"second":return 86400*M+I/1e3;case"millisecond":return Math.floor(864e5*M)+I;default:throw new Error("Unknown unit "+A)}}function gI(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*j(this._months/12)}function eI(A){return function(){return this.as(A)}}function iI(A){return A=f(A),this[A+"s"]()}function TI(A){return function(){return this._data[A]}}function EI(){return x(this.days()/7)}function NI(A,M,t,I,g){return g.relativeTime(M||1,!!t,A,I)}function oI(A,M,t){var I=GM(A).abs(),g=De(I.as("s")),e=De(I.as("m")),i=De(I.as("h")),T=De(I.as("d")),E=De(I.as("M")),N=De(I.as("y")),o=g0,o[4]=t,NI.apply(null,o)}function nI(A){return void 0===A?De:"function"==typeof A&&(De=A,!0)}function CI(A,M){return void 0!==ae[A]&&(void 0===M?ae[A]:(ae[A]=M,!0))}function cI(A){var M=this.localeData(),t=oI(this,!A,M);return A&&(t=M.pastFuture(+this,t)),M.postformat(t)}function DI(){var A,M,t,I=Be(this._milliseconds)/1e3,g=Be(this._days),e=Be(this._months);A=x(I/60),M=x(A/60),I%=60,A%=60,t=x(e/12),e%=12;var i=t,T=e,E=g,N=M,o=A,n=I,C=this.asSeconds();return C?(C<0?"-":"")+"P"+(i?i+"Y":"")+(T?T+"M":"")+(E?E+"D":"")+(N||o||n?"T":"")+(N?N+"H":"")+(o?o+"M":"")+(n?n+"S":""):"P0D"}var aI,BI;BI=Array.prototype.some?Array.prototype.some:function(A){for(var M=Object(this),t=M.length>>>0,I=0;I68?1900:2e3)};var Bg=G("FullYear",!0);V("w",["ww",2],"wo","week"),V("W",["WW",2],"Wo","isoWeek"),F("week","w"),F("isoWeek","W"),R("week",5),R("isoWeek",5),_("w",GI),_("ww",GI,fI),_("W",GI),_("WW",GI,fI),IA(["w","ww","W","WW"],function(A,M,t,I){M[I.substr(0,1)]=j(A)});var Qg={dow:0,doy:6};V("d",0,"do","day"),V("dd",0,0,function(A){return this.localeData().weekdaysMin(this,A)}),V("ddd",0,0,function(A){return this.localeData().weekdaysShort(this,A)}),V("dddd",0,0,function(A){return this.localeData().weekdays(this,A)}),V("e",0,0,"weekday"),V("E",0,0,"isoWeekday"),F("day","d"),F("weekday","e"),F("isoWeekday","E"),R("day",11),R("weekday",11),R("isoWeekday",11),_("d",GI),_("e",GI),_("E",GI),_("dd",function(A,M){return M.weekdaysMinRegex(A)}),_("ddd",function(A,M){return M.weekdaysShortRegex(A)}),_("dddd",function(A,M){return M.weekdaysRegex(A)}),IA(["dd","ddd","dddd"],function(A,M,t,I){var g=t._locale.weekdaysParse(A,I,t._strict);null!=g?M.d=g:c(t).invalidWeekday=A}),IA(["d","e","E"],function(A,M,t,I){M[I]=j(A)});var rg="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),sg="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),xg="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),jg=_I,yg=_I,ug=_I;V("H",["HH",2],0,"hour"),V("h",["hh",2],0,vA),V("k",["kk",2],0,XA),V("hmm",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)}),V("hmmss",0,0,function(){return""+vA.apply(this)+W(this.minutes(),2)+W(this.seconds(),2)}),V("Hmm",0,0,function(){return""+this.hours()+W(this.minutes(),2)}),V("Hmmss",0,0,function(){return""+this.hours()+W(this.minutes(),2)+W(this.seconds(),2)}),WA("a",!0),WA("A",!1),F("hour","h"),R("hour",13),_("a",VA),_("A",VA),_("H",GI),_("h",GI),_("HH",GI,fI),_("hh",GI,fI),_("hmm",HI),_("hmmss",bI),_("Hmm",HI),_("Hmmss",bI),tA(["H","HH"],gg),tA(["a","A"],function(A,M,t){t._isPm=t._locale.isPM(A),t._meridiem=A}),tA(["h","hh"],function(A,M,t){M[gg]=j(A),c(t).bigHour=!0}),tA("hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I)),c(t).bigHour=!0}),tA("hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g)),c(t).bigHour=!0}),tA("Hmm",function(A,M,t){var I=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I))}),tA("Hmmss",function(A,M,t){var I=A.length-4,g=A.length-2;M[gg]=j(A.substr(0,I)),M[eg]=j(A.substr(I,2)),M[ig]=j(A.substr(g))});var wg,lg=/[ap]\.?m?\.?/i,Lg=G("Hours",!0),Yg={calendar:wI,longDateFormat:lI,invalidDate:LI,ordinal:YI,ordinalParse:dI,relativeTime:hI,months:Cg,monthsShort:cg,week:Qg,weekdays:rg,weekdaysMin:xg,weekdaysShort:sg,meridiemParse:lg},dg={},hg={},Sg=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,zg=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,pg=/Z|[+-]\d\d(?::?\d\d)?/,Ug=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Og=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],mg=/^\/?Date\((\-?\d+)/i;M.createFromInputFallback=w("value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(A){A._d=new Date(A._i+(A._useUTC?" UTC":""))}),M.ISO_8601=function(){};var Fg=w("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var A=sM.apply(null,arguments);return this.isValid()&&A.isValid()?Athis?this:A:a()}),kg=function(){return Date.now?Date.now():+new Date};LM("Z",":"),LM("ZZ",""),_("Z",KI),_("ZZ",KI),tA(["Z","ZZ"],function(A,M,t){t._useUTC=!0,t._tzm=YM(KI,A)});var Rg=/([\+\-]|\d\d)/gi;M.updateOffset=function(){};var Jg=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,Gg=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;GM.fn=uM.prototype;var Hg=XM(1,"add"),bg=XM(-1,"subtract");M.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",M.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var vg=w("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(A){return void 0===A?this.localeData():this.locale(A)});V(0,["gg",2],0,function(){return this.weekYear()%100}),V(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Lt("gggg","weekYear"),Lt("ggggg","weekYear"),Lt("GGGG","isoWeekYear"),Lt("GGGGG","isoWeekYear"),F("weekYear","gg"),F("isoWeekYear","GG"),R("weekYear",1),R("isoWeekYear",1),_("G",PI),_("g",PI),_("GG",GI,fI),_("gg",GI,fI),_("GGGG",XI,RI),_("gggg",XI,RI),_("GGGGG",WI,JI),_("ggggg",WI,JI),IA(["gggg","ggggg","GGGG","GGGGG"],function(A,M,t,I){M[I.substr(0,2)]=j(A)}),IA(["gg","GG"],function(A,t,I,g){t[g]=M.parseTwoDigitYear(A)}),V("Q",0,"Qo","quarter"),F("quarter","Q"),R("quarter",7),_("Q",FI),tA("Q",function(A,M){M[tg]=3*(j(A)-1)}),V("D",["DD",2],"Do","date"),F("date","D"),R("date",9),_("D",GI),_("DD",GI,fI),_("Do",function(A,M){return A?M._ordinalParse:M._ordinalParseLenient}),tA(["D","DD"],Ig),tA("Do",function(A,M){M[Ig]=j(A.match(GI)[0],10)});var Xg=G("Date",!0);V("DDD",["DDDD",3],"DDDo","dayOfYear"),F("dayOfYear","DDD"),R("dayOfYear",4),_("DDD",vI),_("DDDD",kI),tA(["DDD","DDDD"],function(A,M,t){t._dayOfYear=j(A)}),V("m",["mm",2],0,"minute"),F("minute","m"),R("minute",14),_("m",GI),_("mm",GI,fI),tA(["m","mm"],eg);var Wg=G("Minutes",!1);V("s",["ss",2],0,"second"),F("second","s"),R("second",15),_("s",GI),_("ss",GI,fI),tA(["s","ss"],ig);var Vg=G("Seconds",!1);V("S",0,0,function(){return~~(this.millisecond()/100)}),V(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),V(0,["SSS",3],0,"millisecond"),V(0,["SSSS",4],0,function(){return 10*this.millisecond()}),V(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),V(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),V(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),V(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),V(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),F("millisecond","ms"),R("millisecond",16),_("S",vI,FI),_("SS",vI,fI),_("SSS",vI,kI);var Pg;for(Pg="SSSS";Pg.length<=9;Pg+="S")_(Pg,VI);for(Pg="S";Pg.length<=9;Pg+="S")tA(Pg,mt);var Zg=G("Milliseconds",!1);V("z",0,0,"zoneAbbr"),V("zz",0,0,"zoneName");var Kg=r.prototype;Kg.add=Hg,Kg.calendar=PM,Kg.clone=ZM,Kg.diff=tt,Kg.endOf=at,Kg.format=Tt,Kg.from=Et,Kg.fromNow=Nt,Kg.to=ot,Kg.toNow=nt,Kg.get=v,Kg.invalidAt=wt,Kg.isAfter=KM,Kg.isBefore=qM,Kg.isBetween=_M,Kg.isSame=$M,Kg.isSameOrAfter=At,Kg.isSameOrBefore=Mt,Kg.isValid=yt,Kg.lang=vg,Kg.locale=Ct,Kg.localeData=ct,Kg.max=fg,Kg.min=Fg,Kg.parsingFlags=ut,Kg.set=X,Kg.startOf=Dt,Kg.subtract=bg,Kg.toArray=st,Kg.toObject=xt,Kg.toDate=rt,Kg.toISOString=et,Kg.inspect=it,Kg.toJSON=jt,Kg.toString=gt,Kg.unix=Qt,Kg.valueOf=Bt,Kg.creationData=lt,Kg.year=Bg,Kg.isLeapYear=rA,Kg.weekYear=Yt,Kg.isoWeekYear=dt,Kg.quarter=Kg.quarters=Ut,Kg.month=nA,Kg.daysInMonth=CA,Kg.week=Kg.weeks=dA,Kg.isoWeek=Kg.isoWeeks=hA,Kg.weeksInYear=St,Kg.isoWeeksInYear=ht,Kg.date=Xg,Kg.day=Kg.days=fA,Kg.weekday=kA,Kg.isoWeekday=RA,Kg.dayOfYear=Ot,Kg.hour=Kg.hours=Lg,Kg.minute=Kg.minutes=Wg,Kg.second=Kg.seconds=Vg,Kg.millisecond=Kg.milliseconds=Zg,Kg.utcOffset=SM,Kg.utc=pM,Kg.local=UM,Kg.parseZone=OM,Kg.hasAlignedHourOffset=mM,Kg.isDST=FM,Kg.isLocal=kM,Kg.isUtcOffset=RM,Kg.isUtc=JM,Kg.isUTC=JM,Kg.zoneAbbr=Ft,Kg.zoneName=ft,Kg.dates=w("dates accessor is deprecated. Use date instead.",Xg),Kg.months=w("months accessor is deprecated. Use month instead",nA),Kg.years=w("years accessor is deprecated. Use year instead",Bg),Kg.zone=w("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",zM),Kg.isDSTShifted=w("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",fM);var qg=h.prototype;qg.calendar=S,qg.longDateFormat=z,qg.invalidDate=p,qg.ordinal=U,qg.preparse=Jt,qg.postformat=Jt,qg.relativeTime=O,qg.pastFuture=m,qg.set=Y,qg.months=iA,qg.monthsShort=TA,qg.monthsParse=NA,qg.monthsRegex=DA,qg.monthsShortRegex=cA,qg.week=lA,qg.firstDayOfYear=YA,qg.firstDayOfWeek=LA,qg.weekdays=pA,qg.weekdaysMin=OA,qg.weekdaysShort=UA,qg.weekdaysParse=FA,qg.weekdaysRegex=JA,qg.weekdaysShortRegex=GA,qg.weekdaysMinRegex=HA,qg.isPM=PA,qg.meridiem=ZA,$A("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(A){var M=A%10,t=1===j(A%100/10)?"th":1===M?"st":2===M?"nd":3===M?"rd":"th";return A+t}}),M.lang=w("moment.lang is deprecated. Use moment.locale instead.",$A),M.langData=w("moment.langData is deprecated. Use moment.localeData instead.",tM);var _g=Math.abs,$g=eI("ms"),Ae=eI("s"),Me=eI("m"),te=eI("h"),Ie=eI("d"),ge=eI("w"),ee=eI("M"),ie=eI("y"),Te=TI("milliseconds"),Ee=TI("seconds"),Ne=TI("minutes"),oe=TI("hours"),ne=TI("days"),Ce=TI("months"),ce=TI("years"),De=Math.round,ae={s:45,m:45,h:22,d:26,M:11},Be=Math.abs,Qe=uM.prototype;return Qe.abs=Zt,Qe.add=qt,Qe.subtract=_t,Qe.as=II,Qe.asMilliseconds=$g,Qe.asSeconds=Ae,Qe.asMinutes=Me,Qe.asHours=te,Qe.asDays=Ie,Qe.asWeeks=ge,Qe.asMonths=ee,Qe.asYears=ie,Qe.valueOf=gI,Qe._bubble=AI,Qe.get=iI,Qe.milliseconds=Te,Qe.seconds=Ee,Qe.minutes=Ne,Qe.hours=oe,Qe.days=ne,Qe.weeks=EI,Qe.months=Ce,Qe.years=ce,Qe.humanize=cI,Qe.toISOString=DI,Qe.toString=DI,Qe.toJSON=DI,Qe.locale=Ct,Qe.localeData=ct,Qe.toIsoString=w("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",DI),Qe.lang=vg,V("X",0,0,"unix"),V("x",0,0,"valueOf"),_("x",PI),_("X",qI),tA("X",function(A,M,t){t._d=new Date(1e3*parseFloat(A,10))}),tA("x",function(A,M,t){t._d=new Date(j(A))}),M.version="2.17.1",t(sM),M.fn=Kg,M.min=jM,M.max=yM,M.now=kg,M.utc=n,M.unix=kt,M.months=vt,M.isDate=T,M.locale=$A,M.invalid=a,M.duration=GM,M.isMoment=s,M.weekdays=Wt,M.parseZone=Rt,M.localeData=tM,M.isDuration=wM,M.monthsShort=Xt,M.weekdaysMin=Pt,M.defineLocale=AM,M.updateLocale=MM,M.locales=IM,M.weekdaysShort=Vt,M.normalizeUnits=f,M.relativeTimeRounding=nI,M.relativeTimeThreshold=CI,M.calendarFormat=VM,M.prototype=Kg,M})}).call(M,t(128)(A))},function(A,M,t){"use strict";var I=t(130).default,g=t(131).default,e=t(78).default;M.__esModule=!0;var i=function(A){return I(g({values:function(){var A=this;return e(this).map(function(M){return A[M]})}}),A)},T={SIZES:{large:"lg",medium:"md",small:"sm",xsmall:"xs",lg:"lg",md:"md",sm:"sm",xs:"xs"},GRID_COLUMNS:12},E=i({LARGE:"large",MEDIUM:"medium",SMALL:"small",XSMALL:"xsmall"});M.Sizes=E;var N=i({SUCCESS:"success",WARNING:"warning",DANGER:"danger",INFO:"info"});M.State=N;var o="default";M.DEFAULT=o;var n="primary";M.PRIMARY=n;var C="link";M.LINK=C;var c="inverse";M.INVERSE=c,M.default=T},function(A,M){"use strict";function t(){for(var A=arguments.length,M=Array(A),t=0;t0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURI(o))):"("===E?g+=1:")"===E?g-=1:":"===E.charAt(0)?(N=E.substring(1),o=M[N],null!=o||g>0?void 0:(0,C.default)(!1),null!=o&&(e+=encodeURIComponent(o))):e+=E;return e.replace(/\/+/g,"/")}M.__esModule=!0,M.compilePattern=i,M.matchPattern=T,M.getParamNames=E,M.getParams=N,M.formatPattern=o;var n=t(8),C=I(n),c=Object.create(null)},function(A,M){"use strict";M.__esModule=!0;var t="PUSH";M.PUSH=t;var I="REPLACE";M.REPLACE=I;var g="POP";M.POP=g,M.default={PUSH:t,REPLACE:I,POP:g}},function(A,M,t){"use strict";function I(A,M){return(A&M)===M}var g=t(2),e={MUST_USE_ATTRIBUTE:1,MUST_USE_PROPERTY:2,HAS_SIDE_EFFECTS:4,HAS_BOOLEAN_VALUE:8,HAS_NUMERIC_VALUE:16,HAS_POSITIVE_NUMERIC_VALUE:48,HAS_OVERLOADED_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(A){var M=e,t=A.Properties||{},i=A.DOMAttributeNamespaces||{},E=A.DOMAttributeNames||{},N=A.DOMPropertyNames||{},o=A.DOMMutationMethods||{};A.isCustomAttribute&&T._isCustomAttributeFunctions.push(A.isCustomAttribute);for(var n in t){T.properties.hasOwnProperty(n)?g(!1):void 0;var C=n.toLowerCase(),c=t[n],D={attributeName:C,attributeNamespace:null,propertyName:n,mutationMethod:null,mustUseAttribute:I(c,M.MUST_USE_ATTRIBUTE),mustUseProperty:I(c,M.MUST_USE_PROPERTY),hasSideEffects:I(c,M.HAS_SIDE_EFFECTS),hasBooleanValue:I(c,M.HAS_BOOLEAN_VALUE),hasNumericValue:I(c,M.HAS_NUMERIC_VALUE),hasPositiveNumericValue:I(c,M.HAS_POSITIVE_NUMERIC_VALUE),hasOverloadedBooleanValue:I(c,M.HAS_OVERLOADED_BOOLEAN_VALUE)};if(D.mustUseAttribute&&D.mustUseProperty?g(!1):void 0,!D.mustUseProperty&&D.hasSideEffects?g(!1):void 0,D.hasBooleanValue+D.hasNumericValue+D.hasOverloadedBooleanValue<=1?void 0:g(!1),E.hasOwnProperty(n)){var a=E[n];D.attributeName=a}i.hasOwnProperty(n)&&(D.attributeNamespace=i[n]),N.hasOwnProperty(n)&&(D.propertyName=N[n]),o.hasOwnProperty(n)&&(D.mutationMethod=o[n]),T.properties[n]=D}}},i={},T={ID_ATTRIBUTE_NAME:"data-reactid",properties:{},getPossibleStandardName:null,_isCustomAttributeFunctions:[],isCustomAttribute:function(A){for(var M=0;M1){var M=A.indexOf(c,1);return M>-1?A.substr(0,M):A}return null},traverseEnterLeave:function(A,M,t,I,g){var e=N(A,M);e!==A&&o(A,e,t,I,!1,!0),e!==M&&o(e,M,t,g,!0,!1)},traverseTwoPhase:function(A,M,t){A&&(o("",A,M,t,!0,!1),o(A,"",M,t,!1,!0))},traverseTwoPhaseSkipTarget:function(A,M,t){A&&(o("",A,M,t,!0,!0),o(A,"",M,t,!0,!0))},traverseAncestors:function(A,M,t){o("",A,M,t,!0,!1)},getFirstCommonAncestorID:N,_getNextDescendantID:E,isAncestorIDOf:i,SEPARATOR:c};A.exports=B},function(A,M){var t=A.exports={version:"1.2.6"};"number"==typeof __e&&(__e=t)},function(A,M,t){"use strict";var I={};A.exports=I},function(A,M,t){"use strict";function I(A,M,t){var I=0;return n.default.Children.map(A,function(A){if(n.default.isValidElement(A)){var g=I;return I++,M.call(t,A,g)}return A})}function g(A,M,t){var I=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I),I++)})}function e(A){var M=0;return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&M++}),M}function i(A){var M=!1;return n.default.Children.forEach(A,function(A){!M&&n.default.isValidElement(A)&&(M=!0)}),M}function T(A,M){var t=void 0;return g(A,function(I,g){!t&&M(I,g,A)&&(t=I)}),t}function E(A,M,t){var I=0,g=[];return n.default.Children.forEach(A,function(A){n.default.isValidElement(A)&&(M.call(t,A,I)&&g.push(A),I++)}),g}var N=t(6).default;M.__esModule=!0;var o=t(1),n=N(o);M.default={map:I,forEach:g,numberOf:e,find:T,findValidComponents:E,hasValidComponent:i},A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=function(A){return(0,T.default)(e.default.findDOMNode(A))};var g=t(16),e=I(g),i=t(39),T=I(i);A.exports=M.default},function(A,M,t){"use strict";var I=t(202),g=t(436),e=t(215),i=t(224),T=t(225),E=t(2),N=(t(3),{}),o=null,n=function(A,M){A&&(g.executeDispatchesInOrder(A,M),A.isPersistent()||A.constructor.release(A))},C=function(A){return n(A,!0)},c=function(A){return n(A,!1)},D=null,a={injection:{injectMount:g.injection.injectMount,injectInstanceHandle:function(A){D=A},getInstanceHandle:function(){return D},injectEventPluginOrder:I.injectEventPluginOrder,injectEventPluginsByName:I.injectEventPluginsByName},eventNameDispatchConfigs:I.eventNameDispatchConfigs,registrationNameModules:I.registrationNameModules,putListener:function(A,M,t){"function"!=typeof t?E(!1):void 0;var g=N[M]||(N[M]={});g[A]=t;var e=I.registrationNameModules[M];e&&e.didPutListener&&e.didPutListener(A,M,t)},getListener:function(A,M){var t=N[M];return t&&t[A]},deleteListener:function(A,M){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M);var g=N[M];g&&delete g[A]},deleteAllListeners:function(A){for(var M in N)if(N[M][A]){var t=I.registrationNameModules[M];t&&t.willDeleteListener&&t.willDeleteListener(A,M),delete N[M][A]}},extractEvents:function(A,M,t,g,e){for(var T,E=I.plugins,N=0;N1?I-1:0),e=1;e":">","<":"<",'"':""","'":"'"},e=/[&><"']/g;A.exports=I},function(A,M,t){"use strict";var I=t(10),g=/^[ \r\n\t\f]/,e=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,i=function(A,M){A.innerHTML=M};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(i=function(A,M){MSApp.execUnsafeLocalFunction(function(){A.innerHTML=M})}),I.canUseDOM){var T=document.createElement("div");T.innerHTML=" ",""===T.innerHTML&&(i=function(A,M){if(A.parentNode&&A.parentNode.replaceChild(A,A),g.test(M)||"<"===M[0]&&e.test(M)){A.innerHTML=String.fromCharCode(65279)+M;var t=A.firstChild;1===t.data.length?A.removeChild(t):t.deleteData(0,1)}else A.innerHTML=M})}A.exports=i},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=function(A){var M=A.label,t=A.id,I=A.name,g=A.value,i=A.onChange,T=A.type,E=A.spellCheck,N=A.required,o=A.readonly,n=A.autoComplete,C=A.align,c=A.className,D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n});return o&&(D=e.default.createElement("input",{id:t,name:I,value:g,onChange:i,className:"ig-text",type:T,spellCheck:E,required:N,autoComplete:n,disabled:!0})),e.default.createElement("div",{className:"input-group "+C+" "+c},D,e.default.createElement("i",{className:"ig-helpers"}),e.default.createElement("label",{className:"ig-label"},M))};M.default=i},function(A,M,t){A.exports={default:t(258),__esModule:!0}},function(A,M,t){var I=t(264),g=t(49),e=t(132),i="prototype",T=function(A,M,t){var E,N,o,n=A&T.F,C=A&T.G,c=A&T.S,D=A&T.P,a=A&T.B,B=A&T.W,Q=C?g:g[M]||(g[M]={}),r=C?I:c?I[M]:(I[M]||{})[i];C&&(t=M);for(E in t)N=!n&&r&&E in r,N&&E in Q||(o=N?r[E]:t[E],Q[E]=C&&"function"!=typeof r[E]?t[E]:a&&N?e(o,I):B&&r[E]==o?function(A){var M=function(M){return this instanceof A?new A(M):A(M)};return M[i]=A[i],M}(o):D&&"function"==typeof o?e(Function.call,o):o,D&&((Q[i]||(Q[i]={}))[E]=o))};T.F=1,T.G=2,T.S=4,T.P=8,T.B=16,T.W=32,A.exports=T},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M,t){"use strict";var I=t(32),g=function(){};I&&(g=function(){return document.addEventListener?function(A,M,t,I){return A.addEventListener(M,t,I||!1)}:document.attachEvent?function(A,M,t){return A.attachEvent("on"+M,t)}:void 0}()),A.exports=g},function(A,M,t){"use strict";var I=t(143),g=t(294),e=t(289),i=t(290),T=Object.prototype.hasOwnProperty;A.exports=function(A,M,t){var E="",N=M;if("string"==typeof M){if(void 0===t)return A.style[I(M)]||e(A).getPropertyValue(g(M));(N={})[M]=t}for(var o in N)T.call(N,o)&&(N[o]||0===N[o]?E+=g(o)+":"+N[o]+";":i(A,g(o)));A.style.cssText+=";"+E}},function(A,M,t){(function(){var t=this,I=t.humanize,g={};"undefined"!=typeof A&&A.exports&&(M=A.exports=g),M.humanize=g,g.noConflict=function(){return t.humanize=I,this},g.pad=function(A,M,t,I){if(A+="",t?t.length>1&&(t=t.charAt(0)):t=" ",I=void 0===I?"left":"right","right"===I)for(;A.length4&&A<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th"},w:function(){return t.getDay()},z:function(){return(o.L()?i[o.n()]:e[o.n()])+o.j()-1},W:function(){var A=o.z()-o.N()+1.5;return g.pad(1+Math.floor(Math.abs(A)/7)+(A%7>3.5?1:0),2,"0")},F:function(){return N[t.getMonth()]},m:function(){return g.pad(o.n(),2,"0")},M:function(){return o.F().slice(0,3)},n:function(){return t.getMonth()+1},t:function(){return new Date(o.Y(),o.n(),0).getDate()},L:function(){return 1===new Date(o.Y(),1,29).getMonth()?1:0},o:function(){var A=o.n(),M=o.W();return o.Y()+(12===A&&M<9?-1:1===A&&M>9)},Y:function(){return t.getFullYear()},y:function(){return String(o.Y()).slice(-2)},a:function(){return t.getHours()>11?"pm":"am"},A:function(){return o.a().toUpperCase()},B:function(){var A=t.getTime()/1e3,M=A%86400+3600;M<0&&(M+=86400);var I=M/86.4%1e3;return A<0?Math.ceil(I):Math.floor(I)},g:function(){return o.G()%12||12},G:function(){return t.getHours()},h:function(){return g.pad(o.g(),2,"0")},H:function(){return g.pad(o.G(),2,"0")},i:function(){return g.pad(t.getMinutes(),2,"0")},s:function(){return g.pad(t.getSeconds(),2,"0")},u:function(){return g.pad(1e3*t.getMilliseconds(),6,"0")},O:function(){var A=t.getTimezoneOffset(),M=Math.abs(A);return(A>0?"-":"+")+g.pad(100*Math.floor(M/60)+M%60,4,"0")},P:function(){var A=o.O();return A.substr(0,3)+":"+A.substr(3,2)},Z:function(){return 60*-t.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(I,T)},r:function(){return"D, d M Y H:i:s O".replace(I,T)},U:function(){return t.getTime()/1e3||0}};return A.replace(I,T)},g.numberFormat=function(A,M,t,I){M=isNaN(M)?2:Math.abs(M),t=void 0===t?".":t,I=void 0===I?",":I;var g=A<0?"-":"";A=Math.abs(+A||0);var e=parseInt(A.toFixed(M),10)+"",i=e.length>3?e.length%3:0;return g+(i?e.substr(0,i)+I:"")+e.substr(i).replace(/(\d{3})(?=\d)/g,"$1"+I)+(M?t+Math.abs(A-e).toFixed(M).slice(2):"")},g.naturalDay=function(A,M){A=void 0===A?g.time():A,M=void 0===M?"Y-m-d":M;var t=86400,I=new Date,e=new Date(I.getFullYear(),I.getMonth(),I.getDate()).getTime()/1e3;return A=e-t?"yesterday":A>=e&&A=e+t&&A-2)return(t>=0?"just ":"")+"now";if(t<60&&t>-60)return t>=0?Math.floor(t)+" seconds ago":"in "+Math.floor(-t)+" seconds";if(t<120&&t>-120)return t>=0?"about a minute ago":"in about a minute";if(t<3600&&t>-3600)return t>=0?Math.floor(t/60)+" minutes ago":"in "+Math.floor(-t/60)+" minutes";if(t<7200&&t>-7200)return t>=0?"about an hour ago":"in about an hour";if(t<86400&&t>-86400)return t>=0?Math.floor(t/3600)+" hours ago":"in "+Math.floor(-t/3600)+" hours";var I=172800;if(t-I)return t>=0?"1 day ago":"in 1 day";var e=2505600;if(t-e)return t>=0?Math.floor(t/86400)+" days ago":"in "+Math.floor(-t/86400)+" days";var i=5184e3;if(t-i)return t>=0?"about a month ago":"in about a month";var T=parseInt(g.date("Y",M),10),E=parseInt(g.date("Y",A),10),N=12*T+parseInt(g.date("n",M),10),o=12*E+parseInt(g.date("n",A),10),n=N-o;if(n<12&&n>-12)return n>=0?n+" months ago":"in "+-n+" months";var C=T-E;return C<2&&C>-2?C>=0?"a year ago":"in a year":C>=0?C+" years ago":"in "+-C+" years"},g.ordinal=function(A){A=parseInt(A,10),A=isNaN(A)?0:A;var M=A<0?"-":"";A=Math.abs(A);var t=A%100;return M+A+(t>4&&t<21?"th":{1:"st",2:"nd",3:"rd"}[A%10]||"th")},g.filesize=function(A,M,t,I,e,i){return M=void 0===M?1024:M,A<=0?"0 bytes":(A

    "),A=A.replace(/\n/g,"
    "),"

    "+A+"

    "},g.nl2br=function(A){return A.replace(/(\r\n|\n|\r)/g,"
    ")},g.truncatechars=function(A,M){return A.length<=M?A:A.substr(0,M)+"…"},g.truncatewords=function(A,M){var t=A.split(" ");return t.length0,Q=C.enumErrorProps&&(A===u||A instanceof Error),r=C.enumPrototypes&&T(A);++IM.documentElement.clientHeight;return{modalStyles:{paddingRight:I&&!g?Q.default():void 0,paddingLeft:!I&&g?Q.default():void 0}}}});v.Body=z.default,v.Header=U.default,v.Title=m.default,v.Footer=f.default,v.Dialog=h.default,v.TRANSITION_DURATION=300,v.BACKDROP_TRANSITION_DURATION=150,M.default=c.bsSizes([a.Sizes.LARGE,a.Sizes.SMALL],c.bsClass("modal",v)),A.exports=M.default},function(A,M,t){"use strict";var I=t(15).default,g=t(14).default,e=t(38).default,i=t(7).default,T=t(6).default; +M.__esModule=!0;var E=t(1),N=T(E),o=t(5),n=T(o),C=t(11),c=T(C),D=t(44),a=T(D),B=function(A){function M(){g(this,M),A.apply(this,arguments)}return I(M,A),M.prototype.render=function(){var A=this.props,M=A["aria-label"],t=e(A,["aria-label"]),I=a.default(this.context.$bs_onModalHide,this.props.onHide);return N.default.createElement("div",i({},t,{className:n.default(this.props.className,c.default.prefix(this.props,"header"))}),this.props.closeButton&&N.default.createElement("button",{type:"button",className:"close","aria-label":M,onClick:I},N.default.createElement("span",{"aria-hidden":"true"},"×")),this.props.children)},M}(N.default.Component);B.propTypes={"aria-label":N.default.PropTypes.string,bsClass:N.default.PropTypes.string,closeButton:N.default.PropTypes.bool,onHide:N.default.PropTypes.func},B.contextTypes={$bs_onModalHide:N.default.PropTypes.func},B.defaultProps={"aria-label":"Close",closeButton:!1},M.default=C.bsClass("modal",B),A.exports=M.default},function(A,M,t){"use strict";function I(A,M){return Array.isArray(M)?M.indexOf(A)>=0:A===M}var g=t(7).default,e=t(78).default,i=t(6).default;M.__esModule=!0;var T=t(40),E=i(T),N=t(168),o=i(N),n=t(1),C=i(n),c=t(16),D=i(c),a=t(127),B=(i(a),t(369)),Q=i(B),r=t(44),s=i(r),x=C.default.createClass({displayName:"OverlayTrigger",propTypes:g({},Q.default.propTypes,{trigger:C.default.PropTypes.oneOfType([C.default.PropTypes.oneOf(["click","hover","focus"]),C.default.PropTypes.arrayOf(C.default.PropTypes.oneOf(["click","hover","focus"]))]),delay:C.default.PropTypes.number,delayShow:C.default.PropTypes.number,delayHide:C.default.PropTypes.number,defaultOverlayShown:C.default.PropTypes.bool,overlay:C.default.PropTypes.node.isRequired,onBlur:C.default.PropTypes.func,onClick:C.default.PropTypes.func,onFocus:C.default.PropTypes.func,onMouseEnter:C.default.PropTypes.func,onMouseLeave:C.default.PropTypes.func,target:function(){},onHide:function(){},show:function(){}}),getDefaultProps:function(){return{defaultOverlayShown:!1,trigger:["hover","focus"]}},getInitialState:function(){return{isOverlayShown:this.props.defaultOverlayShown}},show:function(){this.setState({isOverlayShown:!0})},hide:function(){this.setState({isOverlayShown:!1})},toggle:function(){this.state.isOverlayShown?this.hide():this.show()},componentWillMount:function(){this.handleMouseOver=this.handleMouseOverOut.bind(null,this.handleDelayedShow),this.handleMouseOut=this.handleMouseOverOut.bind(null,this.handleDelayedHide)},componentDidMount:function(){this._mountNode=document.createElement("div"),this.renderOverlay()},renderOverlay:function(){D.default.unstable_renderSubtreeIntoContainer(this,this._overlay,this._mountNode)},componentWillUnmount:function(){D.default.unmountComponentAtNode(this._mountNode),this._mountNode=null,clearTimeout(this._hoverShowDelay),clearTimeout(this._hoverHideDelay)},componentDidUpdate:function(){this._mountNode&&this.renderOverlay()},getOverlayTarget:function(){return D.default.findDOMNode(this)},getOverlay:function(){var A=g({},o.default(this.props,e(Q.default.propTypes)),{show:this.state.isOverlayShown,onHide:this.hide,target:this.getOverlayTarget,onExit:this.props.onExit,onExiting:this.props.onExiting,onExited:this.props.onExited,onEnter:this.props.onEnter,onEntering:this.props.onEntering,onEntered:this.props.onEntered}),M=n.cloneElement(this.props.overlay,{placement:A.placement,container:A.container});return C.default.createElement(Q.default,A,M)},render:function(){var A=C.default.Children.only(this.props.children),M=A.props,t={"aria-describedby":this.props.overlay.props.id};return this._overlay=this.getOverlay(),t.onClick=s.default(M.onClick,this.props.onClick),I("click",this.props.trigger)&&(t.onClick=s.default(this.toggle,t.onClick)),I("hover",this.props.trigger)&&(t.onMouseOver=s.default(this.handleMouseOver,this.props.onMouseOver,M.onMouseOver),t.onMouseOut=s.default(this.handleMouseOut,this.props.onMouseOut,M.onMouseOut)),I("focus",this.props.trigger)&&(t.onFocus=s.default(this.handleDelayedShow,this.props.onFocus,M.onFocus),t.onBlur=s.default(this.handleDelayedHide,this.props.onBlur,M.onBlur)),n.cloneElement(A,t)},handleDelayedShow:function(){var A=this;if(null!=this._hoverHideDelay)return clearTimeout(this._hoverHideDelay),void(this._hoverHideDelay=null);if(!this.state.isOverlayShown&&null==this._hoverShowDelay){var M=null!=this.props.delayShow?this.props.delayShow:this.props.delay;return M?void(this._hoverShowDelay=setTimeout(function(){A._hoverShowDelay=null,A.show()},M)):void this.show()}},handleDelayedHide:function(){var A=this;if(null!=this._hoverShowDelay)return clearTimeout(this._hoverShowDelay),void(this._hoverShowDelay=null);if(this.state.isOverlayShown&&null==this._hoverHideDelay){var M=null!=this.props.delayHide?this.props.delayHide:this.props.delay;return M?void(this._hoverHideDelay=setTimeout(function(){A._hoverHideDelay=null,A.hide()},M)):void this.hide()}},handleMouseOverOut:function(A,M){var t=M.currentTarget,I=M.relatedTarget||M.nativeEvent.toElement;I&&(I===t||E.default(t,I))||A(M)}});M.default=x,A.exports=M.default},function(A,M,t){"use strict";var I=t(7).default,g=t(6).default;M.__esModule=!0;var e=t(1),i=g(e),T=t(5),E=g(T),N=t(11),o=g(N),n=t(181),C=g(n),c=i.default.createClass({displayName:"Tooltip",propTypes:{id:C.default(i.default.PropTypes.oneOfType([i.default.PropTypes.string,i.default.PropTypes.number])),placement:i.default.PropTypes.oneOf(["top","right","bottom","left"]),positionLeft:i.default.PropTypes.number,positionTop:i.default.PropTypes.number,arrowOffsetLeft:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),arrowOffsetTop:i.default.PropTypes.oneOfType([i.default.PropTypes.number,i.default.PropTypes.string]),title:i.default.PropTypes.node},getDefaultProps:function(){return{bsClass:"tooltip",placement:"right"}},render:function(){var A,M=(A={},A[o.default.prefix(this.props)]=!0,A[this.props.placement]=!0,A),t=I({left:this.props.positionLeft,top:this.props.positionTop},this.props.style),g={left:this.props.arrowOffsetLeft,top:this.props.arrowOffsetTop};return i.default.createElement("div",I({role:"tooltip"},this.props,{className:E.default(this.props.className,M),style:t}),i.default.createElement("div",{className:o.default.prefix(this.props,"arrow"),style:g}),i.default.createElement("div",{className:o.default.prefix(this.props,"inner")},this.props.children))}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return A="function"==typeof A?A():A,i.default.findDOMNode(A)||M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=g;var e=t(16),i=I(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement. You can usually obtain a ReactComponent or DOMElement from a ReactElement by attaching a ref to it."):"object"===E&&"function"==typeof i.render||1===i.nodeType?null:new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected a ReactComponent or a ")+"DOMElement.")}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(180),N=I(E);M.default=(0,N.default)(g)},function(A,M,t){"use strict";function I(){function A(A,M,I){for(var g=0;g>",null!=t[I]?A(t,I,g):M?new Error("Required prop '"+I+"' was not specified in '"+g+"'."):void 0}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}M.__esModule=!0,M.errMsg=t,M.createChainableTypeChecker=I},function(A,M){"use strict";function t(A,M,t){function I(){return i=!0,T?void(N=[].concat(Array.prototype.slice.call(arguments))):void t.apply(this,arguments)}function g(){if(!i&&(E=!0,!T)){for(T=!0;!i&&e=A&&E&&(i=!0,t()))}}var e=0,i=!1,T=!1,E=!1,N=void 0;g()}function I(A,M,t){function I(A,M,I){i||(M?(i=!0,t(M)):(e[A]=I,i=++T===g,i&&t(null,e)))}var g=A.length,e=[];if(0===g)return t(null,e);var i=!1,T=0;A.forEach(function(A,t){M(A,t,function(A,M){I(t,A,M)})})}M.__esModule=!0,M.loopAsync=t,M.mapAsync=I},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0,M.router=M.routes=M.route=M.components=M.component=M.location=M.history=M.falsy=M.locationShape=M.routerShape=void 0;var e=t(1),i=t(66),T=(g(i),t(34)),E=I(T),N=t(9),o=(g(N),e.PropTypes.func),n=e.PropTypes.object,C=e.PropTypes.shape,c=e.PropTypes.string,D=M.routerShape=C({push:o.isRequired,replace:o.isRequired,go:o.isRequired,goBack:o.isRequired,goForward:o.isRequired,setRouteLeaveHook:o.isRequired,isActive:o.isRequired}),a=M.locationShape=C({pathname:c.isRequired,search:c.isRequired,state:n,action:c.isRequired,key:c}),B=M.falsy=E.falsy,Q=M.history=E.history,r=M.location=a,s=M.component=E.component,x=M.components=E.components,j=M.route=E.route,y=(M.routes=E.routes,M.router=D),u={falsy:B,history:Q,location:r,component:s,components:x,route:j,router:y};M.default=u},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!0;return!1}function e(A,M){function t(M){var t=!(arguments.length<=1||void 0===arguments[1])&&arguments[1],I=arguments.length<=2||void 0===arguments[2]?null:arguments[2],g=void 0;return t&&t!==!0||null!==I?(M={pathname:M,query:t},g=I||!1):(M=A.createLocation(M),g=t),(0,C.default)(M,g,s.location,s.routes,s.params)}function I(A,t){x&&x.location===A?e(x,t):(0,B.default)(M,A,function(M,I){M?t(M):I?e(i({},I,{location:A}),t):t()})}function e(A,M){function t(t,g){return t||g?I(t,g):void(0,D.default)(A,function(t,I){t?M(t):M(null,null,s=i({},A,{components:I}))})}function I(A,t){A?M(A):M(null,t)}var g=(0,N.default)(s,A),e=g.leaveRoutes,T=g.changeRoutes,E=g.enterRoutes;(0,o.runLeaveHooks)(e,s),e.filter(function(A){return E.indexOf(A)===-1}).forEach(a),(0,o.runChangeHooks)(T,s,A,function(M,g){return M||g?I(M,g):void(0,o.runEnterHooks)(E,A,t)})}function T(A){var M=arguments.length<=1||void 0===arguments[1]||arguments[1];return A.__id__||M&&(A.__id__=j++)}function E(A){return A.reduce(function(A,M){return A.push.apply(A,y[T(M)]),A},[])}function n(A,t){(0,B.default)(M,A,function(M,I){if(null==I)return void t();x=i({},I,{location:A});for(var g=E((0,N.default)(s,x).leaveRoutes),e=void 0,T=0,o=g.length;null==e&&T=32||13===M?M:0}A.exports=t},function(A,M){"use strict";function t(A){var M=this,t=M.nativeEvent;if(t.getModifierState)return t.getModifierState(A);var I=g[A];return!!I&&!!t[I]}function I(A){return t}var g={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};A.exports=I},function(A,M){"use strict";function t(A){var M=A.target||A.srcElement||window;return 3===M.nodeType?M.parentNode:M}A.exports=t},function(A,M){"use strict";function t(A){var M=A&&(I&&A[I]||A[g]);if("function"==typeof M)return M}var I="function"==typeof Symbol&&Symbol.iterator,g="@@iterator";A.exports=t},function(A,M,t){"use strict";function I(A){return"function"==typeof A&&"undefined"!=typeof A.prototype&&"function"==typeof A.prototype.mountComponent&&"function"==typeof A.prototype.receiveComponent}function g(A){var M;if(null===A||A===!1)M=new i(g);else if("object"==typeof A){var t=A;!t||"function"!=typeof t.type&&"string"!=typeof t.type?N(!1):void 0,M="string"==typeof t.type?T.createInternalComponent(t):I(t.type)?new t.type(t):new o}else"string"==typeof A||"number"==typeof A?M=T.createInstanceForText(A):N(!1);return M.construct(A),M._mountIndex=0,M._mountImage=null,M}var e=t(442),i=t(213),T=t(219),E=t(4),N=t(2),o=(t(3),function(){});E(o.prototype,e.Mixin,{_instantiateReactComponent:g}),A.exports=g},function(A,M,t){"use strict";/** * Checks if an event is supported in the current execution environment. * * NOTE: This will not work correctly for non-generic events such as ` + "`" + `change` + "`" + `, @@ -200,42 +200,42 @@ v.Title=m.default,v.Footer=f.default,v.Dialog=h.default,v.TRANSITION_DURATION=30 * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */ -function I(A,M){if(!e.canUseDOM||M&&!("addEventListener"in document))return!1;var t="on"+A,I=t in document;if(!I){var i=document.createElement("div");i.setAttribute(t,"return;"),I="function"==typeof i[t]}return!I&&g&&"wheel"===A&&(I=document.implementation.hasFeature("Events.wheel","3.0")),I}var g,e=t(10);e.canUseDOM&&(g=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),A.exports=I},function(A,M,t){"use strict";var I=t(10),g=t(75),e=t(76),i=function(A,M){A.textContent=M};I.canUseDOM&&("textContent"in document.documentElement||(i=function(A,M){e(A,g(M))})),A.exports=i},function(A,M){"use strict";function t(A,M){var t=null===A||A===!1,I=null===M||M===!1;if(t||I)return t===I;var g=typeof A,e=typeof M;return"string"===g||"number"===g?"string"===e||"number"===e:"object"===e&&A.type===M.type&&A.key===M.key}A.exports=t},function(A,M,t){"use strict";function I(A){return a[A]}function g(A,M){return A&&null!=A.key?i(A.key):M.toString(36)}function e(A){return(""+A).replace(B,I)}function i(A){return"$"+e(A)}function T(A,M,t,I){var e=typeof A;if("undefined"!==e&&"boolean"!==e||(A=null),null===A||"string"===e||"number"===e||N.isValidElement(A))return t(I,A,""===M?c+g(A,0):M),1;var E,o,a=0,B=""===M?c:M+D;if(Array.isArray(A))for(var Q=0;QM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;t":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;i":i.innerHTML="<"+A+">",T[A]=!i.firstChild),T[A]?C[A]:null}var g=t(10),e=t(2),i=g.canUseDOM?document.createElement("div"):null,T={},E=[1,'"],N=[1,"","
    "],o=[3,"","
    "],n=[1,'',""],C={"*":[1,"?
    ","
    "],area:[1,"",""],col:[2,"","
    "],legend:[1,"
    ","
    "],param:[1,"",""],tr:[2,"","
    "],optgroup:E,option:E,caption:N,colgroup:N,tbody:N,tfoot:N,thead:N,td:o,th:o},c=["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"];c.forEach(function(A){C[A]=n,T[A]=!0}),A.exports=I},function(A,M){"use strict";function t(A,M){if(A===M)return!0;if("object"!=typeof A||null===A||"object"!=typeof M||null===M)return!1;var t=Object.keys(A),g=Object.keys(M);if(t.length!==g.length)return!1;for(var e=I.bind(M),i=0;i-1&&A%1==0&&A1)for(var t=1;tA.clientHeight}Object.defineProperty(M,"__esModule",{value:!0}),M.default=i;var T=t(57),E=I(T),N=t(39),o=I(N);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):"function"!==E&&"string"!==E?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):null}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(182),N=I(E);M.default=(0,N.default)(g)},function(A,M){"use strict";function t(A){function M(M,t,I,g,e,i){var T=g||"<>",E=i||I;if(null==t[I])return M?new Error("Required "+e+" ` + "`" + `"+E+"` + "`" + ` was not specified "+("in ` + "`" + `"+T+"` + "`" + `.")):null;for(var N=arguments.length,o=Array(N>6?N-6:0),n=6;n=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return 0===A.button}function i(A){return!!(A.metaKey||A.altKey||A.ctrlKey||A.shiftKey)}function T(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!1;return!0}function E(A,M){var t=M.query,I=M.hash,g=M.state;return t||I||g?{pathname:A,query:t,hash:I,state:g}:A}M.__esModule=!0;var N=Object.assign||function(A){for(var M=1;M=0;I--){var g=A[I],e=g.path||"";if(t=e.replace(/\/*$/,"/")+t,0===e.indexOf("/"))break}return"/"+t}},propTypes:{path:C,from:C,to:C.isRequired,query:c,state:c,onEnter:o.falsy,children:o.falsy},render:function(){(0,T.default)(!1)}});M.default=D,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0;var g=t(1),e=I(g),i=t(8),T=I(i),E=t(30),N=t(34),o=e.default.PropTypes,n=o.string,C=o.func,c=e.default.createClass({displayName:"Route",statics:{createRouteFromReactElement:E.createRouteFromReactElement},propTypes:{path:n,component:N.component,components:N.components,getComponent:C,getComponents:C},render:function(){(0,T.default)(!1)}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return!A||!A.__v2_compatible__}function i(A){return A&&A.getCurrentLocation}M.__esModule=!0;var T=Object.assign||function(A){for(var M=1;M=0&&0===window.sessionStorage.length)return;throw A}}function i(A){var M=void 0;try{M=window.sessionStorage.getItem(g(A))}catch(A){if(A.name===o)return null}if(M)try{return JSON.parse(M)}catch(A){}return null}M.__esModule=!0,M.saveState=e,M.readState=i;var T=t(23),E=(I(T),"@@History/"),N=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],o="SecurityError"},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){function M(A){return E.canUseDOM?void 0:T.default(!1),t.listen(A)}var t=n.default(e({getUserConfirmation:N.getUserConfirmation},A,{go:N.go}));return e({},t,{listen:M})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M1?M-1:0),e=1;e=A.childNodes.length?null:A.childNodes.item(t);A.insertBefore(M,I)}var g=t(434),e=t(220),i=t(17),T=t(76),E=t(121),N=t(2),o={dangerouslyReplaceNodeWithMarkup:g.dangerouslyReplaceNodeWithMarkup,updateTextContent:E,processUpdates:function(A,M){for(var t,i=null,o=null,n=0;n-1?void 0:i(!1),!N.plugins[t]){M.extractEvents?void 0:i(!1),N.plugins[t]=M;var I=M.eventTypes;for(var e in I)g(I[e],M,e)?void 0:i(!1)}}}function g(A,M,t){N.eventNameDispatchConfigs.hasOwnProperty(t)?i(!1):void 0,N.eventNameDispatchConfigs[t]=A;var I=A.phasedRegistrationNames;if(I){for(var g in I)if(I.hasOwnProperty(g)){var T=I[g];e(T,M,t)}return!0}return!!A.registrationName&&(e(A.registrationName,M,t),!0)}function e(A,M,t){N.registrationNameModules[A]?i(!1):void 0,N.registrationNameModules[A]=M,N.registrationNameDependencies[A]=M.eventTypes[t].dependencies}var i=t(2),T=null,E={},N={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(A){T?i(!1):void 0,T=Array.prototype.slice.call(A),I()},injectEventPluginsByName:function(A){var M=!1;for(var t in A)if(A.hasOwnProperty(t)){var g=A[t];E.hasOwnProperty(t)&&E[t]===g||(E[t]?i(!1):void 0,E[t]=g,M=!0)}M&&I()},getPluginModuleForEvent:function(A){var M=A.dispatchConfig;if(M.registrationName)return N.registrationNameModules[M.registrationName]||null;for(var t in M.phasedRegistrationNames)if(M.phasedRegistrationNames.hasOwnProperty(t)){var I=N.registrationNameModules[M.phasedRegistrationNames[t]];if(I)return I}return null},_resetEventPlugins:function(){T=null;for(var A in E)E.hasOwnProperty(A)&&delete E[A];N.plugins.length=0;var M=N.eventNameDispatchConfigs;for(var t in M)M.hasOwnProperty(t)&&delete M[t];var I=N.registrationNameModules;for(var g in I)I.hasOwnProperty(g)&&delete I[g]}};A.exports=N},function(A,M,t){"use strict";function I(A){return(""+A).replace(x,"//")}function g(A,M){this.func=A,this.context=M,this.count=0}function e(A,M,t){var I=A.func,g=A.context;I.call(g,M,A.count++)}function i(A,M,t){if(null==A)return A;var I=g.getPooled(M,t);Q(A,e,I),g.release(I)}function T(A,M,t,I){this.result=A,this.keyPrefix=M,this.func=t,this.context=I,this.count=0}function E(A,M,t){var g=A.result,e=A.keyPrefix,i=A.func,T=A.context,E=i.call(T,M,A.count++);Array.isArray(E)?N(E,g,t,B.thatReturnsArgument):null!=E&&(a.isValidElement(E)&&(E=a.cloneAndReplaceKey(E,e+(E!==M?I(E.key||"")+"/":"")+t)),g.push(E))}function N(A,M,t,g,e){var i="";null!=t&&(i=I(t)+"/");var N=T.getPooled(M,i,g,e);Q(A,E,N),T.release(N)}function o(A,M,t){if(null==A)return A;var I=[];return N(A,I,null,M,t),I}function n(A,M,t){return null}function C(A,M){return Q(A,n,null)}function c(A){var M=[];return N(A,M,null,B.thatReturnsArgument),M}var D=t(31),a=t(13),B=t(20),Q=t(123),r=D.twoArgumentPooler,s=D.fourArgumentPooler,x=/\/(?!\/)/g;g.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},D.addPoolingTo(g,r),T.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},D.addPoolingTo(T,s);var j={forEach:i,map:o,mapIntoWithKeyPrefixInternal:N,count:C,toArray:c};A.exports=j},function(A,M,t){"use strict";function I(A,M){var t=y.hasOwnProperty(M)?y[M]:null;w.hasOwnProperty(M)&&(t!==x.OVERRIDE_BASE?B(!1):void 0),A.hasOwnProperty(M)&&(t!==x.DEFINE_MANY&&t!==x.DEFINE_MANY_MERGED?B(!1):void 0)}function g(A,M){if(M){"function"==typeof M?B(!1):void 0,C.isValidElement(M)?B(!1):void 0;var t=A.prototype;M.hasOwnProperty(s)&&u.mixins(A,M.mixins);for(var g in M)if(M.hasOwnProperty(g)&&g!==s){var e=M[g];if(I(t,g),u.hasOwnProperty(g))u[g](A,e);else{var i=y.hasOwnProperty(g),N=t.hasOwnProperty(g),o="function"==typeof e,n=o&&!i&&!N&&M.autobind!==!1;if(n)t.__reactAutoBindMap||(t.__reactAutoBindMap={}),t.__reactAutoBindMap[g]=e,t[g]=e;else if(N){var c=y[g];!i||c!==x.DEFINE_MANY_MERGED&&c!==x.DEFINE_MANY?B(!1):void 0,c===x.DEFINE_MANY_MERGED?t[g]=T(t[g],e):c===x.DEFINE_MANY&&(t[g]=E(t[g],e))}else t[g]=e}}}}function e(A,M){if(M)for(var t in M){var I=M[t];if(M.hasOwnProperty(t)){var g=t in u;g?B(!1):void 0;var e=t in A;e?B(!1):void 0,A[t]=I}}}function i(A,M){A&&M&&"object"==typeof A&&"object"==typeof M?void 0:B(!1);for(var t in M)M.hasOwnProperty(t)&&(void 0!==A[t]?B(!1):void 0,A[t]=M[t]);return A}function T(A,M){return function(){var t=A.apply(this,arguments),I=M.apply(this,arguments);if(null==t)return I;if(null==I)return t;var g={};return i(g,t),i(g,I),g}}function E(A,M){return function(){A.apply(this,arguments),M.apply(this,arguments)}}function N(A,M){var t=M.bind(A);return t}function o(A){for(var M in A.__reactAutoBindMap)if(A.__reactAutoBindMap.hasOwnProperty(M)){var t=A.__reactAutoBindMap[M];A[M]=N(A,t)}}var n=t(207),C=t(13),c=(t(71),t(70),t(222)),D=t(4),a=t(50),B=t(2),Q=t(59),r=t(27),s=(t(3),r({mixins:null})),x=Q({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),j=[],y={mixins:x.DEFINE_MANY,statics:x.DEFINE_MANY,propTypes:x.DEFINE_MANY,contextTypes:x.DEFINE_MANY,childContextTypes:x.DEFINE_MANY,getDefaultProps:x.DEFINE_MANY_MERGED,getInitialState:x.DEFINE_MANY_MERGED,getChildContext:x.DEFINE_MANY_MERGED,render:x.DEFINE_ONCE,componentWillMount:x.DEFINE_MANY,componentDidMount:x.DEFINE_MANY,componentWillReceiveProps:x.DEFINE_MANY,shouldComponentUpdate:x.DEFINE_ONCE,componentWillUpdate:x.DEFINE_MANY,componentDidUpdate:x.DEFINE_MANY,componentWillUnmount:x.DEFINE_MANY,updateComponent:x.OVERRIDE_BASE},u={displayName:function(A,M){A.displayName=M},mixins:function(A,M){if(M)for(var t=0;t"+T+""},receiveComponent:function(A,M){if(A!==this._currentElement){this._currentElement=A;var t=""+A;if(t!==this._stringText){this._stringText=t;var g=i.getNode(this._rootNodeID);I.updateTextContent(g,t)}}},unmountComponent:function(){e.unmountIDFromEnvironment(this._rootNodeID)}}),A.exports=o},function(A,M,t){"use strict";function I(){this.reinitializeTransaction()}var g=t(18),e=t(73),i=t(4),T=t(20),E={initialize:T,close:function(){C.isBatchingUpdates=!1}},N={initialize:T,close:g.flushBatchedUpdates.bind(g)},o=[N,E];i(I.prototype,e.Mixin,{getTransactionWrappers:function(){return o}});var n=new I,C={isBatchingUpdates:!1,batchedUpdates:function(A,M,t,I,g,e){var i=C.isBatchingUpdates;C.isBatchingUpdates=!0,i?A(M,t,I,g,e):n.perform(A,null,M,t,I,g,e)}};A.exports=C},function(A,M,t){"use strict";function I(){if(!l){l=!0,Q.EventEmitter.injectReactEventListener(B),Q.EventPluginHub.injectEventPluginOrder(T),Q.EventPluginHub.injectInstanceHandle(r),Q.EventPluginHub.injectMount(s),Q.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:u,EnterLeaveEventPlugin:E,ChangeEventPlugin:e,SelectEventPlugin:j,BeforeInputEventPlugin:g}),Q.NativeComponent.injectGenericComponentClass(D),Q.NativeComponent.injectTextComponentClass(a),Q.Class.injectMixin(n),Q.DOMProperty.injectDOMPropertyConfig(o),Q.DOMProperty.injectDOMPropertyConfig(w),Q.EmptyComponent.injectEmptyComponent("noscript"),Q.Updates.injectReconcileTransaction(x),Q.Updates.injectBatchingStrategy(c),Q.RootIndex.injectCreateReactRootIndex(N.canUseDOM?i.createReactRootIndex:y.createReactRootIndex),Q.Component.injectEnvironment(C)}}var g=t(430),e=t(432),i=t(433),T=t(435),E=t(436),N=t(10),o=t(439),n=t(441),C=t(109),c=t(212),D=t(445),a=t(211),B=t(453),Q=t(454),r=t(48),s=t(12),x=t(458),j=t(464),y=t(465),u=t(466),w=t(463),l=!1;A.exports={inject:I}},function(A,M,t){"use strict";function I(){if(n.current){var A=n.current.getName();if(A)return" Check the render method of ` + "`" + `"+A+"` + "`" + `."}return""}function g(A,M){if(A._store&&!A._store.validated&&null==A.key){A._store.validated=!0;e("uniqueKey",A,M)}}function e(A,M,t){var g=I();if(!g){var e="string"==typeof t?t:t.displayName||t.name;e&&(g=" Check the top-level render call using <"+e+">.")}var i=D[A]||(D[A]={});if(i[g])return null;i[g]=!0;var T={parentOrOwner:g,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return M&&M._owner&&M._owner!==n.current&&(T.childOwner=" It was passed a child from "+M._owner.getName()+"."),T}function i(A,M){if("object"==typeof A)if(Array.isArray(A))for(var t=0;t/,e={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(A){var M=I(A);return A.replace(g," "+e.CHECKSUM_ATTR_NAME+'="'+M+'"$&')},canReuseMarkup:function(A,M){var t=M.getAttribute(e.CHECKSUM_ATTR_NAME);t=t&&parseInt(t,10);var g=I(A);return g===t}};A.exports=e},function(A,M,t){"use strict";var I=t(59),g=I({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,SET_MARKUP:null,TEXT_CONTENT:null});A.exports=g},function(A,M,t){"use strict";function I(A){if("function"==typeof A.type)return A.type;var M=A.type,t=n[M];return null==t&&(n[M]=t=N(M)),t}function g(A){return o?void 0:E(!1),new o(A.type,A.props)}function e(A){return new C(A)}function i(A){return A instanceof C}var T=t(4),E=t(2),N=null,o=null,n={},C=null,c={injectGenericComponentClass:function(A){o=A},injectTextComponentClass:function(A){C=A},injectComponentClasses:function(A){T(n,A)}},D={getComponentClassForElement:I,createInternalComponent:g,createInstanceForText:e,isTextComponent:i,injection:c};A.exports=D},function(A,M,t){"use strict";function I(A,M){}var g=(t(3),{isMounted:function(A){return!1},enqueueCallback:function(A,M){},enqueueForceUpdate:function(A){I(A,"forceUpdate")},enqueueReplaceState:function(A,M){I(A,"replaceState")},enqueueSetState:function(A,M){I(A,"setState")},enqueueSetProps:function(A,M){I(A,"setProps")},enqueueReplaceProps:function(A,M){I(A,"replaceProps")}});A.exports=g},function(A,M,t){"use strict";function I(A){function M(M,t,I,g,e,i){if(g=g||y,i=i||I,null==t[I]){var T=s[e];return M?new Error("Required "+T+" ` + "`" + `"+i+"` + "`" + ` was not specified in "+("` + "`" + `"+g+"` + "`" + `.")):null}return A(t,I,g,e,i)}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}function g(A){function M(M,t,I,g,e){var i=M[t],T=a(i);if(T!==A){var E=s[g],N=B(i);return new Error("Invalid "+E+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+N+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected ")+("` + "`" + `"+A+"` + "`" + `."))}return null}return I(M)}function e(){return I(x.thatReturns(null))}function i(A){function M(M,t,I,g,e){var i=M[t];if(!Array.isArray(i)){var T=s[g],E=a(i);return new Error("Invalid "+T+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+E+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected an array."))}for(var N=0;N>"}var r=t(13),s=t(70),x=t(20),j=t(118),y="<>",u={array:g("array"),bool:g("boolean"),func:g("function"),number:g("number"),object:g("object"),string:g("string"),any:e(),arrayOf:i,element:T(),instanceOf:E,node:C(),objectOf:o,oneOf:N,oneOfType:n,shape:c};A.exports=u},function(A,M){"use strict";var t={injectCreateReactRootIndex:function(A){I.createReactRootIndex=A}},I={createReactRootIndex:null,injection:t};A.exports=I},function(A,M){"use strict";var t={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(A){t.currentScrollLeft=A.x,t.currentScrollTop=A.y}};A.exports=t},function(A,M,t){"use strict";function I(A,M){if(null==M?g(!1):void 0,null==A)return M;var t=Array.isArray(A),I=Array.isArray(M);return t&&I?(A.push.apply(A,M),A):t?(A.push(M),A):I?[A].concat(M):[A,M]}var g=t(2);A.exports=I},function(A,M){"use strict";var t=function(A,M,t){Array.isArray(A)?A.forEach(M,t):A&&M.call(t,A)};A.exports=t},function(A,M,t){"use strict";function I(){return!e&&g.canUseDOM&&(e="textContent"in document.documentElement?"textContent":"innerText"),e}var g=t(10),e=null;A.exports=I},function(A,M){"use strict";function t(A){var M=A&&A.nodeName&&A.nodeName.toLowerCase();return M&&("input"===M&&I[A.type]||"textarea"===M)}var I={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};A.exports=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){for(var A=arguments.length,M=Array(A),t=0;t=0&&s.splice(M,1)}function T(A){var M=document.createElement("style");return M.type="text/css",e(A,M),M}function E(A){var M=document.createElement("link");return M.rel="stylesheet",e(A,M),M}function N(A,M){var t,I,g;if(M.singleton){var e=r++;t=Q||(Q=T(M)),I=o.bind(null,t,e,!1),g=o.bind(null,t,e,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=E(M),I=C.bind(null,t),g=function(){i(t),t.href&&URL.revokeObjectURL(t.href)}):(t=T(M),I=n.bind(null,t),g=function(){i(t)});return I(A),function(M){if(M){if(M.css===A.css&&M.media===A.media&&M.sourceMap===A.sourceMap)return;I(A=M)}else g()}}function o(A,M,t,I){var g=t?"":I.css;if(A.styleSheet)A.styleSheet.cssText=x(M,g);else{var e=document.createTextNode(g),i=A.childNodes;i[M]&&A.removeChild(i[M]),i.length?A.insertBefore(e,i[M]):A.appendChild(e)}}function n(A,M){var t=M.css,I=M.media;if(I&&A.setAttribute("media",I),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function C(A,M){var t=M.css,I=M.sourceMap;I&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(I))))+" */");var g=new Blob([t],{type:"text/css"}),e=A.href;A.href=URL.createObjectURL(g),e&&URL.revokeObjectURL(e)}var c={},D=function(A){var M;return function(){return"undefined"==typeof M&&(M=A.apply(this,arguments)),M}},a=D(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),B=D(function(){return document.head||document.getElementsByTagName("head")[0]}),Q=null,r=0,s=[];A.exports=function(A,M){M=M||{},"undefined"==typeof M.singleton&&(M.singleton=a()),"undefined"==typeof M.insertAt&&(M.insertAt="bottom");var t=g(A);return I(t,M),function(A){for(var e=[],i=0;i",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(360);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){var t={animationIterationCount:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridRow:!0,gridColumn:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,stopOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};A.exports=function(A,M){return"number"!=typeof M||t[A]?M:M+"px"}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M,t){return P.LoggedIn()?t():(location.pathname!==z.minioBrowserPrefix&&location.pathname!==z.minioBrowserPrefix+"/"||M(z.minioBrowserPrefix+"/login"),t())}function i(A,M){P.LoggedIn()&&M(""+z.minioBrowserPrefix)}function T(){q<2&&setTimeout(function(){document.querySelector(".page-load").classList.add("pl-"+q),q++,T()},K[q])}t(499);var E=t(1),N=g(E),o=t(16),n=g(o),C=t(485),c=g(C),D=t(125),a=g(D),B=t(230),Q=g(B),r=t(190),s=g(r),x=t(191),j=g(x),y=t(65),u=g(y),w=t(187),l=g(w),L=t(394),Y=g(L),d=t(22),h=g(d),S=t(42),z=(g(S),t(26)),p=t(19),U=I(p),O=t(255),m=g(O),F=t(245),f=g(F),k=t(241),R=g(k),J=t(498),G=(g(J),t(131)),H=g(G),b=t(60),v=g(b);window.Web=H.default;var X=(0,Q.default)(c.default)(a.default)(m.default),W=(0,h.default)(function(A){return A})(R.default),V=(0,h.default)(function(A){return A})(f.default),P=new H.default(window.location.protocol+"//"+window.location.host+z.minioBrowserPrefix+"/webrpc",X.dispatch);window.web=P,X.dispatch(U.setWeb(P));var Z=function(A){return N.default.createElement("div",null,A.children)};n.default.render(N.default.createElement(Y.default,{store:X,web:P},N.default.createElement(j.default,{history:u.default},N.default.createElement(s.default,{path:"/",component:Z},N.default.createElement(s.default,{path:"minio",component:Z},N.default.createElement(l.default,{component:W,onEnter:e}),N.default.createElement(s.default,{path:"login",component:V,onEnter:i}),N.default.createElement(s.default,{path:":bucket",component:W,onEnter:e}),N.default.createElement(s.default,{path:":bucket/*",component:W,onEnter:e}))))),document.getElementById("root"));var K=[0,400],q=0;T(),v.default.getItem("newlyUpdated")&&(X.dispatch(U.showAlert({type:"success",message:"Updated to the latest UI Version."})),v.default.removeItem("newlyUpdated"))},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=M.currentPath,e=M.currentBucket,i=M.deleteConfirmation,T=M.checkedObjects,E=T.length>0?T:[i.object];t.RemoveObject({bucketname:e,objects:E}).then(function(){if(A.hideDeleteConfirmation(),T.length>0){for(var M=0;M0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadSelected.bind(this)}," Download all as zip ")),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.showDeleteConfirmation.bind(this)}," Delete selected ")),o.default.createElement("i",{className:"la-close fa fa-times",onClick:this.clearSelected.bind(this)})),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:5})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:23,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:0,max:59,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1,U.object)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:window.location.protocol+"//"+U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{ -href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&(A.name.endsWith("/")||(Q=e.default.createElement(c.default,{id:"fia-dropdown-"+A.name.replace(".","-")},e.default.createElement(c.default.Toggle,{noCaret:!0,className:"fia-toggle"}),e.default.createElement(c.default.Menu,null,e.default.createElement("a",{href:"",className:"fiad-action",onClick:function(M){return E(M,""+t+A.name)}},e.default.createElement("i",{className:"fa fa-copy"})),r))));var s="",x="";return C.indexOf(A.name)>-1&&(s=" fesl-row-selected",x=!0),e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,checked:x,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",object:""},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy; -break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return t}},function(A,M,t){A.exports={default:t(260),__esModule:!0}},function(A,M,t){t(270),A.exports=t(49).Object.assign},function(A,M,t){var I=t(80);A.exports=function(A,M){return I.create(A,M)}},function(A,M,t){t(271),A.exports=t(49).Object.keys},function(A,M,t){t(272),A.exports=t(49).Object.setPrototypeOf},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M,t){var I=t(136);A.exports=function(A){if(!I(A))throw TypeError(A+" is not an object!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(263);A.exports=Object("z").propertyIsEnumerable(0)?Object:function(A){return"String"==I(A)?A.split(""):Object(A)}},function(A,M,t){var I=t(80),g=t(137),e=t(266);A.exports=t(135)(function(){var A=Object.assign,M={},t={},I=Symbol(),g="abcdefghijklmnopqrst";return M[I]=7,g.split("").forEach(function(A){t[A]=A}),7!=A({},M)[I]||Object.keys(A({},t)).join("")!=g})?function(A,M){for(var t=g(A),i=arguments,T=i.length,E=1,N=I.getKeys,o=I.getSymbols,n=I.isEnum;T>E;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(135);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(136),e=t(262),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(134)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(267)})},function(A,M,t){var I=t(137);t(268)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(269).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;g-1&&A%1==0&&A1)for(var t=1;tA.clientHeight}Object.defineProperty(M,"__esModule",{value:!0}),M.default=i;var T=t(57),E=I(T),N=t(39),o=I(N);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):"function"!==E&&"string"!==E?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):null}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(180),N=I(E);M.default=(0,N.default)(g)},function(A,M){"use strict";function t(A){function M(M,t,I,g,e,i){var T=g||"<>",E=i||I;if(null==t[I])return M?new Error("Required "+e+" ` + "`" + `"+E+"` + "`" + ` was not specified "+("in ` + "`" + `"+T+"` + "`" + `.")):null;for(var N=arguments.length,o=Array(N>6?N-6:0),n=6;n=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return 0===A.button}function i(A){return!!(A.metaKey||A.altKey||A.ctrlKey||A.shiftKey)}function T(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!1;return!0}function E(A,M){var t=M.query,I=M.hash,g=M.state;return t||I||g?{pathname:A,query:t,hash:I,state:g}:A}M.__esModule=!0;var N=Object.assign||function(A){for(var M=1;M=0;I--){var g=A[I],e=g.path||"";if(t=e.replace(/\/*$/,"/")+t,0===e.indexOf("/"))break}return"/"+t}},propTypes:{path:C,from:C,to:C.isRequired,query:c,state:c,onEnter:o.falsy,children:o.falsy},render:function(){(0,T.default)(!1)}});M.default=D,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0;var g=t(1),e=I(g),i=t(8),T=I(i),E=t(30),N=t(34),o=e.default.PropTypes,n=o.string,C=o.func,c=e.default.createClass({displayName:"Route",statics:{createRouteFromReactElement:E.createRouteFromReactElement},propTypes:{path:n,component:N.component,components:N.components,getComponent:C,getComponents:C},render:function(){(0,T.default)(!1)}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return!A||!A.__v2_compatible__}function i(A){return A&&A.getCurrentLocation}M.__esModule=!0;var T=Object.assign||function(A){for(var M=1;M=0&&0===window.sessionStorage.length)return;throw A}}function i(A){var M=void 0;try{M=window.sessionStorage.getItem(g(A))}catch(A){if(A.name===o)return null}if(M)try{return JSON.parse(M)}catch(A){}return null}M.__esModule=!0,M.saveState=e,M.readState=i;var T=t(23),E=(I(T),"@@History/"),N=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],o="SecurityError"},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){function M(A){return E.canUseDOM?void 0:T.default(!1),t.listen(A)}var t=n.default(e({getUserConfirmation:N.getUserConfirmation},A,{go:N.go}));return e({},t,{listen:M})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M1?M-1:0),e=1;e=A.childNodes.length?null:A.childNodes.item(t);A.insertBefore(M,I)}var g=t(433),e=t(218),i=t(17),T=t(76),E=t(121),N=t(2),o={dangerouslyReplaceNodeWithMarkup:g.dangerouslyReplaceNodeWithMarkup,updateTextContent:E,processUpdates:function(A,M){for(var t,i=null,o=null,n=0;n-1?void 0:i(!1),!N.plugins[t]){M.extractEvents?void 0:i(!1),N.plugins[t]=M;var I=M.eventTypes;for(var e in I)g(I[e],M,e)?void 0:i(!1)}}}function g(A,M,t){N.eventNameDispatchConfigs.hasOwnProperty(t)?i(!1):void 0,N.eventNameDispatchConfigs[t]=A;var I=A.phasedRegistrationNames;if(I){for(var g in I)if(I.hasOwnProperty(g)){var T=I[g];e(T,M,t)}return!0}return!!A.registrationName&&(e(A.registrationName,M,t),!0)}function e(A,M,t){N.registrationNameModules[A]?i(!1):void 0,N.registrationNameModules[A]=M,N.registrationNameDependencies[A]=M.eventTypes[t].dependencies}var i=t(2),T=null,E={},N={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(A){T?i(!1):void 0,T=Array.prototype.slice.call(A),I()},injectEventPluginsByName:function(A){var M=!1;for(var t in A)if(A.hasOwnProperty(t)){var g=A[t];E.hasOwnProperty(t)&&E[t]===g||(E[t]?i(!1):void 0,E[t]=g,M=!0)}M&&I()},getPluginModuleForEvent:function(A){var M=A.dispatchConfig;if(M.registrationName)return N.registrationNameModules[M.registrationName]||null;for(var t in M.phasedRegistrationNames)if(M.phasedRegistrationNames.hasOwnProperty(t)){var I=N.registrationNameModules[M.phasedRegistrationNames[t]];if(I)return I}return null},_resetEventPlugins:function(){T=null;for(var A in E)E.hasOwnProperty(A)&&delete E[A];N.plugins.length=0;var M=N.eventNameDispatchConfigs;for(var t in M)M.hasOwnProperty(t)&&delete M[t];var I=N.registrationNameModules;for(var g in I)I.hasOwnProperty(g)&&delete I[g]}};A.exports=N},function(A,M,t){"use strict";function I(A){return(""+A).replace(x,"//")}function g(A,M){this.func=A,this.context=M,this.count=0}function e(A,M,t){var I=A.func,g=A.context;I.call(g,M,A.count++)}function i(A,M,t){if(null==A)return A;var I=g.getPooled(M,t);Q(A,e,I),g.release(I)}function T(A,M,t,I){this.result=A,this.keyPrefix=M,this.func=t,this.context=I,this.count=0}function E(A,M,t){var g=A.result,e=A.keyPrefix,i=A.func,T=A.context,E=i.call(T,M,A.count++);Array.isArray(E)?N(E,g,t,B.thatReturnsArgument):null!=E&&(a.isValidElement(E)&&(E=a.cloneAndReplaceKey(E,e+(E!==M?I(E.key||"")+"/":"")+t)),g.push(E))}function N(A,M,t,g,e){var i="";null!=t&&(i=I(t)+"/");var N=T.getPooled(M,i,g,e);Q(A,E,N),T.release(N)}function o(A,M,t){if(null==A)return A;var I=[];return N(A,I,null,M,t),I}function n(A,M,t){return null}function C(A,M){return Q(A,n,null)}function c(A){var M=[];return N(A,M,null,B.thatReturnsArgument),M}var D=t(31),a=t(13),B=t(20),Q=t(123),r=D.twoArgumentPooler,s=D.fourArgumentPooler,x=/\/(?!\/)/g;g.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},D.addPoolingTo(g,r),T.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},D.addPoolingTo(T,s);var j={forEach:i,map:o,mapIntoWithKeyPrefixInternal:N,count:C,toArray:c};A.exports=j},function(A,M,t){"use strict";function I(A,M){var t=y.hasOwnProperty(M)?y[M]:null;w.hasOwnProperty(M)&&(t!==x.OVERRIDE_BASE?B(!1):void 0),A.hasOwnProperty(M)&&(t!==x.DEFINE_MANY&&t!==x.DEFINE_MANY_MERGED?B(!1):void 0)}function g(A,M){if(M){"function"==typeof M?B(!1):void 0,C.isValidElement(M)?B(!1):void 0;var t=A.prototype;M.hasOwnProperty(s)&&u.mixins(A,M.mixins);for(var g in M)if(M.hasOwnProperty(g)&&g!==s){var e=M[g];if(I(t,g),u.hasOwnProperty(g))u[g](A,e);else{var i=y.hasOwnProperty(g),N=t.hasOwnProperty(g),o="function"==typeof e,n=o&&!i&&!N&&M.autobind!==!1;if(n)t.__reactAutoBindMap||(t.__reactAutoBindMap={}),t.__reactAutoBindMap[g]=e,t[g]=e;else if(N){var c=y[g];!i||c!==x.DEFINE_MANY_MERGED&&c!==x.DEFINE_MANY?B(!1):void 0,c===x.DEFINE_MANY_MERGED?t[g]=T(t[g],e):c===x.DEFINE_MANY&&(t[g]=E(t[g],e))}else t[g]=e}}}}function e(A,M){if(M)for(var t in M){var I=M[t];if(M.hasOwnProperty(t)){var g=t in u;g?B(!1):void 0;var e=t in A;e?B(!1):void 0,A[t]=I}}}function i(A,M){A&&M&&"object"==typeof A&&"object"==typeof M?void 0:B(!1);for(var t in M)M.hasOwnProperty(t)&&(void 0!==A[t]?B(!1):void 0,A[t]=M[t]);return A}function T(A,M){return function(){var t=A.apply(this,arguments),I=M.apply(this,arguments);if(null==t)return I;if(null==I)return t;var g={};return i(g,t),i(g,I),g}}function E(A,M){return function(){A.apply(this,arguments),M.apply(this,arguments)}}function N(A,M){var t=M.bind(A);return t}function o(A){for(var M in A.__reactAutoBindMap)if(A.__reactAutoBindMap.hasOwnProperty(M)){var t=A.__reactAutoBindMap[M];A[M]=N(A,t)}}var n=t(205),C=t(13),c=(t(71),t(70),t(220)),D=t(4),a=t(50),B=t(2),Q=t(59),r=t(27),s=(t(3),r({mixins:null})),x=Q({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),j=[],y={mixins:x.DEFINE_MANY,statics:x.DEFINE_MANY,propTypes:x.DEFINE_MANY,contextTypes:x.DEFINE_MANY,childContextTypes:x.DEFINE_MANY,getDefaultProps:x.DEFINE_MANY_MERGED,getInitialState:x.DEFINE_MANY_MERGED,getChildContext:x.DEFINE_MANY_MERGED,render:x.DEFINE_ONCE,componentWillMount:x.DEFINE_MANY,componentDidMount:x.DEFINE_MANY,componentWillReceiveProps:x.DEFINE_MANY,shouldComponentUpdate:x.DEFINE_ONCE,componentWillUpdate:x.DEFINE_MANY,componentDidUpdate:x.DEFINE_MANY,componentWillUnmount:x.DEFINE_MANY,updateComponent:x.OVERRIDE_BASE},u={displayName:function(A,M){A.displayName=M},mixins:function(A,M){if(M)for(var t=0;t"+T+""},receiveComponent:function(A,M){if(A!==this._currentElement){this._currentElement=A;var t=""+A;if(t!==this._stringText){this._stringText=t;var g=i.getNode(this._rootNodeID);I.updateTextContent(g,t)}}},unmountComponent:function(){e.unmountIDFromEnvironment(this._rootNodeID)}}),A.exports=o},function(A,M,t){"use strict";function I(){this.reinitializeTransaction()}var g=t(18),e=t(73),i=t(4),T=t(20),E={initialize:T,close:function(){C.isBatchingUpdates=!1}},N={initialize:T,close:g.flushBatchedUpdates.bind(g)},o=[N,E];i(I.prototype,e.Mixin,{getTransactionWrappers:function(){return o}});var n=new I,C={isBatchingUpdates:!1,batchedUpdates:function(A,M,t,I,g,e){var i=C.isBatchingUpdates;C.isBatchingUpdates=!0,i?A(M,t,I,g,e):n.perform(A,null,M,t,I,g,e)}};A.exports=C},function(A,M,t){"use strict";function I(){if(!l){l=!0,Q.EventEmitter.injectReactEventListener(B),Q.EventPluginHub.injectEventPluginOrder(T),Q.EventPluginHub.injectInstanceHandle(r),Q.EventPluginHub.injectMount(s),Q.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:u,EnterLeaveEventPlugin:E,ChangeEventPlugin:e,SelectEventPlugin:j,BeforeInputEventPlugin:g}),Q.NativeComponent.injectGenericComponentClass(D),Q.NativeComponent.injectTextComponentClass(a),Q.Class.injectMixin(n),Q.DOMProperty.injectDOMPropertyConfig(o),Q.DOMProperty.injectDOMPropertyConfig(w),Q.EmptyComponent.injectEmptyComponent("noscript"),Q.Updates.injectReconcileTransaction(x),Q.Updates.injectBatchingStrategy(c),Q.RootIndex.injectCreateReactRootIndex(N.canUseDOM?i.createReactRootIndex:y.createReactRootIndex),Q.Component.injectEnvironment(C)}}var g=t(429),e=t(431),i=t(432),T=t(434),E=t(435),N=t(10),o=t(438),n=t(440),C=t(109),c=t(210),D=t(444),a=t(209),B=t(452),Q=t(453),r=t(48),s=t(12),x=t(457),j=t(463),y=t(464),u=t(465),w=t(462),l=!1;A.exports={inject:I}},function(A,M,t){"use strict";function I(){if(n.current){var A=n.current.getName();if(A)return" Check the render method of ` + "`" + `"+A+"` + "`" + `."}return""}function g(A,M){if(A._store&&!A._store.validated&&null==A.key){A._store.validated=!0;e("uniqueKey",A,M)}}function e(A,M,t){var g=I();if(!g){var e="string"==typeof t?t:t.displayName||t.name;e&&(g=" Check the top-level render call using <"+e+">.")}var i=D[A]||(D[A]={});if(i[g])return null;i[g]=!0;var T={parentOrOwner:g,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return M&&M._owner&&M._owner!==n.current&&(T.childOwner=" It was passed a child from "+M._owner.getName()+"."),T}function i(A,M){if("object"==typeof A)if(Array.isArray(A))for(var t=0;t/,e={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(A){var M=I(A);return A.replace(g," "+e.CHECKSUM_ATTR_NAME+'="'+M+'"$&')},canReuseMarkup:function(A,M){var t=M.getAttribute(e.CHECKSUM_ATTR_NAME);t=t&&parseInt(t,10);var g=I(A);return g===t}};A.exports=e},function(A,M,t){"use strict";var I=t(59),g=I({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,SET_MARKUP:null,TEXT_CONTENT:null});A.exports=g},function(A,M,t){"use strict";function I(A){if("function"==typeof A.type)return A.type;var M=A.type,t=n[M];return null==t&&(n[M]=t=N(M)),t}function g(A){return o?void 0:E(!1),new o(A.type,A.props)}function e(A){return new C(A)}function i(A){return A instanceof C}var T=t(4),E=t(2),N=null,o=null,n={},C=null,c={injectGenericComponentClass:function(A){o=A},injectTextComponentClass:function(A){C=A},injectComponentClasses:function(A){T(n,A)}},D={getComponentClassForElement:I,createInternalComponent:g,createInstanceForText:e,isTextComponent:i,injection:c};A.exports=D},function(A,M,t){"use strict";function I(A,M){}var g=(t(3),{isMounted:function(A){return!1},enqueueCallback:function(A,M){},enqueueForceUpdate:function(A){I(A,"forceUpdate")},enqueueReplaceState:function(A,M){I(A,"replaceState")},enqueueSetState:function(A,M){I(A,"setState")},enqueueSetProps:function(A,M){I(A,"setProps")},enqueueReplaceProps:function(A,M){I(A,"replaceProps")}});A.exports=g},function(A,M,t){"use strict";function I(A){function M(M,t,I,g,e,i){if(g=g||y,i=i||I,null==t[I]){var T=s[e];return M?new Error("Required "+T+" ` + "`" + `"+i+"` + "`" + ` was not specified in "+("` + "`" + `"+g+"` + "`" + `.")):null}return A(t,I,g,e,i)}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}function g(A){function M(M,t,I,g,e){var i=M[t],T=a(i);if(T!==A){var E=s[g],N=B(i);return new Error("Invalid "+E+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+N+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected ")+("` + "`" + `"+A+"` + "`" + `."))}return null}return I(M)}function e(){return I(x.thatReturns(null))}function i(A){function M(M,t,I,g,e){var i=M[t];if(!Array.isArray(i)){var T=s[g],E=a(i);return new Error("Invalid "+T+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+E+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected an array."))}for(var N=0;N>"}var r=t(13),s=t(70),x=t(20),j=t(118),y="<>",u={array:g("array"),bool:g("boolean"),func:g("function"),number:g("number"),object:g("object"),string:g("string"),any:e(),arrayOf:i,element:T(),instanceOf:E,node:C(),objectOf:o,oneOf:N,oneOfType:n,shape:c};A.exports=u},function(A,M){"use strict";var t={injectCreateReactRootIndex:function(A){I.createReactRootIndex=A}},I={createReactRootIndex:null,injection:t};A.exports=I},function(A,M){"use strict";var t={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(A){t.currentScrollLeft=A.x,t.currentScrollTop=A.y}};A.exports=t},function(A,M,t){"use strict";function I(A,M){if(null==M?g(!1):void 0,null==A)return M;var t=Array.isArray(A),I=Array.isArray(M);return t&&I?(A.push.apply(A,M),A):t?(A.push(M),A):I?[A].concat(M):[A,M]}var g=t(2);A.exports=I},function(A,M){"use strict";var t=function(A,M,t){Array.isArray(A)?A.forEach(M,t):A&&M.call(t,A)};A.exports=t},function(A,M,t){"use strict";function I(){return!e&&g.canUseDOM&&(e="textContent"in document.documentElement?"textContent":"innerText"),e}var g=t(10),e=null;A.exports=I},function(A,M){"use strict";function t(A){var M=A&&A.nodeName&&A.nodeName.toLowerCase();return M&&("input"===M&&I[A.type]||"textarea"===M)}var I={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};A.exports=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){for(var A=arguments.length,M=Array(A),t=0;t=0&&s.splice(M,1)}function T(A){var M=document.createElement("style");return M.type="text/css",e(A,M),M}function E(A){var M=document.createElement("link");return M.rel="stylesheet",e(A,M),M}function N(A,M){var t,I,g;if(M.singleton){var e=r++;t=Q||(Q=T(M)),I=o.bind(null,t,e,!1),g=o.bind(null,t,e,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=E(M),I=C.bind(null,t),g=function(){i(t),t.href&&URL.revokeObjectURL(t.href)}):(t=T(M),I=n.bind(null,t),g=function(){i(t)});return I(A),function(M){if(M){if(M.css===A.css&&M.media===A.media&&M.sourceMap===A.sourceMap)return;I(A=M)}else g()}}function o(A,M,t,I){var g=t?"":I.css;if(A.styleSheet)A.styleSheet.cssText=x(M,g);else{var e=document.createTextNode(g),i=A.childNodes;i[M]&&A.removeChild(i[M]),i.length?A.insertBefore(e,i[M]):A.appendChild(e)}}function n(A,M){var t=M.css,I=M.media;if(I&&A.setAttribute("media",I),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function C(A,M){var t=M.css,I=M.sourceMap;I&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(I))))+" */");var g=new Blob([t],{type:"text/css"}),e=A.href;A.href=URL.createObjectURL(g),e&&URL.revokeObjectURL(e)}var c={},D=function(A){var M;return function(){return"undefined"==typeof M&&(M=A.apply(this,arguments)),M}},a=D(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),B=D(function(){return document.head||document.getElementsByTagName("head")[0]}),Q=null,r=0,s=[];A.exports=function(A,M){M=M||{},"undefined"==typeof M.singleton&&(M.singleton=a()),"undefined"==typeof M.insertAt&&(M.insertAt="bottom");var t=g(A);return I(t,M),function(A){for(var e=[],i=0;i-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=M.currentPath,e=M.currentBucket,i=M.deleteConfirmation,T=M.checkedObjects,E=T.length>0?T:[i.object];t.RemoveObject({bucketname:e,objects:E}).then(function(){if(A.hideDeleteConfirmation(),T.length>0){for(var M=0;M0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadSelected.bind(this)}," Download all as zip ")),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.showDeleteConfirmation.bind(this)}," Delete selected ")),o.default.createElement("i",{className:"la-close fa fa-times",onClick:this.clearSelected.bind(this)})),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:5})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:23,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:0,max:59,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1,U.object)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:window.location.protocol+"//"+U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&(A.name.endsWith("/")||(Q=e.default.createElement(c.default,{id:"fia-dropdown-"+A.name.replace(".","-")},e.default.createElement(c.default.Toggle,{noCaret:!0,className:"fia-toggle"}),e.default.createElement(c.default.Menu,null,e.default.createElement("a",{href:"",className:"fiad-action",onClick:function(M){return E(M,""+t+A.name)}},e.default.createElement("i",{className:"fa fa-copy"})),r))));var s="",x="";return C.indexOf(A.name)>-1&&(s=" fesl-row-selected",x=!0),e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,checked:x,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",object:""},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return t}},function(A,M,t){"use strict";function I(A){if(Array.isArray(A)){for(var M=0,t=Array(A.length);MM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;tE;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(133);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(134),e=t(261),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(132)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]), +M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(266)})},function(A,M,t){var I=t(135);t(267)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(268).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;gli{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\\F000"}.fa-music:before{content:"\\F001"}.fa-search:before{content:"\\F002"}.fa-envelope-o:before{content:"\\F003"}.fa-heart:before{content:"\\F004"}.fa-star:before{content:"\\F005"}.fa-star-o:before{content:"\\F006"}.fa-user:before{content:"\\F007"}.fa-film:before{content:"\\F008"}.fa-th-large:before{content:"\\F009"}.fa-th:before{content:"\\F00A"}.fa-th-list:before{content:"\\F00B"}.fa-check:before{content:"\\F00C"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\\F00D"}.fa-search-plus:before{content:"\\F00E"}.fa-search-minus:before{content:"\\F010"}.fa-power-off:before{content:"\\F011"}.fa-signal:before{content:"\\F012"}.fa-cog:before,.fa-gear:before{content:"\\F013"}.fa-trash-o:before{content:"\\F014"}.fa-home:before{content:"\\F015"}.fa-file-o:before{content:"\\F016"}.fa-clock-o:before{content:"\\F017"}.fa-road:before{content:"\\F018"}.fa-download:before{content:"\\F019"}.fa-arrow-circle-o-down:before{content:"\\F01A"}.fa-arrow-circle-o-up:before{content:"\\F01B"}.fa-inbox:before{content:"\\F01C"}.fa-play-circle-o:before{content:"\\F01D"}.fa-repeat:before,.fa-rotate-right:before{content:"\\F01E"}.fa-refresh:before{content:"\\F021"}.fa-list-alt:before{content:"\\F022"}.fa-lock:before{content:"\\F023"}.fa-flag:before{content:"\\F024"}.fa-headphones:before{content:"\\F025"}.fa-volume-off:before{content:"\\F026"}.fa-volume-down:before{content:"\\F027"}.fa-volume-up:before{content:"\\F028"}.fa-qrcode:before{content:"\\F029"}.fa-barcode:before{content:"\\F02A"}.fa-tag:before{content:"\\F02B"}.fa-tags:before{content:"\\F02C"}.fa-book:before{content:"\\F02D"}.fa-bookmark:before{content:"\\F02E"}.fa-print:before{content:"\\F02F"}.fa-camera:before{content:"\\F030"}.fa-font:before{content:"\\F031"}.fa-bold:before{content:"\\F032"}.fa-italic:before{content:"\\F033"}.fa-text-height:before{content:"\\F034"}.fa-text-width:before{content:"\\F035"}.fa-align-left:before{content:"\\F036"}.fa-align-center:before{content:"\\F037"}.fa-align-right:before{content:"\\F038"}.fa-align-justify:before{content:"\\F039"}.fa-list:before{content:"\\F03A"}.fa-dedent:before,.fa-outdent:before{content:"\\F03B"}.fa-indent:before{content:"\\F03C"}.fa-video-camera:before{content:"\\F03D"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\\F03E"}.fa-pencil:before{content:"\\F040"}.fa-map-marker:before{content:"\\F041"}.fa-adjust:before{content:"\\F042"}.fa-tint:before{content:"\\F043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\\F044"}.fa-share-square-o:before{content:"\\F045"}.fa-check-square-o:before{content:"\\F046"}.fa-arrows:before{content:"\\F047"}.fa-step-backward:before{content:"\\F048"}.fa-fast-backward:before{content:"\\F049"}.fa-backward:before{content:"\\F04A"}.fa-play:before{content:"\\F04B"}.fa-pause:before{content:"\\F04C"}.fa-stop:before{content:"\\F04D"}.fa-forward:before{content:"\\F04E"}.fa-fast-forward:before{content:"\\F050"}.fa-step-forward:before{content:"\\F051"}.fa-eject:before{content:"\\F052"}.fa-chevron-left:before{content:"\\F053"}.fa-chevron-right:before{content:"\\F054"}.fa-plus-circle:before{content:"\\F055"}.fa-minus-circle:before{content:"\\F056"}.fa-times-circle:before{content:"\\F057"}.fa-check-circle:before{content:"\\F058"}.fa-question-circle:before{content:"\\F059"}.fa-info-circle:before{content:"\\F05A"}.fa-crosshairs:before{content:"\\F05B"}.fa-times-circle-o:before{content:"\\F05C"}.fa-check-circle-o:before{content:"\\F05D"}.fa-ban:before{content:"\\F05E"}.fa-arrow-left:before{content:"\\F060"}.fa-arrow-right:before{content:"\\F061"}.fa-arrow-up:before{content:"\\F062"}.fa-arrow-down:before{content:"\\F063"}.fa-mail-forward:before,.fa-share:before{content:"\\F064"}.fa-expand:before{content:"\\F065"}.fa-compress:before{content:"\\F066"}.fa-plus:before{content:"\\F067"}.fa-minus:before{content:"\\F068"}.fa-asterisk:before{content:"\\F069"}.fa-exclamation-circle:before{content:"\\F06A"}.fa-gift:before{content:"\\F06B"}.fa-leaf:before{content:"\\F06C"}.fa-fire:before{content:"\\F06D"}.fa-eye:before{content:"\\F06E"}.fa-eye-slash:before{content:"\\F070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\\F071"}.fa-plane:before{content:"\\F072"}.fa-calendar:before{content:"\\F073"}.fa-random:before{content:"\\F074"}.fa-comment:before{content:"\\F075"}.fa-magnet:before{content:"\\F076"}.fa-chevron-up:before{content:"\\F077"}.fa-chevron-down:before{content:"\\F078"}.fa-retweet:before{content:"\\F079"}.fa-shopping-cart:before{content:"\\F07A"}.fa-folder:before{content:"\\F07B"}.fa-folder-open:before{content:"\\F07C"}.fa-arrows-v:before{content:"\\F07D"}.fa-arrows-h:before{content:"\\F07E"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\\F080"}.fa-twitter-square:before{content:"\\F081"}.fa-facebook-square:before{content:"\\F082"}.fa-camera-retro:before{content:"\\F083"}.fa-key:before{content:"\\F084"}.fa-cogs:before,.fa-gears:before{content:"\\F085"}.fa-comments:before{content:"\\F086"}.fa-thumbs-o-up:before{content:"\\F087"}.fa-thumbs-o-down:before{content:"\\F088"}.fa-star-half:before{content:"\\F089"}.fa-heart-o:before{content:"\\F08A"}.fa-sign-out:before{content:"\\F08B"}.fa-linkedin-square:before{content:"\\F08C"}.fa-thumb-tack:before{content:"\\F08D"}.fa-external-link:before{content:"\\F08E"}.fa-sign-in:before{content:"\\F090"}.fa-trophy:before{content:"\\F091"}.fa-github-square:before{content:"\\F092"}.fa-upload:before{content:"\\F093"}.fa-lemon-o:before{content:"\\F094"}.fa-phone:before{content:"\\F095"}.fa-square-o:before{content:"\\F096"}.fa-bookmark-o:before{content:"\\F097"}.fa-phone-square:before{content:"\\F098"}.fa-twitter:before{content:"\\F099"}.fa-facebook-f:before,.fa-facebook:before{content:"\\F09A"}.fa-github:before{content:"\\F09B"}.fa-unlock:before{content:"\\F09C"}.fa-credit-card:before{content:"\\F09D"}.fa-feed:before,.fa-rss:before{content:"\\F09E"}.fa-hdd-o:before{content:"\\F0A0"}.fa-bullhorn:before{content:"\\F0A1"}.fa-bell:before{content:"\\F0F3"}.fa-certificate:before{content:"\\F0A3"}.fa-hand-o-right:before{content:"\\F0A4"}.fa-hand-o-left:before{content:"\\F0A5"}.fa-hand-o-up:before{content:"\\F0A6"}.fa-hand-o-down:before{content:"\\F0A7"}.fa-arrow-circle-left:before{content:"\\F0A8"}.fa-arrow-circle-right:before{content:"\\F0A9"}.fa-arrow-circle-up:before{content:"\\F0AA"}.fa-arrow-circle-down:before{content:"\\F0AB"}.fa-globe:before{content:"\\F0AC"}.fa-wrench:before{content:"\\F0AD"}.fa-tasks:before{content:"\\F0AE"}.fa-filter:before{content:"\\F0B0"}.fa-briefcase:before{content:"\\F0B1"}.fa-arrows-alt:before{content:"\\F0B2"}.fa-group:before,.fa-users:before{content:"\\F0C0"}.fa-chain:before,.fa-link:before{content:"\\F0C1"}.fa-cloud:before{content:"\\F0C2"}.fa-flask:before{content:"\\F0C3"}.fa-cut:before,.fa-scissors:before{content:"\\F0C4"}.fa-copy:before,.fa-files-o:before{content:"\\F0C5"}.fa-paperclip:before{content:"\\F0C6"}.fa-floppy-o:before,.fa-save:before{content:"\\F0C7"}.fa-square:before{content:"\\F0C8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\\F0C9"}.fa-list-ul:before{content:"\\F0CA"}.fa-list-ol:before{content:"\\F0CB"}.fa-strikethrough:before{content:"\\F0CC"}.fa-underline:before{content:"\\F0CD"}.fa-table:before{content:"\\F0CE"}.fa-magic:before{content:"\\F0D0"}.fa-truck:before{content:"\\F0D1"}.fa-pinterest:before{content:"\\F0D2"}.fa-pinterest-square:before{content:"\\F0D3"}.fa-google-plus-square:before{content:"\\F0D4"}.fa-google-plus:before{content:"\\F0D5"}.fa-money:before{content:"\\F0D6"}.fa-caret-down:before{content:"\\F0D7"}.fa-caret-up:before{content:"\\F0D8"}.fa-caret-left:before{content:"\\F0D9"}.fa-caret-right:before{content:"\\F0DA"}.fa-columns:before{content:"\\F0DB"}.fa-sort:before,.fa-unsorted:before{content:"\\F0DC"}.fa-sort-desc:before,.fa-sort-down:before{content:"\\F0DD"}.fa-sort-asc:before,.fa-sort-up:before{content:"\\F0DE"}.fa-envelope:before{content:"\\F0E0"}.fa-linkedin:before{content:"\\F0E1"}.fa-rotate-left:before,.fa-undo:before{content:"\\F0E2"}.fa-gavel:before,.fa-legal:before{content:"\\F0E3"}.fa-dashboard:before,.fa-tachometer:before{content:"\\F0E4"}.fa-comment-o:before{content:"\\F0E5"}.fa-comments-o:before{content:"\\F0E6"}.fa-bolt:before,.fa-flash:before{content:"\\F0E7"}.fa-sitemap:before{content:"\\F0E8"}.fa-umbrella:before{content:"\\F0E9"}.fa-clipboard:before,.fa-paste:before{content:"\\F0EA"}.fa-lightbulb-o:before{content:"\\F0EB"}.fa-exchange:before{content:"\\F0EC"}.fa-cloud-download:before{content:"\\F0ED"}.fa-cloud-upload:before{content:"\\F0EE"}.fa-user-md:before{content:"\\F0F0"}.fa-stethoscope:before{content:"\\F0F1"}.fa-suitcase:before{content:"\\F0F2"}.fa-bell-o:before{content:"\\F0A2"}.fa-coffee:before{content:"\\F0F4"}.fa-cutlery:before{content:"\\F0F5"}.fa-file-text-o:before{content:"\\F0F6"}.fa-building-o:before{content:"\\F0F7"}.fa-hospital-o:before{content:"\\F0F8"}.fa-ambulance:before{content:"\\F0F9"}.fa-medkit:before{content:"\\F0FA"}.fa-fighter-jet:before{content:"\\F0FB"}.fa-beer:before{content:"\\F0FC"}.fa-h-square:before{content:"\\F0FD"}.fa-plus-square:before{content:"\\F0FE"}.fa-angle-double-left:before{content:"\\F100"}.fa-angle-double-right:before{content:"\\F101"}.fa-angle-double-up:before{content:"\\F102"}.fa-angle-double-down:before{content:"\\F103"}.fa-angle-left:before{content:"\\F104"}.fa-angle-right:before{content:"\\F105"}.fa-angle-up:before{content:"\\F106"}.fa-angle-down:before{content:"\\F107"}.fa-desktop:before{content:"\\F108"}.fa-laptop:before{content:"\\F109"}.fa-tablet:before{content:"\\F10A"}.fa-mobile-phone:before,.fa-mobile:before{content:"\\F10B"}.fa-circle-o:before{content:"\\F10C"}.fa-quote-left:before{content:"\\F10D"}.fa-quote-right:before{content:"\\F10E"}.fa-spinner:before{content:"\\F110"}.fa-circle:before{content:"\\F111"}.fa-mail-reply:before,.fa-reply:before{content:"\\F112"}.fa-github-alt:before{content:"\\F113"}.fa-folder-o:before{content:"\\F114"}.fa-folder-open-o:before{content:"\\F115"}.fa-smile-o:before{content:"\\F118"}.fa-frown-o:before{content:"\\F119"}.fa-meh-o:before{content:"\\F11A"}.fa-gamepad:before{content:"\\F11B"}.fa-keyboard-o:before{content:"\\F11C"}.fa-flag-o:before{content:"\\F11D"}.fa-flag-checkered:before{content:"\\F11E"}.fa-terminal:before{content:"\\F120"}.fa-code:before{content:"\\F121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\\F122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\\F123"}.fa-location-arrow:before{content:"\\F124"}.fa-crop:before{content:"\\F125"}.fa-code-fork:before{content:"\\F126"}.fa-chain-broken:before,.fa-unlink:before{content:"\\F127"}.fa-question:before{content:"\\F128"}.fa-info:before{content:"\\F129"}.fa-exclamation:before{content:"\\F12A"}.fa-superscript:before{content:"\\F12B"}.fa-subscript:before{content:"\\F12C"}.fa-eraser:before{content:"\\F12D"}.fa-puzzle-piece:before{content:"\\F12E"}.fa-microphone:before{content:"\\F130"}.fa-microphone-slash:before{content:"\\F131"}.fa-shield:before{content:"\\F132"}.fa-calendar-o:before{content:"\\F133"}.fa-fire-extinguisher:before{content:"\\F134"}.fa-rocket:before{content:"\\F135"}.fa-maxcdn:before{content:"\\F136"}.fa-chevron-circle-left:before{content:"\\F137"}.fa-chevron-circle-right:before{content:"\\F138"}.fa-chevron-circle-up:before{content:"\\F139"}.fa-chevron-circle-down:before{content:"\\F13A"}.fa-html5:before{content:"\\F13B"}.fa-css3:before{content:"\\F13C"}.fa-anchor:before{content:"\\F13D"}.fa-unlock-alt:before{content:"\\F13E"}.fa-bullseye:before{content:"\\F140"}.fa-ellipsis-h:before{content:"\\F141"}.fa-ellipsis-v:before{content:"\\F142"}.fa-rss-square:before{content:"\\F143"}.fa-play-circle:before{content:"\\F144"}.fa-ticket:before{content:"\\F145"}.fa-minus-square:before{content:"\\F146"}.fa-minus-square-o:before{content:"\\F147"}.fa-level-up:before{content:"\\F148"}.fa-level-down:before{content:"\\F149"}.fa-check-square:before{content:"\\F14A"}.fa-pencil-square:before{content:"\\F14B"}.fa-external-link-square:before{content:"\\F14C"}.fa-share-square:before{content:"\\F14D"}.fa-compass:before{content:"\\F14E"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\\F150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\\F151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\\F152"}.fa-eur:before,.fa-euro:before{content:"\\F153"}.fa-gbp:before{content:"\\F154"}.fa-dollar:before,.fa-usd:before{content:"\\F155"}.fa-inr:before,.fa-rupee:before{content:"\\F156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\\F157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\\F158"}.fa-krw:before,.fa-won:before{content:"\\F159"}.fa-bitcoin:before,.fa-btc:before{content:"\\F15A"}.fa-file:before{content:"\\F15B"}.fa-file-text:before{content:"\\F15C"}.fa-sort-alpha-asc:before{content:"\\F15D"}.fa-sort-alpha-desc:before{content:"\\F15E"}.fa-sort-amount-asc:before{content:"\\F160"}.fa-sort-amount-desc:before{content:"\\F161"}.fa-sort-numeric-asc:before{content:"\\F162"}.fa-sort-numeric-desc:before{content:"\\F163"}.fa-thumbs-up:before{content:"\\F164"}.fa-thumbs-down:before{content:"\\F165"}.fa-youtube-square:before{content:"\\F166"}.fa-youtube:before{content:"\\F167"}.fa-xing:before{content:"\\F168"}.fa-xing-square:before{content:"\\F169"}.fa-youtube-play:before{content:"\\F16A"}.fa-dropbox:before{content:"\\F16B"}.fa-stack-overflow:before{content:"\\F16C"}.fa-instagram:before{content:"\\F16D"}.fa-flickr:before{content:"\\F16E"}.fa-adn:before{content:"\\F170"}.fa-bitbucket:before{content:"\\F171"}.fa-bitbucket-square:before{content:"\\F172"}.fa-tumblr:before{content:"\\F173"}.fa-tumblr-square:before{content:"\\F174"}.fa-long-arrow-down:before{content:"\\F175"}.fa-long-arrow-up:before{content:"\\F176"}.fa-long-arrow-left:before{content:"\\F177"}.fa-long-arrow-right:before{content:"\\F178"}.fa-apple:before{content:"\\F179"}.fa-windows:before{content:"\\F17A"}.fa-android:before{content:"\\F17B"}.fa-linux:before{content:"\\F17C"}.fa-dribbble:before{content:"\\F17D"}.fa-skype:before{content:"\\F17E"}.fa-foursquare:before{content:"\\F180"}.fa-trello:before{content:"\\F181"}.fa-female:before{content:"\\F182"}.fa-male:before{content:"\\F183"}.fa-gittip:before,.fa-gratipay:before{content:"\\F184"}.fa-sun-o:before{content:"\\F185"}.fa-moon-o:before{content:"\\F186"}.fa-archive:before{content:"\\F187"}.fa-bug:before{content:"\\F188"}.fa-vk:before{content:"\\F189"}.fa-weibo:before{content:"\\F18A"}.fa-renren:before{content:"\\F18B"}.fa-pagelines:before{content:"\\F18C"}.fa-stack-exchange:before{content:"\\F18D"}.fa-arrow-circle-o-right:before{content:"\\F18E"}.fa-arrow-circle-o-left:before{content:"\\F190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\\F191"}.fa-dot-circle-o:before{content:"\\F192"}.fa-wheelchair:before{content:"\\F193"}.fa-vimeo-square:before{content:"\\F194"}.fa-try:before,.fa-turkish-lira:before{content:"\\F195"}.fa-plus-square-o:before{content:"\\F196"}.fa-space-shuttle:before{content:"\\F197"}.fa-slack:before{content:"\\F198"}.fa-envelope-square:before{content:"\\F199"}.fa-wordpress:before{content:"\\F19A"}.fa-openid:before{content:"\\F19B"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\\F19C"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\\F19D"}.fa-yahoo:before{content:"\\F19E"}.fa-google:before{content:"\\F1A0"}.fa-reddit:before{content:"\\F1A1"}.fa-reddit-square:before{content:"\\F1A2"}.fa-stumbleupon-circle:before{content:"\\F1A3"}.fa-stumbleupon:before{content:"\\F1A4"}.fa-delicious:before{content:"\\F1A5"}.fa-digg:before{content:"\\F1A6"}.fa-pied-piper-pp:before{content:"\\F1A7"}.fa-pied-piper-alt:before{content:"\\F1A8"}.fa-drupal:before{content:"\\F1A9"}.fa-joomla:before{content:"\\F1AA"}.fa-language:before{content:"\\F1AB"}.fa-fax:before{content:"\\F1AC"}.fa-building:before{content:"\\F1AD"}.fa-child:before{content:"\\F1AE"}.fa-paw:before{content:"\\F1B0"}.fa-spoon:before{content:"\\F1B1"}.fa-cube:before{content:"\\F1B2"}.fa-cubes:before{content:"\\F1B3"}.fa-behance:before{content:"\\F1B4"}.fa-behance-square:before{content:"\\F1B5"}.fa-steam:before{content:"\\F1B6"}.fa-steam-square:before{content:"\\F1B7"}.fa-recycle:before{content:"\\F1B8"}.fa-automobile:before,.fa-car:before{content:"\\F1B9"}.fa-cab:before,.fa-taxi:before{content:"\\F1BA"}.fa-tree:before{content:"\\F1BB"}.fa-spotify:before{content:"\\F1BC"}.fa-deviantart:before{content:"\\F1BD"}.fa-soundcloud:before{content:"\\F1BE"}.fa-database:before{content:"\\F1C0"}.fa-file-pdf-o:before{content:"\\F1C1"}.fa-file-word-o:before{content:"\\F1C2"}.fa-file-excel-o:before{content:"\\F1C3"}.fa-file-powerpoint-o:before{content:"\\F1C4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\\F1C5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\\F1C6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\\F1C7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\\F1C8"}.fa-file-code-o:before{content:"\\F1C9"}.fa-vine:before{content:"\\F1CA"}.fa-codepen:before{content:"\\F1CB"}.fa-jsfiddle:before{content:"\\F1CC"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\\F1CD"}.fa-circle-o-notch:before{content:"\\F1CE"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\\F1D0"}.fa-empire:before,.fa-ge:before{content:"\\F1D1"}.fa-git-square:before{content:"\\F1D2"}.fa-git:before{content:"\\F1D3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\\F1D4"}.fa-tencent-weibo:before{content:"\\F1D5"}.fa-qq:before{content:"\\F1D6"}.fa-wechat:before,.fa-weixin:before{content:"\\F1D7"}.fa-paper-plane:before,.fa-send:before{content:"\\F1D8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\\F1D9"}.fa-history:before{content:"\\F1DA"}.fa-circle-thin:before{content:"\\F1DB"}.fa-header:before{content:"\\F1DC"}.fa-paragraph:before{content:"\\F1DD"}.fa-sliders:before{content:"\\F1DE"}.fa-share-alt:before{content:"\\F1E0"}.fa-share-alt-square:before{content:"\\F1E1"}.fa-bomb:before{content:"\\F1E2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\\F1E3"}.fa-tty:before{content:"\\F1E4"}.fa-binoculars:before{content:"\\F1E5"}.fa-plug:before{content:"\\F1E6"}.fa-slideshare:before{content:"\\F1E7"}.fa-twitch:before{content:"\\F1E8"}.fa-yelp:before{content:"\\F1E9"}.fa-newspaper-o:before{content:"\\F1EA"}.fa-wifi:before{content:"\\F1EB"}.fa-calculator:before{content:"\\F1EC"}.fa-paypal:before{content:"\\F1ED"}.fa-google-wallet:before{content:"\\F1EE"}.fa-cc-visa:before{content:"\\F1F0"}.fa-cc-mastercard:before{content:"\\F1F1"}.fa-cc-discover:before{content:"\\F1F2"}.fa-cc-amex:before{content:"\\F1F3"}.fa-cc-paypal:before{content:"\\F1F4"}.fa-cc-stripe:before{content:"\\F1F5"}.fa-bell-slash:before{content:"\\F1F6"}.fa-bell-slash-o:before{content:"\\F1F7"}.fa-trash:before{content:"\\F1F8"}.fa-copyright:before{content:"\\F1F9"}.fa-at:before{content:"\\F1FA"}.fa-eyedropper:before{content:"\\F1FB"}.fa-paint-brush:before{content:"\\F1FC"}.fa-birthday-cake:before{content:"\\F1FD"}.fa-area-chart:before{content:"\\F1FE"}.fa-pie-chart:before{content:"\\F200"}.fa-line-chart:before{content:"\\F201"}.fa-lastfm:before{content:"\\F202"}.fa-lastfm-square:before{content:"\\F203"}.fa-toggle-off:before{content:"\\F204"}.fa-toggle-on:before{content:"\\F205"}.fa-bicycle:before{content:"\\F206"}.fa-bus:before{content:"\\F207"}.fa-ioxhost:before{content:"\\F208"}.fa-angellist:before{content:"\\F209"}.fa-cc:before{content:"\\F20A"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\\F20B"}.fa-meanpath:before{content:"\\F20C"}.fa-buysellads:before{content:"\\F20D"}.fa-connectdevelop:before{content:"\\F20E"}.fa-dashcube:before{content:"\\F210"}.fa-forumbee:before{content:"\\F211"}.fa-leanpub:before{content:"\\F212"}.fa-sellsy:before{content:"\\F213"}.fa-shirtsinbulk:before{content:"\\F214"}.fa-simplybuilt:before{content:"\\F215"}.fa-skyatlas:before{content:"\\F216"}.fa-cart-plus:before{content:"\\F217"}.fa-cart-arrow-down:before{content:"\\F218"}.fa-diamond:before{content:"\\F219"}.fa-ship:before{content:"\\F21A"}.fa-user-secret:before{content:"\\F21B"}.fa-motorcycle:before{content:"\\F21C"}.fa-street-view:before{content:"\\F21D"}.fa-heartbeat:before{content:"\\F21E"}.fa-venus:before{content:"\\F221"}.fa-mars:before{content:"\\F222"}.fa-mercury:before{content:"\\F223"}.fa-intersex:before,.fa-transgender:before{content:"\\F224"}.fa-transgender-alt:before{content:"\\F225"}.fa-venus-double:before{content:"\\F226"}.fa-mars-double:before{content:"\\F227"}.fa-venus-mars:before{content:"\\F228"}.fa-mars-stroke:before{content:"\\F229"}.fa-mars-stroke-v:before{content:"\\F22A"}.fa-mars-stroke-h:before{content:"\\F22B"}.fa-neuter:before{content:"\\F22C"}.fa-genderless:before{content:"\\F22D"}.fa-facebook-official:before{content:"\\F230"}.fa-pinterest-p:before{content:"\\F231"}.fa-whatsapp:before{content:"\\F232"}.fa-server:before{content:"\\F233"}.fa-user-plus:before{content:"\\F234"}.fa-user-times:before{content:"\\F235"}.fa-bed:before,.fa-hotel:before{content:"\\F236"}.fa-viacoin:before{content:"\\F237"}.fa-train:before{content:"\\F238"}.fa-subway:before{content:"\\F239"}.fa-medium:before{content:"\\F23A"}.fa-y-combinator:before,.fa-yc:before{content:"\\F23B"}.fa-optin-monster:before{content:"\\F23C"}.fa-opencart:before{content:"\\F23D"}.fa-expeditedssl:before{content:"\\F23E"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:"\\F240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\\F241"}.fa-battery-2:before,.fa-battery-half:before{content:"\\F242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\\F243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\\F244"}.fa-mouse-pointer:before{content:"\\F245"}.fa-i-cursor:before{content:"\\F246"}.fa-object-group:before{content:"\\F247"}.fa-object-ungroup:before{content:"\\F248"}.fa-sticky-note:before{content:"\\F249"}.fa-sticky-note-o:before{content:"\\F24A"}.fa-cc-jcb:before{content:"\\F24B"}.fa-cc-diners-club:before{content:"\\F24C"}.fa-clone:before{content:"\\F24D"}.fa-balance-scale:before{content:"\\F24E"}.fa-hourglass-o:before{content:"\\F250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\\F251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\\F252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\\F253"}.fa-hourglass:before{content:"\\F254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\\F255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\\F256"}.fa-hand-scissors-o:before{content:"\\F257"}.fa-hand-lizard-o:before{content:"\\F258"}.fa-hand-spock-o:before{content:"\\F259"}.fa-hand-pointer-o:before{content:"\\F25A"}.fa-hand-peace-o:before{content:"\\F25B"}.fa-trademark:before{content:"\\F25C"}.fa-registered:before{content:"\\F25D"}.fa-creative-commons:before{content:"\\F25E"}.fa-gg:before{content:"\\F260"}.fa-gg-circle:before{content:"\\F261"}.fa-tripadvisor:before{content:"\\F262"}.fa-odnoklassniki:before{content:"\\F263"}.fa-odnoklassniki-square:before{content:"\\F264"}.fa-get-pocket:before{content:"\\F265"}.fa-wikipedia-w:before{content:"\\F266"}.fa-safari:before{content:"\\F267"}.fa-chrome:before{content:"\\F268"}.fa-firefox:before{content:"\\F269"}.fa-opera:before{content:"\\F26A"}.fa-internet-explorer:before{content:"\\F26B"}.fa-television:before,.fa-tv:before{content:"\\F26C"}.fa-contao:before{content:"\\F26D"}.fa-500px:before{content:"\\F26E"}.fa-amazon:before{content:"\\F270"}.fa-calendar-plus-o:before{content:"\\F271"}.fa-calendar-minus-o:before{content:"\\F272"}.fa-calendar-times-o:before{content:"\\F273"}.fa-calendar-check-o:before{content:"\\F274"}.fa-industry:before{content:"\\F275"}.fa-map-pin:before{content:"\\F276"}.fa-map-signs:before{content:"\\F277"}.fa-map-o:before{content:"\\F278"}.fa-map:before{content:"\\F279"}.fa-commenting:before{content:"\\F27A"}.fa-commenting-o:before{content:"\\F27B"}.fa-houzz:before{content:"\\F27C"}.fa-vimeo:before{content:"\\F27D"}.fa-black-tie:before{content:"\\F27E"}.fa-fonticons:before{content:"\\F280"}.fa-reddit-alien:before{content:"\\F281"}.fa-edge:before{content:"\\F282"}.fa-credit-card-alt:before{content:"\\F283"}.fa-codiepie:before{content:"\\F284"}.fa-modx:before{content:"\\F285"}.fa-fort-awesome:before{content:"\\F286"}.fa-usb:before{content:"\\F287"}.fa-product-hunt:before{content:"\\F288"}.fa-mixcloud:before{content:"\\F289"}.fa-scribd:before{content:"\\F28A"}.fa-pause-circle:before{content:"\\F28B"}.fa-pause-circle-o:before{content:"\\F28C"}.fa-stop-circle:before{content:"\\F28D"}.fa-stop-circle-o:before{content:"\\F28E"}.fa-shopping-bag:before{content:"\\F290"}.fa-shopping-basket:before{content:"\\F291"}.fa-hashtag:before{content:"\\F292"}.fa-bluetooth:before{content:"\\F293"}.fa-bluetooth-b:before{content:"\\F294"}.fa-percent:before{content:"\\F295"}.fa-gitlab:before{content:"\\F296"}.fa-wpbeginner:before{content:"\\F297"}.fa-wpforms:before{content:"\\F298"}.fa-envira:before{content:"\\F299"}.fa-universal-access:before{content:"\\F29A"}.fa-wheelchair-alt:before{content:"\\F29B"}.fa-question-circle-o:before{content:"\\F29C"}.fa-blind:before{content:"\\F29D"}.fa-audio-description:before{content:"\\F29E"}.fa-volume-control-phone:before{content:"\\F2A0"}.fa-braille:before{content:"\\F2A1"}.fa-assistive-listening-systems:before{content:"\\F2A2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\\F2A3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\\F2A4"}.fa-glide:before{content:"\\F2A5"}.fa-glide-g:before{content:"\\F2A6"}.fa-sign-language:before,.fa-signing:before{content:"\\F2A7"}.fa-low-vision:before{content:"\\F2A8"}.fa-viadeo:before{content:"\\F2A9"}.fa-viadeo-square:before{content:"\\F2AA"}.fa-snapchat:before{content:"\\F2AB"}.fa-snapchat-ghost:before{content:"\\F2AC"}.fa-snapchat-square:before{content:"\\F2AD"}.fa-pied-piper:before{content:"\\F2AE"}.fa-first-order:before{content:"\\F2B0"}.fa-yoast:before{content:"\\F2B1"}.fa-themeisle:before{content:"\\F2B2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\\F2B3"}.fa-fa:before,.fa-font-awesome:before{content:"\\F2B4"}.fa-handshake-o:before{content:"\\F2B5"}.fa-envelope-open:before{content:"\\F2B6"}.fa-envelope-open-o:before{content:"\\F2B7"}.fa-linode:before{content:"\\F2B8"}.fa-address-book:before{content:"\\F2B9"}.fa-address-book-o:before{content:"\\F2BA"}.fa-address-card:before,.fa-vcard:before{content:"\\F2BB"}.fa-address-card-o:before,.fa-vcard-o:before{content:"\\F2BC"}.fa-user-circle:before{content:"\\F2BD"}.fa-user-circle-o:before{content:"\\F2BE"}.fa-user-o:before{content:"\\F2C0"}.fa-id-badge:before{content:"\\F2C1"}.fa-drivers-license:before,.fa-id-card:before{content:"\\F2C2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\\F2C3"}.fa-quora:before{content:"\\F2C4"}.fa-free-code-camp:before{content:"\\F2C5"}.fa-telegram:before{content:"\\F2C6"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:"\\F2C7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\\F2C8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\\F2C9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\\F2CA"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\\F2CB"}.fa-shower:before{content:"\\F2CC"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:"\\F2CD"}.fa-podcast:before{content:"\\F2CE"}.fa-window-maximize:before{content:"\\F2D0"}.fa-window-minimize:before{content:"\\F2D1"}.fa-window-restore:before{content:"\\F2D2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\\F2D3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\\F2D4"}.fa-bandcamp:before{content:"\\F2D5"}.fa-grav:before{content:"\\F2D6"}.fa-etsy:before{content:"\\F2D7"}.fa-imdb:before{content:"\\F2D8"}.fa-ravelry:before{content:"\\F2D9"}.fa-eercast:before{content:"\\F2DA"}.fa-microchip:before{content:"\\F2DB"}.fa-snowflake-o:before{content:"\\F2DC"}.fa-superpowers:before{content:"\\F2DD"}.fa-wpexplorer:before{content:"\\F2DE"}.fa-meetup:before{content:"\\F2E0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}',""]); -},function(A,M,t){M=A.exports=t(138)(),M.push([A.id,'*,:after,:before{box-sizing:border-box}body{font-family:Lato,sans-serif;font-size:15px;line-height:1.42857143;color:#8e8e8e;background-color:#edecec}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#46a5e0}a,a:focus,a:hover{text-decoration:none}a:focus,a:hover{color:#1f7fba}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#edecec;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,.08)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#8e8e8e;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#333;background-color:rgba(0,0,0,.05)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#333;text-decoration:none;outline:0;background-color:rgba(0,0,0,.075)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#e4e4e4}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:13px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu>li>a{text-align:right}.navbar-right .dropdown-menu-left{left:0;right:auto}}.modal,.modal-open{overflow:hidden}.modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid transparent;border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:rgba(0,0,0,.1)}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:30px 35px 0;border-bottom:1px solid transparent}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:transparent}.modal-body{position:relative;padding:30px 35px}.modal-footer{padding:30px 35px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:400px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Lato,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:13px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:active,:focus{outline:0}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{min-height:100%}a{-webkit-transition:color;transition:color;-webkit-transition-duration:.3s;transition-duration:.3s}button{border:0}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.text-center{text-align:center!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.modal-footer:after,.modal-header:after,.row:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.p-relative{position:relative}.m-0{margin:0!important}.m-t-0{margin-top:0!important}.m-b-0{margin-bottom:0!important}.m-l-0{margin-left:0!important}.m-r-0{margin-right:0!important}.m-5{margin:5px!important}.m-t-5{margin-top:5px!important}.m-b-5{margin-bottom:5px!important}.m-l-5{margin-left:5px!important}.m-r-5{margin-right:5px!important}.m-10{margin:10px!important}.m-t-10{margin-top:10px!important}.m-b-10{margin-bottom:10px!important}.m-l-10{margin-left:10px!important}.m-r-10{margin-right:10px!important}.m-15{margin:15px!important}.m-t-15{margin-top:15px!important}.m-b-15{margin-bottom:15px!important}.m-l-15{margin-left:15px!important}.m-r-15{margin-right:15px!important}.m-20{margin:20px!important}.m-t-20{margin-top:20px!important}.m-b-20{margin-bottom:20px!important}.m-l-20{margin-left:20px!important}.m-r-20{margin-right:20px!important}.m-25{margin:25px!important}.m-t-25{margin-top:25px!important}.m-b-25{margin-bottom:25px!important}.m-l-25{margin-left:25px!important}.m-r-25{margin-right:25px!important}.m-30{margin:30px!important}.m-t-30{margin-top:30px!important}.m-b-30{margin-bottom:30px!important}.m-l-30{margin-left:30px!important}.m-r-30{margin-right:30px!important}.p-0{padding:0!important}.p-t-0{padding-top:0!important}.p-b-0{padding-bottom:0!important}.p-l-0{padding-left:0!important}.p-r-0{padding-right:0!important}.p-5{padding:5px!important}.p-t-5{padding-top:5px!important}.p-b-5{padding-bottom:5px!important}.p-l-5{padding-left:5px!important}.p-r-5{padding-right:5px!important}.p-10{padding:10px!important}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.p-l-10{padding-left:10px!important}.p-r-10{padding-right:10px!important}.p-15{padding:15px!important}.p-t-15{padding-top:15px!important}.p-b-15{padding-bottom:15px!important}.p-l-15{padding-left:15px!important}.p-r-15{padding-right:15px!important}.p-20{padding:20px!important}.p-t-20{padding-top:20px!important}.p-b-20{padding-bottom:20px!important}.p-l-20{padding-left:20px!important}.p-r-20{padding-right:20px!important}.p-25{padding:25px!important}.p-t-25{padding-top:25px!important}.p-b-25{padding-bottom:25px!important}.p-l-25{padding-left:25px!important}.p-r-25{padding-right:25px!important}.p-30{padding:30px!important}.p-t-30{padding-top:30px!important}.p-b-30{padding-bottom:30px!important}.p-l-30{padding-left:30px!important}.p-r-30{padding-right:30px!important}@font-face{font-family:Lato;src:url('+t(515)+') format("woff2"),url('+t(514)+') format("woff");font-weight:400;font-style:normal}.form-control{border:0;border-bottom:1px solid #eee;color:#32393f;padding:5px;width:100%;font-size:13px;background-color:transparent}select.form-control{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background:url('+t(518)+') no-repeat bottom 7px right}.input-group{position:relative}.input-group:not(:last-child){margin-bottom:25px}.input-group label:not(.ig-label){font-size:13px;display:block;margin-bottom:10px}.ig-label{position:absolute;text-align:center;bottom:7px;left:0;width:100%;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;padding:2px 0 3px;border-radius:2px;font-weight:400}.ig-helpers{z-index:1;width:100%;left:0}.ig-helpers,.ig-helpers:after,.ig-helpers:before{position:absolute;height:2px;bottom:0}.ig-helpers:after,.ig-helpers:before{content:"";width:0;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;background-color:#03a9f4}.ig-helpers:before{left:50%}.ig-helpers:after{right:50%}.ig-text{width:100%;height:40px;border:0;background:transparent;text-align:center;position:relative;z-index:1;border-bottom:1px solid #eee;color:#32393f;font-size:13px}.ig-text:focus+.ig-helpers:after,.ig-text:focus+.ig-helpers:before{width:50%}.ig-text:disabled~.ig-label,.ig-text:focus~.ig-label,.ig-text:valid~.ig-label{bottom:35px;font-size:13px;z-index:1}.ig-text:disabled{opacity:.5;filter:alpha(opacity=50)}.ig-dark .ig-text{color:#fff;border-color:hsla(0,0%,100%,.1)}.ig-dark .ig-helpers:after,.ig-dark .ig-helpers:before{background-color:#dfdfdf;height:1px}.ig-left .ig-label,.ig-left .ig-text{text-align:left}.ig-error .ig-label{color:#e23f3f}.ig-error .ig-helpers i:first-child,.ig-error .ig-helpers i:first-child:after,.ig-error .ig-helpers i:first-child:before{background:rgba(226,63,63,.43)}.ig-error .ig-helpers i:last-child,.ig-error .ig-helpers i:last-child:after,.ig-error .ig-helpers i:last-child:before{background:#e23f3f!important}.ig-error:after{content:"\\F05A";font-family:FontAwesome;position:absolute;top:17px;right:9px;font-size:20px;color:#d33d3e}.ig-search:before{font-family:fontAwesome;content:"\\F002";font-size:15px;position:absolute;left:2px;top:8px}.ig-search .ig-text{padding-left:25px}.set-expire{border:1px solid #eee;margin:35px 0 30px}.set-expire-item{padding:9px 5px 3px;position:relative;display:table-cell;width:1%;text-align:center}.set-expire-item:not(:last-child){border-right:1px solid #eee}.set-expire-title{font-size:10px;text-transform:uppercase}.set-expire-value{display:inline-block;overflow:hidden;position:relative;left:-8px}.set-expire-value input{font-size:20px;text-align:center;position:relative;right:-15px;border:0;color:#333;padding:0;height:25px;width:100%;font-weight:400}.set-expire-decrease,.set-expire-increase{position:absolute;width:20px;height:20px;background:url('+t(516)+') no-repeat 50%;background-size:85%;left:50%;margin-left:-10px;opacity:.2;filter:alpha(opacity=20);cursor:pointer}.set-expire-decrease:hover,.set-expire-increase:hover{opacity:.5;filter:alpha(opacity=50)}.set-expire-increase{top:-25px}.set-expire-decrease{bottom:-27px;-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.btn{border:0;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:2px;text-align:center;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.btn:focus,.btn:hover{opacity:.9;filter:alpha(opacity=90)}.btn-block{display:block;width:100%}.btn-white{color:#5b5b5b;background-color:#fff}.btn-white:focus,.btn-white:hover{color:#5b5b5b;background-color:#f0f0f0}.btn-link{color:#545454;background-color:#eee}.btn-link:focus,.btn-link:hover{color:#545454;background-color:#dfdfdf}.btn-danger{color:#fff;background-color:#ff726f}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff5450}.btn-primary{color:#fff;background-color:#50b2ff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#31a5ff}.btn-success{color:#fff;background-color:#33d46f}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#28c061}.close{right:15px;font-weight:400;opacity:1;font-size:18px;position:absolute;text-align:center;top:16px;z-index:1;padding:0;border:0;background-color:transparent}.close span{width:25px;height:25px;display:block;border-radius:50%;line-height:24px;text-shadow:none}.close:not(.close-alt) span{background-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.close:not(.close-alt):focus span,.close:not(.close-alt):hover span{background-color:hsla(0,0%,100%,.2);color:#fff}.close-alt span{background-color:#efefef;color:#989898}.close-alt:focus span,.close-alt:hover span{background-color:#e8e8e8;color:#7b7b7b}.hidden{display:none!important}.copy-text input{width:100%;border-radius:1px;border:1px solid #eee;padding:7px 12px;font-size:13px;line-height:100%;cursor:text;-webkit-transition:border-color;transition:border-color;-webkit-transition-duration:.3s;transition-duration:.3s}.copy-text input:hover{border-color:#e1e1e1}.share-availability{margin-bottom:40px}.share-availability:after,.share-availability:before{position:absolute;bottom:-30px;font-size:10px}.share-availability:before{content:"01 Sec";left:0}.share-availability:after{content:"7 days";right:0}.modal-aheader{height:100px}.modal-aheader:before{height:0!important}.modal-aheader .modal-dialog{margin:0;vertical-align:top}.login{height:100vh;min-height:500px;background:#32393f;text-align:center}.login:before{height:calc(100% - 110px);width:1px;content:""}.l-wrap,.login:before{display:inline-block;vertical-align:middle}.l-wrap{width:80%;max-width:500px;margin-top:-50px}.l-wrap.toggled{display:inline-block}.l-wrap .input-group:not(:last-child){margin-bottom:40px}.l-footer{height:110px;padding:0 50px}.lf-logo{float:right}.lf-logo img{width:40px}.lf-server{float:left;color:hsla(0,0%,100%,.4);font-size:20px;font-weight:400;padding-top:40px}@media (max-width:768px){.lf-logo,.lf-server{float:none;display:block;text-align:center;width:100%}.lf-logo{margin-bottom:5px}.lf-server{font-size:15px}}.lw-btn{width:50px;height:50px;border:1px solid #fff;display:inline-block;border-radius:50%;font-size:22px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;opacity:.3;background-color:transparent;line-height:45px;padding:0}.lw-btn:hover{color:#fff;opacity:.8;border-color:#fff}.lw-btn i{display:block;width:100%;padding-left:3px}input:-webkit-autofill{-webkit-box-shadow:0 0 0 50px #32393f inset!important;-webkit-text-fill-color:#fff!important}@media (min-width:668px){.fe-header{position:relative;padding:40px 40px 20px 45px}}@media (max-width:667px){.fe-header{padding:20px}}.fe-header h2{font-size:16px;font-weight:400;margin:0}.fe-header h2>span{margin-bottom:7px;display:inline-block}.fe-header h2>span:not(:first-child):before{content:"/";margin:0 4px;color:#8e8e8e}.fe-header p{margin-top:7px}.feh-usage{margin-top:12px;max-width:285px}@media (max-width:667px){.feh-usage{max-width:100%;font-size:12px}}.feh-usage>ul{margin-top:7px;list-style:none;padding:0}.feh-usage>ul>li{padding-right:0;display:inline-block}.fehu-chart{height:5px;background:#eee;position:relative;border-radius:2px;overflow:hidden}.fehu-chart>div{position:absolute;left:0;height:100%;background:#46a5e0}.feh-actions{list-style:none;padding:0;margin:0;position:absolute;right:35px;top:30px;z-index:11}@media (max-width:991px){.feh-actions{top:7px;right:10px;position:fixed}}.feh-actions>li{display:inline-block;text-align:right;vertical-align:top;line-height:100%}.feh-actions>li>.btn-group>button,.feh-actions>li>a{display:block;height:45px;min-width:45px;text-align:center;border-radius:50%;padding:0;border:0;background:none}@media (min-width:992px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{color:#7b7b7b;font-size:21px;line-height:45px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feh-actions>li>.btn-group>button:hover,.feh-actions>li>a:hover{background:rgba(0,0,0,.09)}}@media (max-width:991px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{background:url('+t(237)+') no-repeat 50%}.feh-actions>li>.btn-group>button .fa-reorder,.feh-actions>li>a .fa-reorder{display:none}}@media (max-width:991px){.fe-header-mobile{background-color:#32393f;padding:10px 50px 9px 12px;text-align:center;position:fixed;z-index:10;box-shadow:0 0 10px rgba(0,0,0,.3);left:0;top:0;width:100%}.fe-header-mobile .mh-logo{height:35px;position:relative;top:4px}.feh-trigger{width:41px;height:41px;cursor:pointer;float:left;position:relative;text-align:center}.feh-trigger:after,.feh-trigger:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.feh-trigger:after{z-index:1}.feh-trigger:before{background:hsla(0,0%,100%,.1);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:scale(0);transform:scale(0)}.feht-toggled:before{-webkit-transform:scale(1);transform:scale(1)}.feht-toggled .feht-lines{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.feht-toggled .feht-lines>div.top{width:12px;transform:translateX(8px) translateY(1px) rotate(45deg);-webkit-transform:translateX(8px) translateY(1px) rotate(45deg)}.feht-toggled .feht-lines>div.bottom{width:12px;transform:translateX(8px) translateY(-1px) rotate(-45deg);-webkit-transform:translateX(8px) translateY(-1px) rotate(-45deg)}.feht-lines,.feht-lines>div{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feht-lines{width:18px;height:12px;display:inline-block;margin-top:14px}.feht-lines>div{background-color:#eaeaea;width:18px;height:2px}.feht-lines>div.center{margin:3px 0}}.fe-sidebar{width:320px;background-color:#32393f;position:fixed;height:100%;overflow:hidden;padding:25px}@media (min-width:992px){.fe-sidebar{-webkit-transform:translateZ(0);transform:translateZ(0)}}@media (max-width:991px){.fe-sidebar{padding-top:85px;z-index:9;box-shadow:0 0 10px rgba(0,0,0,.65);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:translate3d(-335px,0,0);transform:translate3d(-335px,0,0)}.fe-sidebar.toggled{-webkit-transform:translateZ(0);transform:translateZ(0)}}.fe-sidebar a{color:hsla(0,0%,100%,.58)}.fe-sidebar a:hover{color:#fff}.fes-header{margin-bottom:40px}.fes-header h2,.fes-header img{float:left}.fes-header h2{margin:13px 0 0 10px;font-weight:400}.fes-header img{width:32px}.fesl-inner{height:calc(100vh - 260px);overflow:auto;padding:0;margin:0 -25px}.fesl-inner li{position:relative}.fesl-inner li>a{display:block;padding:10px 45px 12px 55px;word-wrap:break-word}.fesl-inner li>a:before{font-family:FontAwesome;content:"\\F0A0";font-size:17px;position:absolute;top:10px;left:25px;opacity:.8;filter:alpha(opacity=80)}.fesl-inner li>a.fesli-loading:before{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.1);border-bottom-color:hsla(0,0%,100%,.5);position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:32px;top:0;bottom:0;margin:auto}.fesl-inner li.active{background-color:#282e32}.fesl-inner li.active>a{color:#fff}.fesl-inner li:not(.active):hover{background-color:rgba(0,0,0,.1)}.fesl-inner li:not(.active):hover>a{color:#fff}.fesl-inner li:hover .fesli-trigger{opacity:.6;filter:alpha(opacity=60)}.fesl-inner li:hover .fesli-trigger:hover{opacity:1;filter:alpha(opacity=100)}.fesl-inner ul{list-style:none;padding:0;margin:0}.fesl-inner:hover .scrollbar-vertical{opacity:1}.fesli-trigger{filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;top:0;right:0;width:35px;cursor:pointer;background:url('+t(237)+') no-repeat top 20px left}.fesli-trigger,.scrollbar-vertical{opacity:0;position:absolute;height:100%}.scrollbar-vertical{right:5px;width:4px;-webkit-transition:opacity;transition:opacity;-webkit-transition-duration:.3s;transition-duration:.3s}.scrollbar-vertical div{border-radius:1px!important;background-color:#6a6a6a!important}.fes-host{position:fixed;left:0;bottom:0;z-index:1;background:#32393f;color:hsla(0,0%,100%,.4);font-size:15px;font-weight:400;width:320px;padding:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fes-host>i{margin-right:10px}.fesl-row{position:relative}@media (min-width:668px){.fesl-row{padding:5px 20px 5px 40px;display:flex;flex-flow:row nowrap;justify-content:space-between}}@media (max-width:667px){.fesl-row{padding:5px 20px}}.fesl-row:after,.fesl-row:before{content:" ";display:table}.fesl-row:after{clear:both}@media (min-width:668px){header.fesl-row{margin-bottom:20px;border-bottom:1px solid #f0f0f0;padding-left:30px}header.fesl-row .fesl-item,header.fesl-row .fesli-sort{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}header.fesl-row .fesl-item{cursor:pointer;color:#8e8e8e;font-weight:500;margin-bottom:-5px}header.fesl-row .fesl-item>.fesli-sort{float:right;margin:4px 0 0;opacity:0;filter:alpha(opacity=0);color:#32393f;font-size:14px}header.fesl-row .fesl-item:hover:not(.fesl-item-actions){background:#f5f5f5;color:#32393f}header.fesl-row .fesl-item:hover:not(.fesl-item-actions)>.fesli-sort{opacity:.5;filter:alpha(opacity=50)}}@media (max-width:667px){header.fesl-row{display:none}}div.fesl-row{border-bottom:1px solid transparent;cursor:default;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.5s;transition-duration:.5s}@media (max-width:667px){div.fesl-row{padding:5px 20px}}div.fesl-row:not(.fesl-row-selected):nth-child(2n){background-color:#fafafa}div.fesl-row:hover .fis-icon:before{opacity:0;filter:alpha(opacity=0)}div.fesl-row:hover .fis-helper:before{opacity:1;filter:alpha(opacity=100)}div.fesl-row[data-type=folder] .fis-icon{background-color:#a1d6dd}div.fesl-row[data-type=folder] .fis-icon:before{content:"\\F114"}div.fesl-row[data-type=pdf] .fis-icon{background-color:#fa7775}div.fesl-row[data-type=pdf] .fis-icon:before{content:"\\F1C1"}div.fesl-row[data-type=zip] .fis-icon{background-color:#427089}div.fesl-row[data-type=zip] .fis-icon:before{content:"\\F1C6"}div.fesl-row[data-type=audio] .fis-icon{background-color:#009688}div.fesl-row[data-type=audio] .fis-icon:before{content:"\\F1C7"}div.fesl-row[data-type=code] .fis-icon{background-color:#997867}div.fesl-row[data-type=code] .fis-icon:before{content:"\\F1C9"}div.fesl-row[data-type=excel] .fis-icon{background-color:#f1c3 3}div.fesl-row[data-type=excel] .fis-icon:before{content:"\\F1C3"}div.fesl-row[data-type=image] .fis-icon{background-color:#f06292}div.fesl-row[data-type=image] .fis-icon:before{content:"\\F1C5"}div.fesl-row[data-type=video] .fis-icon{background-color:#f8c363}div.fesl-row[data-type=video] .fis-icon:before{content:"\\F1C8"}div.fesl-row[data-type=other] .fis-icon{background-color:#afafaf}div.fesl-row[data-type=other] .fis-icon:before{content:"\\F016"}div.fesl-row[data-type=text] .fis-icon{background-color:#8a8a8a}div.fesl-row[data-type=text] .fis-icon:before{content:"\\F0F6"}div.fesl-row[data-type=doc] .fis-icon{background-color:#2196f5}div.fesl-row[data-type=doc] .fis-icon:before{content:"\\F1C2"}div.fesl-row[data-type=presentation] .fis-icon{background-color:#896ea6}div.fesl-row[data-type=presentation] .fis-icon:before{content:"\\F1C4"}div.fesl-row.fesl-loading:before{content:""}div.fesl-row.fesl-loading:after{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.5);border-bottom-color:#fff;position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:57px;top:17px}@media (max-width:667px){div.fesl-row.fesl-loading:after{left:27px}}.fesl-row-selected{background-color:#fbf2bf}.fesl-row-selected,.fesl-row-selected .fesl-item a{color:#757575}.fi-select{float:left;position:relative;width:35px;height:35px;margin:3px 0}@media (max-width:667px){.fi-select{margin-right:15px}}.fi-select input{position:absolute;left:0;top:0;width:35px;height:35px;z-index:20;opacity:0;cursor:pointer}.fi-select input:checked~.fis-icon{background-color:#32393f}.fi-select input:checked~.fis-icon:before{opacity:0}.fi-select input:checked~.fis-helper:before{-webkit-transform:scale(0);transform:scale(0)}.fi-select input:checked~.fis-helper:after{-webkit-transform:scale(1);transform:scale(1)}.fis-icon{display:inline-block;vertical-align:top;border-radius:50%;width:35px;height:35px;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-icon:before{width:100%;height:100%;text-align:center;position:absolute;border-radius:50%;font-family:fontAwesome;line-height:35px;font-size:16px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;font-style:normal}.fis-helper:after,.fis-helper:before{position:absolute;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-helper:before{content:"";width:15px;height:15px;border:2px solid #fff;z-index:10;border-radius:2px;top:10px;left:10px;opacity:0}.fis-helper:after{font-family:fontAwesome;content:"\\F00C";top:8px;left:9px;color:#fff;font-size:14px;-webkit-transform:scale(0);transform:scale(0)}.fesl-item{display:block}.fesl-item a{color:#818181}@media (min-width:668px){.fesl-item:not(.fesl-item-actions):not(.fesl-item-icon){text-overflow:ellipsis;padding:10px 15px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-name{flex:3}.fesl-item.fesl-item-size{width:140px}.fesl-item.fesl-item-modified{width:190px}.fesl-item.fesl-item-actions{width:40px}}@media (max-width:667px){.fesl-item{padding:0}.fesl-item.fesl-item-name{width:100%;margin-bottom:3px}.fesl-item.fesl-item-modified,.fesl-item.fesl-item-size{font-size:12px;color:#b5b5b5;float:left}.fesl-item.fesl-item-modified{max-width:72px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-size{margin-right:10px}.fesl-item.fesl-item-actions{position:absolute;top:5px;right:10px}}.fia-toggle{height:36px;width:36px;background:transparent url('+t(517)+') no-repeat 50%;position:relative;top:3px;opacity:.4;filter:alpha(opacity=40)}.fia-toggle:hover{opacity:.7;filter:alpha(opacity=70)}.fesl-item-actions .dropdown-menu{background-color:transparent;box-shadow:none;padding:0;right:38px;left:auto;margin:0;height:100%;text-align:right}.fesl-item-actions .dropdown.open .dropdown-menu .fiad-action{right:0}.fiad-action{height:35px;width:35px;background:#ffc107;display:inline-block;border-radius:50%;text-align:center;line-height:35px;font-weight:400;position:relative;top:4px;margin-left:5px;-webkit-animation-name:fiad-action-anim;animation-name:fiad-action-anim;-webkit-transform-origin:center center;transform-origin:center center;-webkit-backface-visibility:none;backface-visibility:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.fiad-action:nth-child(2){-webkit-animation-duration:.1s;animation-duration:.1s}.fiad-action:first-child{-webkit-animation-duration:.25s;animation-duration:.25s}.fiad-action>i{font-size:14px;color:#fff}.fiad-action:hover{background-color:#f7b900}.list-actions{position:fixed;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);opacity:0;filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;padding:20px 70px 20px 25px;top:0;left:0;width:100%;background-color:#2298f7;z-index:20;box-shadow:0 0 10px rgba(0,0,0,.3);text-align:center}.list-actions.list-actions-toggled{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1;filter:alpha(opacity=100)}.la-close{position:absolute;right:20px;top:0;color:#fff;width:30px;height:30px;border-radius:50%;text-align:center;line-height:30px!important;background:hsla(0,0%,100%,.1);font-weight:400;bottom:0;margin:auto;cursor:pointer}.la-close:hover{background-color:hsla(0,0%,100%,.2)}.la-label{color:#fff;float:left;padding:4px 0}.la-label .fa{font-size:22px;vertical-align:top;margin-right:10px;margin-top:-1px}.la-actions button{background-color:transparent;border:2px solid hsla(0,0%,100%,.9);color:#fff;border-radius:2px;padding:5px 10px;font-size:13px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;margin-left:10px}.la-actions button:hover{background-color:#fff;color:#2298f7}@-webkit-keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}@keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}.file-explorer{background-color:#fff;position:relative;height:100%}.file-explorer.toggled{height:100vh;overflow:hidden}.fe-body{min-height:100vh;overflow:auto}@media (min-width:992px){.fe-body{padding:0 0 40px 320px}}@media (max-width:991px){.fe-body{padding:75px 0 80px}}.feb-actions{position:fixed;bottom:30px;right:30px}.feb-actions .dropdown-menu{min-width:55px;width:55px;text-align:center;background:transparent;box-shadow:none;margin:0}.feb-actions.open .feba-btn{-webkit-transform:scale(1);transform:scale(1)}.feb-actions.open .feba-btn:first-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.3s;animation-duration:.3s}.feb-actions.open .feba-btn:last-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.1s;animation-duration:.1s}.feb-actions.open .feba-toggle{background:#ff403c}.feb-actions.open .feba-toggle>span{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.feba-toggle{width:55px;height:55px;line-height:55px;border-radius:50%;background:#ff726f;box-shadow:0 2px 3px rgba(0,0,0,.15);display:inline-block;text-align:center;border:0;padding:0}.feba-toggle span{display:inline-block;height:100%;width:100%}.feba-toggle i{color:#fff;font-size:17px;line-height:58px}.feba-toggle,.feba-toggle>span{-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;-webkit-backface-visibility:hidden;backface-visibility:hidden}.feba-btn{width:40px;margin-top:10px;height:40px;border-radius:50%;text-align:center;display:inline-block;line-height:40px;box-shadow:0 2px 3px rgba(0,0,0,.15);-webkit-transform:scale(0);transform:scale(0);position:relative}.feba-btn,.feba-btn:focus,.feba-btn:hover{color:#fff}.feba-btn label{width:100%;height:100%;position:absolute;left:0;top:0;cursor:pointer}.feba-bucket{background:#ffc155}.feba-upload{background:#ffc107}@-webkit-keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}@keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}.ie-warning{background-color:#ff5252;width:100%;height:100%;position:fixed;left:0;top:0;text-align:center}.ie-warning:before{width:1px;content:"";height:100%}.ie-warning .iw-inner,.ie-warning:before{display:inline-block;vertical-align:middle}.iw-inner{width:470px;height:300px;background-color:#fff;border-radius:5px;padding:40px;position:relative}.iw-inner ul{list-style:none;padding:0;margin:0;width:230px;margin-left:80px;margin-top:16px}.iw-inner ul>li{float:left}.iw-inner ul>li>a{display:block;padding:10px 15px 7px;font-size:14px;margin:0 1px;border-radius:3px}.iw-inner ul>li>a:hover{background:#eee}.iw-inner ul>li>a img{height:40px;margin-bottom:5px}.iwi-icon{color:#ff5252;font-size:40px;display:block;line-height:100%;margin-bottom:15px}.iwi-skip{position:absolute;left:0;bottom:-35px;width:100%;color:hsla(0,0%,100%,.6);cursor:pointer}.iwi-skip:hover{color:#fff}.dropdown-menu{padding:15px 0;top:0;margin-top:-1px}.dropdown-menu>li>a{padding:8px 20px;font-size:15px}.dropdown-menu>li>a>i{width:20px;position:relative;top:1px}.dropdown-menu-right>li>a{text-align:right}.alert{border:0;position:fixed;max-width:500px;margin:0;box-shadow:0 4px 5px rgba(0,0,0,.1);color:#fff;width:100%;right:20px;border-radius:3px;padding:17px 50px 17px 17px;z-index:10010;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.alert:not(.progress){top:20px}@media (min-width:768px){.alert:not(.progress){left:50%;margin-left:-250px}}.alert.progress{bottom:20px;right:20px}.alert.alert-danger{background:#ff726f}.alert.alert-success{background:#33d46f}.alert.alert-info{background:#50b2ff}@media (max-width:767px){.alert{left:20px;width:calc(100% - 40px);max-width:100%}}.alert .progress{margin:10px 10px 8px 0;height:5px;box-shadow:none;border-radius:1px;background-color:#50b2ff;border-radius:2px;overflow:hidden}.alert .progress-bar{box-shadow:none;background-color:#fff;height:100%}.alert .close{position:absolute;top:15px}@media (min-width:768px){.modal{text-align:center}.modal:before{content:"";height:100%;width:1px}.modal .modal-dialog,.modal:before{display:inline-block;vertical-align:middle}.modal .modal-dialog{text-align:left;margin:10px auto}}.modal-dark .modal-header{color:hsla(0,0%,100%,.4)}.modal-dark .modal-header small{color:hsla(0,0%,100%,.2)}.modal-dark .modal-content{background-color:#32393f}.modal-backdrop{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-backdrop,.modal-dialog{-webkit-animation-duration:.2s;animation-duration:.2s}.modal-dialog{-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-header{color:#333;position:relative}.modal-header small{display:block;text-transform:none;font-size:12px;margin-top:5px;color:#a8a8a8}.modal-content{border-radius:3px;box-shadow:none}.modal-footer{padding:0 30px 30px}.modal-confirm .modal-dialog,.modal-footer{text-align:center}.mc-icon{margin:0 0 10px}.mc-icon>i{font-size:60px}.mci-red{color:#ff8f8f}.mci-amber{color:#ffc107}.mci-green{color:#64e096}.mc-text{color:#333}.mc-sub{color:#bdbdbd;margin-top:5px;font-size:13px}@media (max-width:767px){.modal-about{text-align:center}.modal-about .modal-dialog{max-width:400px;width:90%;margin:20px auto 0}}.ma-inner{display:flex;flex-direction:row;align-items:center;min-height:350px;position:relative}@media (min-width:768px){.ma-inner:before{content:"";width:150px;height:100%;top:0;left:0;position:absolute;border-radius:3px 0 0 3px;background-color:#23282c}}.mai-item:first-child{width:150px;text-align:center}.mai-item:last-child{flex:4;padding:30px}.maii-logo{width:70px;position:relative}.maii-list{list-style:none;padding:0}.maii-list>li{margin-bottom:15px}.maii-list>li div{color:hsla(0,0%,100%,.8);text-transform:uppercase;font-size:14px}.maii-list>li small{font-size:13px;color:hsla(0,0%,100%,.4)}.toggle-password{position:absolute;bottom:30px;right:35px;width:30px;height:30px;border:1px solid #eee;border-radius:0;text-align:center;cursor:pointer;z-index:10;background-color:#fff;padding-top:5px}.toggle-password.toggled{background:#eee}.pm-body{padding-bottom:30px}.pmb-header{margin-bottom:35px}.pmb-list{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;padding:10px 35px}.pmb-list:nth-child(2n){background-color:#f7f7f7}.pmb-list .form-control{padding-left:0;padding-right:0}header.pmb-list{margin:20px 0 10px}.pmbl-item{display:block;font-size:13px}.pmbl-item:first-child{flex:2}.pmbl-item:nth-child(2){margin:0 25px;width:150px}.pmbl-item:nth-child(3){width:70px}div.pmb-list select{border:0}div.pmb-list .pml-item:not(:last-child){padding:0 5px}.modal-create-bucket .modal-dialog{position:fixed;right:25px;bottom:95px;margin:0;height:110px}.modal-create-bucket .modal-content{width:100%;height:100%}',""]); -},function(A,M,t){function I(A){return null===A||void 0===A}function g(A){return!(!A||"object"!=typeof A||"number"!=typeof A.length)&&("function"==typeof A.copy&&"function"==typeof A.slice&&!(A.length>0&&"number"!=typeof A[0]))}function e(A,M,t){var e,o;if(I(A)||I(M))return!1;if(A.prototype!==M.prototype)return!1;if(E(A))return!!E(M)&&(A=i.call(A),M=i.call(M),N(A,M,t));if(g(A)){if(!g(M))return!1;if(A.length!==M.length)return!1;for(e=0;e=0;e--)if(n[e]!=C[e])return!1;for(e=n.length-1;e>=0;e--)if(o=n[e],!N(A[o],M[o],t))return!1;return typeof A==typeof M}var i=Array.prototype.slice,T=t(280),E=t(279),N=A.exports=function(A,M,t){return t||(t={}),A===M||(A instanceof Date&&M instanceof Date?A.getTime()===M.getTime():!A||!M||"object"!=typeof A&&"object"!=typeof M?t.strict?A===M:A==M:e(A,M,t))}},function(A,M){function t(A){return"[object Arguments]"==Object.prototype.toString.call(A)}function I(A){return A&&"object"==typeof A&&"number"==typeof A.length&&Object.prototype.hasOwnProperty.call(A,"callee")&&!Object.prototype.propertyIsEnumerable.call(A,"callee")||!1}var g="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();M=A.exports=g?t:I,M.supported=t,M.unsupported=I},function(A,M){function t(A){var M=[];for(var t in A)M.push(t);return M}M=A.exports="function"==typeof Object.keys?Object.keys:t,M.shim=t},function(A,M,t){"use strict";var I=t(141);A.exports=function(A,M){A.classList?A.classList.add(M):I(A)||(A.className=A.className+" "+M)}},function(A,M,t){"use strict";A.exports={addClass:t(281),removeClass:t(283),hasClass:t(141)}},function(A,M){"use strict";A.exports=function(A,M){A.classList?A.classList.remove(M):A.className=A.className.replace(new RegExp("(^|\\s)"+M+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}},function(A,M,t){"use strict";var I=t(40),g=t(288);A.exports=function(A,M){return function(t){var e=t.currentTarget,i=t.target,T=g(e,A);T.some(function(A){return I(A,i)})&&M.call(this,t)}}},function(A,M,t){"use strict";var I=t(81),g=t(142),e=t(284);A.exports={on:I,off:g,filter:e}},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A){for(var M=(0,T.default)(A),t=A&&A.offsetParent;t&&"html"!==I(A)&&"static"===(0,N.default)(t,"position");)t=t.offsetParent;return t||M.documentElement}var e=t(58);M.__esModule=!0,M.default=g;var i=t(39),T=e.interopRequireDefault(i),E=t(82),N=e.interopRequireDefault(E);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A,M){var t,g={top:0,left:0};return"fixed"===(0,a.default)(A,"position")?t=A.getBoundingClientRect():(M=M||(0,N.default)(A),t=(0,T.default)(A),"html"!==I(M)&&(g=(0,T.default)(M)),g.top+=parseInt((0,a.default)(M,"borderTopWidth"),10)-(0,n.default)(M)||0,g.left+=parseInt((0,a.default)(M,"borderLeftWidth"),10)-(0,c.default)(M)||0),e._extends({},t,{top:t.top-g.top-(parseInt((0,a.default)(A,"marginTop"),10)||0),left:t.left-g.left-(parseInt((0,a.default)(A,"marginLeft"),10)||0)})}var e=t(58);M.__esModule=!0,M.default=g;var i=t(143),T=e.interopRequireDefault(i),E=t(286),N=e.interopRequireDefault(E),o=t(144),n=e.interopRequireDefault(o),C=t(289),c=e.interopRequireDefault(C),D=t(82),a=e.interopRequireDefault(D);A.exports=M.default},function(A,M){"use strict";var t=/^[\w-]*$/,I=Function.prototype.bind.call(Function.prototype.call,[].slice);A.exports=function(A,M){var g,e="#"===M[0],i="."===M[0],T=e||i?M.slice(1):M,E=t.test(T);return E?e?(A=A.getElementById?A:document,(g=A.getElementById(T))?[g]:[]):I(A.getElementsByClassName&&i?A.getElementsByClassName(T):A.getElementsByTagName(M)):I(A.querySelectorAll(M))}},function(A,M,t){"use strict";var I=t(57);A.exports=function(A,M){var t=I(A);return void 0===M?t?"pageXOffset"in t?t.pageXOffset:t.document.documentElement.scrollLeft:A.scrollLeft:void(t?t.scrollTo(M,"pageYOffset"in t?t.pageYOffset:t.document.documentElement.scrollTop):A.scrollLeft=M)}},function(A,M,t){"use strict";var I=t(58),g=t(145),e=I.interopRequireDefault(g),i=/^(top|right|bottom|left)$/,T=/^([+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/i;A.exports=function(A){if(!A)throw new TypeError("No Element passed to ` + "`" + `getComputedStyle()` + "`" + `");var M=A.ownerDocument;return"defaultView"in M?M.defaultView.opener?A.ownerDocument.defaultView.getComputedStyle(A,null):window.getComputedStyle(A,null):{getPropertyValue:function(M){var t=A.style;M=(0,e.default)(M),"float"==M&&(M="styleFloat");var I=A.currentStyle[M]||null;if(null==I&&t&&t[M]&&(I=t[M]),T.test(I)&&!i.test(M)){var g=t.left,E=A.runtimeStyle,N=E&&E.left;N&&(E.left=A.currentStyle.left),t.left="fontSize"===M?"1em":I,I=t.pixelLeft+"px",t.left=g,N&&(E.left=N)}return I}}}},function(A,M){"use strict";A.exports=function(A,M){return"removeProperty"in A.style?A.style.removeProperty(M):A.style.removeAttribute(M)}},function(A,M,t){"use strict";function I(){var A,M="",t={O:"otransitionend",Moz:"transitionend",Webkit:"webkitTransitionEnd",ms:"MSTransitionEnd"},I=document.createElement("div");for(var g in t)if(N.call(t,g)&&void 0!==I.style[g+"TransitionProperty"]){M="-"+g.toLowerCase()+"-",A=t[g];break}return A||void 0===I.style.transitionProperty||(A="transitionend"),{end:A,prefix:M}}var g,e,i,T,E=t(32),N=Object.prototype.hasOwnProperty,o="transform",n={};E&&(n=I(),o=n.prefix+o,i=n.prefix+"transition-property",e=n.prefix+"transition-duration",T=n.prefix+"transition-delay",g=n.prefix+"transition-timing-function"),A.exports={transform:o,end:n.end,property:i,timing:g,delay:T,duration:e}},function(A,M){"use strict";var t=/-(.)/g;A.exports=function(A){return A.replace(t,function(A,M){return M.toUpperCase()})}},function(A,M){"use strict";var t=/([A-Z])/g;A.exports=function(A){return A.replace(t,"-$1").toLowerCase()}},function(A,M,t){"use strict";var I=t(294),g=/^ms-/;A.exports=function(A){return I(A).replace(g,"-ms-")}},function(A,M){"use strict";function t(A){return A.replace(I,function(A,M){return M.toUpperCase()})}var I=/-(.)/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A.replace(e,"ms-"))}var g=t(296),e=/^-ms-/;A.exports=I},function(A,M,t){"use strict";function I(A){return!!A&&("object"==typeof A||"function"==typeof A)&&"length"in A&&!("setInterval"in A)&&"number"!=typeof A.nodeType&&(Array.isArray(A)||"callee"in A||"item"in A)}function g(A){return I(A)?Array.isArray(A)?A.slice():e(A):[A]}var e=t(307);A.exports=g},function(A,M,t){"use strict";function I(A){var M=A.match(o);return M&&M[1].toLowerCase()}function g(A,M){var t=N;N?void 0:E(!1);var g=I(A),e=g&&T(g);if(e){t.innerHTML=e[1]+A+e[2];for(var o=e[0];o--;)t=t.lastChild}else t.innerHTML=A;var n=t.getElementsByTagName("script");n.length&&(M?void 0:E(!1),i(n).forEach(M));for(var C=i(t.childNodes);t.lastChild;)t.removeChild(t.lastChild);return C}var e=t(10),i=t(298),T=t(151),E=t(2),N=e.canUseDOM?document.createElement("div"):null,o=/^\s*<(\w+)/;A.exports=g},function(A,M){"use strict";function t(A){return A===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:A.scrollLeft,y:A.scrollTop}}A.exports=t},function(A,M){"use strict";function t(A){return A.replace(I,"-$1").toLowerCase()}var I=/([A-Z])/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A).replace(e,"-ms-")}var g=t(301),e=/^ms-/;A.exports=I},function(A,M){"use strict";function t(A){return!(!A||!("function"==typeof Node?A instanceof Node:"object"==typeof A&&"number"==typeof A.nodeType&&"string"==typeof A.nodeName))}A.exports=t},function(A,M,t){"use strict";function I(A){return g(A)&&3==A.nodeType}var g=t(303);A.exports=I},function(A,M){"use strict";function t(A,M,t){if(!A)return null;var g={};for(var e in A)I.call(A,e)&&(g[e]=M.call(t,A[e],e,A));return g}var I=Object.prototype.hasOwnProperty;A.exports=t},function(A,M){"use strict";function t(A){var M={};return function(t){return M.hasOwnProperty(t)||(M[t]=A.call(this,t)),M[t]}}A.exports=t},function(A,M,t){"use strict";function I(A){var M=A.length;if(Array.isArray(A)||"object"!=typeof A&&"function"!=typeof A?g(!1):void 0,"number"!=typeof M?g(!1):void 0,0===M||M-1 in A?void 0:g(!1),A.hasOwnProperty)try{return Array.prototype.slice.call(A)}catch(A){}for(var t=Array(M),I=0;Ili{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\\F000"}.fa-music:before{content:"\\F001"}.fa-search:before{content:"\\F002"}.fa-envelope-o:before{content:"\\F003"}.fa-heart:before{content:"\\F004"}.fa-star:before{content:"\\F005"}.fa-star-o:before{content:"\\F006"}.fa-user:before{content:"\\F007"}.fa-film:before{content:"\\F008"}.fa-th-large:before{content:"\\F009"}.fa-th:before{content:"\\F00A"}.fa-th-list:before{content:"\\F00B"}.fa-check:before{content:"\\F00C"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\\F00D"}.fa-search-plus:before{content:"\\F00E"}.fa-search-minus:before{content:"\\F010"}.fa-power-off:before{content:"\\F011"}.fa-signal:before{content:"\\F012"}.fa-cog:before,.fa-gear:before{content:"\\F013"}.fa-trash-o:before{content:"\\F014"}.fa-home:before{content:"\\F015"}.fa-file-o:before{content:"\\F016"}.fa-clock-o:before{content:"\\F017"}.fa-road:before{content:"\\F018"}.fa-download:before{content:"\\F019"}.fa-arrow-circle-o-down:before{content:"\\F01A"}.fa-arrow-circle-o-up:before{content:"\\F01B"}.fa-inbox:before{content:"\\F01C"}.fa-play-circle-o:before{content:"\\F01D"}.fa-repeat:before,.fa-rotate-right:before{content:"\\F01E"}.fa-refresh:before{content:"\\F021"}.fa-list-alt:before{content:"\\F022"}.fa-lock:before{content:"\\F023"}.fa-flag:before{content:"\\F024"}.fa-headphones:before{content:"\\F025"}.fa-volume-off:before{content:"\\F026"}.fa-volume-down:before{content:"\\F027"}.fa-volume-up:before{content:"\\F028"}.fa-qrcode:before{content:"\\F029"}.fa-barcode:before{content:"\\F02A"}.fa-tag:before{content:"\\F02B"}.fa-tags:before{content:"\\F02C"}.fa-book:before{content:"\\F02D"}.fa-bookmark:before{content:"\\F02E"}.fa-print:before{content:"\\F02F"}.fa-camera:before{content:"\\F030"}.fa-font:before{content:"\\F031"}.fa-bold:before{content:"\\F032"}.fa-italic:before{content:"\\F033"}.fa-text-height:before{content:"\\F034"}.fa-text-width:before{content:"\\F035"}.fa-align-left:before{content:"\\F036"}.fa-align-center:before{content:"\\F037"}.fa-align-right:before{content:"\\F038"}.fa-align-justify:before{content:"\\F039"}.fa-list:before{content:"\\F03A"}.fa-dedent:before,.fa-outdent:before{content:"\\F03B"}.fa-indent:before{content:"\\F03C"}.fa-video-camera:before{content:"\\F03D"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\\F03E"}.fa-pencil:before{content:"\\F040"}.fa-map-marker:before{content:"\\F041"}.fa-adjust:before{content:"\\F042"}.fa-tint:before{content:"\\F043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\\F044"}.fa-share-square-o:before{content:"\\F045"}.fa-check-square-o:before{content:"\\F046"}.fa-arrows:before{content:"\\F047"}.fa-step-backward:before{content:"\\F048"}.fa-fast-backward:before{content:"\\F049"}.fa-backward:before{content:"\\F04A"}.fa-play:before{content:"\\F04B"}.fa-pause:before{content:"\\F04C"}.fa-stop:before{content:"\\F04D"}.fa-forward:before{content:"\\F04E"}.fa-fast-forward:before{content:"\\F050"}.fa-step-forward:before{content:"\\F051"}.fa-eject:before{content:"\\F052"}.fa-chevron-left:before{content:"\\F053"}.fa-chevron-right:before{content:"\\F054"}.fa-plus-circle:before{content:"\\F055"}.fa-minus-circle:before{content:"\\F056"}.fa-times-circle:before{content:"\\F057"}.fa-check-circle:before{content:"\\F058"}.fa-question-circle:before{content:"\\F059"}.fa-info-circle:before{content:"\\F05A"}.fa-crosshairs:before{content:"\\F05B"}.fa-times-circle-o:before{content:"\\F05C"}.fa-check-circle-o:before{content:"\\F05D"}.fa-ban:before{content:"\\F05E"}.fa-arrow-left:before{content:"\\F060"}.fa-arrow-right:before{content:"\\F061"}.fa-arrow-up:before{content:"\\F062"}.fa-arrow-down:before{content:"\\F063"}.fa-mail-forward:before,.fa-share:before{content:"\\F064"}.fa-expand:before{content:"\\F065"}.fa-compress:before{content:"\\F066"}.fa-plus:before{content:"\\F067"}.fa-minus:before{content:"\\F068"}.fa-asterisk:before{content:"\\F069"}.fa-exclamation-circle:before{content:"\\F06A"}.fa-gift:before{content:"\\F06B"}.fa-leaf:before{content:"\\F06C"}.fa-fire:before{content:"\\F06D"}.fa-eye:before{content:"\\F06E"}.fa-eye-slash:before{content:"\\F070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\\F071"}.fa-plane:before{content:"\\F072"}.fa-calendar:before{content:"\\F073"}.fa-random:before{content:"\\F074"}.fa-comment:before{content:"\\F075"}.fa-magnet:before{content:"\\F076"}.fa-chevron-up:before{content:"\\F077"}.fa-chevron-down:before{content:"\\F078"}.fa-retweet:before{content:"\\F079"}.fa-shopping-cart:before{content:"\\F07A"}.fa-folder:before{content:"\\F07B"}.fa-folder-open:before{content:"\\F07C"}.fa-arrows-v:before{content:"\\F07D"}.fa-arrows-h:before{content:"\\F07E"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\\F080"}.fa-twitter-square:before{content:"\\F081"}.fa-facebook-square:before{content:"\\F082"}.fa-camera-retro:before{content:"\\F083"}.fa-key:before{content:"\\F084"}.fa-cogs:before,.fa-gears:before{content:"\\F085"}.fa-comments:before{content:"\\F086"}.fa-thumbs-o-up:before{content:"\\F087"}.fa-thumbs-o-down:before{content:"\\F088"}.fa-star-half:before{content:"\\F089"}.fa-heart-o:before{content:"\\F08A"}.fa-sign-out:before{content:"\\F08B"}.fa-linkedin-square:before{content:"\\F08C"}.fa-thumb-tack:before{content:"\\F08D"}.fa-external-link:before{content:"\\F08E"}.fa-sign-in:before{content:"\\F090"}.fa-trophy:before{content:"\\F091"}.fa-github-square:before{content:"\\F092"}.fa-upload:before{content:"\\F093"}.fa-lemon-o:before{content:"\\F094"}.fa-phone:before{content:"\\F095"}.fa-square-o:before{content:"\\F096"}.fa-bookmark-o:before{content:"\\F097"}.fa-phone-square:before{content:"\\F098"}.fa-twitter:before{content:"\\F099"}.fa-facebook-f:before,.fa-facebook:before{content:"\\F09A"}.fa-github:before{content:"\\F09B"}.fa-unlock:before{content:"\\F09C"}.fa-credit-card:before{content:"\\F09D"}.fa-feed:before,.fa-rss:before{content:"\\F09E"}.fa-hdd-o:before{content:"\\F0A0"}.fa-bullhorn:before{content:"\\F0A1"}.fa-bell:before{content:"\\F0F3"}.fa-certificate:before{content:"\\F0A3"}.fa-hand-o-right:before{content:"\\F0A4"}.fa-hand-o-left:before{content:"\\F0A5"}.fa-hand-o-up:before{content:"\\F0A6"}.fa-hand-o-down:before{content:"\\F0A7"}.fa-arrow-circle-left:before{content:"\\F0A8"}.fa-arrow-circle-right:before{content:"\\F0A9"}.fa-arrow-circle-up:before{content:"\\F0AA"}.fa-arrow-circle-down:before{content:"\\F0AB"}.fa-globe:before{content:"\\F0AC"}.fa-wrench:before{content:"\\F0AD"}.fa-tasks:before{content:"\\F0AE"}.fa-filter:before{content:"\\F0B0"}.fa-briefcase:before{content:"\\F0B1"}.fa-arrows-alt:before{content:"\\F0B2"}.fa-group:before,.fa-users:before{content:"\\F0C0"}.fa-chain:before,.fa-link:before{content:"\\F0C1"}.fa-cloud:before{content:"\\F0C2"}.fa-flask:before{content:"\\F0C3"}.fa-cut:before,.fa-scissors:before{content:"\\F0C4"}.fa-copy:before,.fa-files-o:before{content:"\\F0C5"}.fa-paperclip:before{content:"\\F0C6"}.fa-floppy-o:before,.fa-save:before{content:"\\F0C7"}.fa-square:before{content:"\\F0C8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\\F0C9"}.fa-list-ul:before{content:"\\F0CA"}.fa-list-ol:before{content:"\\F0CB"}.fa-strikethrough:before{content:"\\F0CC"}.fa-underline:before{content:"\\F0CD"}.fa-table:before{content:"\\F0CE"}.fa-magic:before{content:"\\F0D0"}.fa-truck:before{content:"\\F0D1"}.fa-pinterest:before{content:"\\F0D2"}.fa-pinterest-square:before{content:"\\F0D3"}.fa-google-plus-square:before{content:"\\F0D4"}.fa-google-plus:before{content:"\\F0D5"}.fa-money:before{content:"\\F0D6"}.fa-caret-down:before{content:"\\F0D7"}.fa-caret-up:before{content:"\\F0D8"}.fa-caret-left:before{content:"\\F0D9"}.fa-caret-right:before{content:"\\F0DA"}.fa-columns:before{content:"\\F0DB"}.fa-sort:before,.fa-unsorted:before{content:"\\F0DC"}.fa-sort-desc:before,.fa-sort-down:before{content:"\\F0DD"}.fa-sort-asc:before,.fa-sort-up:before{content:"\\F0DE"}.fa-envelope:before{content:"\\F0E0"}.fa-linkedin:before{content:"\\F0E1"}.fa-rotate-left:before,.fa-undo:before{content:"\\F0E2"}.fa-gavel:before,.fa-legal:before{content:"\\F0E3"}.fa-dashboard:before,.fa-tachometer:before{content:"\\F0E4"}.fa-comment-o:before{content:"\\F0E5"}.fa-comments-o:before{content:"\\F0E6"}.fa-bolt:before,.fa-flash:before{content:"\\F0E7"}.fa-sitemap:before{content:"\\F0E8"}.fa-umbrella:before{content:"\\F0E9"}.fa-clipboard:before,.fa-paste:before{content:"\\F0EA"}.fa-lightbulb-o:before{content:"\\F0EB"}.fa-exchange:before{content:"\\F0EC"}.fa-cloud-download:before{content:"\\F0ED"}.fa-cloud-upload:before{content:"\\F0EE"}.fa-user-md:before{content:"\\F0F0"}.fa-stethoscope:before{content:"\\F0F1"}.fa-suitcase:before{content:"\\F0F2"}.fa-bell-o:before{content:"\\F0A2"}.fa-coffee:before{content:"\\F0F4"}.fa-cutlery:before{content:"\\F0F5"}.fa-file-text-o:before{content:"\\F0F6"}.fa-building-o:before{content:"\\F0F7"}.fa-hospital-o:before{content:"\\F0F8"}.fa-ambulance:before{content:"\\F0F9"}.fa-medkit:before{content:"\\F0FA"}.fa-fighter-jet:before{content:"\\F0FB"}.fa-beer:before{content:"\\F0FC"}.fa-h-square:before{content:"\\F0FD"}.fa-plus-square:before{content:"\\F0FE"}.fa-angle-double-left:before{content:"\\F100"}.fa-angle-double-right:before{content:"\\F101"}.fa-angle-double-up:before{content:"\\F102"}.fa-angle-double-down:before{content:"\\F103"}.fa-angle-left:before{content:"\\F104"}.fa-angle-right:before{content:"\\F105"}.fa-angle-up:before{content:"\\F106"}.fa-angle-down:before{content:"\\F107"}.fa-desktop:before{content:"\\F108"}.fa-laptop:before{content:"\\F109"}.fa-tablet:before{content:"\\F10A"}.fa-mobile-phone:before,.fa-mobile:before{content:"\\F10B"}.fa-circle-o:before{content:"\\F10C"}.fa-quote-left:before{content:"\\F10D"}.fa-quote-right:before{content:"\\F10E"}.fa-spinner:before{content:"\\F110"}.fa-circle:before{content:"\\F111"}.fa-mail-reply:before,.fa-reply:before{content:"\\F112"}.fa-github-alt:before{content:"\\F113"}.fa-folder-o:before{content:"\\F114"}.fa-folder-open-o:before{content:"\\F115"}.fa-smile-o:before{content:"\\F118"}.fa-frown-o:before{content:"\\F119"}.fa-meh-o:before{content:"\\F11A"}.fa-gamepad:before{content:"\\F11B"}.fa-keyboard-o:before{content:"\\F11C"}.fa-flag-o:before{content:"\\F11D"}.fa-flag-checkered:before{content:"\\F11E"}.fa-terminal:before{content:"\\F120"}.fa-code:before{content:"\\F121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\\F122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\\F123"}.fa-location-arrow:before{content:"\\F124"}.fa-crop:before{content:"\\F125"}.fa-code-fork:before{content:"\\F126"}.fa-chain-broken:before,.fa-unlink:before{content:"\\F127"}.fa-question:before{content:"\\F128"}.fa-info:before{content:"\\F129"}.fa-exclamation:before{content:"\\F12A"}.fa-superscript:before{content:"\\F12B"}.fa-subscript:before{content:"\\F12C"}.fa-eraser:before{content:"\\F12D"}.fa-puzzle-piece:before{content:"\\F12E"}.fa-microphone:before{content:"\\F130"}.fa-microphone-slash:before{content:"\\F131"}.fa-shield:before{content:"\\F132"}.fa-calendar-o:before{content:"\\F133"}.fa-fire-extinguisher:before{content:"\\F134"}.fa-rocket:before{content:"\\F135"}.fa-maxcdn:before{content:"\\F136"}.fa-chevron-circle-left:before{content:"\\F137"}.fa-chevron-circle-right:before{content:"\\F138"}.fa-chevron-circle-up:before{content:"\\F139"}.fa-chevron-circle-down:before{content:"\\F13A"}.fa-html5:before{content:"\\F13B"}.fa-css3:before{content:"\\F13C"}.fa-anchor:before{content:"\\F13D"}.fa-unlock-alt:before{content:"\\F13E"}.fa-bullseye:before{content:"\\F140"}.fa-ellipsis-h:before{content:"\\F141"}.fa-ellipsis-v:before{content:"\\F142"}.fa-rss-square:before{content:"\\F143"}.fa-play-circle:before{content:"\\F144"}.fa-ticket:before{content:"\\F145"}.fa-minus-square:before{content:"\\F146"}.fa-minus-square-o:before{content:"\\F147"}.fa-level-up:before{content:"\\F148"}.fa-level-down:before{content:"\\F149"}.fa-check-square:before{content:"\\F14A"}.fa-pencil-square:before{content:"\\F14B"}.fa-external-link-square:before{content:"\\F14C"}.fa-share-square:before{content:"\\F14D"}.fa-compass:before{content:"\\F14E"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\\F150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\\F151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\\F152"}.fa-eur:before,.fa-euro:before{content:"\\F153"}.fa-gbp:before{content:"\\F154"}.fa-dollar:before,.fa-usd:before{content:"\\F155"}.fa-inr:before,.fa-rupee:before{content:"\\F156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\\F157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\\F158"}.fa-krw:before,.fa-won:before{content:"\\F159"}.fa-bitcoin:before,.fa-btc:before{content:"\\F15A"}.fa-file:before{content:"\\F15B"}.fa-file-text:before{content:"\\F15C"}.fa-sort-alpha-asc:before{content:"\\F15D"}.fa-sort-alpha-desc:before{content:"\\F15E"}.fa-sort-amount-asc:before{content:"\\F160"}.fa-sort-amount-desc:before{content:"\\F161"}.fa-sort-numeric-asc:before{content:"\\F162"}.fa-sort-numeric-desc:before{content:"\\F163"}.fa-thumbs-up:before{content:"\\F164"}.fa-thumbs-down:before{content:"\\F165"}.fa-youtube-square:before{content:"\\F166"}.fa-youtube:before{content:"\\F167"}.fa-xing:before{content:"\\F168"}.fa-xing-square:before{content:"\\F169"}.fa-youtube-play:before{content:"\\F16A"}.fa-dropbox:before{content:"\\F16B"}.fa-stack-overflow:before{content:"\\F16C"}.fa-instagram:before{content:"\\F16D"}.fa-flickr:before{content:"\\F16E"}.fa-adn:before{content:"\\F170"}.fa-bitbucket:before{content:"\\F171"}.fa-bitbucket-square:before{content:"\\F172"}.fa-tumblr:before{content:"\\F173"}.fa-tumblr-square:before{content:"\\F174"}.fa-long-arrow-down:before{content:"\\F175"}.fa-long-arrow-up:before{content:"\\F176"}.fa-long-arrow-left:before{content:"\\F177"}.fa-long-arrow-right:before{content:"\\F178"}.fa-apple:before{content:"\\F179"}.fa-windows:before{content:"\\F17A"}.fa-android:before{content:"\\F17B"}.fa-linux:before{content:"\\F17C"}.fa-dribbble:before{content:"\\F17D"}.fa-skype:before{content:"\\F17E"}.fa-foursquare:before{content:"\\F180"}.fa-trello:before{content:"\\F181"}.fa-female:before{content:"\\F182"}.fa-male:before{content:"\\F183"}.fa-gittip:before,.fa-gratipay:before{content:"\\F184"}.fa-sun-o:before{content:"\\F185"}.fa-moon-o:before{content:"\\F186"}.fa-archive:before{content:"\\F187"}.fa-bug:before{content:"\\F188"}.fa-vk:before{content:"\\F189"}.fa-weibo:before{content:"\\F18A"}.fa-renren:before{content:"\\F18B"}.fa-pagelines:before{content:"\\F18C"}.fa-stack-exchange:before{content:"\\F18D"}.fa-arrow-circle-o-right:before{content:"\\F18E"}.fa-arrow-circle-o-left:before{content:"\\F190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\\F191"}.fa-dot-circle-o:before{content:"\\F192"}.fa-wheelchair:before{content:"\\F193"}.fa-vimeo-square:before{content:"\\F194"}.fa-try:before,.fa-turkish-lira:before{content:"\\F195"}.fa-plus-square-o:before{content:"\\F196"}.fa-space-shuttle:before{content:"\\F197"}.fa-slack:before{content:"\\F198"}.fa-envelope-square:before{content:"\\F199"}.fa-wordpress:before{content:"\\F19A"}.fa-openid:before{content:"\\F19B"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\\F19C"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\\F19D"}.fa-yahoo:before{content:"\\F19E"}.fa-google:before{content:"\\F1A0"}.fa-reddit:before{content:"\\F1A1"}.fa-reddit-square:before{content:"\\F1A2"}.fa-stumbleupon-circle:before{content:"\\F1A3"}.fa-stumbleupon:before{content:"\\F1A4"}.fa-delicious:before{content:"\\F1A5"}.fa-digg:before{content:"\\F1A6"}.fa-pied-piper-pp:before{content:"\\F1A7"}.fa-pied-piper-alt:before{content:"\\F1A8"}.fa-drupal:before{content:"\\F1A9"}.fa-joomla:before{content:"\\F1AA"}.fa-language:before{content:"\\F1AB"}.fa-fax:before{content:"\\F1AC"}.fa-building:before{content:"\\F1AD"}.fa-child:before{content:"\\F1AE"}.fa-paw:before{content:"\\F1B0"}.fa-spoon:before{content:"\\F1B1"}.fa-cube:before{content:"\\F1B2"}.fa-cubes:before{content:"\\F1B3"}.fa-behance:before{content:"\\F1B4"}.fa-behance-square:before{content:"\\F1B5"}.fa-steam:before{content:"\\F1B6"}.fa-steam-square:before{content:"\\F1B7"}.fa-recycle:before{content:"\\F1B8"}.fa-automobile:before,.fa-car:before{content:"\\F1B9"}.fa-cab:before,.fa-taxi:before{content:"\\F1BA"}.fa-tree:before{content:"\\F1BB"}.fa-spotify:before{content:"\\F1BC"}.fa-deviantart:before{content:"\\F1BD"}.fa-soundcloud:before{content:"\\F1BE"}.fa-database:before{content:"\\F1C0"}.fa-file-pdf-o:before{content:"\\F1C1"}.fa-file-word-o:before{content:"\\F1C2"}.fa-file-excel-o:before{content:"\\F1C3"}.fa-file-powerpoint-o:before{content:"\\F1C4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\\F1C5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\\F1C6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\\F1C7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\\F1C8"}.fa-file-code-o:before{content:"\\F1C9"}.fa-vine:before{content:"\\F1CA"}.fa-codepen:before{content:"\\F1CB"}.fa-jsfiddle:before{content:"\\F1CC"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\\F1CD"}.fa-circle-o-notch:before{content:"\\F1CE"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\\F1D0"}.fa-empire:before,.fa-ge:before{content:"\\F1D1"}.fa-git-square:before{content:"\\F1D2"}.fa-git:before{content:"\\F1D3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\\F1D4"}.fa-tencent-weibo:before{content:"\\F1D5"}.fa-qq:before{content:"\\F1D6"}.fa-wechat:before,.fa-weixin:before{content:"\\F1D7"}.fa-paper-plane:before,.fa-send:before{content:"\\F1D8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\\F1D9"}.fa-history:before{content:"\\F1DA"}.fa-circle-thin:before{content:"\\F1DB"}.fa-header:before{content:"\\F1DC"}.fa-paragraph:before{content:"\\F1DD"}.fa-sliders:before{content:"\\F1DE"}.fa-share-alt:before{content:"\\F1E0"}.fa-share-alt-square:before{content:"\\F1E1"}.fa-bomb:before{content:"\\F1E2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\\F1E3"}.fa-tty:before{content:"\\F1E4"}.fa-binoculars:before{content:"\\F1E5"}.fa-plug:before{content:"\\F1E6"}.fa-slideshare:before{content:"\\F1E7"}.fa-twitch:before{content:"\\F1E8"}.fa-yelp:before{content:"\\F1E9"}.fa-newspaper-o:before{content:"\\F1EA"}.fa-wifi:before{content:"\\F1EB"}.fa-calculator:before{content:"\\F1EC"}.fa-paypal:before{content:"\\F1ED"}.fa-google-wallet:before{content:"\\F1EE"}.fa-cc-visa:before{content:"\\F1F0"}.fa-cc-mastercard:before{content:"\\F1F1"}.fa-cc-discover:before{content:"\\F1F2"}.fa-cc-amex:before{content:"\\F1F3"}.fa-cc-paypal:before{content:"\\F1F4"}.fa-cc-stripe:before{content:"\\F1F5"}.fa-bell-slash:before{content:"\\F1F6"}.fa-bell-slash-o:before{content:"\\F1F7"}.fa-trash:before{content:"\\F1F8"}.fa-copyright:before{content:"\\F1F9"}.fa-at:before{content:"\\F1FA"}.fa-eyedropper:before{content:"\\F1FB"}.fa-paint-brush:before{content:"\\F1FC"}.fa-birthday-cake:before{content:"\\F1FD"}.fa-area-chart:before{content:"\\F1FE"}.fa-pie-chart:before{content:"\\F200"}.fa-line-chart:before{content:"\\F201"}.fa-lastfm:before{content:"\\F202"}.fa-lastfm-square:before{content:"\\F203"}.fa-toggle-off:before{content:"\\F204"}.fa-toggle-on:before{content:"\\F205"}.fa-bicycle:before{content:"\\F206"}.fa-bus:before{content:"\\F207"}.fa-ioxhost:before{content:"\\F208"}.fa-angellist:before{content:"\\F209"}.fa-cc:before{content:"\\F20A"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\\F20B"}.fa-meanpath:before{content:"\\F20C"}.fa-buysellads:before{content:"\\F20D"}.fa-connectdevelop:before{content:"\\F20E"}.fa-dashcube:before{content:"\\F210"}.fa-forumbee:before{content:"\\F211"}.fa-leanpub:before{content:"\\F212"}.fa-sellsy:before{content:"\\F213"}.fa-shirtsinbulk:before{content:"\\F214"}.fa-simplybuilt:before{content:"\\F215"}.fa-skyatlas:before{content:"\\F216"}.fa-cart-plus:before{content:"\\F217"}.fa-cart-arrow-down:before{content:"\\F218"}.fa-diamond:before{content:"\\F219"}.fa-ship:before{content:"\\F21A"}.fa-user-secret:before{content:"\\F21B"}.fa-motorcycle:before{content:"\\F21C"}.fa-street-view:before{content:"\\F21D"}.fa-heartbeat:before{content:"\\F21E"}.fa-venus:before{content:"\\F221"}.fa-mars:before{content:"\\F222"}.fa-mercury:before{content:"\\F223"}.fa-intersex:before,.fa-transgender:before{content:"\\F224"}.fa-transgender-alt:before{content:"\\F225"}.fa-venus-double:before{content:"\\F226"}.fa-mars-double:before{content:"\\F227"}.fa-venus-mars:before{content:"\\F228"}.fa-mars-stroke:before{content:"\\F229"}.fa-mars-stroke-v:before{content:"\\F22A"}.fa-mars-stroke-h:before{content:"\\F22B"}.fa-neuter:before{content:"\\F22C"}.fa-genderless:before{content:"\\F22D"}.fa-facebook-official:before{content:"\\F230"}.fa-pinterest-p:before{content:"\\F231"}.fa-whatsapp:before{content:"\\F232"}.fa-server:before{content:"\\F233"}.fa-user-plus:before{content:"\\F234"}.fa-user-times:before{content:"\\F235"}.fa-bed:before,.fa-hotel:before{content:"\\F236"}.fa-viacoin:before{content:"\\F237"}.fa-train:before{content:"\\F238"}.fa-subway:before{content:"\\F239"}.fa-medium:before{content:"\\F23A"}.fa-y-combinator:before,.fa-yc:before{content:"\\F23B"}.fa-optin-monster:before{content:"\\F23C"}.fa-opencart:before{content:"\\F23D"}.fa-expeditedssl:before{content:"\\F23E"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:"\\F240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\\F241"}.fa-battery-2:before,.fa-battery-half:before{content:"\\F242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\\F243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\\F244"}.fa-mouse-pointer:before{content:"\\F245"}.fa-i-cursor:before{content:"\\F246"}.fa-object-group:before{content:"\\F247"}.fa-object-ungroup:before{content:"\\F248"}.fa-sticky-note:before{content:"\\F249"}.fa-sticky-note-o:before{content:"\\F24A"}.fa-cc-jcb:before{content:"\\F24B"}.fa-cc-diners-club:before{content:"\\F24C"}.fa-clone:before{content:"\\F24D"}.fa-balance-scale:before{content:"\\F24E"}.fa-hourglass-o:before{content:"\\F250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\\F251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\\F252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\\F253"}.fa-hourglass:before{content:"\\F254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\\F255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\\F256"}.fa-hand-scissors-o:before{content:"\\F257"}.fa-hand-lizard-o:before{content:"\\F258"}.fa-hand-spock-o:before{content:"\\F259"}.fa-hand-pointer-o:before{content:"\\F25A"}.fa-hand-peace-o:before{content:"\\F25B"}.fa-trademark:before{content:"\\F25C"}.fa-registered:before{content:"\\F25D"}.fa-creative-commons:before{content:"\\F25E"}.fa-gg:before{content:"\\F260"}.fa-gg-circle:before{content:"\\F261"}.fa-tripadvisor:before{content:"\\F262"}.fa-odnoklassniki:before{content:"\\F263"}.fa-odnoklassniki-square:before{content:"\\F264"}.fa-get-pocket:before{content:"\\F265"}.fa-wikipedia-w:before{content:"\\F266"}.fa-safari:before{content:"\\F267"}.fa-chrome:before{content:"\\F268"}.fa-firefox:before{content:"\\F269"}.fa-opera:before{content:"\\F26A"}.fa-internet-explorer:before{content:"\\F26B"}.fa-television:before,.fa-tv:before{content:"\\F26C"}.fa-contao:before{content:"\\F26D"}.fa-500px:before{content:"\\F26E"}.fa-amazon:before{content:"\\F270"}.fa-calendar-plus-o:before{content:"\\F271"}.fa-calendar-minus-o:before{content:"\\F272"}.fa-calendar-times-o:before{content:"\\F273"}.fa-calendar-check-o:before{content:"\\F274"}.fa-industry:before{content:"\\F275"}.fa-map-pin:before{content:"\\F276"}.fa-map-signs:before{content:"\\F277"}.fa-map-o:before{content:"\\F278"}.fa-map:before{content:"\\F279"}.fa-commenting:before{content:"\\F27A"}.fa-commenting-o:before{content:"\\F27B"}.fa-houzz:before{content:"\\F27C"}.fa-vimeo:before{content:"\\F27D"}.fa-black-tie:before{content:"\\F27E"}.fa-fonticons:before{content:"\\F280"}.fa-reddit-alien:before{content:"\\F281"}.fa-edge:before{content:"\\F282"}.fa-credit-card-alt:before{content:"\\F283"}.fa-codiepie:before{content:"\\F284"}.fa-modx:before{content:"\\F285"}.fa-fort-awesome:before{content:"\\F286"}.fa-usb:before{content:"\\F287"}.fa-product-hunt:before{content:"\\F288"}.fa-mixcloud:before{content:"\\F289"}.fa-scribd:before{content:"\\F28A"}.fa-pause-circle:before{content:"\\F28B"}.fa-pause-circle-o:before{content:"\\F28C"}.fa-stop-circle:before{content:"\\F28D"}.fa-stop-circle-o:before{content:"\\F28E"}.fa-shopping-bag:before{content:"\\F290"}.fa-shopping-basket:before{content:"\\F291"}.fa-hashtag:before{content:"\\F292"}.fa-bluetooth:before{content:"\\F293"}.fa-bluetooth-b:before{content:"\\F294"}.fa-percent:before{content:"\\F295"}.fa-gitlab:before{content:"\\F296"}.fa-wpbeginner:before{content:"\\F297"}.fa-wpforms:before{content:"\\F298"}.fa-envira:before{content:"\\F299"}.fa-universal-access:before{content:"\\F29A"}.fa-wheelchair-alt:before{content:"\\F29B"}.fa-question-circle-o:before{content:"\\F29C"}.fa-blind:before{content:"\\F29D"}.fa-audio-description:before{content:"\\F29E"}.fa-volume-control-phone:before{content:"\\F2A0"}.fa-braille:before{content:"\\F2A1"}.fa-assistive-listening-systems:before{content:"\\F2A2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\\F2A3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\\F2A4"}.fa-glide:before{content:"\\F2A5"}.fa-glide-g:before{content:"\\F2A6"}.fa-sign-language:before,.fa-signing:before{content:"\\F2A7"}.fa-low-vision:before{content:"\\F2A8"}.fa-viadeo:before{content:"\\F2A9"}.fa-viadeo-square:before{content:"\\F2AA"}.fa-snapchat:before{content:"\\F2AB"}.fa-snapchat-ghost:before{content:"\\F2AC"}.fa-snapchat-square:before{content:"\\F2AD"}.fa-pied-piper:before{content:"\\F2AE"}.fa-first-order:before{content:"\\F2B0"}.fa-yoast:before{content:"\\F2B1"}.fa-themeisle:before{content:"\\F2B2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\\F2B3"}.fa-fa:before,.fa-font-awesome:before{content:"\\F2B4"}.fa-handshake-o:before{content:"\\F2B5"}.fa-envelope-open:before{content:"\\F2B6"}.fa-envelope-open-o:before{content:"\\F2B7"}.fa-linode:before{content:"\\F2B8"}.fa-address-book:before{content:"\\F2B9"}.fa-address-book-o:before{content:"\\F2BA"}.fa-address-card:before,.fa-vcard:before{content:"\\F2BB"}.fa-address-card-o:before,.fa-vcard-o:before{content:"\\F2BC"}.fa-user-circle:before{content:"\\F2BD"}.fa-user-circle-o:before{content:"\\F2BE"}.fa-user-o:before{content:"\\F2C0"}.fa-id-badge:before{content:"\\F2C1"}.fa-drivers-license:before,.fa-id-card:before{content:"\\F2C2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\\F2C3"}.fa-quora:before{content:"\\F2C4"}.fa-free-code-camp:before{content:"\\F2C5"}.fa-telegram:before{content:"\\F2C6"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:"\\F2C7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\\F2C8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\\F2C9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\\F2CA"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\\F2CB"}.fa-shower:before{content:"\\F2CC"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:"\\F2CD"}.fa-podcast:before{content:"\\F2CE"}.fa-window-maximize:before{content:"\\F2D0"}.fa-window-minimize:before{content:"\\F2D1"}.fa-window-restore:before{content:"\\F2D2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\\F2D3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\\F2D4"}.fa-bandcamp:before{content:"\\F2D5"}.fa-grav:before{content:"\\F2D6"}.fa-etsy:before{content:"\\F2D7"}.fa-imdb:before{content:"\\F2D8"}.fa-ravelry:before{content:"\\F2D9"}.fa-eercast:before{content:"\\F2DA"}.fa-microchip:before{content:"\\F2DB"}.fa-snowflake-o:before{content:"\\F2DC"}.fa-superpowers:before{content:"\\F2DD"}.fa-wpexplorer:before{content:"\\F2DE"}.fa-meetup:before{content:"\\F2E0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}',""]); +},function(A,M,t){M=A.exports=t(136)(),M.push([A.id,'*,:after,:before{box-sizing:border-box}body{font-family:Lato,sans-serif;font-size:15px;line-height:1.42857143;color:#8e8e8e;background-color:#edecec}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#46a5e0}a,a:focus,a:hover{text-decoration:none}a:focus,a:hover{color:#1f7fba}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#edecec;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#fff;border:1px solid transparent;border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,.08)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#8e8e8e;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{text-decoration:none;color:#333;background-color:rgba(0,0,0,.05)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#333;text-decoration:none;outline:0;background-color:rgba(0,0,0,.075)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#e4e4e4}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:13px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid\\9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu>li>a{text-align:right}.navbar-right .dropdown-menu-left{left:0;right:auto}}.modal,.modal-open{overflow:hidden}.modal{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translateY(-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid transparent;border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:rgba(0,0,0,.1)}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:30px 35px 0;border-bottom:1px solid transparent}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:transparent}.modal-body{position:relative;padding:30px 35px}.modal-footer{padding:30px 35px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:400px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Lato,sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:13px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px}.tooltip.top-left .tooltip-arrow,.tooltip.top-right .tooltip-arrow{bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{left:5px}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:active,:focus{outline:0}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body,html{min-height:100%}a{-webkit-transition:color;transition:color;-webkit-transition-duration:.3s;transition-duration:.3s}button{border:0}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px)}to{opacity:1;-webkit-transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(20px)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-20px)}}@keyframes fadeOutUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-20px)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.text-center{text-align:center!important}.text-left{text-align:left!important}.text-right{text-align:right!important}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.modal-footer:after,.modal-header:after,.row:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.p-relative{position:relative}.m-0{margin:0!important}.m-t-0{margin-top:0!important}.m-b-0{margin-bottom:0!important}.m-l-0{margin-left:0!important}.m-r-0{margin-right:0!important}.m-5{margin:5px!important}.m-t-5{margin-top:5px!important}.m-b-5{margin-bottom:5px!important}.m-l-5{margin-left:5px!important}.m-r-5{margin-right:5px!important}.m-10{margin:10px!important}.m-t-10{margin-top:10px!important}.m-b-10{margin-bottom:10px!important}.m-l-10{margin-left:10px!important}.m-r-10{margin-right:10px!important}.m-15{margin:15px!important}.m-t-15{margin-top:15px!important}.m-b-15{margin-bottom:15px!important}.m-l-15{margin-left:15px!important}.m-r-15{margin-right:15px!important}.m-20{margin:20px!important}.m-t-20{margin-top:20px!important}.m-b-20{margin-bottom:20px!important}.m-l-20{margin-left:20px!important}.m-r-20{margin-right:20px!important}.m-25{margin:25px!important}.m-t-25{margin-top:25px!important}.m-b-25{margin-bottom:25px!important}.m-l-25{margin-left:25px!important}.m-r-25{margin-right:25px!important}.m-30{margin:30px!important}.m-t-30{margin-top:30px!important}.m-b-30{margin-bottom:30px!important}.m-l-30{margin-left:30px!important}.m-r-30{margin-right:30px!important}.p-0{padding:0!important}.p-t-0{padding-top:0!important}.p-b-0{padding-bottom:0!important}.p-l-0{padding-left:0!important}.p-r-0{padding-right:0!important}.p-5{padding:5px!important}.p-t-5{padding-top:5px!important}.p-b-5{padding-bottom:5px!important}.p-l-5{padding-left:5px!important}.p-r-5{padding-right:5px!important}.p-10{padding:10px!important}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.p-l-10{padding-left:10px!important}.p-r-10{padding-right:10px!important}.p-15{padding:15px!important}.p-t-15{padding-top:15px!important}.p-b-15{padding-bottom:15px!important}.p-l-15{padding-left:15px!important}.p-r-15{padding-right:15px!important}.p-20{padding:20px!important}.p-t-20{padding-top:20px!important}.p-b-20{padding-bottom:20px!important}.p-l-20{padding-left:20px!important}.p-r-20{padding-right:20px!important}.p-25{padding:25px!important}.p-t-25{padding-top:25px!important}.p-b-25{padding-bottom:25px!important}.p-l-25{padding-left:25px!important}.p-r-25{padding-right:25px!important}.p-30{padding:30px!important}.p-t-30{padding-top:30px!important}.p-b-30{padding-bottom:30px!important}.p-l-30{padding-left:30px!important}.p-r-30{padding-right:30px!important}@font-face{font-family:Lato;src:url('+t(514)+') format("woff2"),url('+t(513)+') format("woff");font-weight:400;font-style:normal}.form-control{border:0;border-bottom:1px solid #eee;color:#32393f;padding:5px;width:100%;font-size:13px;background-color:transparent}select.form-control{-webkit-appearance:none;-moz-appearance:none;border-radius:0;background:url('+t(517)+') no-repeat bottom 7px right}.input-group{position:relative}.input-group:not(:last-child){margin-bottom:25px}.input-group label:not(.ig-label){font-size:13px;display:block;margin-bottom:10px}.ig-label{position:absolute;text-align:center;bottom:7px;left:0;width:100%;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;padding:2px 0 3px;border-radius:2px;font-weight:400}.ig-helpers{z-index:1;width:100%;left:0}.ig-helpers,.ig-helpers:after,.ig-helpers:before{position:absolute;height:2px;bottom:0}.ig-helpers:after,.ig-helpers:before{content:"";width:0;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;background-color:#03a9f4}.ig-helpers:before{left:50%}.ig-helpers:after{right:50%}.ig-text{width:100%;height:40px;border:0;background:transparent;text-align:center;position:relative;z-index:1;border-bottom:1px solid #eee;color:#32393f;font-size:13px}.ig-text:focus+.ig-helpers:after,.ig-text:focus+.ig-helpers:before{width:50%}.ig-text:disabled~.ig-label,.ig-text:focus~.ig-label,.ig-text:valid~.ig-label{bottom:35px;font-size:13px;z-index:1}.ig-text:disabled{opacity:.5;filter:alpha(opacity=50)}.ig-dark .ig-text{color:#fff;border-color:hsla(0,0%,100%,.1)}.ig-dark .ig-helpers:after,.ig-dark .ig-helpers:before{background-color:#dfdfdf;height:1px}.ig-left .ig-label,.ig-left .ig-text{text-align:left}.ig-error .ig-label{color:#e23f3f}.ig-error .ig-helpers i:first-child,.ig-error .ig-helpers i:first-child:after,.ig-error .ig-helpers i:first-child:before{background:rgba(226,63,63,.43)}.ig-error .ig-helpers i:last-child,.ig-error .ig-helpers i:last-child:after,.ig-error .ig-helpers i:last-child:before{background:#e23f3f!important}.ig-error:after{content:"\\F05A";font-family:FontAwesome;position:absolute;top:17px;right:9px;font-size:20px;color:#d33d3e}.ig-search:before{font-family:fontAwesome;content:"\\F002";font-size:15px;position:absolute;left:2px;top:8px}.ig-search .ig-text{padding-left:25px}.set-expire{border:1px solid #eee;margin:35px 0 30px}.set-expire-item{padding:9px 5px 3px;position:relative;display:table-cell;width:1%;text-align:center}.set-expire-item:not(:last-child){border-right:1px solid #eee}.set-expire-title{font-size:10px;text-transform:uppercase}.set-expire-value{display:inline-block;overflow:hidden;position:relative;left:-8px}.set-expire-value input{font-size:20px;text-align:center;position:relative;right:-15px;border:0;color:#333;padding:0;height:25px;width:100%;font-weight:400}.set-expire-decrease,.set-expire-increase{position:absolute;width:20px;height:20px;background:url('+t(515)+') no-repeat 50%;background-size:85%;left:50%;margin-left:-10px;opacity:.2;filter:alpha(opacity=20);cursor:pointer}.set-expire-decrease:hover,.set-expire-increase:hover{opacity:.5;filter:alpha(opacity=50)}.set-expire-increase{top:-25px}.set-expire-decrease{bottom:-27px;-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.btn{border:0;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:2px;text-align:center;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.btn:focus,.btn:hover{opacity:.9;filter:alpha(opacity=90)}.btn-block{display:block;width:100%}.btn-white{color:#5b5b5b;background-color:#fff}.btn-white:focus,.btn-white:hover{color:#5b5b5b;background-color:#f0f0f0}.btn-link{color:#545454;background-color:#eee}.btn-link:focus,.btn-link:hover{color:#545454;background-color:#dfdfdf}.btn-danger{color:#fff;background-color:#ff726f}.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#ff5450}.btn-primary{color:#fff;background-color:#50b2ff}.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#31a5ff}.btn-success{color:#fff;background-color:#33d46f}.btn-success:focus,.btn-success:hover{color:#fff;background-color:#28c061}.close{right:15px;font-weight:400;opacity:1;font-size:18px;position:absolute;text-align:center;top:16px;z-index:1;padding:0;border:0;background-color:transparent}.close span{width:25px;height:25px;display:block;border-radius:50%;line-height:24px;text-shadow:none}.close:not(.close-alt) span{background-color:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.close:not(.close-alt):focus span,.close:not(.close-alt):hover span{background-color:hsla(0,0%,100%,.2);color:#fff}.close-alt span{background-color:#efefef;color:#989898}.close-alt:focus span,.close-alt:hover span{background-color:#e8e8e8;color:#7b7b7b}.hidden{display:none!important}.copy-text input{width:100%;border-radius:1px;border:1px solid #eee;padding:7px 12px;font-size:13px;line-height:100%;cursor:text;-webkit-transition:border-color;transition:border-color;-webkit-transition-duration:.3s;transition-duration:.3s}.copy-text input:hover{border-color:#e1e1e1}.share-availability{margin-bottom:40px}.share-availability:after,.share-availability:before{position:absolute;bottom:-30px;font-size:10px}.share-availability:before{content:"01 Sec";left:0}.share-availability:after{content:"7 days";right:0}.modal-aheader{height:100px}.modal-aheader:before{height:0!important}.modal-aheader .modal-dialog{margin:0;vertical-align:top}.login{height:100vh;min-height:500px;background:#32393f;text-align:center}.login:before{height:calc(100% - 110px);width:1px;content:""}.l-wrap,.login:before{display:inline-block;vertical-align:middle}.l-wrap{width:80%;max-width:500px;margin-top:-50px}.l-wrap.toggled{display:inline-block}.l-wrap .input-group:not(:last-child){margin-bottom:40px}.l-footer{height:110px;padding:0 50px}.lf-logo{float:right}.lf-logo img{width:40px}.lf-server{float:left;color:hsla(0,0%,100%,.4);font-size:20px;font-weight:400;padding-top:40px}@media (max-width:768px){.lf-logo,.lf-server{float:none;display:block;text-align:center;width:100%}.lf-logo{margin-bottom:5px}.lf-server{font-size:15px}}.lw-btn{width:50px;height:50px;border:1px solid #fff;display:inline-block;border-radius:50%;font-size:22px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;opacity:.3;background-color:transparent;line-height:45px;padding:0}.lw-btn:hover{color:#fff;opacity:.8;border-color:#fff}.lw-btn i{display:block;width:100%;padding-left:3px}input:-webkit-autofill{-webkit-box-shadow:0 0 0 50px #32393f inset!important;-webkit-text-fill-color:#fff!important}@media (min-width:668px){.fe-header{position:relative;padding:40px 40px 20px 45px}}@media (max-width:667px){.fe-header{padding:20px}}.fe-header h2{font-size:16px;font-weight:400;margin:0}.fe-header h2>span{margin-bottom:7px;display:inline-block}.fe-header h2>span:not(:first-child):before{content:"/";margin:0 4px;color:#8e8e8e}.fe-header p{margin-top:7px}.feh-usage{margin-top:12px;max-width:285px}@media (max-width:667px){.feh-usage{max-width:100%;font-size:12px}}.feh-usage>ul{margin-top:7px;list-style:none;padding:0}.feh-usage>ul>li{padding-right:0;display:inline-block}.fehu-chart{height:5px;background:#eee;position:relative;border-radius:2px;overflow:hidden}.fehu-chart>div{position:absolute;left:0;height:100%;background:#46a5e0}.feh-actions{list-style:none;padding:0;margin:0;position:absolute;right:35px;top:30px;z-index:11}@media (max-width:991px){.feh-actions{top:7px;right:10px;position:fixed}}.feh-actions>li{display:inline-block;text-align:right;vertical-align:top;line-height:100%}.feh-actions>li>.btn-group>button,.feh-actions>li>a{display:block;height:45px;min-width:45px;text-align:center;border-radius:50%;padding:0;border:0;background:none}@media (min-width:992px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{color:#7b7b7b;font-size:21px;line-height:45px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feh-actions>li>.btn-group>button:hover,.feh-actions>li>a:hover{background:rgba(0,0,0,.09)}}@media (max-width:991px){.feh-actions>li>.btn-group>button,.feh-actions>li>a{background:url('+t(235)+') no-repeat 50%}.feh-actions>li>.btn-group>button .fa-reorder,.feh-actions>li>a .fa-reorder{display:none}}@media (max-width:991px){.fe-header-mobile{background-color:#32393f;padding:10px 50px 9px 12px;text-align:center;position:fixed;z-index:10;box-shadow:0 0 10px rgba(0,0,0,.3);left:0;top:0;width:100%}.fe-header-mobile .mh-logo{height:35px;position:relative;top:4px}.feh-trigger{width:41px;height:41px;cursor:pointer;float:left;position:relative;text-align:center}.feh-trigger:after,.feh-trigger:before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.feh-trigger:after{z-index:1}.feh-trigger:before{background:hsla(0,0%,100%,.1);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:scale(0);transform:scale(0)}.feht-toggled:before{-webkit-transform:scale(1);transform:scale(1)}.feht-toggled .feht-lines{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.feht-toggled .feht-lines>div.top{width:12px;transform:translateX(8px) translateY(1px) rotate(45deg);-webkit-transform:translateX(8px) translateY(1px) rotate(45deg)}.feht-toggled .feht-lines>div.bottom{width:12px;transform:translateX(8px) translateY(-1px) rotate(-45deg);-webkit-transform:translateX(8px) translateY(-1px) rotate(-45deg)}.feht-lines,.feht-lines>div{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}.feht-lines{width:18px;height:12px;display:inline-block;margin-top:14px}.feht-lines>div{background-color:#eaeaea;width:18px;height:2px}.feht-lines>div.center{margin:3px 0}}.fe-sidebar{width:320px;background-color:#32393f;position:fixed;height:100%;overflow:hidden;padding:25px}@media (min-width:992px){.fe-sidebar{-webkit-transform:translateZ(0);transform:translateZ(0)}}@media (max-width:991px){.fe-sidebar{padding-top:85px;z-index:9;box-shadow:0 0 10px rgba(0,0,0,.65);-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:translate3d(-335px,0,0);transform:translate3d(-335px,0,0)}.fe-sidebar.toggled{-webkit-transform:translateZ(0);transform:translateZ(0)}}.fe-sidebar a{color:hsla(0,0%,100%,.58)}.fe-sidebar a:hover{color:#fff}.fes-header{margin-bottom:40px}.fes-header h2,.fes-header img{float:left}.fes-header h2{margin:13px 0 0 10px;font-weight:400}.fes-header img{width:32px}.fesl-inner{height:calc(100vh - 260px);overflow:auto;padding:0;margin:0 -25px}.fesl-inner li{position:relative}.fesl-inner li>a{display:block;padding:10px 45px 12px 55px;word-wrap:break-word}.fesl-inner li>a:before{font-family:FontAwesome;content:"\\F0A0";font-size:17px;position:absolute;top:10px;left:25px;opacity:.8;filter:alpha(opacity=80)}.fesl-inner li>a.fesli-loading:before{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.1);border-bottom-color:hsla(0,0%,100%,.5);position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:32px;top:0;bottom:0;margin:auto}.fesl-inner li.active{background-color:#282e32}.fesl-inner li.active>a{color:#fff}.fesl-inner li:not(.active):hover{background-color:rgba(0,0,0,.1)}.fesl-inner li:not(.active):hover>a{color:#fff}.fesl-inner li:hover .fesli-trigger{opacity:.6;filter:alpha(opacity=60)}.fesl-inner li:hover .fesli-trigger:hover{opacity:1;filter:alpha(opacity=100)}.fesl-inner ul{list-style:none;padding:0;margin:0}.fesl-inner:hover .scrollbar-vertical{opacity:1}.fesli-trigger{filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;top:0;right:0;width:35px;cursor:pointer;background:url('+t(235)+') no-repeat top 20px left}.fesli-trigger,.scrollbar-vertical{opacity:0;position:absolute;height:100%}.scrollbar-vertical{right:5px;width:4px;-webkit-transition:opacity;transition:opacity;-webkit-transition-duration:.3s;transition-duration:.3s}.scrollbar-vertical div{border-radius:1px!important;background-color:#6a6a6a!important}.fes-host{position:fixed;left:0;bottom:0;z-index:1;background:#32393f;color:hsla(0,0%,100%,.4);font-size:15px;font-weight:400;width:320px;padding:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fes-host>i{margin-right:10px}.fesl-row{position:relative}@media (min-width:668px){.fesl-row{padding:5px 20px 5px 40px;display:flex;flex-flow:row nowrap;justify-content:space-between}}@media (max-width:667px){.fesl-row{padding:5px 20px}}.fesl-row:after,.fesl-row:before{content:" ";display:table}.fesl-row:after{clear:both}@media (min-width:668px){header.fesl-row{margin-bottom:20px;border-bottom:1px solid #f0f0f0;padding-left:30px}header.fesl-row .fesl-item,header.fesl-row .fesli-sort{-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s}header.fesl-row .fesl-item{cursor:pointer;color:#8e8e8e;font-weight:500;margin-bottom:-5px}header.fesl-row .fesl-item>.fesli-sort{float:right;margin:4px 0 0;opacity:0;filter:alpha(opacity=0);color:#32393f;font-size:14px}header.fesl-row .fesl-item:hover:not(.fesl-item-actions){background:#f5f5f5;color:#32393f}header.fesl-row .fesl-item:hover:not(.fesl-item-actions)>.fesli-sort{opacity:.5;filter:alpha(opacity=50)}}@media (max-width:667px){header.fesl-row{display:none}}div.fesl-row{border-bottom:1px solid transparent;cursor:default;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.5s;transition-duration:.5s}@media (max-width:667px){div.fesl-row{padding:5px 20px}}div.fesl-row:not(.fesl-row-selected):nth-child(2n){background-color:#fafafa}div.fesl-row:hover .fis-icon:before{opacity:0;filter:alpha(opacity=0)}div.fesl-row:hover .fis-helper:before{opacity:1;filter:alpha(opacity=100)}div.fesl-row[data-type=folder] .fis-icon{background-color:#a1d6dd}div.fesl-row[data-type=folder] .fis-icon:before{content:"\\F114"}div.fesl-row[data-type=pdf] .fis-icon{background-color:#fa7775}div.fesl-row[data-type=pdf] .fis-icon:before{content:"\\F1C1"}div.fesl-row[data-type=zip] .fis-icon{background-color:#427089}div.fesl-row[data-type=zip] .fis-icon:before{content:"\\F1C6"}div.fesl-row[data-type=audio] .fis-icon{background-color:#009688}div.fesl-row[data-type=audio] .fis-icon:before{content:"\\F1C7"}div.fesl-row[data-type=code] .fis-icon{background-color:#997867}div.fesl-row[data-type=code] .fis-icon:before{content:"\\F1C9"}div.fesl-row[data-type=excel] .fis-icon{background-color:#f1c3 3}div.fesl-row[data-type=excel] .fis-icon:before{content:"\\F1C3"}div.fesl-row[data-type=image] .fis-icon{background-color:#f06292}div.fesl-row[data-type=image] .fis-icon:before{content:"\\F1C5"}div.fesl-row[data-type=video] .fis-icon{background-color:#f8c363}div.fesl-row[data-type=video] .fis-icon:before{content:"\\F1C8"}div.fesl-row[data-type=other] .fis-icon{background-color:#afafaf}div.fesl-row[data-type=other] .fis-icon:before{content:"\\F016"}div.fesl-row[data-type=text] .fis-icon{background-color:#8a8a8a}div.fesl-row[data-type=text] .fis-icon:before{content:"\\F0F6"}div.fesl-row[data-type=doc] .fis-icon{background-color:#2196f5}div.fesl-row[data-type=doc] .fis-icon:before{content:"\\F1C2"}div.fesl-row[data-type=presentation] .fis-icon{background-color:#896ea6}div.fesl-row[data-type=presentation] .fis-icon:before{content:"\\F1C4"}div.fesl-row.fesl-loading:before{content:""}div.fesl-row.fesl-loading:after{content:"";width:20px;height:20px;border-radius:50%;-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;border:2px solid hsla(0,0%,100%,.5);border-bottom-color:#fff;position:absolute;z-index:1;-webkit-animation:zoomIn .25s,spin .7s .25s infinite linear;animation:zoomIn .25s,spin .7s .25s infinite linear;left:57px;top:17px}@media (max-width:667px){div.fesl-row.fesl-loading:after{left:27px}}.fesl-row-selected{background-color:#fbf2bf}.fesl-row-selected,.fesl-row-selected .fesl-item a{color:#757575}.fi-select{float:left;position:relative;width:35px;height:35px;margin:3px 0}@media (max-width:667px){.fi-select{margin-right:15px}}.fi-select input{position:absolute;left:0;top:0;width:35px;height:35px;z-index:20;opacity:0;cursor:pointer}.fi-select input:checked~.fis-icon{background-color:#32393f}.fi-select input:checked~.fis-icon:before{opacity:0}.fi-select input:checked~.fis-helper:before{-webkit-transform:scale(0);transform:scale(0)}.fi-select input:checked~.fis-helper:after{-webkit-transform:scale(1);transform:scale(1)}.fis-icon{display:inline-block;vertical-align:top;border-radius:50%;width:35px;height:35px;-webkit-transition:background-color;transition:background-color;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-icon:before{width:100%;height:100%;text-align:center;position:absolute;border-radius:50%;font-family:fontAwesome;line-height:35px;font-size:16px;color:#fff;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;font-style:normal}.fis-helper:after,.fis-helper:before{position:absolute;-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s}.fis-helper:before{content:"";width:15px;height:15px;border:2px solid #fff;z-index:10;border-radius:2px;top:10px;left:10px;opacity:0}.fis-helper:after{font-family:fontAwesome;content:"\\F00C";top:8px;left:9px;color:#fff;font-size:14px;-webkit-transform:scale(0);transform:scale(0)}.fesl-item{display:block}.fesl-item a{color:#818181}@media (min-width:668px){.fesl-item:not(.fesl-item-actions):not(.fesl-item-icon){text-overflow:ellipsis;padding:10px 15px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-name{flex:3}.fesl-item.fesl-item-size{width:140px}.fesl-item.fesl-item-modified{width:190px}.fesl-item.fesl-item-actions{width:40px}}@media (max-width:667px){.fesl-item{padding:0}.fesl-item.fesl-item-name{width:100%;margin-bottom:3px}.fesl-item.fesl-item-modified,.fesl-item.fesl-item-size{font-size:12px;color:#b5b5b5;float:left}.fesl-item.fesl-item-modified{max-width:72px;white-space:nowrap;overflow:hidden}.fesl-item.fesl-item-size{margin-right:10px}.fesl-item.fesl-item-actions{position:absolute;top:5px;right:10px}}.fia-toggle{height:36px;width:36px;background:transparent url('+t(516)+') no-repeat 50%;position:relative;top:3px;opacity:.4;filter:alpha(opacity=40)}.fia-toggle:hover{opacity:.7;filter:alpha(opacity=70)}.fesl-item-actions .dropdown-menu{background-color:transparent;box-shadow:none;padding:0;right:38px;left:auto;margin:0;height:100%;text-align:right}.fesl-item-actions .dropdown.open .dropdown-menu .fiad-action{right:0}.fiad-action{height:35px;width:35px;background:#ffc107;display:inline-block;border-radius:50%;text-align:center;line-height:35px;font-weight:400;position:relative;top:4px;margin-left:5px;-webkit-animation-name:fiad-action-anim;animation-name:fiad-action-anim;-webkit-transform-origin:center center;transform-origin:center center;-webkit-backface-visibility:none;backface-visibility:none;box-shadow:0 2px 4px rgba(0,0,0,.1)}.fiad-action:nth-child(2){-webkit-animation-duration:.1s;animation-duration:.1s}.fiad-action:first-child{-webkit-animation-duration:.25s;animation-duration:.25s}.fiad-action>i{font-size:14px;color:#fff}.fiad-action:hover{background-color:#f7b900}.list-actions{position:fixed;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);opacity:0;filter:alpha(opacity=0);-webkit-transition:all;transition:all;-webkit-transition-duration:.2s;transition-duration:.2s;padding:20px 70px 20px 25px;top:0;left:0;width:100%;background-color:#2298f7;z-index:20;box-shadow:0 0 10px rgba(0,0,0,.3);text-align:center}.list-actions.list-actions-toggled{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1;filter:alpha(opacity=100)}.la-close{position:absolute;right:20px;top:0;color:#fff;width:30px;height:30px;border-radius:50%;text-align:center;line-height:30px!important;background:hsla(0,0%,100%,.1);font-weight:400;bottom:0;margin:auto;cursor:pointer}.la-close:hover{background-color:hsla(0,0%,100%,.2)}.la-label{color:#fff;float:left;padding:4px 0}.la-label .fa{font-size:22px;vertical-align:top;margin-right:10px;margin-top:-1px}.la-actions button{background-color:transparent;border:2px solid hsla(0,0%,100%,.9);color:#fff;border-radius:2px;padding:5px 10px;font-size:13px;-webkit-transition:all;transition:all;-webkit-transition-duration:.3s;transition-duration:.3s;margin-left:10px}.la-actions button:hover{background-color:#fff;color:#2298f7}@-webkit-keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}@keyframes fiad-action-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0);right:-20px}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100);right:0}}.file-explorer{background-color:#fff;position:relative;height:100%}.file-explorer.toggled{height:100vh;overflow:hidden}.fe-body{min-height:100vh;overflow:auto}@media (min-width:992px){.fe-body{padding:0 0 40px 320px}}@media (max-width:991px){.fe-body{padding:75px 0 80px}}.feb-actions{position:fixed;bottom:30px;right:30px}.feb-actions .dropdown-menu{min-width:55px;width:55px;text-align:center;background:transparent;box-shadow:none;margin:0}.feb-actions.open .feba-btn{-webkit-transform:scale(1);transform:scale(1)}.feb-actions.open .feba-btn:first-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.3s;animation-duration:.3s}.feb-actions.open .feba-btn:last-child{-webkit-animation-name:feba-btn-anim;animation-name:feba-btn-anim;-webkit-animation-duration:.1s;animation-duration:.1s}.feb-actions.open .feba-toggle{background:#ff403c}.feb-actions.open .feba-toggle>span{-webkit-transform:rotate(135deg);transform:rotate(135deg)}.feba-toggle{width:55px;height:55px;line-height:55px;border-radius:50%;background:#ff726f;box-shadow:0 2px 3px rgba(0,0,0,.15);display:inline-block;text-align:center;border:0;padding:0}.feba-toggle span{display:inline-block;height:100%;width:100%}.feba-toggle i{color:#fff;font-size:17px;line-height:58px}.feba-toggle,.feba-toggle>span{-webkit-transition:all;transition:all;-webkit-transition-duration:.25s;transition-duration:.25s;-webkit-backface-visibility:hidden;backface-visibility:hidden}.feba-btn{width:40px;margin-top:10px;height:40px;border-radius:50%;text-align:center;display:inline-block;line-height:40px;box-shadow:0 2px 3px rgba(0,0,0,.15);-webkit-transform:scale(0);transform:scale(0);position:relative}.feba-btn,.feba-btn:focus,.feba-btn:hover{color:#fff}.feba-btn label{width:100%;height:100%;position:absolute;left:0;top:0;cursor:pointer}.feba-bucket{background:#ffc155}.feba-upload{background:#ffc107}@-webkit-keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}@keyframes feba-btn-anim{0%{-webkit-transform:scale(0);transform:scale(0);opacity:0;filter:alpha(opacity=0)}to{-webkit-transform:scale(1);transform:scale(1);opacity:1;filter:alpha(opacity=100)}}.ie-warning{background-color:#ff5252;width:100%;height:100%;position:fixed;left:0;top:0;text-align:center}.ie-warning:before{width:1px;content:"";height:100%}.ie-warning .iw-inner,.ie-warning:before{display:inline-block;vertical-align:middle}.iw-inner{width:470px;height:300px;background-color:#fff;border-radius:5px;padding:40px;position:relative}.iw-inner ul{list-style:none;padding:0;margin:0;width:230px;margin-left:80px;margin-top:16px}.iw-inner ul>li{float:left}.iw-inner ul>li>a{display:block;padding:10px 15px 7px;font-size:14px;margin:0 1px;border-radius:3px}.iw-inner ul>li>a:hover{background:#eee}.iw-inner ul>li>a img{height:40px;margin-bottom:5px}.iwi-icon{color:#ff5252;font-size:40px;display:block;line-height:100%;margin-bottom:15px}.iwi-skip{position:absolute;left:0;bottom:-35px;width:100%;color:hsla(0,0%,100%,.6);cursor:pointer}.iwi-skip:hover{color:#fff}.dropdown-menu{padding:15px 0;top:0;margin-top:-1px}.dropdown-menu>li>a{padding:8px 20px;font-size:15px}.dropdown-menu>li>a>i{width:20px;position:relative;top:1px}.dropdown-menu-right>li>a{text-align:right}.alert{border:0;position:fixed;max-width:500px;margin:0;box-shadow:0 4px 5px rgba(0,0,0,.1);color:#fff;width:100%;right:20px;border-radius:3px;padding:17px 50px 17px 17px;z-index:10010;-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.alert:not(.progress){top:20px}@media (min-width:768px){.alert:not(.progress){left:50%;margin-left:-250px}}.alert.progress{bottom:20px;right:20px}.alert.alert-danger{background:#ff726f}.alert.alert-success{background:#33d46f}.alert.alert-info{background:#50b2ff}@media (max-width:767px){.alert{left:20px;width:calc(100% - 40px);max-width:100%}}.alert .progress{margin:10px 10px 8px 0;height:5px;box-shadow:none;border-radius:1px;background-color:#50b2ff;border-radius:2px;overflow:hidden}.alert .progress-bar{box-shadow:none;background-color:#fff;height:100%}.alert .close{position:absolute;top:15px}@media (min-width:768px){.modal{text-align:center}.modal:before{content:"";height:100%;width:1px}.modal .modal-dialog,.modal:before{display:inline-block;vertical-align:middle}.modal .modal-dialog{text-align:left;margin:10px auto}}.modal-dark .modal-header{color:hsla(0,0%,100%,.4)}.modal-dark .modal-header small{color:hsla(0,0%,100%,.2)}.modal-dark .modal-content{background-color:#32393f}.modal-backdrop{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-backdrop,.modal-dialog{-webkit-animation-duration:.2s;animation-duration:.2s}.modal-dialog{-webkit-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-fill-mode:both;animation-fill-mode:both}.modal-header{color:#333;position:relative}.modal-header small{display:block;text-transform:none;font-size:12px;margin-top:5px;color:#a8a8a8}.modal-content{border-radius:3px;box-shadow:none}.modal-footer{padding:0 30px 30px}.modal-confirm .modal-dialog,.modal-footer{text-align:center}.mc-icon{margin:0 0 10px}.mc-icon>i{font-size:60px}.mci-red{color:#ff8f8f}.mci-amber{color:#ffc107}.mci-green{color:#64e096}.mc-text{color:#333}.mc-sub{color:#bdbdbd;margin-top:5px;font-size:13px}@media (max-width:767px){.modal-about{text-align:center}.modal-about .modal-dialog{max-width:400px;width:90%;margin:20px auto 0}}.ma-inner{display:flex;flex-direction:row;align-items:center;min-height:350px;position:relative}@media (min-width:768px){.ma-inner:before{content:"";width:150px;height:100%;top:0;left:0;position:absolute;border-radius:3px 0 0 3px;background-color:#23282c}}.mai-item:first-child{width:150px;text-align:center}.mai-item:last-child{flex:4;padding:30px}.maii-logo{width:70px;position:relative}.maii-list{list-style:none;padding:0}.maii-list>li{margin-bottom:15px}.maii-list>li div{color:hsla(0,0%,100%,.8);text-transform:uppercase;font-size:14px}.maii-list>li small{font-size:13px;color:hsla(0,0%,100%,.4)}.toggle-password{position:absolute;bottom:30px;right:35px;width:30px;height:30px;border:1px solid #eee;border-radius:0;text-align:center;cursor:pointer;z-index:10;background-color:#fff;padding-top:5px}.toggle-password.toggled{background:#eee}.pm-body{padding-bottom:30px}.pmb-header{margin-bottom:35px}.pmb-list{display:flex;flex-flow:row nowrap;align-items:center;justify-content:center;padding:10px 35px}.pmb-list:nth-child(2n){background-color:#f7f7f7}.pmb-list .form-control{padding-left:0;padding-right:0}header.pmb-list{margin:20px 0 10px}.pmbl-item{display:block;font-size:13px}.pmbl-item:first-child{flex:2}.pmbl-item:nth-child(2){margin:0 25px;width:150px}.pmbl-item:nth-child(3){width:70px}div.pmb-list select{border:0}div.pmb-list .pml-item:not(:last-child){padding:0 5px}.modal-create-bucket .modal-dialog{position:fixed;right:25px;bottom:95px;margin:0;height:110px}.modal-create-bucket .modal-content{width:100%;height:100%}',""]); +},function(A,M,t){function I(A){return null===A||void 0===A}function g(A){return!(!A||"object"!=typeof A||"number"!=typeof A.length)&&("function"==typeof A.copy&&"function"==typeof A.slice&&!(A.length>0&&"number"!=typeof A[0]))}function e(A,M,t){var e,o;if(I(A)||I(M))return!1;if(A.prototype!==M.prototype)return!1;if(E(A))return!!E(M)&&(A=i.call(A),M=i.call(M),N(A,M,t));if(g(A)){if(!g(M))return!1;if(A.length!==M.length)return!1;for(e=0;e=0;e--)if(n[e]!=C[e])return!1;for(e=n.length-1;e>=0;e--)if(o=n[e],!N(A[o],M[o],t))return!1;return typeof A==typeof M}var i=Array.prototype.slice,T=t(279),E=t(278),N=A.exports=function(A,M,t){return t||(t={}),A===M||(A instanceof Date&&M instanceof Date?A.getTime()===M.getTime():!A||!M||"object"!=typeof A&&"object"!=typeof M?t.strict?A===M:A==M:e(A,M,t))}},function(A,M){function t(A){return"[object Arguments]"==Object.prototype.toString.call(A)}function I(A){return A&&"object"==typeof A&&"number"==typeof A.length&&Object.prototype.hasOwnProperty.call(A,"callee")&&!Object.prototype.propertyIsEnumerable.call(A,"callee")||!1}var g="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();M=A.exports=g?t:I,M.supported=t,M.unsupported=I},function(A,M){function t(A){var M=[];for(var t in A)M.push(t);return M}M=A.exports="function"==typeof Object.keys?Object.keys:t,M.shim=t},function(A,M,t){"use strict";var I=t(139);A.exports=function(A,M){A.classList?A.classList.add(M):I(A)||(A.className=A.className+" "+M)}},function(A,M,t){"use strict";A.exports={addClass:t(280),removeClass:t(282),hasClass:t(139)}},function(A,M){"use strict";A.exports=function(A,M){A.classList?A.classList.remove(M):A.className=A.className.replace(new RegExp("(^|\\s)"+M+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,"")}},function(A,M,t){"use strict";var I=t(40),g=t(287);A.exports=function(A,M){return function(t){var e=t.currentTarget,i=t.target,T=g(e,A);T.some(function(A){return I(A,i)})&&M.call(this,t)}}},function(A,M,t){"use strict";var I=t(81),g=t(140),e=t(283);A.exports={on:I,off:g,filter:e}},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A){for(var M=(0,T.default)(A),t=A&&A.offsetParent;t&&"html"!==I(A)&&"static"===(0,N.default)(t,"position");)t=t.offsetParent;return t||M.documentElement}var e=t(58);M.__esModule=!0,M.default=g;var i=t(39),T=e.interopRequireDefault(i),E=t(82),N=e.interopRequireDefault(E);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A.nodeName&&A.nodeName.toLowerCase()}function g(A,M){var t,g={top:0,left:0};return"fixed"===(0,a.default)(A,"position")?t=A.getBoundingClientRect():(M=M||(0,N.default)(A),t=(0,T.default)(A),"html"!==I(M)&&(g=(0,T.default)(M)),g.top+=parseInt((0,a.default)(M,"borderTopWidth"),10)-(0,n.default)(M)||0,g.left+=parseInt((0,a.default)(M,"borderLeftWidth"),10)-(0,c.default)(M)||0),e._extends({},t,{top:t.top-g.top-(parseInt((0,a.default)(A,"marginTop"),10)||0),left:t.left-g.left-(parseInt((0,a.default)(A,"marginLeft"),10)||0)})}var e=t(58);M.__esModule=!0,M.default=g;var i=t(141),T=e.interopRequireDefault(i),E=t(285),N=e.interopRequireDefault(E),o=t(142),n=e.interopRequireDefault(o),C=t(288),c=e.interopRequireDefault(C),D=t(82),a=e.interopRequireDefault(D);A.exports=M.default},function(A,M){"use strict";var t=/^[\w-]*$/,I=Function.prototype.bind.call(Function.prototype.call,[].slice);A.exports=function(A,M){var g,e="#"===M[0],i="."===M[0],T=e||i?M.slice(1):M,E=t.test(T);return E?e?(A=A.getElementById?A:document,(g=A.getElementById(T))?[g]:[]):I(A.getElementsByClassName&&i?A.getElementsByClassName(T):A.getElementsByTagName(M)):I(A.querySelectorAll(M))}},function(A,M,t){"use strict";var I=t(57);A.exports=function(A,M){var t=I(A);return void 0===M?t?"pageXOffset"in t?t.pageXOffset:t.document.documentElement.scrollLeft:A.scrollLeft:void(t?t.scrollTo(M,"pageYOffset"in t?t.pageYOffset:t.document.documentElement.scrollTop):A.scrollLeft=M)}},function(A,M,t){"use strict";var I=t(58),g=t(143),e=I.interopRequireDefault(g),i=/^(top|right|bottom|left)$/,T=/^([+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/i;A.exports=function(A){if(!A)throw new TypeError("No Element passed to ` + "`" + `getComputedStyle()` + "`" + `");var M=A.ownerDocument;return"defaultView"in M?M.defaultView.opener?A.ownerDocument.defaultView.getComputedStyle(A,null):window.getComputedStyle(A,null):{getPropertyValue:function(M){var t=A.style;M=(0,e.default)(M),"float"==M&&(M="styleFloat");var I=A.currentStyle[M]||null;if(null==I&&t&&t[M]&&(I=t[M]),T.test(I)&&!i.test(M)){var g=t.left,E=A.runtimeStyle,N=E&&E.left;N&&(E.left=A.currentStyle.left),t.left="fontSize"===M?"1em":I,I=t.pixelLeft+"px",t.left=g,N&&(E.left=N)}return I}}}},function(A,M){"use strict";A.exports=function(A,M){return"removeProperty"in A.style?A.style.removeProperty(M):A.style.removeAttribute(M)}},function(A,M,t){"use strict";function I(){var A,M="",t={O:"otransitionend",Moz:"transitionend",Webkit:"webkitTransitionEnd",ms:"MSTransitionEnd"},I=document.createElement("div");for(var g in t)if(N.call(t,g)&&void 0!==I.style[g+"TransitionProperty"]){M="-"+g.toLowerCase()+"-",A=t[g];break}return A||void 0===I.style.transitionProperty||(A="transitionend"),{end:A,prefix:M}}var g,e,i,T,E=t(32),N=Object.prototype.hasOwnProperty,o="transform",n={};E&&(n=I(),o=n.prefix+o,i=n.prefix+"transition-property",e=n.prefix+"transition-duration",T=n.prefix+"transition-delay",g=n.prefix+"transition-timing-function"),A.exports={transform:o,end:n.end,property:i,timing:g,delay:T,duration:e}},function(A,M){"use strict";var t=/-(.)/g;A.exports=function(A){return A.replace(t,function(A,M){return M.toUpperCase()})}},function(A,M){"use strict";var t=/([A-Z])/g;A.exports=function(A){return A.replace(t,"-$1").toLowerCase()}},function(A,M,t){"use strict";var I=t(293),g=/^ms-/;A.exports=function(A){return I(A).replace(g,"-ms-")}},function(A,M){"use strict";function t(A){return A.replace(I,function(A,M){return M.toUpperCase()})}var I=/-(.)/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A.replace(e,"ms-"))}var g=t(295),e=/^-ms-/;A.exports=I},function(A,M,t){"use strict";function I(A){return!!A&&("object"==typeof A||"function"==typeof A)&&"length"in A&&!("setInterval"in A)&&"number"!=typeof A.nodeType&&(Array.isArray(A)||"callee"in A||"item"in A)}function g(A){return I(A)?Array.isArray(A)?A.slice():e(A):[A]}var e=t(306);A.exports=g},function(A,M,t){"use strict";function I(A){var M=A.match(o);return M&&M[1].toLowerCase()}function g(A,M){var t=N;N?void 0:E(!1);var g=I(A),e=g&&T(g);if(e){t.innerHTML=e[1]+A+e[2];for(var o=e[0];o--;)t=t.lastChild}else t.innerHTML=A;var n=t.getElementsByTagName("script");n.length&&(M?void 0:E(!1),i(n).forEach(M));for(var C=i(t.childNodes);t.lastChild;)t.removeChild(t.lastChild);return C}var e=t(10),i=t(297),T=t(149),E=t(2),N=e.canUseDOM?document.createElement("div"):null,o=/^\s*<(\w+)/;A.exports=g},function(A,M){"use strict";function t(A){return A===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:A.scrollLeft,y:A.scrollTop}}A.exports=t},function(A,M){"use strict";function t(A){return A.replace(I,"-$1").toLowerCase()}var I=/([A-Z])/g;A.exports=t},function(A,M,t){"use strict";function I(A){return g(A).replace(e,"-ms-")}var g=t(300),e=/^ms-/;A.exports=I},function(A,M){"use strict";function t(A){return!(!A||!("function"==typeof Node?A instanceof Node:"object"==typeof A&&"number"==typeof A.nodeType&&"string"==typeof A.nodeName))}A.exports=t},function(A,M,t){"use strict";function I(A){return g(A)&&3==A.nodeType}var g=t(302);A.exports=I},function(A,M){"use strict";function t(A,M,t){if(!A)return null;var g={};for(var e in A)I.call(A,e)&&(g[e]=M.call(t,A[e],e,A));return g}var I=Object.prototype.hasOwnProperty;A.exports=t},function(A,M){"use strict";function t(A){var M={};return function(t){return M.hasOwnProperty(t)||(M[t]=A.call(this,t)),M[t]}}A.exports=t},function(A,M,t){"use strict";function I(A){var M=A.length;if(Array.isArray(A)||"object"!=typeof A&&"function"!=typeof A?g(!1):void 0,"number"!=typeof M?g(!1):void 0,0===M||M-1 in A?void 0:g(!1),A.hasOwnProperty)try{return Array.prototype.slice.call(A)}catch(A){}for(var t=Array(M),I=0;I=T?i(M):null,C=M.length;n&&(N=e,o=!1,M=n);A:for(;++Eg?0:g+M),t=void 0===t||t>g?g:+t||0,t<0&&(t+=g),g=M>t?0:t-M>>>0,M>>>=0;for(var e=Array(g);++I-1?t[N]:void 0}return e(t,I,A)}}var g=t(319),e=t(322),i=t(323),T=t(28);A.exports=I},function(A,M,t){function I(A,M,t,I,e,i,T){var E=-1,N=A.length,o=M.length;if(N!=o&&!(e&&o>N))return!1;for(;++E=T?i(M):null,C=M.length;n&&(N=e,o=!1,M=n);A:for(;++Eg?0:g+M),t=void 0===t||t>g?g:+t||0,t<0&&(t+=g),g=M>t?0:t-M>>>0,M>>>=0;for(var e=Array(g);++I-1?t[N]:void 0}return e(t,I,A)}}var g=t(318),e=t(321),i=t(322),T=t(28);A.exports=I},function(A,M,t){function I(A,M,t,I,e,i,T){var E=-1,N=A.length,o=M.length;if(N!=o&&!(e&&o>N))return!1;for(;++Eo||N===o&&"application/"===M[T].substr(0,12))continue}M[T]=I}}})}var E=t(351),N=t(354).extname,o=/^\s*([^;\s]*)(?:;|\s|$)/,n=/^text\//i;M.charset=I,M.charsets={lookup:I},M.contentType=g,M.extension=e,M.extensions=Object.create(null),M.lookup=i,M.types=Object.create(null),T(M.extensions,M.types)},function(A,M){function t(A){throw new Error("Cannot find module '"+A+"'.")}t.keys=function(){return[]},t.resolve=t,A.exports=t,t.id=353},function(A,M,t){(function(A){function t(A,M){for(var t=0,I=A.length-1;I>=0;I--){var g=A[I];"."===g?A.splice(I,1):".."===g?(A.splice(I,1),t++):t&&(A.splice(I,1),t--)}if(M)for(;t--;t)A.unshift("..");return A}function I(A,M){if(A.filter)return A.filter(M);for(var t=[],I=0;I=-1&&!g;e--){var i=e>=0?arguments[e]:A.cwd();if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(M=i+"/"+M,g="/"===i.charAt(0))}return M=t(I(M.split("/"),function(A){return!!A}),!g).join("/"),(g?"/":"")+M||"."},M.normalize=function(A){var g=M.isAbsolute(A),e="/"===i(A,-1);return A=t(I(A.split("/"),function(A){return!!A}),!g).join("/"),A||g||(A="."),A&&e&&(A+="/"),(g?"/":"")+A},M.isAbsolute=function(A){return"/"===A.charAt(0)},M.join=function(){var A=Array.prototype.slice.call(arguments,0);return M.normalize(I(A,function(A,M){if("string"!=typeof A)throw new TypeError("Arguments to path.join must be strings");return A}).join("/"))},M.relative=function(A,t){function I(A){for(var M=0;M=0&&""===A[t];t--);return M>t?[]:A.slice(M,t-M+1)}A=M.resolve(A).substr(1),t=M.resolve(t).substr(1);for(var g=I(A.split("/")),e=I(t.split("/")),i=Math.min(g.length,e.length),T=i,E=0;E=0;e--){var i=I[e]+g;if(i in M)return i}return!1}},function(A,M,t){"use strict";var I=t(497);M.extract=function(A){return A.split("?")[1]||""},M.parse=function(A){return"string"!=typeof A?{}:(A=A.trim().replace(/^(\?|#|&)/,""),A?A.split("&").reduce(function(A,M){var t=M.replace(/\+/g," ").split("="),I=t.shift(),g=t.length>0?t.join("="):void 0;return I=decodeURIComponent(I),g=void 0===g?null:decodeURIComponent(g),A.hasOwnProperty(I)?Array.isArray(A[I])?A[I].push(g):A[I]=[A[I],g]:A[I]=g,A},{}):{})},M.stringify=function(A){return A?Object.keys(A).sort().map(function(M){var t=A[M];return void 0===t?"":null===t?M:Array.isArray(t)?t.slice().sort().map(function(A){return I(M)+"="+I(A)}).join("&"):I(M)+"="+I(t)}).filter(function(A){return A.length>0}).join("&"):""}},function(A,M){"use strict";function t(A,M){return Object.prototype.hasOwnProperty.call(A,M)}A.exports=function(A,M,I,g){M=M||"&",I=I||"=";var e={};if("string"!=typeof A||0===A.length)return e;var i=/\+/g;A=A.split(M);var T=1e3;g&&"number"==typeof g.maxKeys&&(T=g.maxKeys);var E=A.length;T>0&&E>T&&(E=T);for(var N=0;N=0?(o=D.substr(0,a),n=D.substr(a+1)):(o=D,n=""),C=decodeURIComponent(o),c=decodeURIComponent(n),t(e,C)?Array.isArray(e[C])?e[C].push(c):e[C]=[e[C],c]:e[C]=c}return e}},function(A,M){"use strict";var t=function(A){switch(typeof A){case"string":return A;case"boolean":return A?"true":"false";case"number":return isFinite(A)?A:"";default:return""}};A.exports=function(A,M,I,g){return M=M||"&",I=I||"=",null===A&&(A=void 0),"object"==typeof A?Object.keys(A).map(function(g){var e=encodeURIComponent(t(g))+I;return Array.isArray(A[g])?A[g].map(function(A){return e+encodeURIComponent(t(A))}).join(M):e+encodeURIComponent(t(A[g]))}).join(M):g?encodeURIComponent(t(g))+I+encodeURIComponent(t(A)):""}},function(A,M,t){"use strict";M.decode=M.parse=t(358),M.encode=M.stringify=t(359)},function(A,M,t){(function(M){for(var I=t(355),g="undefined"==typeof window?M:window,e=["moz","webkit"],i="AnimationFrame",T=g["request"+i],E=g["cancel"+i]||g["cancelRequest"+i],N=0;!T&&N1)||(e=A,!1)}),e)return new Error("(children) "+I+" - Duplicate children detected of bsRole: "+e+". Only one child each allowed with the following bsRoles: "+M.join(", "))})}},A.exports=M.default},function(A,M,t){"use strict";function I(A){var M=[];return void 0===A?M:(i.default.forEach(A,function(A){M.push(A)}),M)}var g=t(6).default;M.__esModule=!0,M.default=I;var e=t(51),i=g(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}Object.defineProperty(M,"__esModule",{value:!0}),M.CopyToClipboard=void 0;var e=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){var M=A.style,t=g(A,["style"]),I=o({},M,{height:6,right:2,bottom:2,left:2,borderRadius:3});return C.default.createElement("div",o({style:I},t))}function i(A){var M=A.style,t=g(A,["style"]),I=o({},M,{width:6,right:2,bottom:2,top:2,borderRadius:3});return C.default.createElement("div",o({style:I},t))}function T(A){var M=A.style,t=g(A,["style"]),I=o({},M,{cursor:"pointer",borderRadius:"inherit",backgroundColor:"rgba(0,0,0,.2)"});return C.default.createElement("div",o({style:I},t))}function E(A){var M=A.style,t=g(A,["style"]),I=o({},M,{cursor:"pointer",borderRadius:"inherit",backgroundColor:"rgba(0,0,0,.2)"});return C.default.createElement("div",o({style:I},t))}function N(A){return C.default.createElement("div",A)}var o=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}var e=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M0||(this.setState({isDragActive:!1,isDragReject:!1}),this.props.onDragLeave&&this.props.onDragLeave.call(this,A))}},{key:"onDrop",value:function A(M){var t=this,I=this.props,A=I.onDrop,g=I.onDropAccepted,e=I.onDropRejected,i=I.multiple,T=I.disablePreview,E=(0,a.default)(M,i),N=[],o=[];M.preventDefault(),this.enterCounter=0,this.isFileDialogActive=!1,E.forEach(function(A){T||(A.preview=window.URL.createObjectURL(A)),t.fileAccepted(A)&&t.fileMatchSize(A)?N.push(A):o.push(A)}),A&&A.call(this,N,o,M),o.length>0&&e&&e.call(this,o,M),N.length>0&&g&&g.call(this,N,M),this.setState({isDragActive:!1,isDragReject:!1})}},{key:"onClick",value:function A(M){M.stopPropagation();var t=this.props,A=t.onClick,I=t.disableClick;I||(this.open(),A&&A.call(this,M))}},{key:"onFileDialogCancel",value:function A(){var A=this.props.onFileDialogCancel,M=this.fileInputEl,t=this.isFileDialogActive;A&&t&&setTimeout(function(){var I=M.files;I.length||(t=!1,A())},300)}},{key:"fileAccepted",value:function(A){return(0,c.default)(A,this.props.accept)}},{key:"fileMatchSize",value:function(A){return A.size<=this.props.maxSize&&A.size>=this.props.minSize}},{key:"allFilesAccepted",value:function(A){return A.every(this.fileAccepted)}},{key:"open",value:function(){this.isFileDialogActive=!0,this.fileInputEl.value=null,this.fileInputEl.click()}},{key:"render",value:function(){var A=this,M=this.props,t=M.accept,I=M.activeClassName,e=M.inputProps,i=M.multiple,T=M.name,N=M.rejectClassName,o=g(M,["accept","activeClassName","inputProps","multiple","name","rejectClassName"]),C=o.activeStyle,c=o.className,D=o.rejectStyle,a=o.style,Q=g(o,["activeStyle","className","rejectStyle","style"]),r=this.state,s=r.isDragActive,x=r.isDragReject;c=c||"",s&&I&&(c+=" "+I),x&&N&&(c+=" "+N),c||a||C||D||(a={width:200,height:200,borderWidth:2,borderColor:"#666",borderStyle:"dashed",borderRadius:5},C={borderStyle:"solid",backgroundColor:"#eee"},D={borderStyle:"solid",backgroundColor:"#ffdddd"});var j=void 0;j=C&&s?E({},a,C):D&&x?E({},a,D):E({},a);var y={accept:t,type:"file",style:{display:"none"},multiple:B&&i,ref:function(M){return A.fileInputEl=M},onChange:this.onDrop};T&&T.length&&(y.name=T);var u=["acceptedFiles","disablePreview","disableClick","onDropAccepted","onDropRejected","onFileDialogCancel","maxSize","minSize"],w=E({},Q);return u.forEach(function(A){return delete w[A]}),n.default.createElement("div",E({className:c,style:j},w,{onClick:this.onClick,onDragStart:this.onDragStart,onDragEnter:this.onDragEnter,onDragOver:this.onDragOver,onDragLeave:this.onDragLeave,onDrop:this.onDrop}),this.props.children,n.default.createElement("input",E({},e,y)))}}]),M}(n.default.Component);Q.defaultProps={disablePreview:!1,disableClick:!1,multiple:!0,maxSize:1/0,minSize:0},Q.propTypes={onClick:n.default.PropTypes.func,onDrop:n.default.PropTypes.func,onDropAccepted:n.default.PropTypes.func,onDropRejected:n.default.PropTypes.func,onDragStart:n.default.PropTypes.func,onDragEnter:n.default.PropTypes.func,onDragOver:n.default.PropTypes.func,onDragLeave:n.default.PropTypes.func,children:n.default.PropTypes.node,style:n.default.PropTypes.object,activeStyle:n.default.PropTypes.object,rejectStyle:n.default.PropTypes.object,className:n.default.PropTypes.string,activeClassName:n.default.PropTypes.string,rejectClassName:n.default.PropTypes.string,disablePreview:n.default.PropTypes.bool,disableClick:n.default.PropTypes.bool,onFileDialogCancel:n.default.PropTypes.func,inputProps:n.default.PropTypes.object,multiple:n.default.PropTypes.bool,accept:n.default.PropTypes.string,name:n.default.PropTypes.string,maxSize:n.default.PropTypes.number,minSize:n.default.PropTypes.number},M.default=Q,A.exports=M.default},function(M,t){M.exports=A},function(A,M){A.exports=function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){"use strict";M.__esModule=!0,t(8),t(9),M.default=function(A,M){if(A&&M){var t=function(){var t=Array.isArray(M)?M:M.split(","),I=A.name||"",g=A.type||"",e=g.replace(/\/.*$/,"");return{v:t.some(function(A){var M=A.trim();return"."===M.charAt(0)?I.toLowerCase().endsWith(M.toLowerCase()):/\/\*$/.test(M)?e===M.replace(/\/.*$/,""):g===M})}}();if("object"==typeof t)return t.v}return!0},A.exports=M.default},function(A,M){var t=A.exports={version:"1.2.2"};"number"==typeof __e&&(__e=t)},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(2),g=t(1),e=t(4),i=t(19),T="prototype",E=function(A,M){return function(){return A.apply(M,arguments)}},N=function(A,M,t){var o,n,C,c,D=A&N.G,a=A&N.P,B=D?I:A&N.S?I[M]||(I[M]={}):(I[M]||{})[T],Q=D?g:g[M]||(g[M]={});D&&(t=M);for(o in t)n=!(A&N.F)&&B&&o in B,C=(n?B:t)[o],c=A&N.B&&n?E(C,I):a&&"function"==typeof C?E(Function.call,C):C,B&&!n&&i(B,o,C),Q[o]!=C&&e(Q,o,c),a&&((Q[T]||(Q[T]={}))[o]=C)};I.core=g,N.F=1,N.G=2,N.S=4,N.P=8,N.B=16,N.W=32,A.exports=N},function(A,M,t){var I=t(5),g=t(18);A.exports=t(22)?function(A,M,t){return I.setDesc(A,M,g(1,t))}:function(A,M,t){return A[M]=t,A}},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M){var t=0,I=Math.random();A.exports=function(A){return"Symbol(".concat(void 0===A?"":A,")_",(++t+I).toString(36))}},function(A,M,t){var I=t(20)("wks"),g=t(2).Symbol;A.exports=function(A){return I[A]||(I[A]=g&&g[A]||(g||t(6))("Symbol."+A))}},function(A,M,t){t(26),A.exports=t(1).Array.some},function(A,M,t){t(25),A.exports=t(1).String.endsWith},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M,t){var I=t(10);A.exports=function(A,M,t){if(I(A),void 0===M)return A;switch(t){case 1:return function(t){return A.call(M,t)};case 2:return function(t,I){return A.call(M,t,I)};case 3:return function(t,I,g){return A.call(M,t,I,g)}}return function(){return A.apply(M,arguments)}}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M,t){A.exports=function(A){var M=/./;try{"/./"[A](M)}catch(I){try{return M[t(7)("match")]=!1,!"/./"[A](M)}catch(A){}}return!0}},function(A,M){A.exports=function(A){try{return!!A()}catch(A){return!0}}},function(A,M){A.exports=function(A){return"object"==typeof A?null!==A:"function"==typeof A}},function(A,M,t){var I=t(16),g=t(11),e=t(7)("match");A.exports=function(A){var M;return I(A)&&(void 0!==(M=A[e])?!!M:"RegExp"==g(A))}},function(A,M){A.exports=function(A,M){return{enumerable:!(1&A),configurable:!(2&A),writable:!(4&A),value:M}}},function(A,M,t){var I=t(2),g=t(4),e=t(6)("src"),i="toString",T=Function[i],E=(""+T).split(i);t(1).inspectSource=function(A){return T.call(A)},(A.exports=function(A,M,t,i){"function"==typeof t&&(g(t,e,A[M]?""+A[M]:E.join(String(M))),"name"in t||(t.name=M)),A===I?A[M]=t:(i||delete A[M],g(A,M,t))})(Function.prototype,i,function(){return"function"==typeof this&&this[e]||T.call(this)})},function(A,M,t){var I=t(2),g="__core-js_shared__",e=I[g]||(I[g]={});A.exports=function(A){return e[A]||(e[A]={})}},function(A,M,t){var I=t(17),g=t(13);A.exports=function(A,M,t){if(I(M))throw TypeError("String#"+t+" doesn't accept regex!");return String(g(A))}},function(A,M,t){A.exports=!t(15)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(A,M){var t=Math.ceil,I=Math.floor;A.exports=function(A){return isNaN(A=+A)?0:(A>0?I:t)(A)}},function(A,M,t){var I=t(23),g=Math.min;A.exports=function(A){return A>0?g(I(A),9007199254740991):0}},function(A,M,t){"use strict";var I=t(3),g=t(24),e=t(21),i="endsWith",T=""[i];I(I.P+I.F*t(14)(i),"String",{endsWith:function(A){var M=e(this,A,i),t=arguments,I=t.length>1?t[1]:void 0,E=g(M.length),N=void 0===I?E:Math.min(g(I),E),o=String(A);return T?T.call(M,o,N):M.slice(N-o.length,N)===o}})},function(A,M,t){var I=t(5),g=t(3),e=t(1).Array||Array,i={},T=function(A,M){I.each.call(A.split(","),function(A){void 0==M&&A in e?i[A]=e[A]:A in[]&&(i[A]=t(12)(Function.call,[][A],M))})};T("pop,reverse,shift,keys,values,entries",1),T("indexOf,every,some,forEach,map,filter,find,findIndex,includes",3),T("join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill"),g(g.S,"Array",i)}])},function(A,M){"use strict";function t(A){var M=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],t=[];if(A.dataTransfer){var I=A.dataTransfer;I.files&&I.files.length?t=I.files:I.items&&I.items.length&&(t=I.items)}else A.target&&A.target.files&&(t=A.target.files);return t.length>0&&(t=M?t:[t[0]]),Array.prototype.slice.call(t)}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t,A.exports=M.default}])})},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{},t=M.hideSiblingNodes,I=void 0===t||t,e=M.handleContainerOverflow,i=void 0===e||e;g(this,A),this.hideSiblingNodes=I,this.handleContainerOverflow=i,this.modals=[],this.containers=[],this.data=[]}return N(A,[{key:"add",value:function(A,M,t){var I=this.modals.indexOf(A),g=this.containers.indexOf(M);if(I!==-1)return I;if(I=this.modals.length,this.modals.push(A),this.hideSiblingNodes&&(0,r.hideSiblings)(M,A.mountNode),g!==-1)return this.data[g].modals.push(A),I;var e={modals:[A],classes:t?t.split(/\s+/):[],overflowing:(0,Q.default)(M)};return this.handleContainerOverflow&&T(e,M),e.classes.forEach(c.default.addClass.bind(null,M)),this.containers.push(M),this.data.push(e),I}},{key:"remove",value:function(A){var M=this.modals.indexOf(A);if(M!==-1){var t=i(this.data,A),I=this.data[t],g=this.containers[t];I.modals.splice(I.modals.indexOf(A),1),this.modals.splice(M,1),0===I.modals.length?(I.classes.forEach(c.default.removeClass.bind(null,g)),this.handleContainerOverflow&&E(I,g),this.hideSiblingNodes&&(0,r.showSiblings)(g,A.mountNode),this.containers.splice(t,1),this.data.splice(t,1)):this.hideSiblingNodes&&(0,r.ariaHidden)(!1,I.modals[I.modals.length-1].mountNode)}}},{key:"isTopModal",value:function(A){return!!this.modals.length&&this.modals[this.modals.length-1]===A}}]),A}();M.default=s,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M1?t-1:0),g=1;g=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}function E(){}Object.defineProperty(M,"__esModule",{value:!0}),M.EXITING=M.ENTERED=M.ENTERING=M.EXITED=M.UNMOUNTED=void 0;var N=Object.assign||function(A){for(var M=1;MT?T-N:0}function i(A,M,t,I){var e=g(t),i=e.width,T=A-I,E=A+I+M;return T<0?-T:E>i?i-E:0}function T(A,M,t,I,g){var T="BODY"===I.tagName?(0,N.default)(t):(0,n.default)(t,I),E=(0,N.default)(M),o=E.height,C=E.width,c=void 0,D=void 0,a=void 0,B=void 0;if("left"===A||"right"===A){D=T.top+(T.height-o)/2,c="left"===A?T.left-C:T.left+T.width;var Q=e(D,o,I,g);D+=Q,B=50*(1-2*Q/o)+"%",a=void 0}else{if("top"!==A&&"bottom"!==A)throw new Error('calcOverlayPosition(): No such placement of "'+A+'" found.');c=T.left+(T.width-C)/2,D="top"===A?T.top-o:T.top+T.height;var r=i(c,C,I,g);c+=r,a=50*(1-2*r/C)+"%",B=void 0}return{positionLeft:c,positionTop:D,arrowOffsetLeft:a,arrowOffsetTop:B}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=T;var E=t(143),N=I(E),o=t(287),n=I(o),C=t(144),c=I(C),D=t(52),a=I(D);A.exports=M.default},function(A,M){"use strict";function t(A,M){M&&(A?M.setAttribute("aria-hidden","true"):M.removeAttribute("aria-hidden"))}function I(A,M){T(A,M,function(A){return t(!0,A)})}function g(A,M){T(A,M,function(A){return t(!1,A)})}Object.defineProperty(M,"__esModule",{value:!0}),M.ariaHidden=t,M.hideSiblings=I,M.showSiblings=g;var e=["template","script","style"],i=function(A){var M=A.nodeType,t=A.tagName;return 1===M&&e.indexOf(t.toLowerCase())===-1},T=function(A,M,t){M=[].concat(M),[].forEach.call(A.children,function(A){M.indexOf(A)===-1&&i(A)&&t(A)})}},function(A,M,t){"use strict";var I=function(){};A.exports=I},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return function(t,I,g){if(null!=t[I]){var e='"'+I+'" property of "'+g+'" has been deprecated.\n'+M;E[e]||(T.default(!1,e),E[e]=!0)}return A(t,I,g)}}function e(){E={}}M.__esModule=!0,M.default=g;var i=t(127),T=I(i),E={};g._resetWarned=e,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function e(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function i(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}M.__esModule=!0,M.default=void 0;var T=t(1),E=t(184),N=I(E),o=t(185),n=(I(o),function(A){function M(t,I){g(this,M);var i=e(this,A.call(this,t,I));return i.store=t.store,i}return i(M,A),M.prototype.getChildContext=function(){return{store:this.store}},M.prototype.render=function(){return T.Children.only(this.props.children)},M}(T.Component));M.default=n,n.propTypes={store:N.default.isRequired,children:T.PropTypes.element.isRequired},n.childContextTypes={store:N.default.isRequired}},function(A,M){"use strict";function t(A,M){if(A===M)return!0;var t=Object.keys(A),I=Object.keys(M);if(t.length!==I.length)return!1;for(var g=Object.prototype.hasOwnProperty,e=0;e=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){var t=A.history,I=A.routes,e=A.location,E=g(A,["history","routes","location"]);t||e?void 0:(0,N.default)(!1),t=t?t:(0,n.default)(E);var o=(0,c.default)(t,(0,D.createRoutes)(I)),C=void 0;e?e=t.createLocation(e):C=t.listen(function(A){e=A});var B=(0,a.createRouterObject)(t,o);t=(0,a.createRoutingHistory)(t,o),o.match(e,function(A,I,g){M(A,I&&B.createLocation(I,T.REPLACE),g&&i({},g,{history:t,router:B,matchContext:{history:t,transitionManager:o,router:B}})),C&&C()})}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return function(){var M=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],t=M.routes,I=g(M,["routes"]),e=(0,E.default)(A)(I),T=(0,o.default)(e,t);return i({},e,T)}}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=A&&N&&(T=!0,t()))}}var i=0,T=!1,E=!1,N=!1,o=void 0;e()}M.__esModule=!0;var I=Array.prototype.slice;M.loopAsync=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){function A(A){try{A=A||window.history.state||{}}catch(M){A={}}var M=n.getWindowPath(),t=A,I=t.key,g=void 0;I?g=C.readState(I):(g=null,I=s.createKey(),Q&&window.history.replaceState(e({},A,{key:I}),null));var i=N.parsePath(M);return s.createLocation(e({},i,{state:g}),void 0,I)}function M(M){function t(M){void 0!==M.state&&I(A(M.state))}var I=M.transitionTo;return n.addEventListener(window,"popstate",t),function(){n.removeEventListener(window,"popstate",t)}}function t(A){var M=A.basename,t=A.pathname,I=A.search,g=A.hash,e=A.state,i=A.action,T=A.key;if(i!==E.POP){C.saveState(T,e);var N=(M||"")+t+I+g,o={key:T};if(i===E.PUSH){if(r)return window.location.href=N,!1;window.history.pushState(o,null,N)}else{if(r)return window.location.replace(N),!1;window.history.replaceState(o,null,N)}}}function I(A){1===++x&&(j=M(s));var t=s.listenBefore(A);return function(){t(),0===--x&&j()}}function g(A){1===++x&&(j=M(s));var t=s.listen(A);return function(){t(),0===--x&&j()}}function i(A){1===++x&&(j=M(s)),s.registerTransitionHook(A)}function c(A){s.unregisterTransitionHook(A),0===--x&&j()}var a=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];o.canUseDOM?void 0:T.default(!1);var B=a.forceRefresh,Q=n.supportsHistory(),r=!Q||B,s=D.default(e({},a,{getCurrentLocation:A,finishTransition:t,saveState:C.saveState})),x=0,j=void 0;return e({},s,{listenBefore:I,listen:g,registerTransitionHook:i,unregisterTransitionHook:c})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M=0&&M=0&&B8&&u<=11),L=32,Y=String.fromCharCode(L),d=c.topLevelTypes,h={beforeInput:{phasedRegistrationNames:{bubbled:s({onBeforeInput:null}),captured:s({onBeforeInputCapture:null})},dependencies:[d.topCompositionEnd,d.topKeyPress,d.topTextInput,d.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:s({onCompositionEnd:null}),captured:s({onCompositionEndCapture:null})},dependencies:[d.topBlur,d.topCompositionEnd,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:s({onCompositionStart:null}),captured:s({onCompositionStartCapture:null})},dependencies:[d.topBlur,d.topCompositionStart,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:s({onCompositionUpdate:null}),captured:s({onCompositionUpdateCapture:null})},dependencies:[d.topBlur,d.topCompositionUpdate,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]}},S=!1,z=null,p={eventTypes:h,extractEvents:function(A,M,t,I,g){return[N(A,M,t,I,g),C(A,M,t,I,g)]}};A.exports=p},function(A,M,t){"use strict";var I=t(202),g=t(10),e=t(17),i=(t(297),t(476)),T=t(302),E=t(306),N=(t(3),E(function(A){return T(A)})),o=!1,n="cssFloat";if(g.canUseDOM){var C=document.createElement("div").style;try{C.font=""}catch(A){o=!0}void 0===document.documentElement.style.cssFloat&&(n="styleFloat")}var c={createMarkupForStyles:function(A){var M="";for(var t in A)if(A.hasOwnProperty(t)){var I=A[t];null!=I&&(M+=N(t)+":",M+=i(t,I)+";")}return M||null},setValueForStyles:function(A,M){var t=A.style;for(var g in M)if(M.hasOwnProperty(g)){var e=i(g,M[g]);if("float"===g&&(g=n),e)t[g]=e;else{var T=o&&I.shorthandPropertyExpansions[g];if(T)for(var E in T)t[E]="";else t[g]=""}}}};e.measureMethods(c,"CSSPropertyOperations",{setValueForStyles:"setValueForStyles"}),A.exports=c},function(A,M,t){"use strict";function I(A){var M=A.nodeName&&A.nodeName.toLowerCase();return"select"===M||"input"===M&&"file"===A.type}function g(A){var M=u.getPooled(h.change,z,A,w(A));x.accumulateTwoPhaseDispatches(M),y.batchedUpdates(e,M)}function e(A){s.enqueueEvents(A),s.processEventQueue(!1)}function i(A,M){S=A,z=M,S.attachEvent("onchange",g)}function T(){S&&(S.detachEvent("onchange",g),S=null,z=null)}function E(A,M,t){if(A===d.topChange)return t}function N(A,M,t){A===d.topFocus?(T(),i(M,t)):A===d.topBlur&&T()}function o(A,M){S=A,z=M,p=A.value,U=Object.getOwnPropertyDescriptor(A.constructor.prototype,"value"),Object.defineProperty(S,"value",F),S.attachEvent("onpropertychange",C)}function n(){S&&(delete S.value,S.detachEvent("onpropertychange",C),S=null,z=null,p=null,U=null)}function C(A){if("value"===A.propertyName){var M=A.srcElement.value;M!==p&&(p=M,g(A))}}function c(A,M,t){if(A===d.topInput)return t}function D(A,M,t){A===d.topFocus?(n(),o(M,t)):A===d.topBlur&&n()}function a(A,M,t){if((A===d.topSelectionChange||A===d.topKeyUp||A===d.topKeyDown)&&S&&S.value!==p)return p=S.value,z}function B(A){return A.nodeName&&"input"===A.nodeName.toLowerCase()&&("checkbox"===A.type||"radio"===A.type)}function Q(A,M,t){if(A===d.topClick)return t}var r=t(24),s=t(53),x=t(54),j=t(10),y=t(18),u=t(37),w=t(117),l=t(120),L=t(229),Y=t(27),d=r.topLevelTypes,h={change:{phasedRegistrationNames:{bubbled:Y({onChange:null}),captured:Y({onChangeCapture:null})},dependencies:[d.topBlur,d.topChange,d.topClick,d.topFocus,d.topInput,d.topKeyDown,d.topKeyUp,d.topSelectionChange]}},S=null,z=null,p=null,U=null,O=!1;j.canUseDOM&&(O=l("change")&&(!("documentMode"in document)||document.documentMode>8));var m=!1;j.canUseDOM&&(m=l("input")&&(!("documentMode"in document)||document.documentMode>9));var F={get:function(){return U.get.call(this)},set:function(A){p=""+A,U.set.call(this,A)}},f={eventTypes:h,extractEvents:function(A,M,t,g,e){var i,T;if(I(M)?O?i=E:T=N:L(M)?m?i=c:(i=a,T=D):B(M)&&(i=Q),i){var o=i(A,M,t);if(o){var n=u.getPooled(h.change,o,g,e);return n.type="change",x.accumulateTwoPhaseDispatches(n),n}}T&&T(A,M,t)}};A.exports=f},function(A,M){"use strict";var t=0,I={createReactRootIndex:function(){return t++}};A.exports=I},function(A,M,t){"use strict";function I(A){return A.substring(1,A.indexOf(" "))}var g=t(10),e=t(299),i=t(20),T=t(151),E=t(2),N=/^(<[^ \/>]+)/,o="data-danger-index",n={dangerouslyRenderMarkup:function(A){g.canUseDOM?void 0:E(!1);for(var M,t={},n=0;n1?1-M:void 0;return this._fallbackText=g.slice(A,T),this._fallbackText}}),g.addPoolingTo(I),A.exports=I},function(A,M,t){"use strict";var I,g=t(47),e=t(10),i=g.injection.MUST_USE_ATTRIBUTE,T=g.injection.MUST_USE_PROPERTY,E=g.injection.HAS_BOOLEAN_VALUE,N=g.injection.HAS_SIDE_EFFECTS,o=g.injection.HAS_NUMERIC_VALUE,n=g.injection.HAS_POSITIVE_NUMERIC_VALUE,C=g.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(e.canUseDOM){var c=document.implementation;I=c&&c.hasFeature&&c.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var D={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:i|E,allowTransparency:i,alt:null,async:E,autoComplete:null,autoPlay:E,capture:i|E,cellPadding:null,cellSpacing:null,charSet:i,challenge:i,checked:T|E,classID:i,className:I?i:T,cols:i|n,colSpan:null,content:null,contentEditable:null,contextMenu:i,controls:T|E,coords:null,crossOrigin:null,data:null,dateTime:i,default:E,defer:E,dir:null,disabled:i|E,download:C,draggable:null,encType:null,form:i,formAction:i,formEncType:i,formMethod:i,formNoValidate:E,formTarget:i,frameBorder:i,headers:null,height:i,hidden:i|E,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:T,inputMode:i,integrity:null,is:i,keyParams:i,keyType:i,kind:null,label:null,lang:null,list:i,loop:T|E,low:null,manifest:i,marginHeight:null,marginWidth:null,max:null,maxLength:i,media:i,mediaGroup:null,method:null,min:null,minLength:i,multiple:T|E,muted:T|E,name:null,nonce:i,noValidate:E,open:E,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:T|E,rel:null,required:E,reversed:E,role:i,rows:i|n,rowSpan:null,sandbox:null,scope:null,scoped:E,scrolling:null,seamless:i|E,selected:T|E,shape:null,size:i|n,sizes:i,span:n,spellCheck:null,src:null,srcDoc:T,srcLang:null,srcSet:i,start:o,step:null,style:null,summary:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:T|N,width:i,wmode:i,wrap:null,about:i,datatype:i,inlist:i,prefix:i,property:i,resource:i,typeof:i,vocab:i,autoCapitalize:i,autoCorrect:i,autoSave:null,color:null,itemProp:i,itemScope:i|E,itemType:i,itemID:i,itemRef:i,results:null,security:i,unselectable:i},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",autoSave:"autosave",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};A.exports=D},function(A,M,t){"use strict";var I=t(208),g=t(450),e=t(455),i=t(4),T=t(477),E={};i(E,e),i(E,{findDOMNode:T("findDOMNode","ReactDOM","react-dom",I,I.findDOMNode),render:T("render","ReactDOM","react-dom",I,I.render),unmountComponentAtNode:T("unmountComponentAtNode","ReactDOM","react-dom",I,I.unmountComponentAtNode),renderToString:T("renderToString","ReactDOMServer","react-dom/server",g,g.renderToString),renderToStaticMarkup:T("renderToStaticMarkup","ReactDOMServer","react-dom/server",g,g.renderToStaticMarkup)}),E.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=I,E.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=g,A.exports=E},function(A,M,t){"use strict";var I=(t(55),t(114)),g=(t(3),"_getDOMNodeDidWarn"),e={getDOMNode:function(){return this.constructor[g]=!0,I(this)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t){var I=void 0===A[t];null!=M&&I&&(A[t]=e(M,null))}var g=t(36),e=t(119),i=t(122),T=t(123),E=(t(3),{instantiateChildren:function(A,M,t){if(null==A)return null;var g={};return T(A,I,g),g},updateChildren:function(A,M,t,I){if(!M&&!A)return null;var T;for(T in M)if(M.hasOwnProperty(T)){var E=A&&A[T],N=E&&E._currentElement,o=M[T];if(null!=E&&i(N,o))g.receiveComponent(E,o,t,I),M[T]=E;else{E&&g.unmountComponent(E,T);var n=e(o,null);M[T]=n}}for(T in A)!A.hasOwnProperty(T)||M&&M.hasOwnProperty(T)||g.unmountComponent(A[T]);return M},unmountChildren:function(A){for(var M in A)if(A.hasOwnProperty(M)){var t=A[M];g.unmountComponent(t)}}});A.exports=E},function(A,M,t){"use strict";function I(A){var M=A._currentElement._owner||null;if(M){var t=M.getName();if(t)return" Check the render method of ` + "`" + `"+t+"` + "`" + `."}return""}function g(A){}var e=t(110),i=t(25),T=t(13),E=t(55),N=t(17),o=t(71),n=(t(70),t(36)),C=t(112),c=t(4),D=t(50),a=t(2),B=t(122);t(3);g.prototype.render=function(){var A=E.get(this)._currentElement.type;return A(this.props,this.context,this.updater)};var Q=1,r={construct:function(A){this._currentElement=A,this._rootNodeID=null,this._instance=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._topLevelWrapper=null,this._pendingCallbacks=null},mountComponent:function(A,M,t){this._context=t,this._mountOrder=Q++,this._rootNodeID=A;var I,e,i=this._processProps(this._currentElement.props),N=this._processContext(t),o=this._currentElement.type,c="prototype"in o;c&&(I=new o(i,N,C)),c&&null!==I&&I!==!1&&!T.isValidElement(I)||(e=I,I=new g(o)),I.props=i,I.context=N,I.refs=D,I.updater=C,this._instance=I,E.set(I,this);var B=I.state;void 0===B&&(I.state=B=null),"object"!=typeof B||Array.isArray(B)?a(!1):void 0,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,I.componentWillMount&&(I.componentWillMount(),this._pendingStateQueue&&(I.state=this._processPendingState(I.props,I.context))),void 0===e&&(e=this._renderValidatedComponent()),this._renderedComponent=this._instantiateReactComponent(e);var r=n.mountComponent(this._renderedComponent,A,M,this._processChildContext(t));return I.componentDidMount&&M.getReactMountReady().enqueue(I.componentDidMount,I),r},unmountComponent:function(){var A=this._instance;A.componentWillUnmount&&A.componentWillUnmount(),n.unmountComponent(this._renderedComponent),this._renderedComponent=null,this._instance=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=null,this._topLevelWrapper=null,E.remove(A)},_maskContext:function(A){var M=null,t=this._currentElement.type,I=t.contextTypes;if(!I)return D;M={};for(var g in I)M[g]=A[g];return M},_processContext:function(A){var M=this._maskContext(A);return M},_processChildContext:function(A){var M=this._currentElement.type,t=this._instance,I=t.getChildContext&&t.getChildContext();if(I){"object"!=typeof M.childContextTypes?a(!1):void 0;for(var g in I)g in M.childContextTypes?void 0:a(!1);return c({},A,I)}return A},_processProps:function(A){return A},_checkPropTypes:function(A,M,t){var g=this.getName();for(var e in A)if(A.hasOwnProperty(e)){var i;try{"function"!=typeof A[e]?a(!1):void 0,i=A[e](M,e,g,t)}catch(A){i=A}if(i instanceof Error){I(this);t===o.prop}}},receiveComponent:function(A,M,t){var I=this._currentElement,g=this._context;this._pendingElement=null,this.updateComponent(M,I,A,g,t)},performUpdateIfNecessary:function(A){null!=this._pendingElement&&n.receiveComponent(this,this._pendingElement||this._currentElement,A,this._context),(null!==this._pendingStateQueue||this._pendingForceUpdate)&&this.updateComponent(A,this._currentElement,this._currentElement,this._context,this._context)},updateComponent:function(A,M,t,I,g){var e,i=this._instance,T=this._context===g?i.context:this._processContext(g);M===t?e=t.props:(e=this._processProps(t.props),i.componentWillReceiveProps&&i.componentWillReceiveProps(e,T));var E=this._processPendingState(e,T),N=this._pendingForceUpdate||!i.shouldComponentUpdate||i.shouldComponentUpdate(e,E,T);N?(this._pendingForceUpdate=!1,this._performComponentUpdate(t,e,E,T,A,g)):(this._currentElement=t,this._context=g,i.props=e,i.state=E,i.context=T)},_processPendingState:function(A,M){var t=this._instance,I=this._pendingStateQueue,g=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!I)return t.state;if(g&&1===I.length)return I[0];for(var e=c({},g?I[0]:t.state),i=g?1:0;i=0||null!=M.is}function B(A){D(A),this._tag=A.toLowerCase(),this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._rootNodeID=null,this._wrapperState=null,this._topLevelWrapper=null,this._nodeWithLegacyProperties=null}var Q=t(429),r=t(431),s=t(47),x=t(107),j=t(24),y=t(69),u=t(109),w=t(444),l=t(447),L=t(448),Y=t(210),d=t(451),h=t(12),S=t(456),z=t(17),p=t(112),U=t(4),O=t(74),m=t(75),F=t(2),f=(t(120),t(27)),k=t(76),R=t(121),J=(t(152),t(124),t(3),y.deleteListener),G=y.listenTo,H=y.registrationNameModules,b={string:!0,number:!0},v=f({children:null}),X=f({style:null}),W=f({__html:null}),V=1,P={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},Z={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},K={listing:!0,pre:!0,textarea:!0},q=(U({menuitem:!0},Z),/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/),_={},$={}.hasOwnProperty;B.displayName="ReactDOMComponent",B.Mixin={construct:function(A){this._currentElement=A},mountComponent:function(A,M,t){this._rootNodeID=A;var I=this._currentElement.props;switch(this._tag){case"iframe":case"img":case"form":case"video":case"audio":this._wrapperState={listeners:null},M.getReactMountReady().enqueue(n,this);break;case"button":I=w.getNativeProps(this,I,t);break;case"input":l.mountWrapper(this,I,t),I=l.getNativeProps(this,I,t);break;case"option":L.mountWrapper(this,I,t),I=L.getNativeProps(this,I,t);break;case"select":Y.mountWrapper(this,I,t),I=Y.getNativeProps(this,I,t),t=Y.processChildContext(this,I,t);break;case"textarea":d.mountWrapper(this,I,t),I=d.getNativeProps(this,I,t)}E(this,I);var g;if(M.useCreateElement){var e=t[h.ownerDocumentContextKey],i=e.createElement(this._currentElement.type);x.setAttributeForID(i,this._rootNodeID),h.getID(i),this._updateDOMProperties({},I,M,i),this._createInitialChildren(M,I,t,i),g=i}else{var T=this._createOpenTagMarkupAndPutListeners(M,I),N=this._createContentMarkup(M,I,t);g=!N&&Z[this._tag]?T+"/>":T+">"+N+""}switch(this._tag){case"input":M.getReactMountReady().enqueue(C,this);case"button":case"select":case"textarea":I.autoFocus&&M.getReactMountReady().enqueue(Q.focusDOMComponent,this)}return g},_createOpenTagMarkupAndPutListeners:function(A,M){var t="<"+this._currentElement.type;for(var I in M)if(M.hasOwnProperty(I)){var g=M[I];if(null!=g)if(H.hasOwnProperty(I))g&&N(this._rootNodeID,I,g,A);else{I===X&&(g&&(g=this._previousStyleCopy=U({},M.style)),g=r.createMarkupForStyles(g));var e=null;null!=this._tag&&a(this._tag,M)?I!==v&&(e=x.createMarkupForCustomAttribute(I,g)):e=x.createMarkupForProperty(I,g),e&&(t+=" "+e)}}if(A.renderToStaticMarkup)return t;var i=x.createMarkupForID(this._rootNodeID);return t+" "+i},_createContentMarkup:function(A,M,t){var I="",g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&(I=g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)I=m(e);else if(null!=i){var T=this.mountChildren(i,A,t);I=T.join("")}}return K[this._tag]&&"\n"===I.charAt(0)?"\n"+I:I},_createInitialChildren:function(A,M,t,I){var g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&k(I,g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)R(I,e);else if(null!=i)for(var T=this.mountChildren(i,A,t),E=0;EM.end?(t=M.end,I=M.start):(t=M.start,I=M.end),g.moveToElementText(A),g.moveStart("character",t),g.setEndPoint("EndToStart",g),g.moveEnd("character",I-t),g.select()}function T(A,M){if(window.getSelection){var t=window.getSelection(),I=A[o()].length,g=Math.min(M.start,I),e="undefined"==typeof M.end?g:Math.min(M.end,I);if(!t.extend&&g>e){var i=e;e=g,g=i}var T=N(A,g),E=N(A,e);if(T&&E){var n=document.createRange();n.setStart(T.node,T.offset),t.removeAllRanges(),g>e?(t.addRange(n),t.extend(E.node,E.offset)):(n.setEnd(E.node,E.offset),t.addRange(n))}}}var E=t(10),N=t(480),o=t(228),n=E.canUseDOM&&"selection"in document&&!("getSelection"in window),C={getOffsets:n?g:e,setOffsets:n?i:T};A.exports=C},function(A,M,t){"use strict";var I=t(213),g=t(461),e=t(113);I.inject();var i={renderToString:g.renderToString,renderToStaticMarkup:g.renderToStaticMarkup,version:e};A.exports=i},function(A,M,t){"use strict";function I(){this._rootNodeID&&o.updateWrapper(this)}function g(A){var M=this._currentElement.props,t=e.executeOnChange(M,A);return T.asap(I,this),t}var e=t(108),i=t(111),T=t(18),E=t(4),N=t(2),o=(t(3),{getNativeProps:function(A,M,t){null!=M.dangerouslySetInnerHTML?N(!1):void 0;var I=E({},M,{defaultValue:void 0,value:void 0,children:A._wrapperState.initialValue,onChange:A._wrapperState.onChange});return I},mountWrapper:function(A,M){var t=M.defaultValue,I=M.children;null!=I&&(null!=t?N(!1):void 0,Array.isArray(I)&&(I.length<=1?void 0:N(!1),I=I[0]),t=""+I),null==t&&(t="");var i=e.getValue(M);A._wrapperState={initialValue:""+(null!=i?i:t),onChange:g.bind(A)}},updateWrapper:function(A){var M=A._currentElement.props,t=e.getValue(M);null!=t&&i.updatePropertyByID(A._rootNodeID,"value",""+t)}});A.exports=o},function(A,M,t){"use strict";function I(A){g.enqueueEvents(A),g.processEventQueue(!1)}var g=t(53),e={handleTopLevel:function(A,M,t,e,i){var T=g.extractEvents(A,M,t,e,i);I(T)}};A.exports=e},function(A,M,t){"use strict";function I(A){var M=C.getID(A),t=n.getReactRootIDFromNodeID(M),I=C.findReactContainerForID(t),g=C.getFirstReactDOM(I);return g}function g(A,M){this.topLevelType=A,this.nativeEvent=M,this.ancestors=[]}function e(A){i(A)}function i(A){for(var M=C.getFirstReactDOM(a(A.nativeEvent))||window,t=M;t;)A.ancestors.push(t),t=I(t);for(var g=0;g=M)return{node:g,offset:M-e};e=i}g=t(I(g))}}A.exports=g},function(A,M,t){"use strict";function I(A){return g.isValidElement(A)?void 0:e(!1),A}var g=t(13),e=t(2);A.exports=I},function(A,M,t){"use strict";function I(A){return'"'+g(A)+'"'}var g=t(75);A.exports=I},function(A,M,t){"use strict";var I=t(12);A.exports=I.renderSubtreeIntoContainer},function(A,M){A.exports=function(A,M,t){for(var I=0,g=A.length,e=3==arguments.length?t:A[I++];I=400){ -var T="cannot "+M.method+" "+M.url+" ("+i.status+")";A=new e(T),A.status=i.status,A.body=i.body,A.res=i,I(A)}else g?I(new e(g)):t(i)})})},g.prototype.then=function(){var A=this.promise();return A.then.apply(A,arguments)}},function(A,M,t){function I(){}function g(A){var M={}.toString.call(A);switch(M){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function e(A){if(!s(A))return A;var M=[];for(var t in A)null!=A[t]&&i(M,t,A[t]);return M.join("&")}function i(A,M,t){return Array.isArray(t)?t.forEach(function(t){i(A,M,t)}):void A.push(encodeURIComponent(M)+"="+encodeURIComponent(t))}function T(A){for(var M,t,I={},g=A.split("&"),e=0,i=g.length;e=200&&M.status<300)return t.callback(A,M);var I=new Error(M.statusText||"Unsuccessful HTTP response");I.original=A,I.response=M,I.status=M.status,t.callback(I,M)})}function D(A,M){var t=x("DELETE",A);return M&&t.end(M),t}var a,B=t(273),Q=t(484),r=t(502),s=t(236);a="undefined"!=typeof window?window:"undefined"!=typeof self?self:this;var x=A.exports=t(503).bind(null,c);x.getXHR=function(){if(!(!a.XMLHttpRequest||a.location&&"file:"==a.location.protocol&&a.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(A){}return!1};var j="".trim?function(A){return A.trim()}:function(A){return A.replace(/(^\s*|\s*$)/g,"")};x.serializeObject=e,x.parseString=T,x.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},x.serialize={"application/x-www-form-urlencoded":e,"application/json":JSON.stringify},x.parse={"application/x-www-form-urlencoded":T,"application/json":JSON.parse},C.prototype.get=function(A){return this.header[A.toLowerCase()]},C.prototype.setHeaderProperties=function(A){var M=this.header["content-type"]||"";this.type=o(M);var t=n(M);for(var I in t)this[I]=t[I]},C.prototype.parseBody=function(A){var M=x.parse[this.type];return!M&&N(this.type)&&(M=x.parse["application/json"]),M&&A&&(A.length||A instanceof Object)?M(A):null},C.prototype.setStatusProperties=function(A){1223===A&&(A=204);var M=A/100|0;this.status=this.statusCode=A,this.statusType=M,this.info=1==M,this.ok=2==M,this.clientError=4==M,this.serverError=5==M,this.error=(4==M||5==M)&&this.toError(),this.accepted=202==A,this.noContent=204==A,this.badRequest=400==A,this.unauthorized=401==A,this.notAcceptable=406==A,this.notFound=404==A,this.forbidden=403==A},C.prototype.toError=function(){var A=this.req,M=A.method,t=A.url,I="cannot "+M+" "+t+" ("+this.status+")",g=new Error(I);return g.status=this.status,g.method=M,g.url=t,g},x.Response=C,B(c.prototype);for(var y in r)c.prototype[y]=r[y];c.prototype.abort=function(){if(!this.aborted)return this.aborted=!0,this.xhr&&this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this},c.prototype.type=function(A){return this.set("Content-Type",x.types[A]||A),this},c.prototype.responseType=function(A){return this._responseType=A,this},c.prototype.accept=function(A){return this.set("Accept",x.types[A]||A),this},c.prototype.auth=function(A,M,t){switch(t||(t={type:"basic"}),t.type){case"basic":var I=btoa(A+":"+M);this.set("Authorization","Basic "+I);break;case"auto":this.username=A,this.password=M}return this},c.prototype.query=function(A){return"string"!=typeof A&&(A=e(A)),A&&this._query.push(A),this},c.prototype.attach=function(A,M,t){return this._getFormData().append(A,M,t||M.name),this},c.prototype._getFormData=function(){return this._formData||(this._formData=new a.FormData),this._formData},c.prototype.send=function(A){var M=s(A),t=this._header["content-type"];if(M&&s(this._data))for(var I in A)this._data[I]=A[I];else"string"==typeof A?(t||this.type("form"),t=this._header["content-type"],"application/x-www-form-urlencoded"==t?this._data=this._data?this._data+"&"+A:A:this._data=(this._data||"")+A):this._data=A;return!M||g(A)?this:(t||this.type("json"),this)},C.prototype.parse=function(A){return a.console&&console.warn("Client-side parse() method has been renamed to serialize(). This method is not compatible with superagent v2.0"),this.serialize(A),this},C.prototype.serialize=function(A){return this._parser=A,this},c.prototype.callback=function(A,M){var t=this._callback;this.clearTimeout(),t(A,M)},c.prototype.crossDomainError=function(){var A=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");A.crossDomain=!0,A.status=this.status,A.method=this.method,A.url=this.url,this.callback(A)},c.prototype.timeoutError=function(){var A=this._timeout,M=new Error("timeout of "+A+"ms exceeded");M.timeout=A,this.callback(M)},c.prototype.withCredentials=function(){return this._withCredentials=!0,this},c.prototype.end=function(A){var M=this,t=this.xhr=x.getXHR(),e=this._query.join("&"),i=this._timeout,T=this._formData||this._data;this._callback=A||I,t.onreadystatechange=function(){if(4==t.readyState){var A;try{A=t.status}catch(M){A=0}if(0==A){if(M.timedout)return M.timeoutError();if(M.aborted)return;return M.crossDomainError()}M.emit("end")}};var E=function(A){A.total>0&&(A.percent=A.loaded/A.total*100),A.direction="download",M.emit("progress",A)};this.hasListeners("progress")&&(t.onprogress=E);try{t.upload&&this.hasListeners("progress")&&(t.upload.onprogress=E)}catch(A){}if(i&&!this._timer&&(this._timer=setTimeout(function(){M.timedout=!0,M.abort()},i)),e&&(e=x.serializeObject(e),this.url+=~this.url.indexOf("?")?"&"+e:"?"+e),this.username&&this.password?t.open(this.method,this.url,!0,this.username,this.password):t.open(this.method,this.url,!0),this._withCredentials&&(t.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof T&&!g(T)){var o=this._header["content-type"],n=this._parser||x.serialize[o?o.split(";")[0]:""];!n&&N(o)&&(n=x.serialize["application/json"]),n&&(T=n(T))}for(var C in this.header)null!=this.header[C]&&t.setRequestHeader(C,this.header[C]);return this._responseType&&(t.responseType=this._responseType),this.emit("request",this),t.send("undefined"!=typeof T?T:null),this},x.Request=c,x.get=function(A,M,t){var I=x("GET",A);return"function"==typeof M&&(t=M,M=null),M&&I.query(M),t&&I.end(t),I},x.head=function(A,M,t){var I=x("HEAD",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.del=D,x.delete=D,x.patch=function(A,M,t){var I=x("PATCH",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.post=function(A,M,t){var I=x("POST",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.put=function(A,M,t){var I=x("PUT",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I}},function(A,M,t){var I=t(236);M.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},M.parse=function(A){return this._parser=A,this},M.timeout=function(A){return this._timeout=A,this},M.then=function(A,M){return this.end(function(t,I){t?M(t):A(I)})},M.use=function(A){return A(this),this},M.get=function(A){return this._header[A.toLowerCase()]},M.getHeader=M.get,M.set=function(A,M){if(I(A)){for(var t in A)this.set(t,A[t]);return this}return this._header[A.toLowerCase()]=M,this.header[A]=M,this},M.unset=function(A){return delete this._header[A.toLowerCase()],delete this.header[A],this},M.field=function(A,M){return this._getFormData().append(A,M),this}},function(A,M){function t(A,M,t){return"function"==typeof t?new A("GET",M).end(t):2==arguments.length?new A("GET",M):new A(M,t)}A.exports=t},function(A,M,t){A.exports=t(505)},function(A,M,t){(function(A,I){"use strict";function g(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var e,i=t(506),T=g(i);e="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof A?A:I;var E=(0,T.default)(e);M.default=E}).call(M,function(){return this}(),t(128)(A))},function(A,M){"use strict";function t(A){var M,t=A.Symbol;return"function"==typeof t?t.observable?M=t.observable:(M=t("observable"),t.observable=M):M="@@observable",M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t},function(A,M,t){function I(A){return g(A).replace(/\s(\w)/g,function(A,M){return M.toUpperCase()})}var g=t(509);A.exports=I},function(A,M){function t(A){return e.test(A)?A.toLowerCase():i.test(A)?(I(A)||A).toLowerCase():T.test(A)?g(A).toLowerCase():A.toLowerCase()}function I(A){return A.replace(E,function(A,M){return M?" "+M:""})}function g(A){return A.replace(N,function(A,M,t){return M+" "+t.toLowerCase().split("").join(" ")})}A.exports=t;var e=/\s/,i=/(_|-|\.|:)/,T=/([a-z][A-Z]|[A-Z][a-z])/,E=/[\W_]+(.|$)/g,N=/(.)([A-Z]+)/g},function(A,M,t){function I(A){return g(A).replace(/[\W_]+(.|$)/g,function(A,M){return M?" "+M:""}).trim()}var g=t(508);A.exports=I},function(A,M){A.exports=function(){var A=document.getSelection();if(!A.rangeCount)return function(){};for(var M=document.activeElement,t=[],I=0;I=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function i(A,M){function t(I,g){function i(A,t){var I=c.getLinkName(A),e=this.props[g[A]];I&&E(this.props,I)&&!e&&(e=this.props[I].requestChange);for(var i=arguments.length,T=Array(i>2?i-2:0),N=2;N=15||0===s[0]&&s[1]>=13?A:A.type}function T(A,M){var t=N(M);return t&&!E(A,M)&&E(A,t)?A[t].value:A[M]}function E(A,M){return void 0!==A[M]}function N(A){return"value"===A?"valueLink":"checked"===A?"checkedLink":null}function o(A){return"default"+A.charAt(0).toUpperCase()+A.substr(1)}function n(A,M,t){return function(){for(var I=arguments.length,g=Array(I),e=0;eo||N===o&&"application/"===M[T].substr(0,12))continue}M[T]=I}}})}var E=t(350),N=t(353).extname,o=/^\s*([^;\s]*)(?:;|\s|$)/,n=/^text\//i;M.charset=I,M.charsets={lookup:I},M.contentType=g,M.extension=e,M.extensions=Object.create(null),M.lookup=i,M.types=Object.create(null),T(M.extensions,M.types)},function(A,M){function t(A){throw new Error("Cannot find module '"+A+"'.")}t.keys=function(){return[]},t.resolve=t,A.exports=t,t.id=352},function(A,M,t){(function(A){function t(A,M){for(var t=0,I=A.length-1;I>=0;I--){var g=A[I];"."===g?A.splice(I,1):".."===g?(A.splice(I,1),t++):t&&(A.splice(I,1),t--)}if(M)for(;t--;t)A.unshift("..");return A}function I(A,M){if(A.filter)return A.filter(M);for(var t=[],I=0;I=-1&&!g;e--){var i=e>=0?arguments[e]:A.cwd();if("string"!=typeof i)throw new TypeError("Arguments to path.resolve must be strings");i&&(M=i+"/"+M,g="/"===i.charAt(0))}return M=t(I(M.split("/"),function(A){return!!A}),!g).join("/"),(g?"/":"")+M||"."},M.normalize=function(A){var g=M.isAbsolute(A),e="/"===i(A,-1);return A=t(I(A.split("/"),function(A){return!!A}),!g).join("/"),A||g||(A="."),A&&e&&(A+="/"),(g?"/":"")+A},M.isAbsolute=function(A){return"/"===A.charAt(0)},M.join=function(){var A=Array.prototype.slice.call(arguments,0);return M.normalize(I(A,function(A,M){if("string"!=typeof A)throw new TypeError("Arguments to path.join must be strings");return A}).join("/"))},M.relative=function(A,t){function I(A){for(var M=0;M=0&&""===A[t];t--);return M>t?[]:A.slice(M,t-M+1)}A=M.resolve(A).substr(1),t=M.resolve(t).substr(1);for(var g=I(A.split("/")),e=I(t.split("/")),i=Math.min(g.length,e.length),T=i,E=0;E=0;e--){var i=I[e]+g;if(i in M)return i}return!1}},function(A,M,t){"use strict";var I=t(496);M.extract=function(A){return A.split("?")[1]||""},M.parse=function(A){return"string"!=typeof A?{}:(A=A.trim().replace(/^(\?|#|&)/,""),A?A.split("&").reduce(function(A,M){var t=M.replace(/\+/g," ").split("="),I=t.shift(),g=t.length>0?t.join("="):void 0;return I=decodeURIComponent(I),g=void 0===g?null:decodeURIComponent(g),A.hasOwnProperty(I)?Array.isArray(A[I])?A[I].push(g):A[I]=[A[I],g]:A[I]=g,A},{}):{})},M.stringify=function(A){return A?Object.keys(A).sort().map(function(M){var t=A[M];return void 0===t?"":null===t?M:Array.isArray(t)?t.slice().sort().map(function(A){return I(M)+"="+I(A)}).join("&"):I(M)+"="+I(t)}).filter(function(A){return A.length>0}).join("&"):""}},function(A,M){"use strict";function t(A,M){return Object.prototype.hasOwnProperty.call(A,M)}A.exports=function(A,M,I,g){M=M||"&",I=I||"=";var e={};if("string"!=typeof A||0===A.length)return e;var i=/\+/g;A=A.split(M);var T=1e3;g&&"number"==typeof g.maxKeys&&(T=g.maxKeys);var E=A.length;T>0&&E>T&&(E=T);for(var N=0;N=0?(o=D.substr(0,a),n=D.substr(a+1)):(o=D,n=""),C=decodeURIComponent(o),c=decodeURIComponent(n),t(e,C)?Array.isArray(e[C])?e[C].push(c):e[C]=[e[C],c]:e[C]=c}return e}},function(A,M){"use strict";var t=function(A){switch(typeof A){case"string":return A;case"boolean":return A?"true":"false";case"number":return isFinite(A)?A:"";default:return""}};A.exports=function(A,M,I,g){return M=M||"&",I=I||"=",null===A&&(A=void 0),"object"==typeof A?Object.keys(A).map(function(g){var e=encodeURIComponent(t(g))+I;return Array.isArray(A[g])?A[g].map(function(A){return e+encodeURIComponent(t(A))}).join(M):e+encodeURIComponent(t(A[g]))}).join(M):g?encodeURIComponent(t(g))+I+encodeURIComponent(t(A)):""}},function(A,M,t){"use strict";M.decode=M.parse=t(357),M.encode=M.stringify=t(358)},function(A,M,t){(function(M){for(var I=t(354),g="undefined"==typeof window?M:window,e=["moz","webkit"],i="AnimationFrame",T=g["request"+i],E=g["cancel"+i]||g["cancelRequest"+i],N=0;!T&&N1)||(e=A,!1)}),e)return new Error("(children) "+I+" - Duplicate children detected of bsRole: "+e+". Only one child each allowed with the following bsRoles: "+M.join(", "))})}},A.exports=M.default},function(A,M,t){"use strict";function I(A){var M=[];return void 0===A?M:(i.default.forEach(A,function(A){M.push(A)}),M)}var g=t(6).default;M.__esModule=!0,M.default=I;var e=t(51),i=g(e);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}Object.defineProperty(M,"__esModule",{value:!0}),M.CopyToClipboard=void 0;var e=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){var M=A.style,t=g(A,["style"]),I=o({},M,{height:6,right:2,bottom:2,left:2,borderRadius:3});return C.default.createElement("div",o({style:I},t))}function i(A){var M=A.style,t=g(A,["style"]),I=o({},M,{width:6,right:2,bottom:2,top:2,borderRadius:3});return C.default.createElement("div",o({style:I},t))}function T(A){var M=A.style,t=g(A,["style"]),I=o({},M,{cursor:"pointer",borderRadius:"inherit",backgroundColor:"rgba(0,0,0,.2)"});return C.default.createElement("div",o({style:I},t))}function E(A){var M=A.style,t=g(A,["style"]),I=o({},M,{cursor:"pointer",borderRadius:"inherit",backgroundColor:"rgba(0,0,0,.2)"});return C.default.createElement("div",o({style:I},t))}function N(A){return C.default.createElement("div",A)}var o=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}var e=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M0||(this.setState({isDragActive:!1,isDragReject:!1}),this.props.onDragLeave&&this.props.onDragLeave.call(this,A))}},{key:"onDrop",value:function A(M){var t=this,I=this.props,A=I.onDrop,g=I.onDropAccepted,e=I.onDropRejected,i=I.multiple,T=I.disablePreview,E=(0,a.default)(M,i),N=[],o=[];M.preventDefault(),this.enterCounter=0,this.isFileDialogActive=!1,E.forEach(function(A){T||(A.preview=window.URL.createObjectURL(A)),t.fileAccepted(A)&&t.fileMatchSize(A)?N.push(A):o.push(A)}),A&&A.call(this,N,o,M),o.length>0&&e&&e.call(this,o,M),N.length>0&&g&&g.call(this,N,M),this.setState({isDragActive:!1,isDragReject:!1})}},{key:"onClick",value:function A(M){M.stopPropagation();var t=this.props,A=t.onClick,I=t.disableClick;I||(this.open(),A&&A.call(this,M))}},{key:"onFileDialogCancel",value:function A(){var A=this.props.onFileDialogCancel,M=this.fileInputEl,t=this.isFileDialogActive;A&&t&&setTimeout(function(){var I=M.files;I.length||(t=!1,A())},300)}},{key:"fileAccepted",value:function(A){return(0,c.default)(A,this.props.accept)}},{key:"fileMatchSize",value:function(A){return A.size<=this.props.maxSize&&A.size>=this.props.minSize}},{key:"allFilesAccepted",value:function(A){return A.every(this.fileAccepted)}},{key:"open",value:function(){this.isFileDialogActive=!0,this.fileInputEl.value=null,this.fileInputEl.click()}},{key:"render",value:function(){var A=this,M=this.props,t=M.accept,I=M.activeClassName,e=M.inputProps,i=M.multiple,T=M.name,N=M.rejectClassName,o=g(M,["accept","activeClassName","inputProps","multiple","name","rejectClassName"]),C=o.activeStyle,c=o.className,D=o.rejectStyle,a=o.style,Q=g(o,["activeStyle","className","rejectStyle","style"]),r=this.state,s=r.isDragActive,x=r.isDragReject;c=c||"",s&&I&&(c+=" "+I),x&&N&&(c+=" "+N),c||a||C||D||(a={width:200,height:200,borderWidth:2,borderColor:"#666",borderStyle:"dashed",borderRadius:5},C={borderStyle:"solid",backgroundColor:"#eee"},D={borderStyle:"solid",backgroundColor:"#ffdddd"});var j=void 0;j=C&&s?E({},a,C):D&&x?E({},a,D):E({},a);var y={accept:t,type:"file",style:{display:"none"},multiple:B&&i,ref:function(M){return A.fileInputEl=M},onChange:this.onDrop};T&&T.length&&(y.name=T);var u=["acceptedFiles","disablePreview","disableClick","onDropAccepted","onDropRejected","onFileDialogCancel","maxSize","minSize"],w=E({},Q);return u.forEach(function(A){return delete w[A]}),n.default.createElement("div",E({className:c,style:j},w,{onClick:this.onClick,onDragStart:this.onDragStart,onDragEnter:this.onDragEnter,onDragOver:this.onDragOver,onDragLeave:this.onDragLeave,onDrop:this.onDrop}),this.props.children,n.default.createElement("input",E({},e,y)))}}]),M}(n.default.Component);Q.defaultProps={disablePreview:!1,disableClick:!1,multiple:!0,maxSize:1/0,minSize:0},Q.propTypes={onClick:n.default.PropTypes.func,onDrop:n.default.PropTypes.func,onDropAccepted:n.default.PropTypes.func,onDropRejected:n.default.PropTypes.func,onDragStart:n.default.PropTypes.func,onDragEnter:n.default.PropTypes.func,onDragOver:n.default.PropTypes.func,onDragLeave:n.default.PropTypes.func,children:n.default.PropTypes.node,style:n.default.PropTypes.object,activeStyle:n.default.PropTypes.object,rejectStyle:n.default.PropTypes.object,className:n.default.PropTypes.string,activeClassName:n.default.PropTypes.string,rejectClassName:n.default.PropTypes.string,disablePreview:n.default.PropTypes.bool,disableClick:n.default.PropTypes.bool,onFileDialogCancel:n.default.PropTypes.func,inputProps:n.default.PropTypes.object,multiple:n.default.PropTypes.bool,accept:n.default.PropTypes.string,name:n.default.PropTypes.string,maxSize:n.default.PropTypes.number,minSize:n.default.PropTypes.number},M.default=Q,A.exports=M.default},function(M,t){M.exports=A},function(A,M){A.exports=function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){"use strict";M.__esModule=!0,t(8),t(9),M.default=function(A,M){if(A&&M){var t=function(){var t=Array.isArray(M)?M:M.split(","),I=A.name||"",g=A.type||"",e=g.replace(/\/.*$/,"");return{v:t.some(function(A){var M=A.trim();return"."===M.charAt(0)?I.toLowerCase().endsWith(M.toLowerCase()):/\/\*$/.test(M)?e===M.replace(/\/.*$/,""):g===M})}}();if("object"==typeof t)return t.v}return!0},A.exports=M.default},function(A,M){var t=A.exports={version:"1.2.2"};"number"==typeof __e&&(__e=t)},function(A,M){var t=A.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=t)},function(A,M,t){var I=t(2),g=t(1),e=t(4),i=t(19),T="prototype",E=function(A,M){return function(){return A.apply(M,arguments)}},N=function(A,M,t){var o,n,C,c,D=A&N.G,a=A&N.P,B=D?I:A&N.S?I[M]||(I[M]={}):(I[M]||{})[T],Q=D?g:g[M]||(g[M]={});D&&(t=M);for(o in t)n=!(A&N.F)&&B&&o in B,C=(n?B:t)[o],c=A&N.B&&n?E(C,I):a&&"function"==typeof C?E(Function.call,C):C,B&&!n&&i(B,o,C),Q[o]!=C&&e(Q,o,c),a&&((Q[T]||(Q[T]={}))[o]=C)};I.core=g,N.F=1,N.G=2,N.S=4,N.P=8,N.B=16,N.W=32,A.exports=N},function(A,M,t){var I=t(5),g=t(18);A.exports=t(22)?function(A,M,t){return I.setDesc(A,M,g(1,t))}:function(A,M,t){return A[M]=t,A}},function(A,M){var t=Object;A.exports={create:t.create,getProto:t.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:t.getOwnPropertyDescriptor,setDesc:t.defineProperty,setDescs:t.defineProperties,getKeys:t.keys,getNames:t.getOwnPropertyNames,getSymbols:t.getOwnPropertySymbols,each:[].forEach}},function(A,M){var t=0,I=Math.random();A.exports=function(A){return"Symbol(".concat(void 0===A?"":A,")_",(++t+I).toString(36))}},function(A,M,t){var I=t(20)("wks"),g=t(2).Symbol;A.exports=function(A){return I[A]||(I[A]=g&&g[A]||(g||t(6))("Symbol."+A))}},function(A,M,t){t(26),A.exports=t(1).Array.some},function(A,M,t){t(25),A.exports=t(1).String.endsWith},function(A,M){A.exports=function(A){if("function"!=typeof A)throw TypeError(A+" is not a function!");return A}},function(A,M){var t={}.toString;A.exports=function(A){return t.call(A).slice(8,-1)}},function(A,M,t){var I=t(10);A.exports=function(A,M,t){if(I(A),void 0===M)return A;switch(t){case 1:return function(t){return A.call(M,t)};case 2:return function(t,I){return A.call(M,t,I)};case 3:return function(t,I,g){return A.call(M,t,I,g)}}return function(){return A.apply(M,arguments)}}},function(A,M){A.exports=function(A){if(void 0==A)throw TypeError("Can't call method on "+A);return A}},function(A,M,t){A.exports=function(A){var M=/./;try{"/./"[A](M)}catch(I){try{return M[t(7)("match")]=!1,!"/./"[A](M)}catch(A){}}return!0}},function(A,M){A.exports=function(A){try{return!!A()}catch(A){return!0}}},function(A,M){A.exports=function(A){return"object"==typeof A?null!==A:"function"==typeof A}},function(A,M,t){var I=t(16),g=t(11),e=t(7)("match");A.exports=function(A){var M;return I(A)&&(void 0!==(M=A[e])?!!M:"RegExp"==g(A))}},function(A,M){A.exports=function(A,M){return{enumerable:!(1&A),configurable:!(2&A),writable:!(4&A),value:M}}},function(A,M,t){var I=t(2),g=t(4),e=t(6)("src"),i="toString",T=Function[i],E=(""+T).split(i);t(1).inspectSource=function(A){return T.call(A)},(A.exports=function(A,M,t,i){"function"==typeof t&&(g(t,e,A[M]?""+A[M]:E.join(String(M))),"name"in t||(t.name=M)),A===I?A[M]=t:(i||delete A[M],g(A,M,t))})(Function.prototype,i,function(){return"function"==typeof this&&this[e]||T.call(this)})},function(A,M,t){var I=t(2),g="__core-js_shared__",e=I[g]||(I[g]={});A.exports=function(A){return e[A]||(e[A]={})}},function(A,M,t){var I=t(17),g=t(13);A.exports=function(A,M,t){if(I(M))throw TypeError("String#"+t+" doesn't accept regex!");return String(g(A))}},function(A,M,t){A.exports=!t(15)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(A,M){var t=Math.ceil,I=Math.floor;A.exports=function(A){return isNaN(A=+A)?0:(A>0?I:t)(A)}},function(A,M,t){var I=t(23),g=Math.min;A.exports=function(A){return A>0?g(I(A),9007199254740991):0}},function(A,M,t){"use strict";var I=t(3),g=t(24),e=t(21),i="endsWith",T=""[i];I(I.P+I.F*t(14)(i),"String",{endsWith:function(A){var M=e(this,A,i),t=arguments,I=t.length>1?t[1]:void 0,E=g(M.length),N=void 0===I?E:Math.min(g(I),E),o=String(A);return T?T.call(M,o,N):M.slice(N-o.length,N)===o}})},function(A,M,t){var I=t(5),g=t(3),e=t(1).Array||Array,i={},T=function(A,M){I.each.call(A.split(","),function(A){void 0==M&&A in e?i[A]=e[A]:A in[]&&(i[A]=t(12)(Function.call,[][A],M))})};T("pop,reverse,shift,keys,values,entries",1),T("indexOf,every,some,forEach,map,filter,find,findIndex,includes",3),T("join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill"),g(g.S,"Array",i)}])},function(A,M){"use strict";function t(A){var M=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],t=[];if(A.dataTransfer){var I=A.dataTransfer;I.files&&I.files.length?t=I.files:I.items&&I.items.length&&(t=I.items)}else A.target&&A.target.files&&(t=A.target.files);return t.length>0&&(t=M?t:[t[0]]),Array.prototype.slice.call(t)}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t,A.exports=M.default}])})},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{},t=M.hideSiblingNodes,I=void 0===t||t,e=M.handleContainerOverflow,i=void 0===e||e;g(this,A),this.hideSiblingNodes=I,this.handleContainerOverflow=i,this.modals=[],this.containers=[],this.data=[]}return N(A,[{key:"add",value:function(A,M,t){var I=this.modals.indexOf(A),g=this.containers.indexOf(M);if(I!==-1)return I;if(I=this.modals.length,this.modals.push(A),this.hideSiblingNodes&&(0,r.hideSiblings)(M,A.mountNode),g!==-1)return this.data[g].modals.push(A),I;var e={modals:[A],classes:t?t.split(/\s+/):[],overflowing:(0,Q.default)(M)};return this.handleContainerOverflow&&T(e,M),e.classes.forEach(c.default.addClass.bind(null,M)),this.containers.push(M),this.data.push(e),I}},{key:"remove",value:function(A){var M=this.modals.indexOf(A);if(M!==-1){var t=i(this.data,A),I=this.data[t],g=this.containers[t];I.modals.splice(I.modals.indexOf(A),1),this.modals.splice(M,1),0===I.modals.length?(I.classes.forEach(c.default.removeClass.bind(null,g)),this.handleContainerOverflow&&E(I,g),this.hideSiblingNodes&&(0,r.showSiblings)(g,A.mountNode),this.containers.splice(t,1),this.data.splice(t,1)):this.hideSiblingNodes&&(0,r.ariaHidden)(!1,I.modals[I.modals.length-1].mountNode)}}},{key:"isTopModal",value:function(A){return!!this.modals.length&&this.modals[this.modals.length-1]===A}}]),A}();M.default=s,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M1?t-1:0),g=1;g=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}function E(){}Object.defineProperty(M,"__esModule",{value:!0}),M.EXITING=M.ENTERED=M.ENTERING=M.EXITED=M.UNMOUNTED=void 0;var N=Object.assign||function(A){for(var M=1;MT?T-N:0}function i(A,M,t,I){var e=g(t),i=e.width,T=A-I,E=A+I+M;return T<0?-T:E>i?i-E:0}function T(A,M,t,I,g){var T="BODY"===I.tagName?(0,N.default)(t):(0,n.default)(t,I),E=(0,N.default)(M),o=E.height,C=E.width,c=void 0,D=void 0,a=void 0,B=void 0;if("left"===A||"right"===A){D=T.top+(T.height-o)/2,c="left"===A?T.left-C:T.left+T.width;var Q=e(D,o,I,g);D+=Q,B=50*(1-2*Q/o)+"%",a=void 0}else{if("top"!==A&&"bottom"!==A)throw new Error('calcOverlayPosition(): No such placement of "'+A+'" found.');c=T.left+(T.width-C)/2,D="top"===A?T.top-o:T.top+T.height;var r=i(c,C,I,g);c+=r,a=50*(1-2*r/C)+"%",B=void 0}return{positionLeft:c,positionTop:D,arrowOffsetLeft:a,arrowOffsetTop:B}}Object.defineProperty(M,"__esModule",{value:!0}),M.default=T;var E=t(141),N=I(E),o=t(286),n=I(o),C=t(142),c=I(C),D=t(52),a=I(D);A.exports=M.default},function(A,M){"use strict";function t(A,M){M&&(A?M.setAttribute("aria-hidden","true"):M.removeAttribute("aria-hidden"))}function I(A,M){T(A,M,function(A){return t(!0,A)})}function g(A,M){T(A,M,function(A){return t(!1,A)})}Object.defineProperty(M,"__esModule",{value:!0}),M.ariaHidden=t,M.hideSiblings=I,M.showSiblings=g;var e=["template","script","style"],i=function(A){var M=A.nodeType,t=A.tagName;return 1===M&&e.indexOf(t.toLowerCase())===-1},T=function(A,M,t){M=[].concat(M),[].forEach.call(A.children,function(A){M.indexOf(A)===-1&&i(A)&&t(A)})}},function(A,M,t){"use strict";var I=function(){};A.exports=I},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){return function(t,I,g){if(null!=t[I]){var e='"'+I+'" property of "'+g+'" has been deprecated.\n'+M;E[e]||(T.default(!1,e),E[e]=!0)}return A(t,I,g)}}function e(){E={}}M.__esModule=!0,M.default=g;var i=t(127),T=I(i),E={};g._resetWarned=e,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function e(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function i(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}M.__esModule=!0,M.default=void 0;var T=t(1),E=t(182),N=I(E),o=t(183),n=(I(o),function(A){function M(t,I){g(this,M);var i=e(this,A.call(this,t,I));return i.store=t.store,i}return i(M,A),M.prototype.getChildContext=function(){return{store:this.store}},M.prototype.render=function(){return T.Children.only(this.props.children)},M}(T.Component));M.default=n,n.propTypes={store:N.default.isRequired,children:T.PropTypes.element.isRequired},n.childContextTypes={store:N.default.isRequired}},function(A,M){"use strict";function t(A,M){if(A===M)return!0;var t=Object.keys(A),I=Object.keys(M);if(t.length!==I.length)return!1;for(var g=Object.prototype.hasOwnProperty,e=0;e=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A,M){var t=A.history,I=A.routes,e=A.location,E=g(A,["history","routes","location"]);t||e?void 0:(0,N.default)(!1),t=t?t:(0,n.default)(E);var o=(0,c.default)(t,(0,D.createRoutes)(I)),C=void 0;e?e=t.createLocation(e):C=t.listen(function(A){e=A});var B=(0,a.createRouterObject)(t,o);t=(0,a.createRoutingHistory)(t,o),o.match(e,function(A,I,g){M(A,I&&B.createLocation(I,T.REPLACE),g&&i({},g,{history:t,router:B,matchContext:{history:t,transitionManager:o,router:B}})),C&&C()})}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return function(){var M=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],t=M.routes,I=g(M,["routes"]),e=(0,E.default)(A)(I),T=(0,o.default)(e,t);return i({},e,T)}}M.__esModule=!0;var i=Object.assign||function(A){for(var M=1;M=A&&N&&(T=!0,t()))}}var i=0,T=!1,E=!1,N=!1,o=void 0;e()}M.__esModule=!0;var I=Array.prototype.slice;M.loopAsync=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){function A(A){try{A=A||window.history.state||{}}catch(M){A={}}var M=n.getWindowPath(),t=A,I=t.key,g=void 0;I?g=C.readState(I):(g=null,I=s.createKey(),Q&&window.history.replaceState(e({},A,{key:I}),null));var i=N.parsePath(M);return s.createLocation(e({},i,{state:g}),void 0,I)}function M(M){function t(M){void 0!==M.state&&I(A(M.state))}var I=M.transitionTo;return n.addEventListener(window,"popstate",t),function(){n.removeEventListener(window,"popstate",t)}}function t(A){var M=A.basename,t=A.pathname,I=A.search,g=A.hash,e=A.state,i=A.action,T=A.key;if(i!==E.POP){C.saveState(T,e);var N=(M||"")+t+I+g,o={key:T};if(i===E.PUSH){if(r)return window.location.href=N,!1;window.history.pushState(o,null,N)}else{if(r)return window.location.replace(N),!1;window.history.replaceState(o,null,N)}}}function I(A){1===++x&&(j=M(s));var t=s.listenBefore(A);return function(){t(),0===--x&&j()}}function g(A){1===++x&&(j=M(s));var t=s.listen(A);return function(){t(),0===--x&&j()}}function i(A){1===++x&&(j=M(s)),s.registerTransitionHook(A)}function c(A){s.unregisterTransitionHook(A),0===--x&&j()}var a=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];o.canUseDOM?void 0:T.default(!1);var B=a.forceRefresh,Q=n.supportsHistory(),r=!Q||B,s=D.default(e({},a,{getCurrentLocation:A,finishTransition:t,saveState:C.saveState})),x=0,j=void 0;return e({},s,{listenBefore:I,listen:g,registerTransitionHook:i,unregisterTransitionHook:c})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M=0&&M=0&&B8&&u<=11),L=32,Y=String.fromCharCode(L),d=c.topLevelTypes,h={beforeInput:{phasedRegistrationNames:{bubbled:s({onBeforeInput:null}),captured:s({onBeforeInputCapture:null})},dependencies:[d.topCompositionEnd,d.topKeyPress,d.topTextInput,d.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:s({onCompositionEnd:null}),captured:s({onCompositionEndCapture:null})},dependencies:[d.topBlur,d.topCompositionEnd,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:s({onCompositionStart:null}),captured:s({onCompositionStartCapture:null})},dependencies:[d.topBlur,d.topCompositionStart,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:s({onCompositionUpdate:null}),captured:s({onCompositionUpdateCapture:null})},dependencies:[d.topBlur,d.topCompositionUpdate,d.topKeyDown,d.topKeyPress,d.topKeyUp,d.topMouseDown]}},S=!1,z=null,p={eventTypes:h,extractEvents:function(A,M,t,I,g){return[N(A,M,t,I,g),C(A,M,t,I,g)]}};A.exports=p},function(A,M,t){"use strict";var I=t(200),g=t(10),e=t(17),i=(t(296),t(475)),T=t(301),E=t(305),N=(t(3),E(function(A){return T(A)})),o=!1,n="cssFloat";if(g.canUseDOM){var C=document.createElement("div").style;try{C.font=""}catch(A){o=!0}void 0===document.documentElement.style.cssFloat&&(n="styleFloat")}var c={createMarkupForStyles:function(A){var M="";for(var t in A)if(A.hasOwnProperty(t)){var I=A[t];null!=I&&(M+=N(t)+":",M+=i(t,I)+";")}return M||null},setValueForStyles:function(A,M){var t=A.style;for(var g in M)if(M.hasOwnProperty(g)){var e=i(g,M[g]);if("float"===g&&(g=n),e)t[g]=e;else{var T=o&&I.shorthandPropertyExpansions[g];if(T)for(var E in T)t[E]="";else t[g]=""}}}};e.measureMethods(c,"CSSPropertyOperations",{setValueForStyles:"setValueForStyles"}),A.exports=c},function(A,M,t){"use strict";function I(A){var M=A.nodeName&&A.nodeName.toLowerCase();return"select"===M||"input"===M&&"file"===A.type}function g(A){var M=u.getPooled(h.change,z,A,w(A));x.accumulateTwoPhaseDispatches(M),y.batchedUpdates(e,M)}function e(A){s.enqueueEvents(A),s.processEventQueue(!1)}function i(A,M){S=A,z=M,S.attachEvent("onchange",g)}function T(){S&&(S.detachEvent("onchange",g),S=null,z=null)}function E(A,M,t){if(A===d.topChange)return t}function N(A,M,t){A===d.topFocus?(T(),i(M,t)):A===d.topBlur&&T()}function o(A,M){S=A,z=M,p=A.value,U=Object.getOwnPropertyDescriptor(A.constructor.prototype,"value"),Object.defineProperty(S,"value",F),S.attachEvent("onpropertychange",C)}function n(){S&&(delete S.value,S.detachEvent("onpropertychange",C),S=null,z=null,p=null,U=null)}function C(A){if("value"===A.propertyName){var M=A.srcElement.value;M!==p&&(p=M,g(A))}}function c(A,M,t){if(A===d.topInput)return t}function D(A,M,t){A===d.topFocus?(n(),o(M,t)):A===d.topBlur&&n()}function a(A,M,t){if((A===d.topSelectionChange||A===d.topKeyUp||A===d.topKeyDown)&&S&&S.value!==p)return p=S.value,z}function B(A){return A.nodeName&&"input"===A.nodeName.toLowerCase()&&("checkbox"===A.type||"radio"===A.type)}function Q(A,M,t){if(A===d.topClick)return t}var r=t(24),s=t(53),x=t(54),j=t(10),y=t(18),u=t(37),w=t(117),l=t(120),L=t(227),Y=t(27),d=r.topLevelTypes,h={change:{phasedRegistrationNames:{bubbled:Y({onChange:null}),captured:Y({onChangeCapture:null})},dependencies:[d.topBlur,d.topChange,d.topClick,d.topFocus,d.topInput,d.topKeyDown,d.topKeyUp,d.topSelectionChange]}},S=null,z=null,p=null,U=null,O=!1;j.canUseDOM&&(O=l("change")&&(!("documentMode"in document)||document.documentMode>8));var m=!1;j.canUseDOM&&(m=l("input")&&(!("documentMode"in document)||document.documentMode>9));var F={get:function(){return U.get.call(this)},set:function(A){p=""+A,U.set.call(this,A)}},f={eventTypes:h,extractEvents:function(A,M,t,g,e){var i,T;if(I(M)?O?i=E:T=N:L(M)?m?i=c:(i=a,T=D):B(M)&&(i=Q),i){var o=i(A,M,t);if(o){var n=u.getPooled(h.change,o,g,e);return n.type="change",x.accumulateTwoPhaseDispatches(n),n}}T&&T(A,M,t)}};A.exports=f},function(A,M){"use strict";var t=0,I={createReactRootIndex:function(){return t++}};A.exports=I},function(A,M,t){"use strict";function I(A){return A.substring(1,A.indexOf(" "))}var g=t(10),e=t(298),i=t(20),T=t(149),E=t(2),N=/^(<[^ \/>]+)/,o="data-danger-index",n={dangerouslyRenderMarkup:function(A){g.canUseDOM?void 0:E(!1);for(var M,t={},n=0;n1?1-M:void 0;return this._fallbackText=g.slice(A,T),this._fallbackText}}),g.addPoolingTo(I),A.exports=I},function(A,M,t){"use strict";var I,g=t(47),e=t(10),i=g.injection.MUST_USE_ATTRIBUTE,T=g.injection.MUST_USE_PROPERTY,E=g.injection.HAS_BOOLEAN_VALUE,N=g.injection.HAS_SIDE_EFFECTS,o=g.injection.HAS_NUMERIC_VALUE,n=g.injection.HAS_POSITIVE_NUMERIC_VALUE,C=g.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(e.canUseDOM){var c=document.implementation;I=c&&c.hasFeature&&c.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var D={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:i|E,allowTransparency:i,alt:null,async:E,autoComplete:null,autoPlay:E,capture:i|E,cellPadding:null,cellSpacing:null,charSet:i,challenge:i,checked:T|E,classID:i,className:I?i:T,cols:i|n,colSpan:null,content:null,contentEditable:null,contextMenu:i,controls:T|E,coords:null,crossOrigin:null,data:null,dateTime:i,default:E,defer:E,dir:null,disabled:i|E,download:C,draggable:null,encType:null,form:i,formAction:i,formEncType:i,formMethod:i,formNoValidate:E,formTarget:i,frameBorder:i,headers:null,height:i,hidden:i|E,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:T,inputMode:i,integrity:null,is:i,keyParams:i,keyType:i,kind:null,label:null,lang:null,list:i,loop:T|E,low:null,manifest:i,marginHeight:null,marginWidth:null,max:null,maxLength:i,media:i,mediaGroup:null,method:null,min:null,minLength:i,multiple:T|E,muted:T|E,name:null,nonce:i,noValidate:E,open:E,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:T|E,rel:null,required:E,reversed:E,role:i,rows:i|n,rowSpan:null,sandbox:null,scope:null,scoped:E,scrolling:null,seamless:i|E,selected:T|E,shape:null,size:i|n,sizes:i,span:n,spellCheck:null,src:null,srcDoc:T,srcLang:null,srcSet:i,start:o,step:null,style:null,summary:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:T|N,width:i,wmode:i,wrap:null,about:i,datatype:i,inlist:i,prefix:i,property:i,resource:i,typeof:i,vocab:i,autoCapitalize:i,autoCorrect:i,autoSave:null,color:null,itemProp:i,itemScope:i|E,itemType:i,itemID:i,itemRef:i,results:null,security:i,unselectable:i},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",autoSave:"autosave",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};A.exports=D},function(A,M,t){"use strict";var I=t(206),g=t(449),e=t(454),i=t(4),T=t(476),E={};i(E,e),i(E,{findDOMNode:T("findDOMNode","ReactDOM","react-dom",I,I.findDOMNode),render:T("render","ReactDOM","react-dom",I,I.render),unmountComponentAtNode:T("unmountComponentAtNode","ReactDOM","react-dom",I,I.unmountComponentAtNode),renderToString:T("renderToString","ReactDOMServer","react-dom/server",g,g.renderToString),renderToStaticMarkup:T("renderToStaticMarkup","ReactDOMServer","react-dom/server",g,g.renderToStaticMarkup)}),E.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=I,E.__SECRET_DOM_SERVER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=g,A.exports=E},function(A,M,t){"use strict";var I=(t(55),t(114)),g=(t(3),"_getDOMNodeDidWarn"),e={getDOMNode:function(){return this.constructor[g]=!0,I(this)}};A.exports=e},function(A,M,t){"use strict";function I(A,M,t){var I=void 0===A[t];null!=M&&I&&(A[t]=e(M,null))}var g=t(36),e=t(119),i=t(122),T=t(123),E=(t(3),{instantiateChildren:function(A,M,t){if(null==A)return null;var g={};return T(A,I,g),g},updateChildren:function(A,M,t,I){if(!M&&!A)return null;var T;for(T in M)if(M.hasOwnProperty(T)){var E=A&&A[T],N=E&&E._currentElement,o=M[T];if(null!=E&&i(N,o))g.receiveComponent(E,o,t,I),M[T]=E;else{E&&g.unmountComponent(E,T);var n=e(o,null);M[T]=n}}for(T in A)!A.hasOwnProperty(T)||M&&M.hasOwnProperty(T)||g.unmountComponent(A[T]);return M},unmountChildren:function(A){for(var M in A)if(A.hasOwnProperty(M)){var t=A[M];g.unmountComponent(t)}}});A.exports=E},function(A,M,t){"use strict";function I(A){var M=A._currentElement._owner||null;if(M){var t=M.getName();if(t)return" Check the render method of ` + "`" + `"+t+"` + "`" + `."}return""}function g(A){}var e=t(110),i=t(25),T=t(13),E=t(55),N=t(17),o=t(71),n=(t(70),t(36)),C=t(112),c=t(4),D=t(50),a=t(2),B=t(122);t(3);g.prototype.render=function(){var A=E.get(this)._currentElement.type;return A(this.props,this.context,this.updater)};var Q=1,r={construct:function(A){this._currentElement=A,this._rootNodeID=null,this._instance=null,this._pendingElement=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._renderedComponent=null,this._context=null,this._mountOrder=0,this._topLevelWrapper=null,this._pendingCallbacks=null},mountComponent:function(A,M,t){this._context=t,this._mountOrder=Q++,this._rootNodeID=A;var I,e,i=this._processProps(this._currentElement.props),N=this._processContext(t),o=this._currentElement.type,c="prototype"in o;c&&(I=new o(i,N,C)),c&&null!==I&&I!==!1&&!T.isValidElement(I)||(e=I,I=new g(o)),I.props=i,I.context=N,I.refs=D,I.updater=C,this._instance=I,E.set(I,this);var B=I.state;void 0===B&&(I.state=B=null),"object"!=typeof B||Array.isArray(B)?a(!1):void 0,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,I.componentWillMount&&(I.componentWillMount(),this._pendingStateQueue&&(I.state=this._processPendingState(I.props,I.context))),void 0===e&&(e=this._renderValidatedComponent()),this._renderedComponent=this._instantiateReactComponent(e);var r=n.mountComponent(this._renderedComponent,A,M,this._processChildContext(t));return I.componentDidMount&&M.getReactMountReady().enqueue(I.componentDidMount,I),r},unmountComponent:function(){var A=this._instance;A.componentWillUnmount&&A.componentWillUnmount(),n.unmountComponent(this._renderedComponent),this._renderedComponent=null,this._instance=null,this._pendingStateQueue=null,this._pendingReplaceState=!1,this._pendingForceUpdate=!1,this._pendingCallbacks=null,this._pendingElement=null,this._context=null,this._rootNodeID=null,this._topLevelWrapper=null,E.remove(A)},_maskContext:function(A){var M=null,t=this._currentElement.type,I=t.contextTypes;if(!I)return D;M={};for(var g in I)M[g]=A[g];return M},_processContext:function(A){var M=this._maskContext(A);return M},_processChildContext:function(A){var M=this._currentElement.type,t=this._instance,I=t.getChildContext&&t.getChildContext();if(I){"object"!=typeof M.childContextTypes?a(!1):void 0;for(var g in I)g in M.childContextTypes?void 0:a(!1);return c({},A,I)}return A},_processProps:function(A){return A},_checkPropTypes:function(A,M,t){var g=this.getName();for(var e in A)if(A.hasOwnProperty(e)){var i;try{"function"!=typeof A[e]?a(!1):void 0,i=A[e](M,e,g,t)}catch(A){i=A}if(i instanceof Error){I(this);t===o.prop}}},receiveComponent:function(A,M,t){var I=this._currentElement,g=this._context;this._pendingElement=null,this.updateComponent(M,I,A,g,t)},performUpdateIfNecessary:function(A){null!=this._pendingElement&&n.receiveComponent(this,this._pendingElement||this._currentElement,A,this._context),(null!==this._pendingStateQueue||this._pendingForceUpdate)&&this.updateComponent(A,this._currentElement,this._currentElement,this._context,this._context)},updateComponent:function(A,M,t,I,g){var e,i=this._instance,T=this._context===g?i.context:this._processContext(g);M===t?e=t.props:(e=this._processProps(t.props),i.componentWillReceiveProps&&i.componentWillReceiveProps(e,T));var E=this._processPendingState(e,T),N=this._pendingForceUpdate||!i.shouldComponentUpdate||i.shouldComponentUpdate(e,E,T);N?(this._pendingForceUpdate=!1,this._performComponentUpdate(t,e,E,T,A,g)):(this._currentElement=t,this._context=g,i.props=e,i.state=E,i.context=T)},_processPendingState:function(A,M){var t=this._instance,I=this._pendingStateQueue,g=this._pendingReplaceState;if(this._pendingReplaceState=!1,this._pendingStateQueue=null,!I)return t.state;if(g&&1===I.length)return I[0];for(var e=c({},g?I[0]:t.state),i=g?1:0;i=0||null!=M.is}function B(A){D(A),this._tag=A.toLowerCase(),this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._rootNodeID=null,this._wrapperState=null,this._topLevelWrapper=null,this._nodeWithLegacyProperties=null}var Q=t(428),r=t(430),s=t(47),x=t(107),j=t(24),y=t(69),u=t(109),w=t(443),l=t(446),L=t(447),Y=t(208),d=t(450),h=t(12),S=t(455),z=t(17),p=t(112),U=t(4),O=t(74),m=t(75),F=t(2),f=(t(120),t(27)),k=t(76),R=t(121),J=(t(150),t(124),t(3),y.deleteListener),G=y.listenTo,H=y.registrationNameModules,b={string:!0,number:!0},v=f({children:null}),X=f({style:null}),W=f({__html:null}),V=1,P={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"},Z={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},K={listing:!0,pre:!0,textarea:!0},q=(U({menuitem:!0},Z),/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/),_={},$={}.hasOwnProperty;B.displayName="ReactDOMComponent",B.Mixin={construct:function(A){this._currentElement=A},mountComponent:function(A,M,t){this._rootNodeID=A;var I=this._currentElement.props;switch(this._tag){case"iframe":case"img":case"form":case"video":case"audio":this._wrapperState={listeners:null},M.getReactMountReady().enqueue(n,this);break;case"button":I=w.getNativeProps(this,I,t);break;case"input":l.mountWrapper(this,I,t),I=l.getNativeProps(this,I,t);break;case"option":L.mountWrapper(this,I,t),I=L.getNativeProps(this,I,t);break;case"select":Y.mountWrapper(this,I,t),I=Y.getNativeProps(this,I,t),t=Y.processChildContext(this,I,t);break;case"textarea":d.mountWrapper(this,I,t),I=d.getNativeProps(this,I,t)}E(this,I);var g;if(M.useCreateElement){var e=t[h.ownerDocumentContextKey],i=e.createElement(this._currentElement.type);x.setAttributeForID(i,this._rootNodeID),h.getID(i),this._updateDOMProperties({},I,M,i),this._createInitialChildren(M,I,t,i),g=i}else{var T=this._createOpenTagMarkupAndPutListeners(M,I),N=this._createContentMarkup(M,I,t);g=!N&&Z[this._tag]?T+"/>":T+">"+N+""}switch(this._tag){case"input":M.getReactMountReady().enqueue(C,this);case"button":case"select":case"textarea":I.autoFocus&&M.getReactMountReady().enqueue(Q.focusDOMComponent,this)}return g},_createOpenTagMarkupAndPutListeners:function(A,M){var t="<"+this._currentElement.type;for(var I in M)if(M.hasOwnProperty(I)){var g=M[I];if(null!=g)if(H.hasOwnProperty(I))g&&N(this._rootNodeID,I,g,A);else{I===X&&(g&&(g=this._previousStyleCopy=U({},M.style)),g=r.createMarkupForStyles(g));var e=null;null!=this._tag&&a(this._tag,M)?I!==v&&(e=x.createMarkupForCustomAttribute(I,g)):e=x.createMarkupForProperty(I,g),e&&(t+=" "+e)}}if(A.renderToStaticMarkup)return t;var i=x.createMarkupForID(this._rootNodeID);return t+" "+i},_createContentMarkup:function(A,M,t){var I="",g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&(I=g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)I=m(e);else if(null!=i){var T=this.mountChildren(i,A,t);I=T.join("")}}return K[this._tag]&&"\n"===I.charAt(0)?"\n"+I:I},_createInitialChildren:function(A,M,t,I){var g=M.dangerouslySetInnerHTML;if(null!=g)null!=g.__html&&k(I,g.__html);else{var e=b[typeof M.children]?M.children:null,i=null!=e?null:M.children;if(null!=e)R(I,e);else if(null!=i)for(var T=this.mountChildren(i,A,t),E=0;EM.end?(t=M.end,I=M.start):(t=M.start,I=M.end),g.moveToElementText(A),g.moveStart("character",t),g.setEndPoint("EndToStart",g),g.moveEnd("character",I-t),g.select()}function T(A,M){if(window.getSelection){var t=window.getSelection(),I=A[o()].length,g=Math.min(M.start,I),e="undefined"==typeof M.end?g:Math.min(M.end,I);if(!t.extend&&g>e){var i=e;e=g,g=i}var T=N(A,g),E=N(A,e);if(T&&E){var n=document.createRange();n.setStart(T.node,T.offset),t.removeAllRanges(),g>e?(t.addRange(n),t.extend(E.node,E.offset)):(n.setEnd(E.node,E.offset),t.addRange(n))}}}var E=t(10),N=t(479),o=t(226),n=E.canUseDOM&&"selection"in document&&!("getSelection"in window),C={getOffsets:n?g:e,setOffsets:n?i:T};A.exports=C},function(A,M,t){"use strict";var I=t(211),g=t(460),e=t(113);I.inject();var i={renderToString:g.renderToString,renderToStaticMarkup:g.renderToStaticMarkup,version:e};A.exports=i},function(A,M,t){"use strict";function I(){this._rootNodeID&&o.updateWrapper(this)}function g(A){var M=this._currentElement.props,t=e.executeOnChange(M,A);return T.asap(I,this),t}var e=t(108),i=t(111),T=t(18),E=t(4),N=t(2),o=(t(3),{getNativeProps:function(A,M,t){null!=M.dangerouslySetInnerHTML?N(!1):void 0;var I=E({},M,{defaultValue:void 0,value:void 0,children:A._wrapperState.initialValue,onChange:A._wrapperState.onChange});return I},mountWrapper:function(A,M){var t=M.defaultValue,I=M.children;null!=I&&(null!=t?N(!1):void 0,Array.isArray(I)&&(I.length<=1?void 0:N(!1),I=I[0]),t=""+I),null==t&&(t="");var i=e.getValue(M);A._wrapperState={initialValue:""+(null!=i?i:t),onChange:g.bind(A)}},updateWrapper:function(A){var M=A._currentElement.props,t=e.getValue(M);null!=t&&i.updatePropertyByID(A._rootNodeID,"value",""+t)}});A.exports=o},function(A,M,t){"use strict";function I(A){g.enqueueEvents(A),g.processEventQueue(!1)}var g=t(53),e={handleTopLevel:function(A,M,t,e,i){var T=g.extractEvents(A,M,t,e,i);I(T)}};A.exports=e},function(A,M,t){"use strict";function I(A){var M=C.getID(A),t=n.getReactRootIDFromNodeID(M),I=C.findReactContainerForID(t),g=C.getFirstReactDOM(I);return g}function g(A,M){this.topLevelType=A,this.nativeEvent=M,this.ancestors=[]}function e(A){i(A)}function i(A){for(var M=C.getFirstReactDOM(a(A.nativeEvent))||window,t=M;t;)A.ancestors.push(t),t=I(t);for(var g=0;g=M)return{node:g,offset:M-e};e=i}g=t(I(g))}}A.exports=g},function(A,M,t){"use strict";function I(A){return g.isValidElement(A)?void 0:e(!1),A}var g=t(13),e=t(2);A.exports=I},function(A,M,t){"use strict";function I(A){return'"'+g(A)+'"'}var g=t(75);A.exports=I},function(A,M,t){"use strict";var I=t(12);A.exports=I.renderSubtreeIntoContainer},function(A,M){A.exports=function(A,M,t){for(var I=0,g=A.length,e=3==arguments.length?t:A[I++];I=400){ +var T="cannot "+M.method+" "+M.url+" ("+i.status+")";A=new e(T),A.status=i.status,A.body=i.body,A.res=i,I(A)}else g?I(new e(g)):t(i)})})},g.prototype.then=function(){var A=this.promise();return A.then.apply(A,arguments)}},function(A,M,t){function I(){}function g(A){var M={}.toString.call(A);switch(M){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function e(A){if(!s(A))return A;var M=[];for(var t in A)null!=A[t]&&i(M,t,A[t]);return M.join("&")}function i(A,M,t){return Array.isArray(t)?t.forEach(function(t){i(A,M,t)}):void A.push(encodeURIComponent(M)+"="+encodeURIComponent(t))}function T(A){for(var M,t,I={},g=A.split("&"),e=0,i=g.length;e=200&&M.status<300)return t.callback(A,M);var I=new Error(M.statusText||"Unsuccessful HTTP response");I.original=A,I.response=M,I.status=M.status,t.callback(I,M)})}function D(A,M){var t=x("DELETE",A);return M&&t.end(M),t}var a,B=t(272),Q=t(483),r=t(501),s=t(234);a="undefined"!=typeof window?window:"undefined"!=typeof self?self:this;var x=A.exports=t(502).bind(null,c);x.getXHR=function(){if(!(!a.XMLHttpRequest||a.location&&"file:"==a.location.protocol&&a.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(A){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(A){}return!1};var j="".trim?function(A){return A.trim()}:function(A){return A.replace(/(^\s*|\s*$)/g,"")};x.serializeObject=e,x.parseString=T,x.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},x.serialize={"application/x-www-form-urlencoded":e,"application/json":JSON.stringify},x.parse={"application/x-www-form-urlencoded":T,"application/json":JSON.parse},C.prototype.get=function(A){return this.header[A.toLowerCase()]},C.prototype.setHeaderProperties=function(A){var M=this.header["content-type"]||"";this.type=o(M);var t=n(M);for(var I in t)this[I]=t[I]},C.prototype.parseBody=function(A){var M=x.parse[this.type];return!M&&N(this.type)&&(M=x.parse["application/json"]),M&&A&&(A.length||A instanceof Object)?M(A):null},C.prototype.setStatusProperties=function(A){1223===A&&(A=204);var M=A/100|0;this.status=this.statusCode=A,this.statusType=M,this.info=1==M,this.ok=2==M,this.clientError=4==M,this.serverError=5==M,this.error=(4==M||5==M)&&this.toError(),this.accepted=202==A,this.noContent=204==A,this.badRequest=400==A,this.unauthorized=401==A,this.notAcceptable=406==A,this.notFound=404==A,this.forbidden=403==A},C.prototype.toError=function(){var A=this.req,M=A.method,t=A.url,I="cannot "+M+" "+t+" ("+this.status+")",g=new Error(I);return g.status=this.status,g.method=M,g.url=t,g},x.Response=C,B(c.prototype);for(var y in r)c.prototype[y]=r[y];c.prototype.abort=function(){if(!this.aborted)return this.aborted=!0,this.xhr&&this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this},c.prototype.type=function(A){return this.set("Content-Type",x.types[A]||A),this},c.prototype.responseType=function(A){return this._responseType=A,this},c.prototype.accept=function(A){return this.set("Accept",x.types[A]||A),this},c.prototype.auth=function(A,M,t){switch(t||(t={type:"basic"}),t.type){case"basic":var I=btoa(A+":"+M);this.set("Authorization","Basic "+I);break;case"auto":this.username=A,this.password=M}return this},c.prototype.query=function(A){return"string"!=typeof A&&(A=e(A)),A&&this._query.push(A),this},c.prototype.attach=function(A,M,t){return this._getFormData().append(A,M,t||M.name),this},c.prototype._getFormData=function(){return this._formData||(this._formData=new a.FormData),this._formData},c.prototype.send=function(A){var M=s(A),t=this._header["content-type"];if(M&&s(this._data))for(var I in A)this._data[I]=A[I];else"string"==typeof A?(t||this.type("form"),t=this._header["content-type"],"application/x-www-form-urlencoded"==t?this._data=this._data?this._data+"&"+A:A:this._data=(this._data||"")+A):this._data=A;return!M||g(A)?this:(t||this.type("json"),this)},C.prototype.parse=function(A){return a.console&&console.warn("Client-side parse() method has been renamed to serialize(). This method is not compatible with superagent v2.0"),this.serialize(A),this},C.prototype.serialize=function(A){return this._parser=A,this},c.prototype.callback=function(A,M){var t=this._callback;this.clearTimeout(),t(A,M)},c.prototype.crossDomainError=function(){var A=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");A.crossDomain=!0,A.status=this.status,A.method=this.method,A.url=this.url,this.callback(A)},c.prototype.timeoutError=function(){var A=this._timeout,M=new Error("timeout of "+A+"ms exceeded");M.timeout=A,this.callback(M)},c.prototype.withCredentials=function(){return this._withCredentials=!0,this},c.prototype.end=function(A){var M=this,t=this.xhr=x.getXHR(),e=this._query.join("&"),i=this._timeout,T=this._formData||this._data;this._callback=A||I,t.onreadystatechange=function(){if(4==t.readyState){var A;try{A=t.status}catch(M){A=0}if(0==A){if(M.timedout)return M.timeoutError();if(M.aborted)return;return M.crossDomainError()}M.emit("end")}};var E=function(A){A.total>0&&(A.percent=A.loaded/A.total*100),A.direction="download",M.emit("progress",A)};this.hasListeners("progress")&&(t.onprogress=E);try{t.upload&&this.hasListeners("progress")&&(t.upload.onprogress=E)}catch(A){}if(i&&!this._timer&&(this._timer=setTimeout(function(){M.timedout=!0,M.abort()},i)),e&&(e=x.serializeObject(e),this.url+=~this.url.indexOf("?")?"&"+e:"?"+e),this.username&&this.password?t.open(this.method,this.url,!0,this.username,this.password):t.open(this.method,this.url,!0),this._withCredentials&&(t.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof T&&!g(T)){var o=this._header["content-type"],n=this._parser||x.serialize[o?o.split(";")[0]:""];!n&&N(o)&&(n=x.serialize["application/json"]),n&&(T=n(T))}for(var C in this.header)null!=this.header[C]&&t.setRequestHeader(C,this.header[C]);return this._responseType&&(t.responseType=this._responseType),this.emit("request",this),t.send("undefined"!=typeof T?T:null),this},x.Request=c,x.get=function(A,M,t){var I=x("GET",A);return"function"==typeof M&&(t=M,M=null),M&&I.query(M),t&&I.end(t),I},x.head=function(A,M,t){var I=x("HEAD",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.del=D,x.delete=D,x.patch=function(A,M,t){var I=x("PATCH",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.post=function(A,M,t){var I=x("POST",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I},x.put=function(A,M,t){var I=x("PUT",A);return"function"==typeof M&&(t=M,M=null),M&&I.send(M),t&&I.end(t),I}},function(A,M,t){var I=t(234);M.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},M.parse=function(A){return this._parser=A,this},M.timeout=function(A){return this._timeout=A,this},M.then=function(A,M){return this.end(function(t,I){t?M(t):A(I)})},M.use=function(A){return A(this),this},M.get=function(A){return this._header[A.toLowerCase()]},M.getHeader=M.get,M.set=function(A,M){if(I(A)){for(var t in A)this.set(t,A[t]);return this}return this._header[A.toLowerCase()]=M,this.header[A]=M,this},M.unset=function(A){return delete this._header[A.toLowerCase()],delete this.header[A],this},M.field=function(A,M){return this._getFormData().append(A,M),this}},function(A,M){function t(A,M,t){return"function"==typeof t?new A("GET",M).end(t):2==arguments.length?new A("GET",M):new A(M,t)}A.exports=t},function(A,M,t){A.exports=t(504)},function(A,M,t){(function(A,I){"use strict";function g(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var e,i=t(505),T=g(i);e="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof A?A:I;var E=(0,T.default)(e);M.default=E}).call(M,function(){return this}(),t(128)(A))},function(A,M){"use strict";function t(A){var M,t=A.Symbol;return"function"==typeof t?t.observable?M=t.observable:(M=t("observable"),t.observable=M):M="@@observable",M}Object.defineProperty(M,"__esModule",{value:!0}),M.default=t},function(A,M,t){function I(A){return g(A).replace(/\s(\w)/g,function(A,M){return M.toUpperCase()})}var g=t(508);A.exports=I},function(A,M){function t(A){return e.test(A)?A.toLowerCase():i.test(A)?(I(A)||A).toLowerCase():T.test(A)?g(A).toLowerCase():A.toLowerCase()}function I(A){return A.replace(E,function(A,M){return M?" "+M:""})}function g(A){return A.replace(N,function(A,M,t){return M+" "+t.toLowerCase().split("").join(" ")})}A.exports=t;var e=/\s/,i=/(_|-|\.|:)/,T=/([a-z][A-Z]|[A-Z][a-z])/,E=/[\W_]+(.|$)/g,N=/(.)([A-Z]+)/g},function(A,M,t){function I(A){return g(A).replace(/[\W_]+(.|$)/g,function(A,M){return M?" "+M:""}).trim()}var g=t(507);A.exports=I},function(A,M){A.exports=function(){var A=document.getSelection();if(!A.rangeCount)return function(){};for(var M=document.activeElement,t=[],I=0;I=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function i(A,M){function t(I,g){function i(A,t){var I=c.getLinkName(A),e=this.props[g[A]];I&&E(this.props,I)&&!e&&(e=this.props[I].requestChange);for(var i=arguments.length,T=Array(i>2?i-2:0),N=2;N=15||0===s[0]&&s[1]>=13?A:A.type}function T(A,M){var t=N(M);return t&&!E(A,M)&&E(A,t)?A[t].value:A[M]}function E(A,M){return void 0!==A[M]}function N(A){return"value"===A?"valueLink":"checked"===A?"checkedLink":null}function o(A){return"default"+A.charAt(0).toUpperCase()+A.substr(1)}function n(A,M,t){return function(){for(var I=arguments.length,g=Array(I),e=0;e1&&(I=t[0]+"@",A=t[1]),A=A.replace(z,".");var g=A.split("."),e=T(g,M).join(".");return I+e}function N(A){for(var M,t,I=[],g=0,e=A.length;g=55296&&M<=56319&&g65535&&(A-=65536,M+=m(A>>>10&1023|55296),A=56320|1023&A),M+=m(A)}).join("")}function n(A){return A-48<10?A-22:A-65<26?A-65:A-97<26?A-97:j}function C(A,M){return A+22+75*(A<26)-((0!=M)<<5)}function c(A,M,t){var I=0;for(A=t?O(A/l):A>>1,A+=O(A/M);A>U*u>>1;I+=j)A=O(A/U);return O(I+(U+1)*A/(A+w))}function D(A){var M,t,I,g,e,T,E,N,C,D,a=[],B=A.length,Q=0,r=Y,s=L;for(t=A.lastIndexOf(d),t<0&&(t=0),I=0;I=128&&i("not-basic"),a.push(A.charCodeAt(I));for(g=t>0?t+1:0;g=B&&i("invalid-input"),N=n(A.charCodeAt(g++)),(N>=j||N>O((x-Q)/T))&&i("overflow"),Q+=N*T,C=E<=s?y:E>=s+u?u:E-s,!(NO(x/D)&&i("overflow"),T*=D;M=a.length+1,s=c(Q-e,M,0==e),O(Q/M)>x-r&&i("overflow"),r+=O(Q/M),Q%=M,a.splice(Q++,0,r)}return o(a)}function a(A){var M,t,I,g,e,T,E,o,n,D,a,B,Q,r,s,w=[];for(A=N(A),B=A.length,M=Y,t=0,e=L,T=0;T=M&&aO((x-t)/Q)&&i("overflow"),t+=(E-M)*Q,M=E,T=0;Tx&&i("overflow"),a==M){for(o=t,n=j;D=n<=e?y:n>=e+u?u:n-e,!(o= 0x80 (not a basic code point)","invalid-input":"Invalid input"},U=j-y,O=Math.floor,m=String.fromCharCode;s={version:"1.3.2",ucs2:{decode:N,encode:o},decode:D,encode:a,toASCII:Q,toUnicode:B},I=function(){return s}.call(M,t,M,A),!(void 0!==I&&(A.exports=I))}(this)}).call(M,t(128)(A),function(){return this}())},function(A,M){"use strict";A.exports={isString:function(A){return"string"==typeof A},isObject:function(A){return"object"==typeof A&&null!==A},isNull:function(A){return null===A},isNullOrUndefined:function(A){return null==A}}}]);`) +},function(A,M,t){var I;(function(A,g){!function(e){function i(A){throw RangeError(p[A])}function T(A,M){for(var t=A.length,I=[];t--;)I[t]=M(A[t]);return I}function E(A,M){var t=A.split("@"),I="";t.length>1&&(I=t[0]+"@",A=t[1]),A=A.replace(z,".");var g=A.split("."),e=T(g,M).join(".");return I+e}function N(A){for(var M,t,I=[],g=0,e=A.length;g=55296&&M<=56319&&g65535&&(A-=65536,M+=m(A>>>10&1023|55296),A=56320|1023&A),M+=m(A)}).join("")}function n(A){return A-48<10?A-22:A-65<26?A-65:A-97<26?A-97:j}function C(A,M){return A+22+75*(A<26)-((0!=M)<<5)}function c(A,M,t){var I=0;for(A=t?O(A/l):A>>1,A+=O(A/M);A>U*u>>1;I+=j)A=O(A/U);return O(I+(U+1)*A/(A+w))}function D(A){var M,t,I,g,e,T,E,N,C,D,a=[],B=A.length,Q=0,r=Y,s=L;for(t=A.lastIndexOf(d),t<0&&(t=0),I=0;I=128&&i("not-basic"),a.push(A.charCodeAt(I));for(g=t>0?t+1:0;g=B&&i("invalid-input"),N=n(A.charCodeAt(g++)),(N>=j||N>O((x-Q)/T))&&i("overflow"),Q+=N*T,C=E<=s?y:E>=s+u?u:E-s,!(NO(x/D)&&i("overflow"),T*=D;M=a.length+1,s=c(Q-e,M,0==e),O(Q/M)>x-r&&i("overflow"),r+=O(Q/M),Q%=M,a.splice(Q++,0,r)}return o(a)}function a(A){var M,t,I,g,e,T,E,o,n,D,a,B,Q,r,s,w=[];for(A=N(A),B=A.length,M=Y,t=0,e=L,T=0;T=M&&aO((x-t)/Q)&&i("overflow"),t+=(E-M)*Q,M=E,T=0;Tx&&i("overflow"),a==M){for(o=t,n=j;D=n<=e?y:n>=e+u?u:n-e,!(o= 0x80 (not a basic code point)","invalid-input":"Invalid input"},U=j-y,O=Math.floor,m=String.fromCharCode;s={version:"1.3.2",ucs2:{decode:N,encode:o},decode:D,encode:a,toASCII:Q,toUnicode:B},I=function(){return s}.call(M,t,M,A),!(void 0!==I&&(A.exports=I))}(this)}).call(M,t(128)(A),function(){return this}())},function(A,M,t){"use strict";function I(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function g(A,M,t){if(A&&N.isObject(A)&&A instanceof I)return A;var g=new I;return g.parse(A,M,t),g}function e(A){return N.isString(A)&&(A=g(A)),A instanceof I?A.format():I.prototype.format.call(A)}function i(A,M){return g(A,!1,!0).resolve(M)}function T(A,M){return A?g(A,!1,!0).resolveObject(M):M}var E=t(524),N=t(526);M.parse=g,M.resolve=i,M.resolveObject=T,M.format=e,M.Url=I;var o=/^([a-z0-9.+-]+:)/i,n=/:[0-9]*$/,C=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,c=["<",">",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(359);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){"use strict";A.exports={isString:function(A){return"string"==typeof A},isObject:function(A){return"object"==typeof A&&null!==A},isNull:function(A){return null===A},isNullOrUndefined:function(A){return null==A}}}]);`) -func productionIndex_bundle20170309t221146zJsBytes() ([]byte, error) { - return _productionIndex_bundle20170309t221146zJs, nil +func productionIndex_bundle20170310t231226zJsBytes() ([]byte, error) { + return _productionIndex_bundle20170310t231226zJs, nil } -func productionIndex_bundle20170309t221146zJs() (*asset, error) { - bytes, err := productionIndex_bundle20170309t221146zJsBytes() +func productionIndex_bundle20170310t231226zJs() (*asset, error) { + bytes, err := productionIndex_bundle20170310t231226zJsBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "production/index_bundle-2017-03-09T22-11-46Z.js", size: 2283985, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/index_bundle-2017-03-10T23-12-26Z.js", size: 2283908, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -370,7 +370,7 @@ func productionLoaderCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -444,7 +444,7 @@ func productionLogoSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -461,7 +461,7 @@ func productionSafariPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1489097522, 0)} + info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -522,7 +522,7 @@ var _bindata = map[string]func() (*asset, error){ "production/favicon.ico": productionFaviconIco, "production/firefox.png": productionFirefoxPng, "production/index.html": productionIndexHTML, - "production/index_bundle-2017-03-09T22-11-46Z.js": productionIndex_bundle20170309t221146zJs, + "production/index_bundle-2017-03-10T23-12-26Z.js": productionIndex_bundle20170310t231226zJs, "production/loader.css": productionLoaderCss, "production/logo.svg": productionLogoSvg, "production/safari.png": productionSafariPng, @@ -574,7 +574,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "favicon.ico": {productionFaviconIco, map[string]*bintree{}}, "firefox.png": {productionFirefoxPng, map[string]*bintree{}}, "index.html": {productionIndexHTML, map[string]*bintree{}}, - "index_bundle-2017-03-09T22-11-46Z.js": {productionIndex_bundle20170309t221146zJs, map[string]*bintree{}}, + "index_bundle-2017-03-10T23-12-26Z.js": {productionIndex_bundle20170310t231226zJs, map[string]*bintree{}}, "loader.css": {productionLoaderCss, map[string]*bintree{}}, "logo.svg": {productionLogoSvg, map[string]*bintree{}}, "safari.png": {productionSafariPng, map[string]*bintree{}}, @@ -635,6 +635,6 @@ func assetFS() *assetfs.AssetFS { panic("unreachable") } -var UIReleaseTag = "RELEASE.2017-03-09T22-11-46Z" -var UICommitID = "d602495600970254a1f485a99dd1516b68dbc497" -var UIVersion = "2017-03-09T22:11:46Z" +var UIReleaseTag = "RELEASE.2017-03-10T23-12-26Z" +var UICommitID = "e77885d671070805edad89e0cc1d60525dc9a51c" +var UIVersion = "2017-03-10T23:12:26Z" From 5e0032e1651939f087bb01cc5555693fb9a25f70 Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Sat, 11 Mar 2017 13:41:07 +0530 Subject: [PATCH 78/94] Update links (#3886) --- docs/orchestration/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/orchestration/README.md b/docs/orchestration/README.md index 7ba563615..344658c8c 100644 --- a/docs/orchestration/README.md +++ b/docs/orchestration/README.md @@ -1,12 +1,12 @@ -# Minio on orchestration platforms [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) +# Minio Orchestration Platforms Deployment Quickstart Guide [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) Minio is a cloud-native application designed to scale in a sustainable manner in multi-tenant environments. Orchestration platforms provide perfect launchpad for Minio to scale. Below is the list of documented orchestration platforms for Minio server: | Orchestration platforms| |:---| -| [`Kubernetes`](https://raw.githubusercontent.com/minio/minio/master/docs/orchestration/kubernetes/README.md) | -| [`Docker Swarm`](https://raw.githubusercontent.com/minio/minio/master/docs/orchestration/docker-swarm/README.md) | -| [`DC/OS`](https://raw.githubusercontent.com/minio/minio/master/docs/orchestration/dcos/README.md) | +| [`Kubernetes`](https://github.com/minio/minio/blob/master/docs/orchestration/kubernetes/README.md) | +| [`Docker Swarm`](https://github.com/minio/minio/blob/master/docs/orchestration/docker-swarm/README.md) | +| [`DC/OS`](https://github.com/minio/minio/blob/master/docs/orchestration/dcos/README.md) | ## Why is Minio cloud-native? The term cloud-native revolves around the idea of applications deployed as micro services, that can be scaled well. Its not about just retrofitting monolithic applications onto modern container based compute environment. A cloud-native application is portable and resilient by design, and can scale horizontally by simply replicating. Modern orchestration platforms like DC/OS, Kubernetes and Swarm make replicating and managing containers in huge clusters easier than ever. From 9d53a646a1857ade06ba04000d85480bf6a16eea Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 11 Mar 2017 02:17:03 -0800 Subject: [PATCH 79/94] Simplify the title for orchestration and some words. (#3887) --- docs/orchestration/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/orchestration/README.md b/docs/orchestration/README.md index 344658c8c..b5a264579 100644 --- a/docs/orchestration/README.md +++ b/docs/orchestration/README.md @@ -1,15 +1,15 @@ -# Minio Orchestration Platforms Deployment Quickstart Guide [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) +# Minio Deployment Quickstart Guide [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) -Minio is a cloud-native application designed to scale in a sustainable manner in multi-tenant environments. Orchestration platforms provide perfect launchpad for Minio to scale. Below is the list of documented orchestration platforms for Minio server: +Minio is a cloud-native application designed to scale in a sustainable manner in multi-tenant environments. Orchestration platforms provide perfect launchpad for Minio to scale. Below is the list of Minio deployment documents for various orchestration platforms: | Orchestration platforms| |:---| -| [`Kubernetes`](https://github.com/minio/minio/blob/master/docs/orchestration/kubernetes/README.md) | -| [`Docker Swarm`](https://github.com/minio/minio/blob/master/docs/orchestration/docker-swarm/README.md) | -| [`DC/OS`](https://github.com/minio/minio/blob/master/docs/orchestration/dcos/README.md) | +| [`Docker Swarm`](http://docs.minio.io/docs/deploy-minio-on-docker-swarm) | +| [`Kubernetes`](http://docs.minio.io/docs/deploy-minio-on-kubernetes) | +| [`DC/OS`](http://docs.minio.io/docs/deploy-minio-on-dc-os) | ## Why is Minio cloud-native? -The term cloud-native revolves around the idea of applications deployed as micro services, that can be scaled well. Its not about just retrofitting monolithic applications onto modern container based compute environment. A cloud-native application is portable and resilient by design, and can scale horizontally by simply replicating. Modern orchestration platforms like DC/OS, Kubernetes and Swarm make replicating and managing containers in huge clusters easier than ever. +The term cloud-native revolves around the idea of applications deployed as micro services, that scale well. It is not about just retrofitting monolithic applications onto modern container based compute environment. A cloud-native application is portable and resilient by design, and can scale horizontally by simply replicating. Modern orchestration platforms like Swarm, Kubernetes and DC/OS make replicating and managing containers in huge clusters easier than ever. While containers provide isolated application execution environment, orchestration platforms allow seamless scaling by helping replicate and manage containers. Minio extends this by adding isolated storage environment for each tenant. @@ -17,6 +17,6 @@ Minio is built ground up on the cloud-native premise. With features like erasure > In a cloud-native environment, scalability is not a function of the application but the orchestration platform. -In a typical modern infrastructure deployment, application, Database, Key-store, etc. already live in containers and are managed by orchestration platforms. Minio brings robust, scalable, AWS S3 compatible object storage to the lot. +In a typical modern infrastructure deployment, application, database, key-store, etc. already live in containers and are managed by orchestration platforms. Minio brings robust, scalable, AWS S3 compatible object storage to the lot. ![Cloud-native](https://raw.githubusercontent.com/NitishT/minio/master/docs/screenshots/Minio_Cloud_Native_Arch.png?raw=true) From 3314501f1915482008295e85aeacf39ff351401b Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Mon, 13 Mar 2017 04:47:03 +0530 Subject: [PATCH 80/94] Simplify shared mode document (#3888) --- docs/shared-backend/README.md | 68 +++++++++++++---------------------- 1 file changed, 24 insertions(+), 44 deletions(-) diff --git a/docs/shared-backend/README.md b/docs/shared-backend/README.md index 26dc64f84..ee4e02b7d 100644 --- a/docs/shared-backend/README.md +++ b/docs/shared-backend/README.md @@ -1,76 +1,58 @@ # Shared Backend Minio Quickstart Guide [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) [![Go Report Card](https://goreportcard.com/badge/minio/minio)](https://goreportcard.com/report/minio/minio) [![Docker Pulls](https://img.shields.io/docker/pulls/minio/minio.svg?maxAge=604800)](https://hub.docker.com/r/minio/minio/) [![codecov](https://codecov.io/gh/minio/minio/branch/master/graph/badge.svg)](https://codecov.io/gh/minio/minio) -Minio now supports shared backend across multiple instances. This solves certain specific use cases. +Minio shared mode lets you use single [NAS](https://en.wikipedia.org/wiki/Network-attached_storage) (like NFS, GlusterFS, and other +distributed filesystems) as the storage backend for multiple Minio servers. Synchronization among Minio servers is taken care by design. +Read more about the Minio shared mode design [here](https://github.com/minio/minio/blob/master/docs/shared-backend/DESIGN.md). -## Use Cases +Minio shared mode is developed to solve several real world use cases. Some of these are -- Minio on NAS -- Minio on Distributed Filesystems -- Multi-user Shared Backend. +- You have already invested in NAS and would like to use Minio to add S3 compatibility to your storage tier. +- You need to use NAS with an S3 interface due to your application architecture requirements. +- You expect huge traffic and need a load balanced S3 compatible server, serving files from a single NAS backend. -## Why Minio On Shared Backend? - -This feature allows Minio to serve a shared NAS drive across multiple Minio instances. There are no special configuration changes required to enable this feature. Access to files stored on NAS volume are locked and synchronized by default. +With a proxy running in front of multiple, shared mode Minio servers, it is very easy to create a Highly Available, load balanced, AWS S3 compatible storage system. # Get started -If you're aware of stand-alone Minio set up, the installation and running remains the same. +If you're aware of stand-alone Minio set up, the installation and running remains the same. ## 1. Prerequisites Install Minio - [Minio Quickstart Guide](https://docs.minio.io/docs/minio). -## 2. Run Minio On Shared Backend +## 2. Run Minio on Shared Backend -Below examples will clarify further for each operating system of your choice: +To run Minio shared backend instances, you need to start multiple Minio servers pointing to the same backend storage. We'll see examples on how to do this in the following sections. -### Ubuntu 16.04 LTS +*Note* -Run the following commands on all the object storage gateway servers where your NAS volume is accessible. By explicitly passing access and secret keys through the environment variable you make sure that all the gateway servers share the same key across. +- All the nodes running shared Minio need to have same access key and secret key. To achieve this, we export access key and secret key as environment variables on all the nodes before executing Minio server command. +- The drive paths below are for demonstration purposes only, you need to replace these with the actual drive paths/folders. -Example 1: Start Minio instance on a shared backend mounted and available at `/mnt/nfs`. +#### Minio shared mode on Ubuntu 16.04 LTS. + +You'll need the path to the shared volume, e.g. `/mnt/nfs`. Then run the following commands on all the nodes you'd like to launch Minio. -On linux server1 ```sh +export MINIO_ACCESS_KEY= +export MINIO_SECRET_KEY= minio server /mnt/nfs ``` -On linux server2 -```sh -minio server /mnt/nfs -``` +#### Minio shared mode on Windows 2012 Server -### Windows 2012 Server +You'll need the path to the shared volume, e.g. `\\remote-server\smb`. Then run the following commands on all the nodes you'd like to launch Minio. -Run the following commands on all the object storage gateway servers where your NAS volume is accessible. By explicitly passing access and secret keys through the environment variable you make sure that all the gateway servers share the same key across. - -Example 1: Start Minio instance on a shared backend mounted and available at `\\remote-server\smb`. - -On windows server1 ```cmd set MINIO_ACCESS_KEY=my-username set MINIO_SECRET_KEY=my-password minio.exe server \\remote-server\smb\export ``` -On windows server2 -```cmd -set MINIO_ACCESS_KEY=my-username -set MINIO_SECRET_KEY=my-password -minio.exe server \\remote-server\smb\export -``` +*Windows Tip* -Alternatively if `\\remote-server\smb` is mounted as `M:\` drive. +If a remote volume, e.g. `\\remote-server\smb` is mounted as a drive, e.g. `M:\`. You can use [`net use`](https://technet.microsoft.com/en-us/library/bb490717.aspx) command to map the drive to a folder. -On windows server1 -```cmd -set MINIO_ACCESS_KEY=my-username -set MINIO_SECRET_KEY=my-password -net use m: \\remote-server\smb\export /P:Yes -minio.exe server M:\export -``` - -On windows server2 ```cmd set MINIO_ACCESS_KEY=my-username set MINIO_SECRET_KEY=my-password @@ -80,7 +62,7 @@ minio.exe server M:\export ## 3. Test your setup -To test this setup, access the Minio server via browser or [`mc`](https://docs.minio.io/docs/minio-client-quickstart-guide). You’ll see the uploaded files are accessible from the node2 endpoint as well. +To test this setup, access the Minio server via browser or [`mc`](https://docs.minio.io/docs/minio-client-quickstart-guide). You’ll see the uploaded files are accessible from the all the Minio shared backend endpoints. ## Explore Further - [Use `mc` with Minio Server](https://docs.minio.io/docs/minio-client-quickstart-guide) @@ -88,5 +70,3 @@ To test this setup, access the Minio server via browser or [`mc`](https://docs.m - [Use `s3cmd` with Minio Server](https://docs.minio.io/docs/s3cmd-with-minio) - [Use `minio-go` SDK with Minio Server](https://docs.minio.io/docs/golang-client-quickstart-guide) - [The Minio documentation website](https://docs.minio.io) - - From 5f7565762e4efeaceeefdcd191aae9dd79f96a98 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 13 Mar 2017 14:41:13 -0700 Subject: [PATCH 81/94] api: postPolicy cleanup. Simplify the code and re-use. (#3890) This change is cleanup of the postPolicyHandler code primarily to address the flow and also converting certain critical parts into self contained functions. --- cmd/bucket-handlers.go | 95 ++++++++++++++++++-------------------- cmd/handler-utils.go | 84 ++++++++++++++++++++------------- cmd/handler-utils_test.go | 44 ++++++++++++++++++ cmd/object-handlers.go | 34 ++++++-------- cmd/post-policy_test.go | 14 ++++-- cmd/postpolicyform.go | 6 +-- cmd/postpolicyform_test.go | 26 +++++------ cmd/signature-v2.go | 8 ++-- cmd/signature-v2_test.go | 8 ++-- cmd/signature-v4.go | 14 +++--- cmd/signature-v4_test.go | 37 ++++++++------- cmd/web-handlers.go | 14 ++---- 12 files changed, 222 insertions(+), 162 deletions(-) diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index a1d2d4a3d..a27552f69 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -19,7 +19,6 @@ package cmd import ( "encoding/base64" "encoding/xml" - "fmt" "io" "net/http" "net/url" @@ -327,9 +326,7 @@ func (api objectAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, ObjInfo: ObjectInfo{ Name: dobj.ObjectName, }, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, + ReqParams: extractReqParams(r), }) } } @@ -439,14 +436,25 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h defer fileBody.Close() bucket := mux.Vars(r)["bucket"] - formValues["Bucket"] = bucket + formValues.Set("Bucket", bucket) - if fileName != "" && strings.Contains(formValues["Key"], "${filename}") { + if fileName != "" && strings.Contains(formValues.Get("Key"), "${filename}") { // S3 feature to replace ${filename} found in Key form field // by the filename attribute passed in multipart - formValues["Key"] = strings.Replace(formValues["Key"], "${filename}", fileName, -1) + formValues.Set("Key", strings.Replace(formValues.Get("Key"), "${filename}", fileName, -1)) + } + object := formValues.Get("Key") + + successRedirect := formValues.Get("success_action_redirect") + successStatus := formValues.Get("success_action_status") + var redirectURL *url.URL + if successRedirect != "" { + redirectURL, err = url.Parse(successRedirect) + if err != nil { + writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL) + return + } } - object := formValues["Key"] // Verify policy signature. apiErr := doesPolicySignatureMatch(formValues) @@ -455,7 +463,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h return } - policyBytes, err := base64.StdEncoding.DecodeString(formValues["Policy"]) + policyBytes, err := base64.StdEncoding.DecodeString(formValues.Get("Policy")) if err != nil { writeErrorResponse(w, ErrMalformedPOSTRequest, r.URL) return @@ -492,7 +500,6 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h // Extract metadata to be saved from received Form. metadata := extractMetadataFromForm(formValues) - sha256sum := "" objectLock := globalNSMutex.NewNSLock(bucket, object) @@ -505,50 +512,40 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h writeErrorResponse(w, toAPIErrorCode(err), r.URL) return } - w.Header().Set("ETag", "\""+objInfo.MD5Sum+"\"") + + w.Header().Set("ETag", `"`+objInfo.MD5Sum+`"`) w.Header().Set("Location", getObjectLocation(bucket, object)) - successRedirect := formValues[http.CanonicalHeaderKey("success_action_redirect")] - successStatus := formValues[http.CanonicalHeaderKey("success_action_status")] + // Notify object created event. + defer eventNotify(eventData{ + Type: ObjectCreatedPost, + Bucket: objInfo.Bucket, + ObjInfo: objInfo, + ReqParams: extractReqParams(r), + }) - if successStatus == "" && successRedirect == "" { - writeSuccessNoContent(w) - } else { - if successRedirect != "" { - redirectURL := successRedirect + "?" + fmt.Sprintf("bucket=%s&key=%s&etag=%s", - bucket, - getURLEncodedName(object), - getURLEncodedName("\""+objInfo.MD5Sum+"\"")) - - writeRedirectSeeOther(w, redirectURL) - } else { - // Decide what http response to send depending on success_action_status parameter - switch successStatus { - case "201": - resp := encodeResponse(PostResponse{ - Bucket: bucket, - Key: object, - ETag: "\"" + objInfo.MD5Sum + "\"", - Location: getObjectLocation(bucket, object), - }) - writeResponse(w, http.StatusCreated, resp, "application/xml") - case "200": - writeSuccessResponseHeadersOnly(w) - default: - writeSuccessNoContent(w) - } - } + if successRedirect != "" { + // Replace raw query params.. + redirectURL.RawQuery = getRedirectPostRawQuery(objInfo) + writeRedirectSeeOther(w, redirectURL.String()) + return } - // Notify object created event. - eventNotify(eventData{ - Type: ObjectCreatedPost, - Bucket: bucket, - ObjInfo: objInfo, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, - }) + // Decide what http response to send depending on success_action_status parameter + switch successStatus { + case "201": + resp := encodeResponse(PostResponse{ + Bucket: objInfo.Bucket, + Key: objInfo.Name, + ETag: `"` + objInfo.MD5Sum + `"`, + Location: getObjectLocation(objInfo.Bucket, objInfo.Name), + }) + writeResponse(w, http.StatusCreated, resp, "application/xml") + case "200": + writeSuccessResponseHeadersOnly(w) + default: + writeSuccessNoContent(w) + } } // HeadBucketHandler - HEAD Bucket diff --git a/cmd/handler-utils.go b/cmd/handler-utils.go index 3b0e852e1..19319f6a4 100644 --- a/cmd/handler-utils.go +++ b/cmd/handler-utils.go @@ -20,6 +20,7 @@ import ( "io" "mime/multipart" "net/http" + "net/url" "strings" ) @@ -105,6 +106,9 @@ func path2BucketAndObject(path string) (bucket, object string) { // extractMetadataFromHeader extracts metadata from HTTP header. func extractMetadataFromHeader(header http.Header) map[string]string { + if header == nil { + return nil + } metadata := make(map[string]string) // Save standard supported headers. for _, supportedHeader := range supportedHeaders { @@ -126,51 +130,67 @@ func extractMetadataFromHeader(header http.Header) map[string]string { metadata[cKey] = header.Get(key) } } - // Return. + + // Success. return metadata } +// The Query string for the redirect URL the client is +// redirected on successful upload. +func getRedirectPostRawQuery(objInfo ObjectInfo) string { + redirectValues := make(url.Values) + redirectValues.Set("bucket", objInfo.Bucket) + redirectValues.Set("key", objInfo.Name) + redirectValues.Set("etag", "\""+objInfo.MD5Sum+"\"") + return redirectValues.Encode() +} + +// Extract request params to be sent with event notifiation. +func extractReqParams(r *http.Request) map[string]string { + if r == nil { + return nil + } + + // Success. + return map[string]string{ + "sourceIPAddress": r.RemoteAddr, + // Add more fields here. + } +} + // extractMetadataFromForm extracts metadata from Post Form. -func extractMetadataFromForm(formValues map[string]string) map[string]string { - metadata := make(map[string]string) - // Save standard supported headers. - for _, supportedHeader := range supportedHeaders { - canonicalHeader := http.CanonicalHeaderKey(supportedHeader) - // Form field names are case insensitive, look for both canonical - // and non canonical entries. - if _, ok := formValues[canonicalHeader]; ok { - metadata[supportedHeader] = formValues[canonicalHeader] - } else if _, ok := formValues[supportedHeader]; ok { - metadata[supportedHeader] = formValues[canonicalHeader] +func extractMetadataFromForm(formValues http.Header) map[string]string { + return extractMetadataFromHeader(formValues) +} + +// Validate form field size for s3 specification requirement. +func validateFormFieldSize(formValues http.Header) error { + // Iterate over form values + for k := range formValues { + // Check if value's field exceeds S3 limit + if int64(len(formValues.Get(k))) > maxFormFieldSize { + return traceError(errSizeUnexpected) } } - // Go through all other form values for any additional headers that needs to be saved. - for key := range formValues { - cKey := http.CanonicalHeaderKey(key) - if strings.HasPrefix(cKey, "X-Amz-Meta-") { - metadata[cKey] = formValues[key] - } else if strings.HasPrefix(cKey, "X-Minio-Meta-") { - metadata[cKey] = formValues[key] - } - } - return metadata + + // Success. + return nil } // Extract form fields and file data from a HTTP POST Policy -func extractPostPolicyFormValues(form *multipart.Form) (filePart io.ReadCloser, fileName string, fileSize int64, formValues map[string]string, err error) { +func extractPostPolicyFormValues(form *multipart.Form) (filePart io.ReadCloser, fileName string, fileSize int64, formValues http.Header, err error) { /// HTML Form values - formValues = make(map[string]string) fileName = "" - // Iterate over form values + // Canonicalize the form values into http.Header. + formValues = make(http.Header) for k, v := range form.Value { - canonicalFormName := http.CanonicalHeaderKey(k) - // Check if value's field exceeds S3 limit - if int64(len(v[0])) > maxFormFieldSize { - return nil, "", 0, nil, traceError(errSizeUnexpected) - } - // Set the form value - formValues[canonicalFormName] = v[0] + formValues[http.CanonicalHeaderKey(k)] = v + } + + // Validate form values. + if err = validateFormFieldSize(formValues); err != nil { + return nil, "", 0, nil, err } // Iterator until we find a valid File field and break diff --git a/cmd/handler-utils_test.go b/cmd/handler-utils_test.go index 0bf34b3c5..3c0b4c2a8 100644 --- a/cmd/handler-utils_test.go +++ b/cmd/handler-utils_test.go @@ -22,6 +22,7 @@ import ( "io/ioutil" "net/http" "reflect" + "strings" "testing" ) @@ -83,6 +84,44 @@ func TestIsValidLocationContraint(t *testing.T) { } } +// Test validate form field size. +func TestValidateFormFieldSize(t *testing.T) { + testCases := []struct { + header http.Header + err error + }{ + // Empty header returns error as nil, + { + header: nil, + err: nil, + }, + // Valid header returns error as nil. + { + header: http.Header{ + "Content-Type": []string{"image/png"}, + }, + err: nil, + }, + // Invalid header value > maxFormFieldSize+1 + { + header: http.Header{ + "Garbage": []string{strings.Repeat("a", int(maxFormFieldSize)+1)}, + }, + err: errSizeUnexpected, + }, + } + + // Run validate form field size check under all test cases. + for i, testCase := range testCases { + err := validateFormFieldSize(testCase.header) + if err != nil { + if errorCause(err).Error() != testCase.err.Error() { + t.Errorf("Test %d: Expected error %s, got %s", i+1, testCase.err, err) + } + } + } +} + // Tests validate metadata extraction from http headers. func TestExtractMetadataHeaders(t *testing.T) { testCases := []struct { @@ -115,6 +154,11 @@ func TestExtractMetadataHeaders(t *testing.T) { "X-Amz-Meta-Appid": "amz-meta", "X-Minio-Meta-Appid": "minio-meta"}, }, + // Empty header input returns empty metadata. + { + header: nil, + metadata: nil, + }, } // Validate if the extracting headers. diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index e0e6c1beb..3e2037ed2 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -359,12 +359,10 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re // Notify object created event. eventNotify(eventData{ - Type: ObjectCreatedCopy, - Bucket: dstBucket, - ObjInfo: objInfo, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, + Type: ObjectCreatedCopy, + Bucket: dstBucket, + ObjInfo: objInfo, + ReqParams: extractReqParams(r), }) } @@ -492,12 +490,10 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req // Notify object created event. eventNotify(eventData{ - Type: ObjectCreatedPut, - Bucket: bucket, - ObjInfo: objInfo, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, + Type: ObjectCreatedPut, + Bucket: bucket, + ObjInfo: objInfo, + ReqParams: extractReqParams(r), }) } @@ -922,12 +918,10 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite // Notify object created event. eventNotify(eventData{ - Type: ObjectCreatedCompleteMultipartUpload, - Bucket: bucket, - ObjInfo: objInfo, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, + Type: ObjectCreatedCompleteMultipartUpload, + Bucket: bucket, + ObjInfo: objInfo, + ReqParams: extractReqParams(r), }) } @@ -970,8 +964,6 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http. ObjInfo: ObjectInfo{ Name: object, }, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, + ReqParams: extractReqParams(r), }) } diff --git a/cmd/post-policy_test.go b/cmd/post-policy_test.go index 14018979a..29df94acc 100644 --- a/cmd/post-policy_test.go +++ b/cmd/post-policy_test.go @@ -24,6 +24,7 @@ import ( "mime/multipart" "net/http" "net/http/httptest" + "net/url" "testing" "time" @@ -444,7 +445,10 @@ func testPostPolicyBucketHandlerRedirect(obj ObjectLayer, instanceType string, t targetObj := keyName + "/upload.txt" // The url of success_action_redirect field - redirectURL := "http://www.google.com" + redirectURL, err := url.Parse("http://www.google.com") + if err != nil { + t.Fatal(err) + } // Register the API end points with XL/FS object layer. apiRouter := initTestAPIEndPoints(obj, []string{"PostPolicy"}) @@ -464,7 +468,7 @@ func testPostPolicyBucketHandlerRedirect(obj ObjectLayer, instanceType string, t rec := httptest.NewRecorder() dates := []interface{}{curTimePlus5Min.Format(expirationDateFormat), curTime.Format(iso8601DateFormat), curTime.Format(yyyymmdd)} - policy := `{"expiration": "%s","conditions":[["eq", "$bucket", "` + bucketName + `"], {"success_action_redirect":"` + redirectURL + `"},["starts-with", "$key", "test/"], ["eq", "$x-amz-algorithm", "AWS4-HMAC-SHA256"], ["eq", "$x-amz-date", "%s"], ["eq", "$x-amz-credential", "` + credentials.AccessKey + `/%s/us-east-1/s3/aws4_request"]]}` + policy := `{"expiration": "%s","conditions":[["eq", "$bucket", "` + bucketName + `"], {"success_action_redirect":"` + redirectURL.String() + `"},["starts-with", "$key", "test/"], ["eq", "$x-amz-algorithm", "AWS4-HMAC-SHA256"], ["eq", "$x-amz-date", "%s"], ["eq", "$x-amz-credential", "` + credentials.AccessKey + `/%s/us-east-1/s3/aws4_request"]]}` // Generate the final policy document policy = fmt.Sprintf(policy, dates...) @@ -472,7 +476,7 @@ func testPostPolicyBucketHandlerRedirect(obj ObjectLayer, instanceType string, t // Create a new POST request with success_action_redirect field specified req, perr := newPostRequestV4Generic("", bucketName, keyName, []byte("objData"), credentials.AccessKey, credentials.SecretKey, curTime, - []byte(policy), map[string]string{"success_action_redirect": redirectURL}, false, false) + []byte(policy), map[string]string{"success_action_redirect": redirectURL.String()}, false, false) if perr != nil { t.Fatalf("%s: Failed to create HTTP request for PostPolicyHandler: %v", instanceType, perr) @@ -492,8 +496,8 @@ func testPostPolicyBucketHandlerRedirect(obj ObjectLayer, instanceType string, t t.Error("Unexpected error: ", err) } - expectedLocation := fmt.Sprintf(redirectURL+"?bucket=%s&key=%s&etag=%s", - bucketName, getURLEncodedName(targetObj), getURLEncodedName("\""+info.MD5Sum+"\"")) + redirectURL.RawQuery = getRedirectPostRawQuery(info) + expectedLocation := redirectURL.String() // Check the new location url if rec.HeaderMap.Get("Location") != expectedLocation { diff --git a/cmd/postpolicyform.go b/cmd/postpolicyform.go index 799f5f818..6c90a294e 100644 --- a/cmd/postpolicyform.go +++ b/cmd/postpolicyform.go @@ -219,7 +219,7 @@ func checkPolicyCond(op string, input1, input2 string) bool { // checkPostPolicy - apply policy conditions and validate input values. // (http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html) -func checkPostPolicy(formValues map[string]string, postPolicyForm PostPolicyForm) APIErrorCode { +func checkPostPolicy(formValues http.Header, postPolicyForm PostPolicyForm) APIErrorCode { // Check if policy document expiry date is still not reached if !postPolicyForm.Expiration.After(time.Now().UTC()) { return ErrPolicyAlreadyExpired @@ -242,12 +242,12 @@ func checkPostPolicy(formValues map[string]string, postPolicyForm PostPolicyForm return ErrAccessDenied } // Check if current policy condition is satisfied - condPassed = checkPolicyCond(op, formValues[formCanonicalName], v.Value) + condPassed = checkPolicyCond(op, formValues.Get(formCanonicalName), v.Value) } else { // This covers all conditions X-Amz-Meta-* and X-Amz-* if strings.HasPrefix(cond, "$x-amz-meta-") || strings.HasPrefix(cond, "$x-amz-") { // Check if policy condition is satisfied - condPassed = checkPolicyCond(op, formValues[formCanonicalName], v.Value) + condPassed = checkPolicyCond(op, formValues.Get(formCanonicalName), v.Value) } } // Check if current policy condition is satisfied, quit immediately otherwise diff --git a/cmd/postpolicyform_test.go b/cmd/postpolicyform_test.go index 11bb712d4..d2c35c43f 100644 --- a/cmd/postpolicyform_test.go +++ b/cmd/postpolicyform_test.go @@ -18,12 +18,12 @@ package cmd import ( "encoding/base64" + "net/http" "testing" ) // Test Post Policy parsing and checking conditions func TestPostPolicyForm(t *testing.T) { - type testCase struct { Bucket string Key string @@ -60,18 +60,18 @@ func TestPostPolicyForm(t *testing.T) { } // Validate all the test cases. for i, tt := range testCases { - formValues := make(map[string]string) - formValues["Bucket"] = tt.Bucket - formValues["Acl"] = tt.ACL - formValues["Key"] = tt.Key - formValues["X-Amz-Date"] = tt.XAmzDate - formValues["X-Amz-Meta-Uuid"] = tt.XAmzMetaUUID - formValues["X-Amz-Server-Side-Encryption"] = tt.XAmzServerSideEncryption - formValues["X-Amz-Algorithm"] = tt.XAmzAlgorithm - formValues["X-Amz-Credential"] = tt.XAmzCredential - formValues["Content-Type"] = tt.ContentType - formValues["Policy"] = tt.Policy - formValues["Success_action_redirect"] = tt.SuccessActionRedirect + formValues := make(http.Header) + formValues.Set("Bucket", tt.Bucket) + formValues.Set("Acl", tt.ACL) + formValues.Set("Key", tt.Key) + formValues.Set("X-Amz-Date", tt.XAmzDate) + formValues.Set("X-Amz-Meta-Uuid", tt.XAmzMetaUUID) + formValues.Set("X-Amz-Server-Side-Encryption", tt.XAmzServerSideEncryption) + formValues.Set("X-Amz-Algorithm", tt.XAmzAlgorithm) + formValues.Set("X-Amz-Credential", tt.XAmzCredential) + formValues.Set("Content-Type", tt.ContentType) + formValues.Set("Policy", tt.Policy) + formValues.Set("Success_action_redirect", tt.SuccessActionRedirect) policyBytes, err := base64.StdEncoding.DecodeString(tt.Policy) if err != nil { t.Fatal(err) diff --git a/cmd/signature-v2.go b/cmd/signature-v2.go index 107dbe8c5..e1eecbc90 100644 --- a/cmd/signature-v2.go +++ b/cmd/signature-v2.go @@ -64,14 +64,14 @@ var resourceList = []string{ "website", } -func doesPolicySignatureV2Match(formValues map[string]string) APIErrorCode { +func doesPolicySignatureV2Match(formValues http.Header) APIErrorCode { cred := serverConfig.GetCredential() - accessKey := formValues["Awsaccesskeyid"] + accessKey := formValues.Get("AWSAccessKeyId") if accessKey != cred.AccessKey { return ErrInvalidAccessKeyID } - signature := formValues["Signature"] - policy := formValues["Policy"] + policy := formValues.Get("Policy") + signature := formValues.Get("Signature") if signature != calculateSignatureV2(policy, cred.SecretKey) { return ErrSignatureDoesNotMatch } diff --git a/cmd/signature-v2_test.go b/cmd/signature-v2_test.go index fc5b2dee9..3a2b778aa 100644 --- a/cmd/signature-v2_test.go +++ b/cmd/signature-v2_test.go @@ -208,10 +208,10 @@ func TestDoesPolicySignatureV2Match(t *testing.T) { {creds.AccessKey, policy, calculateSignatureV2(policy, creds.SecretKey), ErrNone}, } for i, test := range testCases { - formValues := make(map[string]string) - formValues["Awsaccesskeyid"] = test.accessKey - formValues["Signature"] = test.signature - formValues["Policy"] = test.policy + formValues := make(http.Header) + formValues.Set("Awsaccesskeyid", test.accessKey) + formValues.Set("Signature", test.signature) + formValues.Set("Policy", test.policy) errCode := doesPolicySignatureV2Match(formValues) if errCode != test.errCode { t.Fatalf("(%d) expected to get %s, instead got %s", i+1, niceError(test.errCode), niceError(errCode)) diff --git a/cmd/signature-v4.go b/cmd/signature-v4.go index f6a5ea2fb..d32d22435 100644 --- a/cmd/signature-v4.go +++ b/cmd/signature-v4.go @@ -147,9 +147,9 @@ func getSignature(signingKey []byte, stringToSign string) string { } // Check to see if Policy is signed correctly. -func doesPolicySignatureMatch(formValues map[string]string) APIErrorCode { +func doesPolicySignatureMatch(formValues http.Header) APIErrorCode { // For SignV2 - Signature field will be valid - if formValues["Signature"] != "" { + if _, ok := formValues["Signature"]; ok { return doesPolicySignatureV2Match(formValues) } return doesPolicySignatureV4Match(formValues) @@ -158,7 +158,7 @@ func doesPolicySignatureMatch(formValues map[string]string) APIErrorCode { // doesPolicySignatureMatch - Verify query headers with post policy // - http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html // returns ErrNone if the signature matches. -func doesPolicySignatureV4Match(formValues map[string]string) APIErrorCode { +func doesPolicySignatureV4Match(formValues http.Header) APIErrorCode { // Access credentials. cred := serverConfig.GetCredential() @@ -166,7 +166,7 @@ func doesPolicySignatureV4Match(formValues map[string]string) APIErrorCode { region := serverConfig.GetRegion() // Parse credential tag. - credHeader, err := parseCredentialHeader("Credential=" + formValues["X-Amz-Credential"]) + credHeader, err := parseCredentialHeader("Credential=" + formValues.Get("X-Amz-Credential")) if err != ErrNone { return ErrMissingFields } @@ -186,12 +186,14 @@ func doesPolicySignatureV4Match(formValues map[string]string) APIErrorCode { signingKey := getSigningKey(cred.SecretKey, credHeader.scope.date, region) // Get signature. - newSignature := getSignature(signingKey, formValues["Policy"]) + newSignature := getSignature(signingKey, formValues.Get("Policy")) // Verify signature. - if newSignature != formValues["X-Amz-Signature"] { + if newSignature != formValues.Get("X-Amz-Signature") { return ErrSignatureDoesNotMatch } + + // Success. return ErrNone } diff --git a/cmd/signature-v4_test.go b/cmd/signature-v4_test.go index 12137d1e1..41422671d 100644 --- a/cmd/signature-v4_test.go +++ b/cmd/signature-v4_test.go @@ -39,45 +39,50 @@ func TestDoesPolicySignatureMatch(t *testing.T) { accessKey := serverConfig.GetCredential().AccessKey testCases := []struct { - form map[string]string + form http.Header expected APIErrorCode }{ // (0) It should fail if 'X-Amz-Credential' is missing. { - form: map[string]string{}, + form: http.Header{}, expected: ErrMissingFields, }, // (1) It should fail if the access key is incorrect. { - form: map[string]string{ - "X-Amz-Credential": fmt.Sprintf(credentialTemplate, "EXAMPLEINVALIDEXAMPL", now.Format(yyyymmdd), globalMinioDefaultRegion), + form: http.Header{ + "X-Amz-Credential": []string{fmt.Sprintf(credentialTemplate, "EXAMPLEINVALIDEXAMPL", now.Format(yyyymmdd), globalMinioDefaultRegion)}, }, expected: ErrInvalidAccessKeyID, }, // (2) It should fail if the region is invalid. { - form: map[string]string{ - "X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), "invalidregion"), + form: http.Header{ + "X-Amz-Credential": []string{fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), "invalidregion")}, }, expected: ErrInvalidRegion, }, // (3) It should fail with a bad signature. { - form: map[string]string{ - "X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), - "X-Amz-Date": now.Format(iso8601Format), - "X-Amz-Signature": "invalidsignature", - "Policy": "policy", + form: http.Header{ + "X-Amz-Credential": []string{fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion)}, + "X-Amz-Date": []string{now.Format(iso8601Format)}, + "X-Amz-Signature": []string{"invalidsignature"}, + "Policy": []string{"policy"}, }, expected: ErrSignatureDoesNotMatch, }, // (4) It should succeed if everything is correct. { - form: map[string]string{ - "X-Amz-Credential": fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), - "X-Amz-Date": now.Format(iso8601Format), - "X-Amz-Signature": getSignature(getSigningKey(serverConfig.GetCredential().SecretKey, now, globalMinioDefaultRegion), "policy"), - "Policy": "policy", + form: http.Header{ + "X-Amz-Credential": []string{ + fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), + }, + "X-Amz-Date": []string{now.Format(iso8601Format)}, + "X-Amz-Signature": []string{ + getSignature(getSigningKey(serverConfig.GetCredential().SecretKey, now, + globalMinioDefaultRegion), "policy"), + }, + "Policy": []string{"policy"}, }, expected: ErrNone, }, diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index c139e6f27..e5a189358 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -292,9 +292,7 @@ objectLoop: ObjInfo: ObjectInfo{ Name: objectName, }, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, + ReqParams: extractReqParams(r), }) } return err @@ -528,12 +526,10 @@ func (web *webAPIHandlers) Upload(w http.ResponseWriter, r *http.Request) { // Notify object created event. eventNotify(eventData{ - Type: ObjectCreatedPut, - Bucket: bucket, - ObjInfo: objInfo, - ReqParams: map[string]string{ - "sourceIPAddress": r.RemoteAddr, - }, + Type: ObjectCreatedPut, + Bucket: bucket, + ObjInfo: objInfo, + ReqParams: extractReqParams(r), }) } From a5e60706a2a5eeb8188fd9614787083018cc102c Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Tue, 14 Mar 2017 06:20:46 +0100 Subject: [PATCH 82/94] xl,fs: Return 404 if object ends with a separator (#3897) HEAD Object for FS and XL was returning invalid object name when an object name has a trailing slash separator, this PR changes the behavior and will always return 404 object not found, this guarantees a better compatibility with S3 spec. --- cmd/fs-v1.go | 6 ++++ cmd/object_api_suite_test.go | 58 +++++++++++++----------------------- cmd/xl-v1-object.go | 6 ++++ 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index f651a6d52..fc1cd2d1b 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -470,6 +470,12 @@ func (fs fsObjects) getObjectInfo(bucket, object string) (ObjectInfo, error) { // GetObjectInfo - reads object metadata and replies back ObjectInfo. func (fs fsObjects) GetObjectInfo(bucket, object string) (ObjectInfo, error) { + // This is a special case with object whose name ends with + // a slash separator, we always return object not found here. + if hasSuffix(object, slashSeparator) { + return ObjectInfo{}, toObjectErr(traceError(errFileNotFound), bucket, object) + } + if err := checkGetObjArgs(bucket, object); err != nil { return ObjectInfo{}, err } diff --git a/cmd/object_api_suite_test.go b/cmd/object_api_suite_test.go index e382af73a..73af5b23d 100644 --- a/cmd/object_api_suite_test.go +++ b/cmd/object_api_suite_test.go @@ -735,12 +735,13 @@ func (s *ObjectLayerAPISuite) TestGetDirectoryReturnsObjectNotFound(c *C) { // Tests validate that GetObject on an existing directory fails as expected. func testGetDirectoryReturnsObjectNotFound(obj ObjectLayer, instanceType string, c TestErrHandler) { - err := obj.MakeBucket("bucket") + bucketName := "bucket" + err := obj.MakeBucket(bucketName) if err != nil { c.Fatalf("%s: %s", instanceType, err) } - _, err = obj.PutObject("bucket", "dir1/dir3/object", + _, err = obj.PutObject(bucketName, "dir1/dir3/object", int64(len("The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload might have been aborted or completed.")), bytes.NewBufferString("One or more of the specified parts could not be found. The part might not have been uploaded, or the specified entity tag might not have matched the part's entity tag."), nil, "") @@ -748,41 +749,24 @@ func testGetDirectoryReturnsObjectNotFound(obj ObjectLayer, instanceType string, c.Fatalf("%s: %s", instanceType, err) } - _, err = obj.GetObjectInfo("bucket", "dir1") - if isErrObjectNotFound(err) { - err = errorCause(err) - err1 := err.(ObjectNotFound) - if err1.Bucket != "bucket" { - c.Errorf("%s: Expected the bucket name in the error message to be `%s`, but instead found `%s`", - instanceType, "bucket", err1.Bucket) - } - if err1.Object != "dir1" { - c.Errorf("%s: Expected the object name in the error message to be `%s`, but instead found `%s`", - instanceType, "dir1", err1.Object) - } - } else { - if err.Error() != "ObjectNotFound" { - c.Errorf("%s: Expected the error message to be `%s`, but instead found `%s`", instanceType, - "ObjectNotFound", err.Error()) - } - } - - _, err = obj.GetObjectInfo("bucket", "dir1/") - if isErrObjectNameInvalid(err) { - err = errorCause(err) - err1 := err.(ObjectNameInvalid) - if err1.Bucket != "bucket" { - c.Errorf("%s: Expected the bucket name in the error message to be `%s`, but instead found `%s`", - instanceType, "bucket", err1.Bucket) - } - if err1.Object != "dir1/" { - c.Errorf("%s: Expected the object name in the error message to be `%s`, but instead found `%s`", - instanceType, "dir1/", err1.Object) - } - } else { - // force a failure with a line number. - if err.Error() != "ObjectNotFound" { - c.Errorf("%s: Expected the error message to be `%s`, but instead found `%s`", instanceType, "ObjectNotFound", err.Error()) + for i, objName := range []string{"dir1", "dir1/", "dir1/dir3", "dir1/dir3/"} { + _, err = obj.GetObjectInfo(bucketName, objName) + if isErrObjectNotFound(err) { + err = errorCause(err) + err1 := err.(ObjectNotFound) + if err1.Bucket != bucketName { + c.Errorf("Test %d, %s: Expected the bucket name in the error message to be `%s`, but instead found `%s`", + i+1, instanceType, bucketName, err1.Bucket) + } + if err1.Object != objName { + c.Errorf("Test %d, %s: Expected the object name in the error message to be `%s`, but instead found `%s`", + i+1, instanceType, objName, err1.Object) + } + } else { + if err.Error() != "ObjectNotFound" { + c.Errorf("Test %d, %s: Expected the error message to be `%s`, but instead found `%s`", i+1, instanceType, + "ObjectNotFound", err.Error()) + } } } } diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index 0c85d3980..f7ecf76c9 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -321,6 +321,12 @@ func (xl xlObjects) GetObject(bucket, object string, startOffset int64, length i // GetObjectInfo - reads object metadata and replies back ObjectInfo. func (xl xlObjects) GetObjectInfo(bucket, object string) (ObjectInfo, error) { + // This is a special case with object whose name ends with + // a slash separator, we always return object not found here. + if hasSuffix(object, slashSeparator) { + return ObjectInfo{}, toObjectErr(traceError(errFileNotFound), bucket, object) + } + if err := checkGetObjArgs(bucket, object); err != nil { return ObjectInfo{}, err } From a27d1b3d86f9d60aba52b52a90f7ff7827263976 Mon Sep 17 00:00:00 2001 From: Rushan Date: Wed, 15 Mar 2017 03:32:20 +0530 Subject: [PATCH 83/94] Browser: Use babel-polyfill to support new ES6 built-ins in older browsers (#3900) --- browser/app/index.js | 2 -- browser/package.json | 2 +- browser/webpack.config.js | 2 ++ 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/browser/app/index.js b/browser/app/index.js index 5c2a33749..26a1cc1d3 100644 --- a/browser/app/index.js +++ b/browser/app/index.js @@ -44,8 +44,6 @@ import Web from './js/web' window.Web = Web import storage from 'local-storage-fallback' -import objectAssign from 'es6-object-assign' -objectAssign.polyfill() const store = applyMiddleware(thunkMiddleware)(createStore)(reducer) const Browse = connect(state => state)(_Browse) diff --git a/browser/package.json b/browser/package.json index a60f80759..227efdf5d 100644 --- a/browser/package.json +++ b/browser/package.json @@ -26,6 +26,7 @@ "babel-loader": "^6.2.5", "babel-plugin-syntax-object-rest-spread": "^6.13.0", "babel-plugin-transform-object-rest-spread": "^6.8.0", + "babel-polyfill": "^6.23.0", "babel-preset-es2015": "^6.14.0", "babel-preset-react": "^6.11.1", "babel-register": "^6.14.0", @@ -67,7 +68,6 @@ "dependencies": { "bootstrap": "^3.3.6", "classnames": "^2.2.3", - "es6-object-assign": "^1.0.3", "font-awesome": "^4.7.0", "humanize": "0.0.9", "json-loader": "^0.5.4", diff --git a/browser/webpack.config.js b/browser/webpack.config.js index 769b84c56..b8e86ff94 100644 --- a/browser/webpack.config.js +++ b/browser/webpack.config.js @@ -22,6 +22,7 @@ var purify = require("purifycss-webpack-plugin") var exports = { context: __dirname, entry: [ + "babel-polyfill", path.resolve(__dirname, 'app/index.js') ], output: { @@ -100,6 +101,7 @@ var exports = { if (process.env.NODE_ENV === 'dev') { exports.entry = [ + "babel-polyfill", 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8080', path.resolve(__dirname, 'app/index.js') From 96050c1e215cbeef0056d703f0880ddb9aa0919b Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Tue, 14 Mar 2017 19:07:23 -0700 Subject: [PATCH 84/94] browser: Do not show "Loading..." if there are no buckets. (#3904) --- browser/app/js/components/Browse.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/app/js/components/Browse.js b/browser/app/js/components/Browse.js index 6a8894f11..85550ccb6 100644 --- a/browser/app/js/components/Browse.js +++ b/browser/app/js/components/Browse.js @@ -603,7 +603,7 @@ export default class Browse extends React.Component { checkObject={ this.checkObject.bind(this) } checkedObjectsArray={ checkedObjects } /> -
    +
    Loading...
    From ba0c11757ef3723de74fd13faa5c88bb79d2c889 Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Wed, 15 Mar 2017 20:52:03 +0530 Subject: [PATCH 85/94] Added that no special config changes reqd (#3906) Added a line saying no special config changes are required for Shared mode. Also the previous `Why Shared Backend` and current `Use cases` are already merged. This fixes the comment: https://github.com/minio/minio/pull/3888#discussion_r105573494 --- docs/shared-backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/shared-backend/README.md b/docs/shared-backend/README.md index ee4e02b7d..1dc565f27 100644 --- a/docs/shared-backend/README.md +++ b/docs/shared-backend/README.md @@ -4,7 +4,7 @@ Minio shared mode lets you use single [NAS](https://en.wikipedia.org/wiki/Networ distributed filesystems) as the storage backend for multiple Minio servers. Synchronization among Minio servers is taken care by design. Read more about the Minio shared mode design [here](https://github.com/minio/minio/blob/master/docs/shared-backend/DESIGN.md). -Minio shared mode is developed to solve several real world use cases. Some of these are +Minio shared mode is developed to solve several real world use cases, without any special configuration changes. Some of these are - You have already invested in NAS and would like to use Minio to add S3 compatibility to your storage tier. - You need to use NAS with an S3 interface due to your application architecture requirements. From cad0d0eb7a7b7cb80ebef933757969c9b2d79fb8 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Wed, 15 Mar 2017 11:32:51 -0700 Subject: [PATCH 86/94] browser: Update ui-assets.go (#3902) fixes #3898 --- browser/ui-assets.go | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/browser/ui-assets.go b/browser/ui-assets.go index c0f13d848..e4b435709 100644 --- a/browser/ui-assets.go +++ b/browser/ui-assets.go @@ -4,7 +4,7 @@ // production/favicon.ico // production/firefox.png // production/index.html -// production/index_bundle-2017-03-10T23-12-26Z.js +// production/index_bundle-2017-03-15T17-49-51Z.js // production/loader.css // production/logo.svg // production/safari.png @@ -65,7 +65,7 @@ func productionChromePng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/chrome.png", size: 3726, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -82,7 +82,7 @@ func productionFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/favicon.ico", size: 1340, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -99,7 +99,7 @@ func productionFirefoxPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/firefox.png", size: 4795, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -156,8 +156,8 @@ var _productionIndexHTML = []byte(` - - + + `) @@ -172,12 +172,12 @@ func productionIndexHTML() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/index.html", size: 1996, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _productionIndex_bundle20170310t231226zJs = []byte(`!function(A){function M(I){if(t[I])return t[I].exports;var g=t[I]={exports:{},id:I,loaded:!1};return A[I].call(g.exports,g,g.exports,M),g.loaded=!0,g.exports}var t={};return M.m=A,M.c=t,M.p="",M(0)}([function(A,M,t){A.exports=t(237)},function(A,M,t){"use strict";A.exports=t(439)},function(A,M,t){"use strict";function I(A,M,t,I,g,e,i,T){if(!A){var E;if(void 0===M)E=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var N=[t,I,g,e,i,T],o=0;E=new Error(M.replace(/%s/g,function(){return N[o++]})),E.name="Invariant Violation"}throw E.framesToPop=1,E}}A.exports=I},function(A,M,t){"use strict";var I=t(20),g=I;A.exports=g},function(A,M){"use strict";function t(A,M){if(null==A)throw new TypeError("Object.assign target cannot be null or undefined");for(var t=Object(A),I=Object.prototype.hasOwnProperty,g=1;g-1&&A%1==0&&A1)for(var t=1;tA.clientHeight}Object.defineProperty(M,"__esModule",{value:!0}),M.default=i;var T=t(57),E=I(T),N=t(39),o=I(N);A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M,t,I,g){var i=A[M],E="undefined"==typeof i?"undefined":e(i);return T.default.isValidElement(i)?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of type ReactElement "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):"function"!==E&&"string"!==E?new Error("Invalid "+I+" ` + "`" + `"+g+"` + "`" + ` of value ` + "`" + `"+i+"` + "`" + ` "+("supplied to ` + "`" + `"+t+"` + "`" + `, expected an element type (a string ")+"or a ReactClass)."):null}M.__esModule=!0;var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(A){return typeof A}:function(A){return A&&"function"==typeof Symbol&&A.constructor===Symbol?"symbol":typeof A},i=t(1),T=I(i),E=t(180),N=I(E);M.default=(0,N.default)(g)},function(A,M){"use strict";function t(A){function M(M,t,I,g,e,i){var T=g||"<>",E=i||I;if(null==t[I])return M?new Error("Required "+e+" ` + "`" + `"+E+"` + "`" + ` was not specified "+("in ` + "`" + `"+T+"` + "`" + `.")):null;for(var N=arguments.length,o=Array(N>6?N-6:0),n=6;n=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return 0===A.button}function i(A){return!!(A.metaKey||A.altKey||A.ctrlKey||A.shiftKey)}function T(A){for(var M in A)if(Object.prototype.hasOwnProperty.call(A,M))return!1;return!0}function E(A,M){var t=M.query,I=M.hash,g=M.state;return t||I||g?{pathname:A,query:t,hash:I,state:g}:A}M.__esModule=!0;var N=Object.assign||function(A){for(var M=1;M=0;I--){var g=A[I],e=g.path||"";if(t=e.replace(/\/*$/,"/")+t,0===e.indexOf("/"))break}return"/"+t}},propTypes:{path:C,from:C,to:C.isRequired,query:c,state:c,onEnter:o.falsy,children:o.falsy},render:function(){(0,T.default)(!1)}});M.default=D,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}M.__esModule=!0;var g=t(1),e=I(g),i=t(8),T=I(i),E=t(30),N=t(34),o=e.default.PropTypes,n=o.string,C=o.func,c=e.default.createClass({displayName:"Route",statics:{createRouteFromReactElement:E.createRouteFromReactElement},propTypes:{path:n,component:N.component,components:N.components,getComponent:C,getComponents:C},render:function(){(0,T.default)(!1)}});M.default=c,A.exports=M.default},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A,M){var t={};for(var I in A)M.indexOf(I)>=0||Object.prototype.hasOwnProperty.call(A,I)&&(t[I]=A[I]);return t}function e(A){return!A||!A.__v2_compatible__}function i(A){return A&&A.getCurrentLocation}M.__esModule=!0;var T=Object.assign||function(A){for(var M=1;M=0&&0===window.sessionStorage.length)return;throw A}}function i(A){var M=void 0;try{M=window.sessionStorage.getItem(g(A))}catch(A){if(A.name===o)return null}if(M)try{return JSON.parse(M)}catch(A){}return null}M.__esModule=!0,M.saveState=e,M.readState=i;var T=t(23),E=(I(T),"@@History/"),N=["QuotaExceededError","QUOTA_EXCEEDED_ERR"],o="SecurityError"},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(A){function M(A){return E.canUseDOM?void 0:T.default(!1),t.listen(A)}var t=n.default(e({getUserConfirmation:N.getUserConfirmation},A,{go:N.go}));return e({},t,{listen:M})}M.__esModule=!0;var e=Object.assign||function(A){for(var M=1;M1?M-1:0),e=1;e=A.childNodes.length?null:A.childNodes.item(t);A.insertBefore(M,I)}var g=t(433),e=t(218),i=t(17),T=t(76),E=t(121),N=t(2),o={dangerouslyReplaceNodeWithMarkup:g.dangerouslyReplaceNodeWithMarkup,updateTextContent:E,processUpdates:function(A,M){for(var t,i=null,o=null,n=0;n-1?void 0:i(!1),!N.plugins[t]){M.extractEvents?void 0:i(!1),N.plugins[t]=M;var I=M.eventTypes;for(var e in I)g(I[e],M,e)?void 0:i(!1)}}}function g(A,M,t){N.eventNameDispatchConfigs.hasOwnProperty(t)?i(!1):void 0,N.eventNameDispatchConfigs[t]=A;var I=A.phasedRegistrationNames;if(I){for(var g in I)if(I.hasOwnProperty(g)){var T=I[g];e(T,M,t)}return!0}return!!A.registrationName&&(e(A.registrationName,M,t),!0)}function e(A,M,t){N.registrationNameModules[A]?i(!1):void 0,N.registrationNameModules[A]=M,N.registrationNameDependencies[A]=M.eventTypes[t].dependencies}var i=t(2),T=null,E={},N={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(A){T?i(!1):void 0,T=Array.prototype.slice.call(A),I()},injectEventPluginsByName:function(A){var M=!1;for(var t in A)if(A.hasOwnProperty(t)){var g=A[t];E.hasOwnProperty(t)&&E[t]===g||(E[t]?i(!1):void 0,E[t]=g,M=!0)}M&&I()},getPluginModuleForEvent:function(A){var M=A.dispatchConfig;if(M.registrationName)return N.registrationNameModules[M.registrationName]||null;for(var t in M.phasedRegistrationNames)if(M.phasedRegistrationNames.hasOwnProperty(t)){var I=N.registrationNameModules[M.phasedRegistrationNames[t]];if(I)return I}return null},_resetEventPlugins:function(){T=null;for(var A in E)E.hasOwnProperty(A)&&delete E[A];N.plugins.length=0;var M=N.eventNameDispatchConfigs;for(var t in M)M.hasOwnProperty(t)&&delete M[t];var I=N.registrationNameModules;for(var g in I)I.hasOwnProperty(g)&&delete I[g]}};A.exports=N},function(A,M,t){"use strict";function I(A){return(""+A).replace(x,"//")}function g(A,M){this.func=A,this.context=M,this.count=0}function e(A,M,t){var I=A.func,g=A.context;I.call(g,M,A.count++)}function i(A,M,t){if(null==A)return A;var I=g.getPooled(M,t);Q(A,e,I),g.release(I)}function T(A,M,t,I){this.result=A,this.keyPrefix=M,this.func=t,this.context=I,this.count=0}function E(A,M,t){var g=A.result,e=A.keyPrefix,i=A.func,T=A.context,E=i.call(T,M,A.count++);Array.isArray(E)?N(E,g,t,B.thatReturnsArgument):null!=E&&(a.isValidElement(E)&&(E=a.cloneAndReplaceKey(E,e+(E!==M?I(E.key||"")+"/":"")+t)),g.push(E))}function N(A,M,t,g,e){var i="";null!=t&&(i=I(t)+"/");var N=T.getPooled(M,i,g,e);Q(A,E,N),T.release(N)}function o(A,M,t){if(null==A)return A;var I=[];return N(A,I,null,M,t),I}function n(A,M,t){return null}function C(A,M){return Q(A,n,null)}function c(A){var M=[];return N(A,M,null,B.thatReturnsArgument),M}var D=t(31),a=t(13),B=t(20),Q=t(123),r=D.twoArgumentPooler,s=D.fourArgumentPooler,x=/\/(?!\/)/g;g.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},D.addPoolingTo(g,r),T.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},D.addPoolingTo(T,s);var j={forEach:i,map:o,mapIntoWithKeyPrefixInternal:N,count:C,toArray:c};A.exports=j},function(A,M,t){"use strict";function I(A,M){var t=y.hasOwnProperty(M)?y[M]:null;w.hasOwnProperty(M)&&(t!==x.OVERRIDE_BASE?B(!1):void 0),A.hasOwnProperty(M)&&(t!==x.DEFINE_MANY&&t!==x.DEFINE_MANY_MERGED?B(!1):void 0)}function g(A,M){if(M){"function"==typeof M?B(!1):void 0,C.isValidElement(M)?B(!1):void 0;var t=A.prototype;M.hasOwnProperty(s)&&u.mixins(A,M.mixins);for(var g in M)if(M.hasOwnProperty(g)&&g!==s){var e=M[g];if(I(t,g),u.hasOwnProperty(g))u[g](A,e);else{var i=y.hasOwnProperty(g),N=t.hasOwnProperty(g),o="function"==typeof e,n=o&&!i&&!N&&M.autobind!==!1;if(n)t.__reactAutoBindMap||(t.__reactAutoBindMap={}),t.__reactAutoBindMap[g]=e,t[g]=e;else if(N){var c=y[g];!i||c!==x.DEFINE_MANY_MERGED&&c!==x.DEFINE_MANY?B(!1):void 0,c===x.DEFINE_MANY_MERGED?t[g]=T(t[g],e):c===x.DEFINE_MANY&&(t[g]=E(t[g],e))}else t[g]=e}}}}function e(A,M){if(M)for(var t in M){var I=M[t];if(M.hasOwnProperty(t)){var g=t in u;g?B(!1):void 0;var e=t in A;e?B(!1):void 0,A[t]=I}}}function i(A,M){A&&M&&"object"==typeof A&&"object"==typeof M?void 0:B(!1);for(var t in M)M.hasOwnProperty(t)&&(void 0!==A[t]?B(!1):void 0,A[t]=M[t]);return A}function T(A,M){return function(){var t=A.apply(this,arguments),I=M.apply(this,arguments);if(null==t)return I;if(null==I)return t;var g={};return i(g,t),i(g,I),g}}function E(A,M){return function(){A.apply(this,arguments),M.apply(this,arguments)}}function N(A,M){var t=M.bind(A);return t}function o(A){for(var M in A.__reactAutoBindMap)if(A.__reactAutoBindMap.hasOwnProperty(M)){var t=A.__reactAutoBindMap[M];A[M]=N(A,t)}}var n=t(205),C=t(13),c=(t(71),t(70),t(220)),D=t(4),a=t(50),B=t(2),Q=t(59),r=t(27),s=(t(3),r({mixins:null})),x=Q({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),j=[],y={mixins:x.DEFINE_MANY,statics:x.DEFINE_MANY,propTypes:x.DEFINE_MANY,contextTypes:x.DEFINE_MANY,childContextTypes:x.DEFINE_MANY,getDefaultProps:x.DEFINE_MANY_MERGED,getInitialState:x.DEFINE_MANY_MERGED,getChildContext:x.DEFINE_MANY_MERGED,render:x.DEFINE_ONCE,componentWillMount:x.DEFINE_MANY,componentDidMount:x.DEFINE_MANY,componentWillReceiveProps:x.DEFINE_MANY,shouldComponentUpdate:x.DEFINE_ONCE,componentWillUpdate:x.DEFINE_MANY,componentDidUpdate:x.DEFINE_MANY,componentWillUnmount:x.DEFINE_MANY,updateComponent:x.OVERRIDE_BASE},u={displayName:function(A,M){A.displayName=M},mixins:function(A,M){if(M)for(var t=0;t"+T+""},receiveComponent:function(A,M){if(A!==this._currentElement){this._currentElement=A;var t=""+A;if(t!==this._stringText){this._stringText=t;var g=i.getNode(this._rootNodeID);I.updateTextContent(g,t)}}},unmountComponent:function(){e.unmountIDFromEnvironment(this._rootNodeID)}}),A.exports=o},function(A,M,t){"use strict";function I(){this.reinitializeTransaction()}var g=t(18),e=t(73),i=t(4),T=t(20),E={initialize:T,close:function(){C.isBatchingUpdates=!1}},N={initialize:T,close:g.flushBatchedUpdates.bind(g)},o=[N,E];i(I.prototype,e.Mixin,{getTransactionWrappers:function(){return o}});var n=new I,C={isBatchingUpdates:!1,batchedUpdates:function(A,M,t,I,g,e){var i=C.isBatchingUpdates;C.isBatchingUpdates=!0,i?A(M,t,I,g,e):n.perform(A,null,M,t,I,g,e)}};A.exports=C},function(A,M,t){"use strict";function I(){if(!l){l=!0,Q.EventEmitter.injectReactEventListener(B),Q.EventPluginHub.injectEventPluginOrder(T),Q.EventPluginHub.injectInstanceHandle(r),Q.EventPluginHub.injectMount(s),Q.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:u,EnterLeaveEventPlugin:E,ChangeEventPlugin:e,SelectEventPlugin:j,BeforeInputEventPlugin:g}),Q.NativeComponent.injectGenericComponentClass(D),Q.NativeComponent.injectTextComponentClass(a),Q.Class.injectMixin(n),Q.DOMProperty.injectDOMPropertyConfig(o),Q.DOMProperty.injectDOMPropertyConfig(w),Q.EmptyComponent.injectEmptyComponent("noscript"),Q.Updates.injectReconcileTransaction(x),Q.Updates.injectBatchingStrategy(c),Q.RootIndex.injectCreateReactRootIndex(N.canUseDOM?i.createReactRootIndex:y.createReactRootIndex),Q.Component.injectEnvironment(C)}}var g=t(429),e=t(431),i=t(432),T=t(434),E=t(435),N=t(10),o=t(438),n=t(440),C=t(109),c=t(210),D=t(444),a=t(209),B=t(452),Q=t(453),r=t(48),s=t(12),x=t(457),j=t(463),y=t(464),u=t(465),w=t(462),l=!1;A.exports={inject:I}},function(A,M,t){"use strict";function I(){if(n.current){var A=n.current.getName();if(A)return" Check the render method of ` + "`" + `"+A+"` + "`" + `."}return""}function g(A,M){if(A._store&&!A._store.validated&&null==A.key){A._store.validated=!0;e("uniqueKey",A,M)}}function e(A,M,t){var g=I();if(!g){var e="string"==typeof t?t:t.displayName||t.name;e&&(g=" Check the top-level render call using <"+e+">.")}var i=D[A]||(D[A]={});if(i[g])return null;i[g]=!0;var T={parentOrOwner:g,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return M&&M._owner&&M._owner!==n.current&&(T.childOwner=" It was passed a child from "+M._owner.getName()+"."),T}function i(A,M){if("object"==typeof A)if(Array.isArray(A))for(var t=0;t/,e={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(A){var M=I(A);return A.replace(g," "+e.CHECKSUM_ATTR_NAME+'="'+M+'"$&')},canReuseMarkup:function(A,M){var t=M.getAttribute(e.CHECKSUM_ATTR_NAME);t=t&&parseInt(t,10);var g=I(A);return g===t}};A.exports=e},function(A,M,t){"use strict";var I=t(59),g=I({INSERT_MARKUP:null,MOVE_EXISTING:null,REMOVE_NODE:null,SET_MARKUP:null,TEXT_CONTENT:null});A.exports=g},function(A,M,t){"use strict";function I(A){if("function"==typeof A.type)return A.type;var M=A.type,t=n[M];return null==t&&(n[M]=t=N(M)),t}function g(A){return o?void 0:E(!1),new o(A.type,A.props)}function e(A){return new C(A)}function i(A){return A instanceof C}var T=t(4),E=t(2),N=null,o=null,n={},C=null,c={injectGenericComponentClass:function(A){o=A},injectTextComponentClass:function(A){C=A},injectComponentClasses:function(A){T(n,A)}},D={getComponentClassForElement:I,createInternalComponent:g,createInstanceForText:e,isTextComponent:i,injection:c};A.exports=D},function(A,M,t){"use strict";function I(A,M){}var g=(t(3),{isMounted:function(A){return!1},enqueueCallback:function(A,M){},enqueueForceUpdate:function(A){I(A,"forceUpdate")},enqueueReplaceState:function(A,M){I(A,"replaceState")},enqueueSetState:function(A,M){I(A,"setState")},enqueueSetProps:function(A,M){I(A,"setProps")},enqueueReplaceProps:function(A,M){I(A,"replaceProps")}});A.exports=g},function(A,M,t){"use strict";function I(A){function M(M,t,I,g,e,i){if(g=g||y,i=i||I,null==t[I]){var T=s[e];return M?new Error("Required "+T+" ` + "`" + `"+i+"` + "`" + ` was not specified in "+("` + "`" + `"+g+"` + "`" + `.")):null}return A(t,I,g,e,i)}var t=M.bind(null,!1);return t.isRequired=M.bind(null,!0),t}function g(A){function M(M,t,I,g,e){var i=M[t],T=a(i);if(T!==A){var E=s[g],N=B(i);return new Error("Invalid "+E+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+N+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected ")+("` + "`" + `"+A+"` + "`" + `."))}return null}return I(M)}function e(){return I(x.thatReturns(null))}function i(A){function M(M,t,I,g,e){var i=M[t];if(!Array.isArray(i)){var T=s[g],E=a(i);return new Error("Invalid "+T+" ` + "`" + `"+e+"` + "`" + ` of type "+("` + "`" + `"+E+"` + "`" + ` supplied to ` + "`" + `"+I+"` + "`" + `, expected an array."))}for(var N=0;N>"}var r=t(13),s=t(70),x=t(20),j=t(118),y="<>",u={array:g("array"),bool:g("boolean"),func:g("function"),number:g("number"),object:g("object"),string:g("string"),any:e(),arrayOf:i,element:T(),instanceOf:E,node:C(),objectOf:o,oneOf:N,oneOfType:n,shape:c};A.exports=u},function(A,M){"use strict";var t={injectCreateReactRootIndex:function(A){I.createReactRootIndex=A}},I={createReactRootIndex:null,injection:t};A.exports=I},function(A,M){"use strict";var t={currentScrollLeft:0,currentScrollTop:0,refreshScrollValues:function(A){t.currentScrollLeft=A.x,t.currentScrollTop=A.y}};A.exports=t},function(A,M,t){"use strict";function I(A,M){if(null==M?g(!1):void 0,null==A)return M;var t=Array.isArray(A),I=Array.isArray(M);return t&&I?(A.push.apply(A,M),A):t?(A.push(M),A):I?[A].concat(M):[A,M]}var g=t(2);A.exports=I},function(A,M){"use strict";var t=function(A,M,t){Array.isArray(A)?A.forEach(M,t):A&&M.call(t,A)};A.exports=t},function(A,M,t){"use strict";function I(){return!e&&g.canUseDOM&&(e="textContent"in document.documentElement?"textContent":"innerText"),e}var g=t(10),e=null;A.exports=I},function(A,M){"use strict";function t(A){var M=A&&A.nodeName&&A.nodeName.toLowerCase();return M&&("input"===M&&I[A.type]||"textarea"===M)}var I={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};A.exports=t},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}function g(){for(var A=arguments.length,M=Array(A),t=0;t=0&&s.splice(M,1)}function T(A){var M=document.createElement("style");return M.type="text/css",e(A,M),M}function E(A){var M=document.createElement("link");return M.rel="stylesheet",e(A,M),M}function N(A,M){var t,I,g;if(M.singleton){var e=r++;t=Q||(Q=T(M)),I=o.bind(null,t,e,!1),g=o.bind(null,t,e,!0)}else A.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(t=E(M),I=C.bind(null,t),g=function(){i(t),t.href&&URL.revokeObjectURL(t.href)}):(t=T(M),I=n.bind(null,t),g=function(){i(t)});return I(A),function(M){if(M){if(M.css===A.css&&M.media===A.media&&M.sourceMap===A.sourceMap)return;I(A=M)}else g()}}function o(A,M,t,I){var g=t?"":I.css;if(A.styleSheet)A.styleSheet.cssText=x(M,g);else{var e=document.createTextNode(g),i=A.childNodes;i[M]&&A.removeChild(i[M]),i.length?A.insertBefore(e,i[M]):A.appendChild(e)}}function n(A,M){var t=M.css,I=M.media;if(I&&A.setAttribute("media",I),A.styleSheet)A.styleSheet.cssText=t;else{for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(document.createTextNode(t))}}function C(A,M){var t=M.css,I=M.sourceMap;I&&(t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(I))))+" */");var g=new Blob([t],{type:"text/css"}),e=A.href;A.href=URL.createObjectURL(g),e&&URL.revokeObjectURL(e)}var c={},D=function(A){var M;return function(){return"undefined"==typeof M&&(M=A.apply(this,arguments)),M}},a=D(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),B=D(function(){return document.head||document.getElementsByTagName("head")[0]}),Q=null,r=0,s=[];A.exports=function(A,M){M=M||{},"undefined"==typeof M.singleton&&(M.singleton=a()),"undefined"==typeof M.insertAt&&(M.insertAt="bottom");var t=g(A);return I(t,M),function(A){for(var e=[],i=0;i-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=M.currentPath,e=M.currentBucket,i=M.deleteConfirmation,T=M.checkedObjects,E=T.length>0?T:[i.object];t.RemoveObject({bucketname:e,objects:E}).then(function(){if(A.hideDeleteConfirmation(),T.length>0){for(var M=0;M0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadSelected.bind(this)}," Download all as zip ")),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.showDeleteConfirmation.bind(this)}," Delete selected ")),o.default.createElement("i",{className:"la-close fa fa-times",onClick:this.clearSelected.bind(this)})),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:5})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:23,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:0,max:59,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1,U.object)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:window.location.protocol+"//"+U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&(A.name.endsWith("/")||(Q=e.default.createElement(c.default,{id:"fia-dropdown-"+A.name.replace(".","-")},e.default.createElement(c.default.Toggle,{noCaret:!0,className:"fia-toggle"}),e.default.createElement(c.default.Menu,null,e.default.createElement("a",{href:"",className:"fiad-action",onClick:function(M){return E(M,""+t+A.name)}},e.default.createElement("i",{className:"fa fa-copy"})),r))));var s="",x="";return C.indexOf(A.name)>-1&&(s=" fesl-row-selected",x=!0),e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,checked:x,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",object:""},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return t}},function(A,M,t){"use strict";function I(A){if(Array.isArray(A)){for(var M=0,t=Array(A.length);MM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;tE;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(133);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(134),e=t(261),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(132)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]), -M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(266)})},function(A,M,t){var I=t(135);t(267)("keys",function(A){return function(M){return A(I(M))}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(268).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;g-1})))}},{key:"listObjects",value:function(){var A=this.props.dispatch;A(eA.listObjects())}},{key:"selectPrefix",value:function(A,M){A.preventDefault();var t=this.props,I=(t.dispatch,t.currentPath),g=(t.web,t.currentBucket),e=encodeURI(M);if(M.endsWith("/")||""===M){if(M===I)return;D.default.push(TA.pathJoin(g,e))}else window.location=window.location.origin+"/minio/download/"+g+"/"+e+"?token="+DA.default.getItem("token")}},{key:"makeBucket",value:function(A){A.preventDefault();var M=this.refs.makeBucketRef.value;this.refs.makeBucketRef.value="";var t=this.props,I=t.web,g=t.dispatch;this.hideMakeBucketModal(),I.MakeBucket({bucketName:M}).then(function(){g(eA.addBucket(M)),g(eA.selectBucket(M))}).catch(function(A){return g(eA.showAlert({type:"danger",message:A.message}))})}},{key:"hideMakeBucketModal",value:function(){var A=this.props.dispatch;A(eA.hideMakeBucketModal())}},{key:"showMakeBucketModal",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showMakeBucketModal())}},{key:"showAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showAbout())}},{key:"hideAbout",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideAbout())}},{key:"showBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.showBucketPolicy())}},{key:"hideBucketPolicy",value:function(A){A.preventDefault();var M=this.props.dispatch;M(eA.hideBucketPolicy())}},{key:"uploadFile",value:function(A){A.preventDefault();var M=this.props,t=M.dispatch,I=M.buckets;if(0===I.length)return void t(eA.showAlert({type:"danger",message:"Bucket needs to be created before trying to upload files."}));var g=A.target.files[0];A.target.value=null,this.xhr=new XMLHttpRequest,t(eA.uploadFile(g,this.xhr))}},{key:"removeObject",value:function(){var A=this,M=this.props,t=M.web,I=M.dispatch,g=M.currentPath,e=M.currentBucket,i=M.deleteConfirmation,T=M.checkedObjects,E=T.length>0?T:[i.object];t.RemoveObject({bucketname:e,objects:E}).then(function(){if(A.hideDeleteConfirmation(),T.length>0){for(var M=0;M0})},o.default.createElement("span",{className:"la-label"},o.default.createElement("i",{className:"fa fa-check-circle"})," ",c.length," Objects selected"),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.downloadSelected.bind(this)}," Download all as zip ")),o.default.createElement("span",{className:"la-actions pull-right"},o.default.createElement("button",{onClick:this.showDeleteConfirmation.bind(this)}," Delete selected ")),o.default.createElement("i",{className:"la-close fa fa-times",onClick:this.clearSelected.bind(this)})),o.default.createElement(m.default,null,v,o.default.createElement("header",{className:"fe-header-mobile hidden-lg hidden-md"},o.default.createElement("div",{id:"feh-trigger",className:"feh-trigger "+(0,C.default)({"feht-toggled":y}),onClick:this.toggleSidebar.bind(this,!y)},o.default.createElement("div",{className:"feht-lines"},o.default.createElement("div",{className:"top"}),o.default.createElement("div",{className:"center"}),o.default.createElement("div",{className:"bottom"}))),o.default.createElement("img",{className:"mh-logo",src:IA.default,alt:""})),o.default.createElement("header",{className:"fe-header"},o.default.createElement(G.default,{selectPrefix:this.selectPrefix.bind(this)}),AA,o.default.createElement("ul",{className:"feh-actions"},o.default.createElement(b.default,null),K,_)),o.default.createElement("div",{className:"feb-container"},o.default.createElement("header",{className:"fesl-row","data-type":"folder"},o.default.createElement("div",{className:"fesl-item fesl-item-icon"}),o.default.createElement("div",{className:"fesl-item fesl-item-name",onClick:this.sortObjectsByName.bind(this),"data-sort":"name"},"Name",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-alpha-desc":i,"fa-sort-alpha-asc":!i})})),o.default.createElement("div",{className:"fesl-item fesl-item-size",onClick:this.sortObjectsBySize.bind(this),"data-sort":"size"},"Size",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-amount-desc":T,"fa-sort-amount-asc":!T})})),o.default.createElement("div",{className:"fesl-item fesl-item-modified",onClick:this.sortObjectsByDate.bind(this),"data-sort":"last-modified"},"Last Modified",o.default.createElement("i",{className:(0,C.default)({"fesli-sort":!0,fa:!0,"fa-sort-numeric-desc":E,"fa-sort-numeric-asc":!E})})),o.default.createElement("div",{className:"fesl-item fesl-item-actions"}))),o.default.createElement("div",{className:"feb-container"},o.default.createElement(BA.default,{loadMore:this.listObjects.bind(this),hasMore:J,useWindow:!0,initialLoad:!1},o.default.createElement(f.default,{dataType:this.dataType.bind(this),selectPrefix:this.selectPrefix.bind(this),showDeleteConfirmation:this.showDeleteConfirmation.bind(this),shareObject:this.shareObject.bind(this),checkObject:this.checkObject.bind(this),checkedObjectsArray:c})),o.default.createElement("div",{className:"text-center",style:{display:J&&S?"block":"none"}},o.default.createElement("span",null,"Loading..."))),o.default.createElement(X.default,null),eA,o.default.createElement(s.default,{className:"modal-create-bucket",bsSize:"small",animation:!1,show:g,onHide:this.hideMakeBucketModal.bind(this)},o.default.createElement("button",{className:"close close-alt",onClick:this.hideMakeBucketModal.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement(j.default,null,o.default.createElement("form",{onSubmit:this.makeBucket.bind(this)},o.default.createElement("div",{className:"input-group"},o.default.createElement("input",{className:"ig-text",type:"text",ref:"makeBucketRef",placeholder:"Bucket Name",autoFocus:!0}),o.default.createElement("i",{className:"ig-helpers"}))))),o.default.createElement(s.default,{className:"modal-about modal-dark",animation:!1,show:N,onHide:this.hideAbout.bind(this)},o.default.createElement("button",{className:"close",onClick:this.hideAbout.bind(this)},o.default.createElement("span",null,"×")),o.default.createElement("div",{className:"ma-inner"},o.default.createElement("div",{className:"mai-item hidden-xs"},o.default.createElement("a",{href:"https://minio.io",target:"_blank"},o.default.createElement("img",{className:"maii-logo",src:IA.default,alt:""}))),o.default.createElement("div",{className:"mai-item"},o.default.createElement("ul",{className:"maii-list"},o.default.createElement("li",null,o.default.createElement("div",null,"Version"),o.default.createElement("small",null,a)),o.default.createElement("li",null,o.default.createElement("div",null,"Memory"),o.default.createElement("small",null,Q)),o.default.createElement("li",null,o.default.createElement("div",null,"Platform"),o.default.createElement("small",null,r)),o.default.createElement("li",null,o.default.createElement("div",null,"Runtime"),o.default.createElement("small",null,x)))))),o.default.createElement(s.default,{className:"modal-policy",animation:!1,show:n,onHide:this.hideBucketPolicy.bind(this)},o.default.createElement(u.default,null,"Bucket Policy (",S,")",o.default.createElement("button",{className:"close close-alt",onClick:this.hideBucketPolicy.bind(this)},o.default.createElement("span",null,"×"))),o.default.createElement("div",{className:"pm-body"},o.default.createElement(Z.default,{bucket:S}),d.map(function(A,M){return o.default.createElement(q.default,{key:M,prefix:A.prefix,policy:A.policy})}))),o.default.createElement(MA.default,{show:p.show,icon:"fa fa-exclamation-triangle mci-red",text:"Are you sure you want to delete?",sub:"This cannot be undone!",okText:"Delete",cancelText:"Cancel",okHandler:this.removeObject.bind(this),cancelHandler:this.hideDeleteConfirmation.bind(this)}),o.default.createElement(s.default,{show:U.show,animation:!1,onHide:this.hideShareObjectModal.bind(this),bsSize:"small"},o.default.createElement(u.default,null,"Share Object"),o.default.createElement(j.default,null,o.default.createElement("div",{className:"input-group copy-text"},o.default.createElement("label",null,"Shareable Link"),o.default.createElement("input",{type:"text",ref:"copyTextInput",readOnly:"readOnly",value:window.location.protocol+"//"+U.url,onClick:this.selectTexts.bind(this)})),o.default.createElement("div",{className:"input-group",style:{display:F.LoggedIn()?"block":"none"}},o.default.createElement("label",null,"Expires in"),o.default.createElement("div",{className:"set-expire"},o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireDays",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Days"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireDays",type:"number",min:0,max:7,defaultValue:5})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireDays",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireHours",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Hours"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireHours",type:"number",min:0,max:23,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireHours",-1,U.object)})),o.default.createElement("div",{className:"set-expire-item"},o.default.createElement("i",{className:"set-expire-increase",onClick:this.handleExpireValue.bind(this,"expireMins",1,U.object)}),o.default.createElement("div",{className:"set-expire-title"},"Minutes"),o.default.createElement("div",{className:"set-expire-value"},o.default.createElement("input",{ref:"expireMins",type:"number",min:0,max:59,defaultValue:0})),o.default.createElement("i",{className:"set-expire-decrease",onClick:this.handleExpireValue.bind(this,"expireMins",-1,U.object)}))))),o.default.createElement("div",{className:"modal-footer"},o.default.createElement(CA.default,{text:window.location.protocol+"//"+U.url,onCopy:this.showMessage.bind(this)},o.default.createElement("button",{className:"btn btn-success"},"Copy Link")),o.default.createElement("button",{className:"btn btn-link",onClick:this.hideShareObjectModal.bind(this)},"Cancel"))),H)))}}]),M}(o.default.Component);M.default=QA},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(91),N=I(E),o=function(A){var M=A.fullScreenFunc,t=A.aboutFunc,I=A.settingsFunc,g=A.logoutFunc;return e.default.createElement("li",null,e.default.createElement(N.default,{pullRight:!0,id:"top-right-menu"},e.default.createElement(N.default.Toggle,{noCaret:!0},e.default.createElement("i",{className:"fa fa-reorder"})),e.default.createElement(N.default.Menu,{className:"dropdown-menu-right"},e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://github.com/minio/minio"},"Github ",e.default.createElement("i",{className:"fa fa-github"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:M},"Fullscreen ",e.default.createElement("i",{className:"fa fa-expand"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://docs.minio.io/"},"Documentation ",e.default.createElement("i",{className:"fa fa-book"}))),e.default.createElement("li",null,e.default.createElement("a",{target:"_blank",href:"https://slack.minio.io"},"Ask for help ",e.default.createElement("i",{className:"fa fa-question-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:t},"About ",e.default.createElement("i",{className:"fa fa-info-circle"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:I},"Settings ",e.default.createElement("i",{className:"fa fa-cog"}))),e.default.createElement("li",null,e.default.createElement("a",{href:"",onClick:g},"Sign Out ",e.default.createElement("i",{className:"fa fa-sign-out"}))))))};M.default=(0,T.default)(function(A){return A})(o)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=t(95),N=I(E),o=t(94),n=I(o),C=function(A){var M=A.latestUiVersion;return M===currentUiVersion?e.default.createElement("noscript",null):e.default.createElement("li",{className:"hidden-xs hidden-sm"},e.default.createElement("a",{href:""},e.default.createElement(n.default,{placement:"left",overlay:e.default.createElement(N.default,{id:"tt-version-update"},"New update available. Click to refresh.")}," ",e.default.createElement("i",{className:"fa fa-refresh"})," ")))};M.default=(0,T.default)(function(A){return{latestUiVersion:A.latestUiVersion}})(C)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&(A.name.endsWith("/")||(Q=e.default.createElement(c.default,{id:"fia-dropdown-"+A.name.replace(".","-")},e.default.createElement(c.default.Toggle,{noCaret:!0,className:"fia-toggle"}),e.default.createElement(c.default.Menu,null,e.default.createElement("a",{href:"",className:"fiad-action",onClick:function(M){return E(M,""+t+A.name)}},e.default.createElement("i",{className:"fa fa-copy"})),r))));var s="",x="";return C.indexOf(A.name)>-1&&(s=" fesl-row-selected",x=!0),e.default.createElement("div",{key:M,className:"fesl-row "+B+s,"data-type":g(A.name,A.contentType)},e.default.createElement("div",{className:"fesl-item fesl-item-icon"},e.default.createElement("div",{className:"fi-select"},e.default.createElement("input",{type:"checkbox",name:A.name,checked:x,onChange:function(M){return n(M,A.name)}}),e.default.createElement("i",{className:"fis-icon"}),e.default.createElement("i",{className:"fis-helper"}))),e.default.createElement("div",{className:"fesl-item fesl-item-name"},e.default.createElement("a",{href:"",onClick:function(M){return I(M,""+t+A.name)}},A.name)),e.default.createElement("div",{className:"fesl-item fesl-item-size"},D),e.default.createElement("div",{className:"fesl-item fesl-item-modified"},a),e.default.createElement("div",{className:"fesl-item fesl-item-actions"},Q))});return e.default.createElement("div",null,D)};M.default=(0,n.default)(function(A){return{objects:A.objects,currentPath:A.currentPath,loadPath:A.loadPath}})(D)},function(A,M,t){"use strict";function I(A){return A&&A.__esModule?A:{default:A}}Object.defineProperty(M,"__esModule",{value:!0});var g=t(1),e=I(g),i=t(22),T=I(i),E=function(A){var M=A.currentBucket,t=A.currentPath,I=A.selectPrefix,g=[],i="";return t&&(i=t.split("/").map(function(A,M){g.push(A);var t=g.join("/")+"/";return e.default.createElement("span",{key:M},e.default.createElement("a",{href:"",onClick:function(A){return I(A,t)}},A))})),e.default.createElement("h2",null,e.default.createElement("span",{className:"main"},e.default.createElement("a",{onClick:function(A){return I(A,"")},href:""},M)),i)};M.default=(0,T.default)(function(A){return{currentBucket:A.currentBucket,currentPath:A.currentPath}})(E)},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}function i(A,M){if(!A)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!M||"object"!=typeof M&&"function"!=typeof M?A:M}function T(A,M){if("function"!=typeof M&&null!==M)throw new TypeError("Super expression must either be null or a function, not "+typeof M);A.prototype=Object.create(M&&M.prototype,{constructor:{value:A,enumerable:!1,writable:!0,configurable:!0}}),M&&(Object.setPrototypeOf?Object.setPrototypeOf(A,M):A.__proto__=M)}Object.defineProperty(M,"__esModule",{value:!0});var E=function(){function A(A,M){for(var t=0;t0&&void 0!==arguments[0]?arguments[0]:{buckets:[],visibleBuckets:[],objects:[],istruncated:!0,storageInfo:{},serverInfo:{},currentBucket:"",currentPath:"",showMakeBucketModal:!1,uploads:{},alert:{show:!1,type:"danger",message:""},loginError:!1,sortNameOrder:!1,sortSizeOrder:!1,sortDateOrder:!1,latestUiVersion:currentUiVersion,sideBarActive:!1,loginRedirectPath:E.minioBrowserPrefix,settings:{accessKey:"",secretKey:"",secretKeyVisible:!1},showSettings:!1,policies:[],deleteConfirmation:{object:"",show:!1},shareObject:{show:!1,url:"",object:""},prefixWritable:!1,checkedObjects:[]},M=arguments[1],t=Object.assign({},A);switch(M.type){case T.SET_WEB:t.web=M.web;break;case T.SET_BUCKETS:t.buckets=M.buckets;break;case T.ADD_BUCKET:t.buckets=[M.bucket].concat(e(t.buckets)),t.visibleBuckets=[M.bucket].concat(e(t.visibleBuckets));break;case T.SET_VISIBLE_BUCKETS:t.visibleBuckets=M.visibleBuckets;break;case T.SET_CURRENT_BUCKET:t.currentBucket=M.currentBucket;break;case T.SET_OBJECTS:M.objects.length?(t.objects=[].concat(e(M.objects)),t.marker=M.marker,t.istruncated=M.istruncated):(t.objects=[],t.marker="",t.istruncated=M.istruncated);break;case T.SET_CURRENT_PATH:t.currentPath=M.currentPath;break;case T.SET_STORAGE_INFO:t.storageInfo=M.storageInfo;break;case T.SET_SERVER_INFO:t.serverInfo=M.serverInfo;break;case T.SHOW_MAKEBUCKET_MODAL:t.showMakeBucketModal=M.showMakeBucketModal;break;case T.UPLOAD_PROGRESS:t.uploads=Object.assign({},t.uploads),t.uploads[M.slug].loaded=M.loaded;break;case T.ADD_UPLOAD:t.uploads=Object.assign({},t.uploads,g({},M.slug,{loaded:0,size:M.size,xhr:M.xhr,name:M.name}));break;case T.STOP_UPLOAD:t.uploads=Object.assign({},t.uploads),delete t.uploads[M.slug];break;case T.SET_ALERT:t.alert.alertTimeout&&clearTimeout(t.alert.alertTimeout),M.alert.show?t.alert=M.alert:t.alert=Object.assign({},t.alert,{show:!1});break;case T.SET_LOGIN_ERROR:t.loginError=!0;break;case T.SET_SHOW_ABORT_MODAL:t.showAbortModal=M.showAbortModal;break;case T.SHOW_ABOUT:t.showAbout=M.showAbout;break;case T.SET_SORT_NAME_ORDER:t.sortNameOrder=M.sortNameOrder;break;case T.SET_SORT_SIZE_ORDER:t.sortSizeOrder=M.sortSizeOrder;break;case T.SET_SORT_DATE_ORDER:t.sortDateOrder=M.sortDateOrder;break;case T.SET_LATEST_UI_VERSION:t.latestUiVersion=M.latestUiVersion;break;case T.SET_SIDEBAR_STATUS:t.sidebarStatus=M.sidebarStatus;break;case T.SET_LOGIN_REDIRECT_PATH:t.loginRedirectPath=M.path;case T.SET_LOAD_BUCKET:t.loadBucket=M.loadBucket;break;case T.SET_LOAD_PATH:t.loadPath=M.loadPath;break;case T.SHOW_SETTINGS:t.showSettings=M.showSettings;break;case T.SET_SETTINGS:t.settings=Object.assign({},t.settings,M.settings);break;case T.SHOW_BUCKET_POLICY:t.showBucketPolicy=M.showBucketPolicy;break;case T.SET_POLICIES:t.policies=M.policies;break;case T.DELETE_CONFIRMATION:t.deleteConfirmation=Object.assign({},M.payload);break;case T.SET_SHARE_OBJECT:t.shareObject=Object.assign({},M.shareObject);break;case T.SET_PREFIX_WRITABLE:t.prefixWritable=M.prefixWritable;break;case T.REMOVE_OBJECT:var I=t.objects.findIndex(function(A){return A.name===M.object});if(I==-1)break;t.objects=[].concat(e(t.objects.slice(0,I)),e(t.objects.slice(I+1)));break;case T.CHECKED_OBJECTS_ADD:t.checkedObjects=[].concat(e(t.checkedObjects),[M.objectName]);break;case T.CHECKED_OBJECTS_REMOVE:var i=t.checkedObjects.indexOf(M.objectName);if(i==-1)break;t.checkedObjects=[].concat(e(t.checkedObjects.slice(0,i)),e(t.checkedObjects.slice(i+1)));break;case T.CHECKED_OBJECTS_RESET:t.checkedObjects=[]}return t}},function(A,M,t){"use strict";function I(A){if(Array.isArray(A)){for(var M=0,t=Array(A.length);MM.name.toLowerCase()?1:0}),g=g.sort(function(A,M){return A.name.toLowerCase()M.name.toLowerCase()?1:0}),M&&(t=t.reverse(),g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsBySize=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return A.size-M.size}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.sortObjectsByDate=function(A,M){var t=A.filter(function(A){return A.name.endsWith("/")}),g=A.filter(function(A){return!A.name.endsWith("/")});return g=g.sort(function(A,M){return new Date(A.lastModified).getTime()-new Date(M.lastModified).getTime()}),M&&(g=g.reverse()),[].concat(I(t),I(g))},M.pathSlice=function(A){A=A.replace(g.minioBrowserPrefix,"");var M="",t="";if(!A)return{bucket:t,prefix:M};var I=A.indexOf("/",1);return I==-1?(t=A.slice(1),{bucket:t,prefix:M}):(t=A.slice(1,I),M=A.slice(I+1),{bucket:t,prefix:M})},M.pathJoin=function(A,M){return M||(M=""),g.minioBrowserPrefix+"/"+A+"/"+M}},function(A,M,t){"use strict";function I(A){if(A&&A.__esModule)return A;var M={};if(null!=A)for(var t in A)Object.prototype.hasOwnProperty.call(A,t)&&(M[t]=A[t]);return M.default=A,M}function g(A){return A&&A.__esModule?A:{default:A}}function e(A,M){if(!(A instanceof M))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(M,"__esModule",{value:!0});var i=function(){function A(A,M){for(var t=0;tE;)for(var C,c=e(i[E++]),D=o?N(c).concat(o(c)):N(c),a=D.length,B=0;a>B;)n.call(c,C=D[B++])&&(t[C]=c[C]);return t}:Object.assign},function(A,M,t){var I=t(79),g=t(49),e=t(133);A.exports=function(A,M){var t=(g.Object||{})[A]||Object[A],i={};i[A]=M(t),I(I.S+I.F*e(function(){t(1)}),"Object",i)}},function(A,M,t){var I=t(80).getDesc,g=t(134),e=t(261),i=function(A,M){if(e(A),!g(M)&&null!==M)throw TypeError(M+": can't set as prototype!")};A.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(A,M,g){try{g=t(132)(Function.call,I(Object.prototype,"__proto__").set,2),g(A,[]),M=!(A instanceof Array)}catch(A){M=!0}return function(A,t){return i(A,t),M?A.__proto__=t:g(A,t),A}}({},!1):void 0),check:i}},function(A,M,t){var I=t(79);I(I.S+I.F,"Object",{assign:t(266)})},function(A,M,t){var I=t(135);t(267)("keys",function(A){return function(M){return A(I(M)); +}})},function(A,M,t){var I=t(79);I(I.S,"Object",{setPrototypeOf:t(268).set})},function(A,M,t){function I(A){if(A)return g(A)}function g(A){for(var M in I.prototype)A[M]=I.prototype[M];return A}A.exports=I,I.prototype.on=I.prototype.addEventListener=function(A,M){return this._callbacks=this._callbacks||{},(this._callbacks["$"+A]=this._callbacks["$"+A]||[]).push(M),this},I.prototype.once=function(A,M){function t(){this.off(A,t),M.apply(this,arguments)}return t.fn=M,this.on(A,t),this},I.prototype.off=I.prototype.removeListener=I.prototype.removeAllListeners=I.prototype.removeEventListener=function(A,M){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var t=this._callbacks["$"+A];if(!t)return this;if(1==arguments.length)return delete this._callbacks["$"+A],this;for(var I,g=0;g1&&(I=t[0]+"@",A=t[1]),A=A.replace(z,".");var g=A.split("."),e=T(g,M).join(".");return I+e}function N(A){for(var M,t,I=[],g=0,e=A.length;g=55296&&M<=56319&&g65535&&(A-=65536,M+=m(A>>>10&1023|55296),A=56320|1023&A),M+=m(A)}).join("")}function n(A){return A-48<10?A-22:A-65<26?A-65:A-97<26?A-97:j}function C(A,M){return A+22+75*(A<26)-((0!=M)<<5)}function c(A,M,t){var I=0;for(A=t?O(A/l):A>>1,A+=O(A/M);A>U*u>>1;I+=j)A=O(A/U);return O(I+(U+1)*A/(A+w))}function D(A){var M,t,I,g,e,T,E,N,C,D,a=[],B=A.length,Q=0,r=Y,s=L;for(t=A.lastIndexOf(d),t<0&&(t=0),I=0;I=128&&i("not-basic"),a.push(A.charCodeAt(I));for(g=t>0?t+1:0;g=B&&i("invalid-input"),N=n(A.charCodeAt(g++)),(N>=j||N>O((x-Q)/T))&&i("overflow"),Q+=N*T,C=E<=s?y:E>=s+u?u:E-s,!(NO(x/D)&&i("overflow"),T*=D;M=a.length+1,s=c(Q-e,M,0==e),O(Q/M)>x-r&&i("overflow"),r+=O(Q/M),Q%=M,a.splice(Q++,0,r)}return o(a)}function a(A){var M,t,I,g,e,T,E,o,n,D,a,B,Q,r,s,w=[];for(A=N(A),B=A.length,M=Y,t=0,e=L,T=0;T=M&&aO((x-t)/Q)&&i("overflow"),t+=(E-M)*Q,M=E,T=0;Tx&&i("overflow"),a==M){for(o=t,n=j;D=n<=e?y:n>=e+u?u:n-e,!(o= 0x80 (not a basic code point)","invalid-input":"Invalid input"},U=j-y,O=Math.floor,m=String.fromCharCode;s={version:"1.3.2",ucs2:{decode:N,encode:o},decode:D,encode:a,toASCII:Q,toUnicode:B},I=function(){return s}.call(M,t,M,A),!(void 0!==I&&(A.exports=I))}(this)}).call(M,t(128)(A),function(){return this}())},function(A,M,t){"use strict";function I(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function g(A,M,t){if(A&&N.isObject(A)&&A instanceof I)return A;var g=new I;return g.parse(A,M,t),g}function e(A){return N.isString(A)&&(A=g(A)),A instanceof I?A.format():I.prototype.format.call(A)}function i(A,M){return g(A,!1,!0).resolve(M)}function T(A,M){return A?g(A,!1,!0).resolveObject(M):M}var E=t(524),N=t(526);M.parse=g,M.resolve=i,M.resolveObject=T,M.format=e,M.Url=I;var o=/^([a-z0-9.+-]+:)/i,n=/:[0-9]*$/,C=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,c=["<",">",'"',"` + "`" + `"," ","\r","\n","\t"],D=["{","}","|","\\","^","` + "`" + `"].concat(c),a=["'"].concat(D),B=["%","/","?",";","#"].concat(a),Q=["/","?","#"],r=255,s=/^[+a-z0-9A-Z_-]{0,63}$/,x=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,j={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},u={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},w=t(359);I.prototype.parse=function(A,M,t){if(!N.isString(A))throw new TypeError("Parameter 'url' must be a string, not "+typeof A);var I=A.indexOf("?"),g=I!==-1&&I127?"x":O[F];if(!m.match(s)){var k=p.slice(0,Y),R=p.slice(Y+1),J=O.match(x);J&&(k.push(J[1]),R.unshift(J[2])),R.length&&(T="/"+R.join(".")+T),this.hostname=k.join(".");break}}}this.hostname.length>r?this.hostname="":this.hostname=this.hostname.toLowerCase(),z||(this.hostname=E.toASCII(this.hostname));var G=this.port?":"+this.port:"",H=this.hostname||"";this.host=H+G,this.href+=this.host,z&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==T[0]&&(T="/"+T))}if(!j[D])for(var Y=0,U=a.length;Y0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return t.search=A.search,t.query=A.query,N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.href=t.format(),t}if(!j.length)return t.pathname=null,t.search?t.path="/"+t.search:t.path=null,t.href=t.format(),t;for(var L=j.slice(-1)[0],Y=(t.host||A.host||j.length>1)&&("."===L||".."===L)||""===L,d=0,h=j.length;h>=0;h--)L=j[h],"."===L?j.splice(h,1):".."===L?(j.splice(h,1),d++):d&&(j.splice(h,1),d--);if(!s&&!x)for(;d--;d)j.unshift("..");!s||""===j[0]||j[0]&&"/"===j[0].charAt(0)||j.unshift(""),Y&&"/"!==j.join("/").substr(-1)&&j.push("");var S=""===j[0]||j[0]&&"/"===j[0].charAt(0);if(w){t.hostname=t.host=S?"":j.length?j.shift():"";var l=!!(t.host&&t.host.indexOf("@")>0)&&t.host.split("@");l&&(t.auth=l.shift(),t.host=t.hostname=l.shift())}return s=s||t.host&&j.length,s&&!S&&j.unshift(""),j.length?t.pathname=j.join("/"):(t.pathname=null,t.path=null),N.isNull(t.pathname)&&N.isNull(t.search)||(t.path=(t.pathname?t.pathname:"")+(t.search?t.search:"")),t.auth=A.auth||t.auth,t.slashes=t.slashes||A.slashes,t.href=t.format(),t},I.prototype.parseHost=function(){var A=this.host,M=n.exec(A);M&&(M=M[0],":"!==M&&(this.port=M.substr(1)),A=A.substr(0,A.length-M.length)),A&&(this.hostname=A)}},function(A,M){"use strict";A.exports={isString:function(A){return"string"==typeof A},isObject:function(A){return"object"==typeof A&&null!==A},isNull:function(A){return null===A},isNullOrUndefined:function(A){return null==A}}}]);`) -func productionIndex_bundle20170310t231226zJsBytes() ([]byte, error) { - return _productionIndex_bundle20170310t231226zJs, nil +func productionIndex_bundle20170315t174951zJsBytes() ([]byte, error) { + return _productionIndex_bundle20170315t174951zJs, nil } -func productionIndex_bundle20170310t231226zJs() (*asset, error) { - bytes, err := productionIndex_bundle20170310t231226zJsBytes() +func productionIndex_bundle20170315t174951zJs() (*asset, error) { + bytes, err := productionIndex_bundle20170315t174951zJsBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "production/index_bundle-2017-03-10T23-12-26Z.js", size: 2283908, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/index_bundle-2017-03-15T17-49-51Z.js", size: 2283772, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -370,7 +370,7 @@ func productionLoaderCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/loader.css", size: 1738, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -444,7 +444,7 @@ func productionLogoSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/logo.svg", size: 3079, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -461,7 +461,7 @@ func productionSafariPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1489187566, 0)} + info := bindataFileInfo{name: "production/safari.png", size: 4971, mode: os.FileMode(436), modTime: time.Unix(1489600214, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -522,7 +522,7 @@ var _bindata = map[string]func() (*asset, error){ "production/favicon.ico": productionFaviconIco, "production/firefox.png": productionFirefoxPng, "production/index.html": productionIndexHTML, - "production/index_bundle-2017-03-10T23-12-26Z.js": productionIndex_bundle20170310t231226zJs, + "production/index_bundle-2017-03-15T17-49-51Z.js": productionIndex_bundle20170315t174951zJs, "production/loader.css": productionLoaderCss, "production/logo.svg": productionLogoSvg, "production/safari.png": productionSafariPng, @@ -574,7 +574,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "favicon.ico": {productionFaviconIco, map[string]*bintree{}}, "firefox.png": {productionFirefoxPng, map[string]*bintree{}}, "index.html": {productionIndexHTML, map[string]*bintree{}}, - "index_bundle-2017-03-10T23-12-26Z.js": {productionIndex_bundle20170310t231226zJs, map[string]*bintree{}}, + "index_bundle-2017-03-15T17-49-51Z.js": {productionIndex_bundle20170315t174951zJs, map[string]*bintree{}}, "loader.css": {productionLoaderCss, map[string]*bintree{}}, "logo.svg": {productionLogoSvg, map[string]*bintree{}}, "safari.png": {productionSafariPng, map[string]*bintree{}}, @@ -635,6 +635,6 @@ func assetFS() *assetfs.AssetFS { panic("unreachable") } -var UIReleaseTag = "RELEASE.2017-03-10T23-12-26Z" -var UICommitID = "e77885d671070805edad89e0cc1d60525dc9a51c" -var UIVersion = "2017-03-10T23:12:26Z" +var UIReleaseTag = "RELEASE.2017-03-15T17-49-51Z" +var UICommitID = "ba0c11757ef3723de74fd13faa5c88bb79d2c889" +var UIVersion = "2017-03-15T17:49:51Z" From ae4361cc45d555f25ae6c8982bd8019099474264 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Thu, 16 Mar 2017 00:30:34 +0100 Subject: [PATCH 87/94] config: Check for duplicated entries in all scopes (#3872) Validate Minio config by checking if there is double json key in any scope level. The returned error contains the json path to the duplicated key. --- cmd/config-v14.go | 112 ++++ cmd/config-v14_test.go | 118 ++++ cmd/credential.go | 11 + cmd/logger-console-hook.go | 15 +- cmd/logger-file-hook.go | 9 + cmd/logger.go | 14 + cmd/notifier-config.go | 96 ++- cmd/notify-amqp.go | 10 + cmd/notify-elasticsearch.go | 10 + cmd/notify-kafka.go | 11 + cmd/notify-nats.go | 10 + cmd/notify-postgresql.go | 10 + cmd/notify-redis.go | 10 + cmd/notify-webhook.go | 10 + cmd/server-main.go | 9 +- cmd/utils.go | 13 + vendor/github.com/tidwall/gjson/README.md | 109 +++- vendor/github.com/tidwall/gjson/gjson.go | 733 ++++++++++++++++++++-- vendor/vendor.json | 6 +- 19 files changed, 1261 insertions(+), 55 deletions(-) diff --git a/cmd/config-v14.go b/cmd/config-v14.go index 14ae16725..070b7cce5 100644 --- a/cmd/config-v14.go +++ b/cmd/config-v14.go @@ -18,11 +18,13 @@ package cmd import ( "errors" + "io/ioutil" "os" "strings" "sync" "github.com/minio/minio/pkg/quick" + "github.com/tidwall/gjson" ) // Read Write mutex for safe access to ServerConfig. @@ -158,6 +160,116 @@ func loadConfig(envParams envParams) error { return nil } +// doCheckDupJSONKeys recursively detects duplicate json keys +func doCheckDupJSONKeys(key, value gjson.Result) error { + // Key occurrences map of the current scope to count + // if there is any duplicated json key. + keysOcc := make(map[string]int) + + // Holds the found error + var checkErr error + + // Iterate over keys in the current json scope + value.ForEach(func(k, v gjson.Result) bool { + // If current key is not null, check if its + // value contains some duplicated keys. + if k.Type != gjson.Null { + keysOcc[k.String()]++ + checkErr = doCheckDupJSONKeys(k, v) + } + return checkErr == nil + }) + + // Check found err + if checkErr != nil { + return errors.New(key.String() + " => " + checkErr.Error()) + } + + // Check for duplicated keys + for k, v := range keysOcc { + if v > 1 { + return errors.New(key.String() + " => `" + k + "` entry is duplicated") + } + } + + return nil +} + +// Check recursively if a key is duplicated in the same json scope +// e.g.: +// `{ "key" : { "key" ..` is accepted +// `{ "key" : { "subkey" : "val1", "subkey": "val2" ..` throws subkey duplicated error +func checkDupJSONKeys(json string) error { + // Parse config with gjson library + config := gjson.Parse(json) + + // Create a fake rootKey since root json doesn't seem to have representation + // in gjson library. + rootKey := gjson.Result{Type: gjson.String, Str: minioConfigFile} + + // Check if loaded json contains any duplicated keys + return doCheckDupJSONKeys(rootKey, config) +} + +// validateConfig checks for +func validateConfig() error { + + // Get file config path + configFile := getConfigFile() + + srvCfg := &serverConfigV14{} + + // Load config file + qc, err := quick.New(srvCfg) + if err != nil { + return err + } + if err = qc.Load(configFile); err != nil { + return err + } + + // Check if config version is valid + if srvCfg.GetVersion() != v14 { + return errors.New("bad config version, expected: " + v14) + } + + // Load config file json and check for duplication json keys + jsonBytes, err := ioutil.ReadFile(configFile) + if err != nil { + return err + } + if err := checkDupJSONKeys(string(jsonBytes)); err != nil { + return err + } + + // Validate region field + if srvCfg.GetRegion() == "" { + return errors.New("region config is empty") + } + + // Validate browser field + if b := strings.ToLower(srvCfg.GetBrowser()); b != "on" && b != "off" { + return errors.New("invalid browser config") + } + + // Validate credential field + if err := srvCfg.Credential.Validate(); err != nil { + return err + } + + // Validate logger field + if err := srvCfg.Logger.Validate(); err != nil { + return err + } + + // Validate notify field + if err := srvCfg.Notify.Validate(); err != nil { + return err + } + + return nil +} + // serverConfig server config. var serverConfig *serverConfigV14 diff --git a/cmd/config-v14_test.go b/cmd/config-v14_test.go index d3ca1aba4..eadb5966a 100644 --- a/cmd/config-v14_test.go +++ b/cmd/config-v14_test.go @@ -17,9 +17,13 @@ package cmd import ( + "io/ioutil" "os" + "path/filepath" "reflect" "testing" + + "github.com/tidwall/gjson" ) func TestServerConfig(t *testing.T) { @@ -167,3 +171,117 @@ func TestServerConfigWithEnvs(t *testing.T) { t.Errorf("Expecting access key to be `minio123` found %s", cred.SecretKey) } } + +func TestCheckDupJSONKeys(t *testing.T) { + testCases := []struct { + json string + shouldPass bool + }{ + {`{}`, true}, + {`{"version" : "13"}`, true}, + {`{"version" : "13", "version": "14"}`, false}, + {`{"version" : "13", "credential": {"accessKey": "12345"}}`, true}, + {`{"version" : "13", "credential": {"accessKey": "12345", "accessKey":"12345"}}`, false}, + {`{"version" : "13", "notify": {"amqp": {"1"}, "webhook":{"3"}}}`, true}, + {`{"version" : "13", "notify": {"amqp": {"1"}, "amqp":{"3"}}}`, false}, + {`{"version" : "13", "notify": {"amqp": {"1":{}, "2":{}}}}`, true}, + {`{"version" : "13", "notify": {"amqp": {"1":{}, "1":{}}}}`, false}, + } + + for i, testCase := range testCases { + err := doCheckDupJSONKeys(gjson.Result{}, gjson.Parse(testCase.json)) + if testCase.shouldPass && err != nil { + t.Errorf("Test %d, should pass but it failed with err = %v", i+1, err) + } + if !testCase.shouldPass && err == nil { + t.Errorf("Test %d, should fail but it succeed.", i+1) + } + } + +} + +func TestValidateConfig(t *testing.T) { + rootPath, err := newTestConfig(globalMinioDefaultRegion) + if err != nil { + t.Fatalf("Init Test config failed") + } + // remove the root directory after the test ends. + defer removeAll(rootPath) + + configPath := filepath.Join(rootPath, minioConfigFile) + + v := v14 + + testCases := []struct { + configData string + shouldPass bool + }{ + // Test 1 - wrong json + {`{`, false}, + + // Test 2 - empty json + {`{}`, false}, + + // Test 3 - wrong config version + {`{"version": "10"}`, false}, + + // Test 4 - wrong browser parameter + {`{"version": "` + v + `", "browser": "foo"}`, false}, + + // Test 5 - missing credential + {`{"version": "` + v + `", "browser": "on"}`, false}, + + // Test 6 - missing secret key + {`{"version": "` + v + `", "browser": "on", "credential" : {"accessKey":"minio", "secretKey":""}}`, false}, + + // Test 7 - missing region + {`{"version": "` + v + `", "browser": "on", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, false}, + + // Test 8 - success + {`{"version": "` + v + `", "browser": "on", "region":"us-east-1", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, true}, + + // Test 9 - duplicated json keys + {`{"version": "` + v + `", "browser": "on", "browser": "on", "region":"us-east-1", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, false}, + + // Test 10 - Wrong Console logger level + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "logger": { "console": { "enable": true, "level": "foo" } }}`, false}, + + // Test 11 - Wrong File logger level + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "logger": { "file": { "enable": true, "level": "foo" } }}`, false}, + + // Test 12 - Test AMQP + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "amqp": { "1": { "enable": true, "url": "", "exchange": "", "routingKey": "", "exchangeType": "", "mandatory": false, "immediate": false, "durable": false, "internal": false, "noWait": false, "autoDeleted": false }}}}`, false}, + + // Test 13 - Test NATS + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "nats": { "1": { "enable": true, "address": "", "subject": "", "username": "", "password": "", "token": "", "secure": false, "pingInterval": 0, "streaming": { "enable": false, "clusterID": "", "clientID": "", "async": false, "maxPubAcksInflight": 0 } } }}}`, false}, + + // Test 14 - Test ElasticSearch + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "elasticsearch": { "1": { "enable": true, "url": "", "index": "" } }}}`, false}, + + // Test 15 - Test Redis + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "redis": { "1": { "enable": true, "address": "", "password": "", "key": "" } }}}`, false}, + + // Test 16 - Test PostgreSQL + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "postgresql": { "1": { "enable": true, "connectionString": "", "table": "", "host": "", "port": "", "user": "", "password": "", "database": "" }}}}`, false}, + + // Test 17 - Test Kafka + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "kafka": { "1": { "enable": true, "brokers": null, "topic": "" } }}}`, false}, + + // Test 18 - Test Webhook + {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "webhook": { "1": { "enable": true, "endpoint": "" } }}}`, false}, + } + + for i, testCase := range testCases { + if err := ioutil.WriteFile(configPath, []byte(testCase.configData), 0700); err != nil { + t.Error(err) + } + err := validateConfig() + if testCase.shouldPass && err != nil { + t.Errorf("Test %d, should pass but it failed with err = %v", i+1, err) + } + if !testCase.shouldPass && err == nil { + t.Errorf("Test %d, should fail but it succeed.", i+1) + } + } + +} diff --git a/cmd/credential.go b/cmd/credential.go index c75049050..c6f9953a4 100644 --- a/cmd/credential.go +++ b/cmd/credential.go @@ -19,6 +19,7 @@ package cmd import ( "crypto/rand" "encoding/base64" + "errors" "os" "github.com/minio/mc/pkg/console" @@ -75,6 +76,16 @@ type credential struct { secretKeyHash []byte } +func (c *credential) Validate() error { + if !isAccessKeyValid(c.AccessKey) { + return errors.New("Invalid access key") + } + if !isSecretKeyValid(c.SecretKey) { + return errors.New("Invalid secret key") + } + return nil +} + // Generate a bcrypt hashed key for input secret key. func mustGetHashedSecretKey(secretKey string) []byte { hashedSecretKey, err := bcrypt.GenerateFromPassword([]byte(secretKey), bcrypt.DefaultCost) diff --git a/cmd/logger-console-hook.go b/cmd/logger-console-hook.go index fdc5264e8..a437ec1ad 100644 --- a/cmd/logger-console-hook.go +++ b/cmd/logger-console-hook.go @@ -16,7 +16,12 @@ package cmd -import "github.com/Sirupsen/logrus" +import ( + "fmt" + "strings" + + "github.com/Sirupsen/logrus" +) // consoleLogger - default logger if not other logging is enabled. type consoleLogger struct { @@ -24,6 +29,14 @@ type consoleLogger struct { Level string `json:"level"` } +func (c *consoleLogger) Validate() error { + level := strings.ToLower(c.Level) + if level != "error" && level != "fatal" && level != "" { + return fmt.Errorf("`%s` level value not recognized", c.Level) + } + return nil +} + // enable console logger. func enableConsoleLogger() { clogger := serverConfig.Logger.GetConsole() diff --git a/cmd/logger-file-hook.go b/cmd/logger-file-hook.go index c7b5f6652..9fbd20ea2 100644 --- a/cmd/logger-file-hook.go +++ b/cmd/logger-file-hook.go @@ -20,6 +20,7 @@ import ( "fmt" "io/ioutil" "os" + "strings" "github.com/Sirupsen/logrus" ) @@ -30,6 +31,14 @@ type fileLogger struct { Level string `json:"level"` } +func (f *fileLogger) Validate() error { + level := strings.ToLower(f.Level) + if level != "error" && level != "fatal" && level != "" { + return fmt.Errorf("`%s` level value not recognized", f.Level) + } + return nil +} + type localFile struct { *os.File } diff --git a/cmd/logger.go b/cmd/logger.go index a0f999fcf..a6ef792b8 100644 --- a/cmd/logger.go +++ b/cmd/logger.go @@ -47,6 +47,20 @@ type logger struct { /// Logger related. +// Validate logger contents +func (l *logger) Validate() error { + if l == nil { + return nil + } + if err := l.Console.Validate(); err != nil { + return fmt.Errorf("`Console` field: %s", err.Error()) + } + if err := l.File.Validate(); err != nil { + return fmt.Errorf("`File` field: %s", err.Error()) + } + return nil +} + // SetFile set new file logger. func (l *logger) SetFile(flogger fileLogger) { l.Lock() diff --git a/cmd/notifier-config.go b/cmd/notifier-config.go index 2c9728158..531b4d016 100644 --- a/cmd/notifier-config.go +++ b/cmd/notifier-config.go @@ -16,7 +16,10 @@ package cmd -import "sync" +import ( + "fmt" + "sync" +) // Notifier represents collection of supported notification queues. type notifier struct { @@ -41,6 +44,15 @@ func (a amqpConfigs) Clone() amqpConfigs { return a2 } +func (a amqpConfigs) Validate() error { + for k, v := range a { + if err := v.Validate(); err != nil { + return fmt.Errorf("AMQP [%s] configuration invalid: %s", k, err.Error()) + } + } + return nil +} + type natsConfigs map[string]natsNotify func (a natsConfigs) Clone() natsConfigs { @@ -51,6 +63,15 @@ func (a natsConfigs) Clone() natsConfigs { return a2 } +func (a natsConfigs) Validate() error { + for k, v := range a { + if err := v.Validate(); err != nil { + return fmt.Errorf("NATS [%s] configuration invalid: %s", k, err.Error()) + } + } + return nil +} + type elasticSearchConfigs map[string]elasticSearchNotify func (a elasticSearchConfigs) Clone() elasticSearchConfigs { @@ -61,6 +82,15 @@ func (a elasticSearchConfigs) Clone() elasticSearchConfigs { return a2 } +func (a elasticSearchConfigs) Validate() error { + for k, v := range a { + if err := v.Validate(); err != nil { + return fmt.Errorf("ElasticSearch [%s] configuration invalid: %s", k, err.Error()) + } + } + return nil +} + type redisConfigs map[string]redisNotify func (a redisConfigs) Clone() redisConfigs { @@ -71,6 +101,15 @@ func (a redisConfigs) Clone() redisConfigs { return a2 } +func (a redisConfigs) Validate() error { + for k, v := range a { + if err := v.Validate(); err != nil { + return fmt.Errorf("Redis [%s] configuration invalid: %s", k, err.Error()) + } + } + return nil +} + type postgreSQLConfigs map[string]postgreSQLNotify func (a postgreSQLConfigs) Clone() postgreSQLConfigs { @@ -81,6 +120,15 @@ func (a postgreSQLConfigs) Clone() postgreSQLConfigs { return a2 } +func (a postgreSQLConfigs) Validate() error { + for k, v := range a { + if err := v.Validate(); err != nil { + return fmt.Errorf("PostgreSQL [%s] configuration invalid: %s", k, err.Error()) + } + } + return nil +} + type kafkaConfigs map[string]kafkaNotify func (a kafkaConfigs) Clone() kafkaConfigs { @@ -91,6 +139,15 @@ func (a kafkaConfigs) Clone() kafkaConfigs { return a2 } +func (a kafkaConfigs) Validate() error { + for k, v := range a { + if err := v.Validate(); err != nil { + return fmt.Errorf("Kafka [%s] configuration invalid: %s", k, err.Error()) + } + } + return nil +} + type webhookConfigs map[string]webhookNotify func (a webhookConfigs) Clone() webhookConfigs { @@ -101,6 +158,43 @@ func (a webhookConfigs) Clone() webhookConfigs { return a2 } +func (a webhookConfigs) Validate() error { + for k, v := range a { + if err := v.Validate(); err != nil { + return fmt.Errorf("Webhook [%s] configuration invalid: %s", k, err.Error()) + } + } + return nil +} + +func (n *notifier) Validate() error { + if n == nil { + return nil + } + if err := n.AMQP.Validate(); err != nil { + return err + } + if err := n.NATS.Validate(); err != nil { + return err + } + if err := n.ElasticSearch.Validate(); err != nil { + return err + } + if err := n.Redis.Validate(); err != nil { + return err + } + if err := n.PostgreSQL.Validate(); err != nil { + return err + } + if err := n.Kafka.Validate(); err != nil { + return err + } + if err := n.Webhook.Validate(); err != nil { + return err + } + return nil +} + func (n *notifier) SetAMQPByID(accountID string, amqpn amqpNotify) { n.Lock() defer n.Unlock() diff --git a/cmd/notify-amqp.go b/cmd/notify-amqp.go index f3b09379c..8e3b4652e 100644 --- a/cmd/notify-amqp.go +++ b/cmd/notify-amqp.go @@ -40,6 +40,16 @@ type amqpNotify struct { AutoDeleted bool `json:"autoDeleted"` } +func (a *amqpNotify) Validate() error { + if !a.Enable { + return nil + } + if _, err := checkNetURL(a.URL); err != nil { + return err + } + return nil +} + type amqpConn struct { params amqpNotify *amqp.Connection diff --git a/cmd/notify-elasticsearch.go b/cmd/notify-elasticsearch.go index 508b7ed9e..4773feaf2 100644 --- a/cmd/notify-elasticsearch.go +++ b/cmd/notify-elasticsearch.go @@ -33,6 +33,16 @@ type elasticSearchNotify struct { Index string `json:"index"` } +func (e *elasticSearchNotify) Validate() error { + if !e.Enable { + return nil + } + if _, err := checkNetURL(e.URL); err != nil { + return err + } + return nil +} + type elasticClient struct { *elastic.Client params elasticSearchNotify diff --git a/cmd/notify-kafka.go b/cmd/notify-kafka.go index 7ddf454b8..3ce4112d2 100644 --- a/cmd/notify-kafka.go +++ b/cmd/notify-kafka.go @@ -17,6 +17,7 @@ package cmd import ( + "errors" "fmt" "io/ioutil" @@ -39,6 +40,16 @@ type kafkaNotify struct { Topic string `json:"topic"` } +func (k *kafkaNotify) Validate() error { + if !k.Enable { + return nil + } + if len(k.Brokers) == 0 { + return errors.New("No broker specified") + } + return nil +} + // kafkaConn contains the active connection to the Kafka cluster and // the topic to send event notifications to. type kafkaConn struct { diff --git a/cmd/notify-nats.go b/cmd/notify-nats.go index b18751ded..8fe0654d7 100644 --- a/cmd/notify-nats.go +++ b/cmd/notify-nats.go @@ -48,6 +48,16 @@ type natsNotify struct { Streaming natsNotifyStreaming `json:"streaming"` } +func (n *natsNotify) Validate() error { + if !n.Enable { + return nil + } + if _, err := checkNetURL(n.Address); err != nil { + return err + } + return nil +} + // natsIOConn abstracts connection to any type of NATS server type natsIOConn struct { params natsNotify diff --git a/cmd/notify-postgresql.go b/cmd/notify-postgresql.go index 116092520..1ea092f5b 100644 --- a/cmd/notify-postgresql.go +++ b/cmd/notify-postgresql.go @@ -84,6 +84,16 @@ type postgreSQLNotify struct { Database string `json:"database"` } +func (p *postgreSQLNotify) Validate() error { + if !p.Enable { + return nil + } + if _, err := checkNetURL(p.Host); err != nil { + return err + } + return nil +} + type pgConn struct { connStr string table string diff --git a/cmd/notify-redis.go b/cmd/notify-redis.go index 8e382edb5..b4730e404 100644 --- a/cmd/notify-redis.go +++ b/cmd/notify-redis.go @@ -32,6 +32,16 @@ type redisNotify struct { Key string `json:"key"` } +func (r *redisNotify) Validate() error { + if !r.Enable { + return nil + } + if _, err := checkNetURL(r.Addr); err != nil { + return err + } + return nil +} + type redisConn struct { *redis.Pool params redisNotify diff --git a/cmd/notify-webhook.go b/cmd/notify-webhook.go index 7bdb8f086..b028c8e4e 100644 --- a/cmd/notify-webhook.go +++ b/cmd/notify-webhook.go @@ -32,6 +32,16 @@ type webhookNotify struct { Endpoint string `json:"endpoint"` } +func (w *webhookNotify) Validate() error { + if !w.Enable { + return nil + } + if _, err := checkNetURL(w.Endpoint); err != nil { + return err + } + return nil +} + type httpConn struct { *http.Client Endpoint string diff --git a/cmd/server-main.go b/cmd/server-main.go index 6f44624ca..5f91e4de3 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -127,7 +127,7 @@ func initConfig() { // Config file does not exist, we create it fresh and return upon success. if !isConfigFileExists() { if err := newConfig(envs); err != nil { - console.Fatalf("Unable to initialize minio config for the first time. Err: %s.\n", err) + console.Fatalf("Unable to initialize minio config for the first time. Error: %s.\n", err) } console.Println("Created minio configuration file successfully at " + getConfigDir()) return @@ -136,9 +136,14 @@ func initConfig() { // Migrate any old version of config / state files to newer format. migrate() + // Validate config file + if err := validateConfig(); err != nil { + console.Fatalf("Cannot validate configuration file. Error: %s\n", err) + } + // Once we have migrated all the old config, now load them. if err := loadConfig(envs); err != nil { - console.Fatalf("Unable to initialize minio config. Err: %s.\n", err) + console.Fatalf("Unable to initialize minio config. Error: %s.\n", err) } } diff --git a/cmd/utils.go b/cmd/utils.go index 3eeedae09..4d8512408 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -285,3 +285,16 @@ func isFile(path string) bool { return false } + +// checkNetURL - checks if passed address correspond +// to a network address (and not file system path) +func checkNetURL(address string) (*url.URL, error) { + u, err := url.Parse(address) + if err != nil { + return nil, fmt.Errorf("`%s` invalid: %s", address, err.Error()) + } + if u.Host == "" { + return nil, fmt.Errorf("`%s` invalid network URL", address) + } + return u, nil +} diff --git a/vendor/github.com/tidwall/gjson/README.md b/vendor/github.com/tidwall/gjson/README.md index 1ee5ae3dd..b38f920bf 100644 --- a/vendor/github.com/tidwall/gjson/README.md +++ b/vendor/github.com/tidwall/gjson/README.md @@ -11,7 +11,7 @@

    get a json value quickly

    -GJSON is a Go package the provides a [very fast](#performance) and simple way to get a value from a json document. The reason for this library it to give efficient json indexing for the [BuntDB](https://github.com/tidwall/buntdb) project. +GJSON is a Go package that provides a [very fast](#performance) and simple way to get a value from a json document. The purpose for this library it to give efficient json indexing for the [BuntDB](https://github.com/tidwall/buntdb) project. Getting Started =============== @@ -27,7 +27,7 @@ $ go get -u github.com/tidwall/gjson This will retrieve the library. ## Get a value -Get searches json for the specified path. A path is in dot syntax, such as "name.last" or "age". This function expects that the json is well-formed and validates. Invalid json will not panic, but it may return back unexpected results. When the value is found it's returned immediately. +Get searches json for the specified path. A path is in dot syntax, such as "name.last" or "age". This function expects that the json is well-formed and validates. Invalid json will not panic, but it may return back unexpected results. When the value is found it's returned immediately. ```go package main @@ -47,6 +47,7 @@ This will print: ``` Prichard ``` +*There's also the [GetMany](#get-multiple-values-at-once) function to get multiple values at once, and [GetBytes](#working-with-bytes) for working with JSON byte slices.* ## Path Syntax @@ -63,25 +64,33 @@ The dot and wildcard characters can be escaped with '\'. "children": ["Sara","Alex","Jack"], "fav.movie": "Deer Hunter", "friends": [ - {"first": "James", "last": "Murphy"}, - {"first": "Roger", "last": "Craig"} + {"first": "Dale", "last": "Murphy", "age": 44}, + {"first": "Roger", "last": "Craig", "age": 68}, + {"first": "Jane", "last": "Murphy", "age": 47} ] } ``` ``` "name.last" >> "Anderson" "age" >> 37 +"children" >> ["Sara","Alex","Jack"] "children.#" >> 3 "children.1" >> "Alex" "child*.2" >> "Jack" "c?ildren.0" >> "Sara" "fav\.movie" >> "Deer Hunter" -"friends.#.first" >> [ "James", "Roger" ] +"friends.#.first" >> ["Dale","Roger","Jane"] "friends.1.last" >> "Craig" ``` -To query an array: + +You can also query an array for the first match by using `#[...]`, or find all matches with `#[...]#`. +Queries support the `==`, `!=`, `<`, `<=`, `>`, `>=` comparison operators and the simple pattern matching `%` operator. + ``` -`friends.#[last="Murphy"].first` >> "James" +friends.#[last=="Murphy"].first >> "Dale" +friends.#[last=="Murphy"]#.first >> ["Dale","Jane"] +friends.#[age>45]#.last >> ["Craig","Murphy"] +friends.#[first%"D*"].last >> "Murphy" ``` ## Result Type @@ -105,7 +114,7 @@ result.Type // can be String, Number, True, False, Null, or JSON result.Str // holds the string result.Num // holds the float64 number result.Raw // holds the raw json -result.Multi // holds nested array values +result.Index // index of raw value in original json, zero means index unknown ``` There are a variety of handy functions that work on a result: @@ -113,16 +122,25 @@ There are a variety of handy functions that work on a result: ```go result.Value() interface{} result.Int() int64 +result.Uint() uint64 result.Float() float64 result.String() string result.Bool() bool result.Array() []gjson.Result result.Map() map[string]gjson.Result result.Get(path string) Result +result.ForEach(iterator func(key, value Result) bool) +result.Less(token Result, caseSensitive bool) bool ``` The `result.Value()` function returns an `interface{}` which requires type assertion and is one of the following Go types: + + +The `result.Array()` function returns back an array of values. +If the result represents a non-existent value, then an empty array will be returned. +If the result is not a JSON array, the return value will be an array containing one result. + ```go boolean >> bool number >> float64 @@ -169,6 +187,20 @@ name := gjson.Get(json, `programmers.#[lastName="Hunter"].firstName`) println(name.String()) // prints "Elliotte" ``` +## Iterate through an object or array + +The `ForEach` function allows for quickly iterating through an object or array. +The key and value are passed to the iterator function for objects. +Only the value is passed for arrays. +Returning `false` from an iterator will stop iteration. + +```go +result := gjson.Get(json, "programmers") +result.ForEach(func(key, value gjson.Result) bool{ + println(value.String()) + return true // keep iterating +}) +``` ## Simple Parse and Get @@ -184,7 +216,7 @@ gjson.Get(json, "name.last") ## Check for the existence of a value -Sometimes you just want to know you if a value exists. +Sometimes you just want to know if a value exists. ```go value := gjson.Get(json, "name.last") @@ -211,6 +243,40 @@ if !ok{ } ``` +## Working with Bytes + +If your JSON is contained in a `[]byte` slice, there's the [GetBytes](https://godoc.org/github.com/tidwall/gjson#GetBytes) function. This is preferred over `Get(string(data), path)`. + +```go +var json []byte = ... +result := gjson.GetBytes(json, path) +``` + +If you are using the `gjson.GetBytes(json, path)` function and you want to avoid converting `result.Raw` to a `[]byte`, then you can use this pattern: + +```go +var json []byte = ... +result := gjson.GetBytes(json, path) +var raw []byte +if result.Index > 0 { + raw = json[result.Index:result.Index+len(result.Raw)] +} else { + raw = []byte(result.Raw) +} +``` + +This is a best-effort no allocation sub slice of the original json. This method utilizes the `result.Index` field, which is the position of the raw data in the original json. It's possible that the value of `result.Index` equals zero, in which case the `result.Raw` is converted to a `[]byte`. + +## Get multiple values at once + +The `GetMany` function can be used to get multiple values at the same time, and is optimized to scan over a JSON payload once. + +```go +results := gjson.GetMany(json, "name.first", "name.last", "age") +``` + +The return value is a `[]Result`, which will always contain exactly the same number of items as the input paths. + ## Performance Benchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/json/), @@ -229,6 +295,17 @@ BenchmarkEasyJSONLexer-8 3000000 938 ns/op 613 B/op BenchmarkJSONParserGet-8 3000000 442 ns/op 21 B/op 0 allocs/op ``` +Benchmarks for the `GetMany` function: + +``` +BenchmarkGJSONGetMany4Paths-8 4000000 319 ns/op 112 B/op 0 allocs/op +BenchmarkGJSONGetMany8Paths-8 8000000 218 ns/op 56 B/op 0 allocs/op +BenchmarkGJSONGetMany16Paths-8 16000000 160 ns/op 56 B/op 0 allocs/op +BenchmarkGJSONGetMany32Paths-8 32000000 130 ns/op 64 B/op 0 allocs/op +BenchmarkGJSONGetMany64Paths-8 64000000 117 ns/op 64 B/op 0 allocs/op +BenchmarkGJSONGetMany128Paths-8 128000000 109 ns/op 64 B/op 0 allocs/op +``` + JSON document used: ```json @@ -267,6 +344,20 @@ widget.image.hOffset widget.text.onMouseUp ``` +For the `GetMany` benchmarks these paths are used: + +``` +widget.window.name +widget.image.hOffset +widget.text.onMouseUp +widget.window.title +widget.image.alignment +widget.text.style +widget.window.height +widget.image.src +widget.text.data +widget.text.size +``` *These benchmarks were run on a MacBook Pro 15" 2.8 GHz Intel Core i7 using Go 1.7.* diff --git a/vendor/github.com/tidwall/gjson/gjson.go b/vendor/github.com/tidwall/gjson/gjson.go index 5ad877455..9b28df2ca 100644 --- a/vendor/github.com/tidwall/gjson/gjson.go +++ b/vendor/github.com/tidwall/gjson/gjson.go @@ -4,6 +4,10 @@ package gjson import ( "reflect" "strconv" + + // It's totally safe to use this package, but in case your + // project or organization restricts the use of 'unsafe', + // there's the "github.com/tidwall/gjson-safe" package. "unsafe" "github.com/tidwall/match" @@ -27,6 +31,26 @@ const ( JSON ) +// String returns a string representation of the type. +func (t Type) String() string { + switch t { + default: + return "" + case Null: + return "Null" + case False: + return "False" + case Number: + return "Number" + case String: + return "String" + case True: + return "True" + case JSON: + return "JSON" + } +} + // Result represents a json value that is returned from Get(). type Result struct { // Type is the json type @@ -37,6 +61,8 @@ type Result struct { Str string // Num is the json number Num float64 + // Index of raw value in original json, zero means index unknown + Index int } // String returns a string representation of the value. @@ -86,6 +112,21 @@ func (t Result) Int() int64 { } } +// Uint returns an unsigned integer representation. +func (t Result) Uint() uint64 { + switch t.Type { + default: + return 0 + case True: + return 1 + case String: + n, _ := strconv.ParseUint(t.Str, 10, 64) + return n + case Number: + return uint64(t.Num) + } +} + // Float returns an float64 representation. func (t Result) Float() float64 { switch t.Type { @@ -101,16 +142,91 @@ func (t Result) Float() float64 { } } -// Array returns back an array of children. The result must be a JSON array. +// Array returns back an array of values. +// If the result represents a non-existent value, then an empty array will be returned. +// If the result is not a JSON array, the return value will be an array containing one result. func (t Result) Array() []Result { - if t.Type != JSON { + if !t.Exists() { return nil } + if t.Type != JSON { + return []Result{t} + } r := t.arrayOrMap('[', false) return r.a } -// Map returns back an map of children. The result should be a JSON array. +// ForEach iterates through values. +// If the result represents a non-existent value, then no values will be iterated. +// If the result is an Object, the iterator will pass the key and value of each item. +// If the result is an Array, the iterator will only pass the value of each item. +// If the result is not a JSON array or object, the iterator will pass back one value equal to the result. +func (t Result) ForEach(iterator func(key, value Result) bool) { + if !t.Exists() { + return + } + if t.Type != JSON { + iterator(Result{}, t) + return + } + json := t.Raw + var keys bool + var i int + var key, value Result + for ; i < len(json); i++ { + if json[i] == '{' { + i++ + key.Type = String + keys = true + break + } else if json[i] == '[' { + i++ + break + } + if json[i] > ' ' { + return + } + } + var str string + var vesc bool + var ok bool + for ; i < len(json); i++ { + if keys { + if json[i] != '"' { + continue + } + s := i + i, str, vesc, ok = parseString(json, i+1) + if !ok { + return + } + if vesc { + key.Str = unescape(str[1 : len(str)-1]) + } else { + key.Str = str[1 : len(str)-1] + } + key.Raw = str + key.Index = s + } + for ; i < len(json); i++ { + if json[i] <= ' ' || json[i] == ',' || json[i] == ':' { + continue + } + break + } + s := i + i, value, ok = parseAny(json, i, true) + if !ok { + return + } + value.Index = s + if !iterator(key, value) { + return + } + } +} + +// Map returns back an map of values. The result should be a JSON array. func (t Result) Map() map[string]Result { if t.Type != JSON { return map[string]Result{} @@ -232,7 +348,7 @@ end: return } -// Parse parses the json and returns a result +// Parse parses the json and returns a result. func Parse(json string) Result { var value Result for i := 0; i < len(json); i++ { @@ -270,6 +386,12 @@ func Parse(json string) Result { return value } +// ParseBytes parses the json and returns a result. +// If working with bytes, this method preferred over Parse(string(data)) +func ParseBytes(json []byte) Result { + return Parse(string(json)) +} + func squash(json string) string { // expects that the lead character is a '[' or '{' // squash the value, ignoring all nested arrays and objects. @@ -387,7 +509,13 @@ func tostr(json string) (raw string, str string) { break } } - return json[:i+1], unescape(json[1:i]) + var ret string + if i+1 < len(json) { + ret = json[:i+1] + } else { + ret = json[:i] + } + return ret, unescape(json[1:i]) } } return json, json[1:] @@ -506,6 +634,7 @@ type arrayPathResult struct { path string op string value string + all bool } } @@ -536,8 +665,12 @@ func parseArrayPath(path string) (r arrayPathResult) { } s := i for ; i < len(path); i++ { - if path[i] <= ' ' || path[i] == '=' || - path[i] == '<' || path[i] == '>' || + if path[i] <= ' ' || + path[i] == '!' || + path[i] == '=' || + path[i] == '<' || + path[i] == '>' || + path[i] == '%' || path[i] == ']' { break } @@ -551,7 +684,11 @@ func parseArrayPath(path string) (r arrayPathResult) { } if i < len(path) { s = i - if path[i] == '<' || path[i] == '>' { + if path[i] == '!' { + if i < len(path)-1 && path[i+1] == '=' { + i++ + } + } else if path[i] == '<' || path[i] == '>' { if i < len(path)-1 && path[i+1] == '=' { i++ } @@ -596,6 +733,9 @@ func parseArrayPath(path string) (r arrayPathResult) { } } } else if path[i] == ']' { + if i+1 < len(path) && path[i+1] == '#' { + r.query.all = true + } break } } @@ -877,6 +1017,8 @@ func queryMatches(rp *arrayPathResult, value Result) bool { switch rp.query.op { case "=": return value.Str == rpv + case "!=": + return value.Str != rpv case "<": return value.Str < rpv case "<=": @@ -885,12 +1027,16 @@ func queryMatches(rp *arrayPathResult, value Result) bool { return value.Str > rpv case ">=": return value.Str >= rpv + case "%": + return match.Match(value.Str, rpv) } case Number: rpvn, _ := strconv.ParseFloat(rpv, 64) switch rp.query.op { case "=": return value.Num == rpvn + case "!=": + return value.Num == rpvn case "<": return value.Num < rpvn case "<=": @@ -904,6 +1050,8 @@ func queryMatches(rp *arrayPathResult, value Result) bool { switch rp.query.op { case "=": return rpv == "true" + case "!=": + return rpv != "true" case ">": return rpv == "false" case ">=": @@ -913,6 +1061,8 @@ func queryMatches(rp *arrayPathResult, value Result) bool { switch rp.query.op { case "=": return rpv == "false" + case "!=": + return rpv != "false" case "<": return rpv == "true" case "<=": @@ -927,6 +1077,7 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { var h int var alog []int var partidx int + var multires []byte rp := parseArrayPath(path) if !rp.arrch { n, err := strconv.ParseUint(rp.part, 10, 64) @@ -983,12 +1134,21 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { res := Get(val, rp.query.path) if queryMatches(&rp, res) { if rp.more { - c.value = Get(val, rp.path) + res = Get(val, rp.path) } else { - c.value.Raw = val - c.value.Type = JSON + res = Result{Raw: val, Type: JSON} + } + if rp.query.all { + if len(multires) == 0 { + multires = append(multires, '[') + } else { + multires = append(multires, ',') + } + multires = append(multires, res.Raw...) + } else { + c.value = res + return i, true } - return i, true } } else if hit { if rp.alogok { @@ -1051,13 +1211,14 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { if rp.alogok { var jsons = make([]byte, 0, 64) jsons = append(jsons, '[') - for j := 0; j < len(alog); j++ { + for j, k := 0, 0; j < len(alog); j++ { res := Get(c.json[alog[j]:], rp.alogkey) if res.Exists() { - if j > 0 { + if k > 0 { jsons = append(jsons, ',') } jsons = append(jsons, []byte(res.Raw)...) + k++ } } jsons = append(jsons, ']') @@ -1071,9 +1232,16 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { c.value.Raw = val c.value.Type = Number c.value.Num = float64(h - 1) + c.calcd = true return i + 1, true } } + if len(multires) > 0 && !c.value.Exists() { + c.value = Result{ + Raw: string(append(multires, ']')), + Type: JSON, + } + } return i + 1, false } break @@ -1085,6 +1253,7 @@ func parseArray(c *parseContext, i int, path string) (int, bool) { type parseContext struct { json string value Result + calcd bool } // Get searches json for the specified path. @@ -1093,7 +1262,7 @@ type parseContext struct { // Invalid json will not panic, but it may return back unexpected results. // When the value is found it's returned immediately. // -// A path is a series of keys seperated by a dot. +// A path is a series of keys searated by a dot. // A key may contain special wildcard characters '*' and '?'. // To access an array value use the index as the key. // To get the number of elements in an array or to access a child path, use the '#' character. @@ -1110,11 +1279,12 @@ type parseContext struct { // } // "name.last" >> "Anderson" // "age" >> 37 +// "children" >> ["Sara","Alex","Jack"] // "children.#" >> 3 // "children.1" >> "Alex" // "child*.2" >> "Jack" // "c?ildren.0" >> "Sara" -// "friends.#.first" >> [ "James", "Roger" ] +// "friends.#.first" >> ["James","Roger"] // func Get(json, path string) Result { var i int @@ -1131,8 +1301,53 @@ func Get(json, path string) Result { break } } + if len(c.value.Raw) > 0 && !c.calcd { + jhdr := *(*reflect.StringHeader)(unsafe.Pointer(&json)) + rhdr := *(*reflect.StringHeader)(unsafe.Pointer(&(c.value.Raw))) + c.value.Index = int(rhdr.Data - jhdr.Data) + if c.value.Index < 0 || c.value.Index >= len(json) { + c.value.Index = 0 + } + } return c.value } +func fromBytesGet(result Result) Result { + // safely get the string headers + rawhi := *(*reflect.StringHeader)(unsafe.Pointer(&result.Raw)) + strhi := *(*reflect.StringHeader)(unsafe.Pointer(&result.Str)) + // create byte slice headers + rawh := reflect.SliceHeader{Data: rawhi.Data, Len: rawhi.Len} + strh := reflect.SliceHeader{Data: strhi.Data, Len: strhi.Len} + if strh.Data == 0 { + // str is nil + if rawh.Data == 0 { + // raw is nil + result.Raw = "" + } else { + // raw has data, safely copy the slice header to a string + result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh))) + } + result.Str = "" + } else if rawh.Data == 0 { + // raw is nil + result.Raw = "" + // str has data, safely copy the slice header to a string + result.Str = string(*(*[]byte)(unsafe.Pointer(&strh))) + } else if strh.Data >= rawh.Data && + int(strh.Data)+strh.Len <= int(rawh.Data)+rawh.Len { + // Str is a substring of Raw. + start := int(strh.Data - rawh.Data) + // safely copy the raw slice header + result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh))) + // substring the raw + result.Str = result.Raw[start : start+strh.Len] + } else { + // safely copy both the raw and str slice headers to strings + result.Raw = string(*(*[]byte)(unsafe.Pointer(&rawh))) + result.Str = string(*(*[]byte)(unsafe.Pointer(&strh))) + } + return result +} // GetBytes searches json for the specified path. // If working with bytes, this method preferred over Get(string(data), path) @@ -1141,29 +1356,7 @@ func GetBytes(json []byte, path string) Result { if json != nil { // unsafe cast to string result = Get(*(*string)(unsafe.Pointer(&json)), path) - // copy of string data for safety. - rawh := *(*reflect.SliceHeader)(unsafe.Pointer(&result.Raw)) - strh := *(*reflect.SliceHeader)(unsafe.Pointer(&result.Str)) - if strh.Data == 0 { - if rawh.Data == 0 { - result.Raw = "" - } else { - result.Raw = string(*(*[]byte)(unsafe.Pointer(&result.Raw))) - } - result.Str = "" - } else if rawh.Data == 0 { - result.Raw = "" - result.Str = string(*(*[]byte)(unsafe.Pointer(&result.Str))) - } else if strh.Data >= rawh.Data && - int(strh.Data)+strh.Len <= int(rawh.Data)+rawh.Len { - // Str is a substring of Raw. - start := int(strh.Data - rawh.Data) - result.Raw = string(*(*[]byte)(unsafe.Pointer(&result.Raw))) - result.Str = result.Raw[start : start+strh.Len] - } else { - result.Raw = string(*(*[]byte)(unsafe.Pointer(&result.Raw))) - result.Str = string(*(*[]byte)(unsafe.Pointer(&result.Str))) - } + result = fromBytesGet(result) } return result } @@ -1289,3 +1482,465 @@ func stringLessInsensitive(a, b string) bool { } return len(a) < len(b) } + +// parseAny parses the next value from a json string. +// A Result is returned when the hit param is set. +// The return values are (i int, res Result, ok bool) +func parseAny(json string, i int, hit bool) (int, Result, bool) { + var res Result + var val string + for ; i < len(json); i++ { + if json[i] == '{' || json[i] == '[' { + i, val = parseSquash(json, i) + if hit { + res.Raw = val + res.Type = JSON + } + return i, res, true + } + if json[i] <= ' ' { + continue + } + switch json[i] { + case '"': + i++ + var vesc bool + var ok bool + i, val, vesc, ok = parseString(json, i) + if !ok { + return i, res, false + } + if hit { + res.Type = String + res.Raw = val + if vesc { + res.Str = unescape(val[1 : len(val)-1]) + } else { + res.Str = val[1 : len(val)-1] + } + } + return i, res, true + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + i, val = parseNumber(json, i) + if hit { + res.Raw = val + res.Type = Number + res.Num, _ = strconv.ParseFloat(val, 64) + } + return i, res, true + case 't', 'f', 'n': + vc := json[i] + i, val = parseLiteral(json, i) + if hit { + res.Raw = val + switch vc { + case 't': + res.Type = True + case 'f': + res.Type = False + } + return i, res, true + } + } + } + return i, res, false +} + +var ( // used for testing + testWatchForFallback bool + testLastWasFallback bool +) + +// areSimplePaths returns true if all the paths are simple enough +// to parse quickly for GetMany(). Allows alpha-numeric, dots, +// underscores, and the dollar sign. It does not allow non-alnum, +// escape characters, or keys which start with a numbers. +// For example: +// "name.last" == OK +// "user.id0" == OK +// "user.ID" == OK +// "user.first_name" == OK +// "user.firstName" == OK +// "user.0item" == BAD +// "user.#id" == BAD +// "user\.name" == BAD +func areSimplePaths(paths []string) bool { + for _, path := range paths { + var fi int // first key index, for keys with numeric prefix + for i := 0; i < len(path); i++ { + if path[i] >= 'a' && path[i] <= 'z' { + // a-z is likely to be the highest frequency charater. + continue + } + if path[i] == '.' { + fi = i + 1 + continue + } + if path[i] >= 'A' && path[i] <= 'Z' { + continue + } + if path[i] == '_' || path[i] == '$' { + continue + } + if i > fi && path[i] >= '0' && path[i] <= '9' { + continue + } + return false + } + } + return true +} + +// GetMany searches json for the multiple paths. +// The return value is a Result array where the number of items +// will be equal to the number of input paths. +func GetMany(json string, paths ...string) []Result { + if len(paths) < 4 { + if testWatchForFallback { + testLastWasFallback = false + } + switch len(paths) { + case 0: + // return nil when no paths are specified. + return nil + case 1: + return []Result{Get(json, paths[0])} + case 2: + return []Result{Get(json, paths[0]), Get(json, paths[1])} + case 3: + return []Result{Get(json, paths[0]), Get(json, paths[1]), Get(json, paths[2])} + } + } + var results []Result + var ok bool + var i int + if len(paths) > 512 { + // we can only support up to 512 paths. Is that too many? + goto fallback + } + if !areSimplePaths(paths) { + // If there is even one path that is not considered "simple" then + // we need to use the fallback method. + goto fallback + } + // locate the object token. + for ; i < len(json); i++ { + if json[i] == '{' { + i++ + break + } + if json[i] <= ' ' { + continue + } + goto fallback + } + // use the call function table. + if len(paths) <= 8 { + results, ok = getMany8(json, i, paths) + } else if len(paths) <= 16 { + results, ok = getMany16(json, i, paths) + } else if len(paths) <= 32 { + results, ok = getMany32(json, i, paths) + } else if len(paths) <= 64 { + results, ok = getMany64(json, i, paths) + } else if len(paths) <= 128 { + results, ok = getMany128(json, i, paths) + } else if len(paths) <= 256 { + results, ok = getMany256(json, i, paths) + } else if len(paths) <= 512 { + results, ok = getMany512(json, i, paths) + } + if !ok { + // there was some fault while parsing. we should try the + // fallback method. This could result in performance + // degregation in some cases. + goto fallback + } + if testWatchForFallback { + testLastWasFallback = false + } + return results +fallback: + results = results[:0] + for i := 0; i < len(paths); i++ { + results = append(results, Get(json, paths[i])) + } + if testWatchForFallback { + testLastWasFallback = true + } + return results +} + +// GetManyBytes searches json for the specified path. +// If working with bytes, this method preferred over +// GetMany(string(data), paths...) +func GetManyBytes(json []byte, paths ...string) []Result { + if json == nil { + return GetMany("", paths...) + } + results := GetMany(*(*string)(unsafe.Pointer(&json)), paths...) + for i := range results { + results[i] = fromBytesGet(results[i]) + } + return results +} + +// parseGetMany parses a json object for keys that match against the callers +// paths. It's a best-effort attempt and quickly locating and assigning the +// values to the []Result array. If there are failures such as bad json, or +// invalid input paths, or too much recursion, the function will exit with a +// return value of 'false'. +func parseGetMany( + json string, i int, + level uint, kplen int, + paths []string, completed []bool, matches []uint64, results []Result, +) (int, bool) { + if level > 62 { + // The recursion level is limited because the matches []uint64 + // array cannot handle more the 64-bits. + return i, false + } + // At this point the last character read was a '{'. + // Read all object keys and try to match against the paths. + var key string + var val string + var vesc, ok bool +next_key: + for ; i < len(json); i++ { + if json[i] == '"' { + // read the key + i, val, vesc, ok = parseString(json, i+1) + if !ok { + return i, false + } + if vesc { + // the value is escaped + key = unescape(val[1 : len(val)-1]) + } else { + // just a plain old ascii key + key = val[1 : len(val)-1] + } + var hasMatch bool + var parsedVal bool + var valOrgIndex int + var valPathIndex int + for j := 0; j < len(key); j++ { + if key[j] == '.' { + // we need to look for keys with dot and ignore them. + if i, _, ok = parseAny(json, i, false); !ok { + return i, false + } + continue next_key + } + } + var usedPaths int + // loop through paths and look for matches + for j := 0; j < len(paths); j++ { + if completed[j] { + usedPaths++ + // ignore completed paths + continue + } + if level > 0 && (matches[j]>>(level-1))&1 == 0 { + // ignore unmatched paths + usedPaths++ + continue + } + + // try to match the key to the path + // this is spaghetti code but the idea is to minimize + // calls and variable assignments when comparing the + // key to paths + if len(paths[j])-kplen >= len(key) { + i, k := kplen, 0 + for ; k < len(key); k, i = k+1, i+1 { + if key[k] != paths[j][i] { + // no match + goto nomatch + } + } + if i < len(paths[j]) { + if paths[j][i] == '.' { + // matched, but there still more keys in the path + goto match_not_atend + } + } + // matched and at the end of the path + goto match_atend + } + // no match, jump to the nomatch label + goto nomatch + match_atend: + // found a match + // at the end of the path. we must take the value. + usedPaths++ + if !parsedVal { + // the value has not been parsed yet. let's do so. + valOrgIndex = i // keep track of the current position. + i, results[j], ok = parseAny(json, i, true) + if !ok { + return i, false + } + parsedVal = true + valPathIndex = j + } else { + results[j] = results[valPathIndex] + } + // mark as complete + completed[j] = true + // jump over the match_not_atend label + goto nomatch + match_not_atend: + // found a match + // still in the middle of the path. + usedPaths++ + // mark the path as matched + matches[j] |= 1 << level + if !hasMatch { + hasMatch = true + } + nomatch: // noop label + } + + if !parsedVal { + if hasMatch { + // we found a match and the value has not been parsed yet. + // let's find out if the next value type is an object. + for ; i < len(json); i++ { + if json[i] <= ' ' || json[i] == ':' { + continue + } + break + } + if i < len(json) { + if json[i] == '{' { + // it's an object. let's go deeper + i, ok = parseGetMany(json, i+1, level+1, kplen+len(key)+1, paths, completed, matches, results) + if !ok { + return i, false + } + } else { + // not an object. just parse and ignore. + if i, _, ok = parseAny(json, i, false); !ok { + return i, false + } + } + } + } else { + // Since there was no matches we can just parse the value and + // ignore the result. + if i, _, ok = parseAny(json, i, false); !ok { + return i, false + } + } + } else if hasMatch && len(results[valPathIndex].Raw) > 0 && results[valPathIndex].Raw[0] == '{' { + // The value was already parsed and the value type is an object. + // Rewind the json index and let's parse deeper. + i = valOrgIndex + for ; i < len(json); i++ { + if json[i] == '{' { + break + } + } + i, ok = parseGetMany(json, i+1, level+1, kplen+len(key)+1, paths, completed, matches, results) + if !ok { + return i, false + } + } + if usedPaths == len(paths) { + // all paths have been used, either completed or matched. + // we should stop parsing this object to save CPU cycles. + if level > 0 && i < len(json) { + i, _ = parseSquash(json, i) + } + return i, true + } + } else if json[i] == '}' { + // reached the end of the object. end it here. + return i + 1, true + } + } + return i, true +} + +// Call table for GetMany. Using an isolated function allows for allocating +// arrays with know capacities on the stack, as opposed to dynamically +// allocating on the heap. This can provide a tremendous performance boost +// by avoiding the GC. +func getMany8(json string, i int, paths []string) ([]Result, bool) { + const max = 8 + var completed = make([]bool, 0, max) + var matches = make([]uint64, 0, max) + var results = make([]Result, 0, max) + completed = completed[0:len(paths):max] + matches = matches[0:len(paths):max] + results = results[0:len(paths):max] + _, ok := parseGetMany(json, i, 0, 0, paths, completed, matches, results) + return results, ok +} +func getMany16(json string, i int, paths []string) ([]Result, bool) { + const max = 16 + var completed = make([]bool, 0, max) + var matches = make([]uint64, 0, max) + var results = make([]Result, 0, max) + completed = completed[0:len(paths):max] + matches = matches[0:len(paths):max] + results = results[0:len(paths):max] + _, ok := parseGetMany(json, i, 0, 0, paths, completed, matches, results) + return results, ok +} +func getMany32(json string, i int, paths []string) ([]Result, bool) { + const max = 32 + var completed = make([]bool, 0, max) + var matches = make([]uint64, 0, max) + var results = make([]Result, 0, max) + completed = completed[0:len(paths):max] + matches = matches[0:len(paths):max] + results = results[0:len(paths):max] + _, ok := parseGetMany(json, i, 0, 0, paths, completed, matches, results) + return results, ok +} +func getMany64(json string, i int, paths []string) ([]Result, bool) { + const max = 64 + var completed = make([]bool, 0, max) + var matches = make([]uint64, 0, max) + var results = make([]Result, 0, max) + completed = completed[0:len(paths):max] + matches = matches[0:len(paths):max] + results = results[0:len(paths):max] + _, ok := parseGetMany(json, i, 0, 0, paths, completed, matches, results) + return results, ok +} +func getMany128(json string, i int, paths []string) ([]Result, bool) { + const max = 128 + var completed = make([]bool, 0, max) + var matches = make([]uint64, 0, max) + var results = make([]Result, 0, max) + completed = completed[0:len(paths):max] + matches = matches[0:len(paths):max] + results = results[0:len(paths):max] + _, ok := parseGetMany(json, i, 0, 0, paths, completed, matches, results) + return results, ok +} +func getMany256(json string, i int, paths []string) ([]Result, bool) { + const max = 256 + var completed = make([]bool, 0, max) + var matches = make([]uint64, 0, max) + var results = make([]Result, 0, max) + completed = completed[0:len(paths):max] + matches = matches[0:len(paths):max] + results = results[0:len(paths):max] + _, ok := parseGetMany(json, i, 0, 0, paths, completed, matches, results) + return results, ok +} +func getMany512(json string, i int, paths []string) ([]Result, bool) { + const max = 512 + var completed = make([]bool, 0, max) + var matches = make([]uint64, 0, max) + var results = make([]Result, 0, max) + completed = completed[0:len(paths):max] + matches = matches[0:len(paths):max] + results = results[0:len(paths):max] + _, ok := parseGetMany(json, i, 0, 0, paths, completed, matches, results) + return results, ok +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 48432de87..645342f9c 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -296,10 +296,10 @@ "revisionTime": "2016-03-11T21:55:03Z" }, { - "checksumSHA1": "+Pcohsuq0Mi/y8bgaDFjb/CGzkk=", + "checksumSHA1": "k/Xh0p5L7+tBCXAL2dOCwUf9J3Y=", "path": "github.com/tidwall/gjson", - "revision": "7c631e98686a791e5fc60ff099512968122afb52", - "revisionTime": "2016-09-08T16:02:40Z" + "revision": "09d1c5c5bc64e094394dfe2150220d906c55ac37", + "revisionTime": "2017-02-05T16:10:42Z" }, { "checksumSHA1": "qmePMXEDYGwkAfT9QvtMC58JN/E=", From 6509589adbac959168fdb6ba6f7e26719c397a89 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 15 Mar 2017 20:48:49 -0700 Subject: [PATCH 88/94] Use canonicalETag helper wherever needed. (#3910) --- cmd/object-handlers.go | 4 +--- cmd/object-handlers_test.go | 3 +-- cmd/server_test.go | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 3e2037ed2..7e423fd6c 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -25,7 +25,6 @@ import ( "path" "sort" "strconv" - "strings" mux "github.com/gorilla/mux" ) @@ -874,8 +873,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite // Complete parts. var completeParts []completePart for _, part := range complMultipartUpload.Parts { - part.ETag = strings.TrimPrefix(part.ETag, "\"") - part.ETag = strings.TrimSuffix(part.ETag, "\"") + part.ETag = canonicalizeETag(part.ETag) completeParts = append(completeParts, part) } diff --git a/cmd/object-handlers_test.go b/cmd/object-handlers_test.go index 591477f63..feda6e29b 100644 --- a/cmd/object-handlers_test.go +++ b/cmd/object-handlers_test.go @@ -26,7 +26,6 @@ import ( "net/http/httptest" "net/url" "strconv" - "strings" "sync" "testing" @@ -1037,7 +1036,7 @@ func testAPICopyObjectPartHandlerSanity(obj ObjectLayer, instanceType, bucketNam parts = append(parts, completePart{ PartNumber: partNumber, - ETag: strings.Trim(resp.ETag, "\""), + ETag: canonicalizeETag(resp.ETag), }) } diff --git a/cmd/server_test.go b/cmd/server_test.go index edfdcafa0..70fb9e6ce 100644 --- a/cmd/server_test.go +++ b/cmd/server_test.go @@ -2579,10 +2579,10 @@ func (s *TestSuiteCommon) TestObjectMultipart(c *C) { c.Assert(response.StatusCode, Equals, http.StatusOK) var parts []completePart for _, part := range completeUploads.Parts { - part.ETag = strings.Trim(part.ETag, "\"") + part.ETag = canonicalizeETag(part.ETag) parts = append(parts, part) } etag, err := getCompleteMultipartMD5(parts) c.Assert(err, IsNil) - c.Assert(strings.Trim(response.Header.Get("Etag"), "\""), Equals, etag) + c.Assert(canonicalizeETag(response.Header.Get("Etag")), Equals, etag) } From 051f9bb5c6d0a31c1771a6978ec78c6930bac8b5 Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Thu, 16 Mar 2017 12:45:06 +0530 Subject: [PATCH 89/94] Implement list uploads heal admin API (#3885) --- cmd/admin-handlers.go | 87 +++++++-- cmd/admin-handlers_test.go | 139 ++++++++++++++- cmd/admin-router.go | 2 + cmd/api-response.go | 14 +- cmd/fs-v1.go | 5 + cmd/object-api-datatypes.go | 2 + cmd/object-api-interface.go | 2 + cmd/xl-v1-list-objects-heal.go | 217 +++++++++++++++++++++++ cmd/xl-v1-list-objects-heal_test.go | 77 ++++++++ pkg/madmin/API.md | 44 +++++ pkg/madmin/examples/heal-uploads-list.go | 74 ++++++++ pkg/madmin/heal-commands.go | 215 +++++++++++++++++++++- 12 files changed, 845 insertions(+), 33 deletions(-) create mode 100644 pkg/madmin/examples/heal-uploads-list.go diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index c5231ba68..d549d81b9 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -36,16 +36,19 @@ const ( // Type-safe query params. type mgmtQueryKey string -// Only valid query params for list/clear locks management APIs. +// Only valid query params for mgmt admin APIs. const ( - mgmtBucket mgmtQueryKey = "bucket" - mgmtObject mgmtQueryKey = "object" - mgmtPrefix mgmtQueryKey = "prefix" - mgmtLockDuration mgmtQueryKey = "duration" - mgmtDelimiter mgmtQueryKey = "delimiter" - mgmtMarker mgmtQueryKey = "marker" - mgmtMaxKey mgmtQueryKey = "max-key" - mgmtDryRun mgmtQueryKey = "dry-run" + mgmtBucket mgmtQueryKey = "bucket" + mgmtObject mgmtQueryKey = "object" + mgmtPrefix mgmtQueryKey = "prefix" + mgmtLockDuration mgmtQueryKey = "duration" + mgmtDelimiter mgmtQueryKey = "delimiter" + mgmtMarker mgmtQueryKey = "marker" + mgmtKeyMarker mgmtQueryKey = "key-marker" + mgmtMaxKey mgmtQueryKey = "max-key" + mgmtDryRun mgmtQueryKey = "dry-run" + mgmtUploadIDMarker mgmtQueryKey = "upload-id-marker" + mgmtMaxUploads mgmtQueryKey = "max-uploads" ) // ServerVersion - server version @@ -400,8 +403,57 @@ func (adminAPI adminAPIHandlers) ClearLocksHandler(w http.ResponseWriter, r *htt writeSuccessResponseJSON(w, jsonBytes) } -// validateHealQueryParams - Validates query params for heal list management API. -func validateHealQueryParams(vars url.Values) (string, string, string, string, int, APIErrorCode) { +// ListUploadsHealHandler - similar to listObjectsHealHandler +// GET +// /?heal&bucket=mybucket&prefix=myprefix&key-marker=mymarker&upload-id-marker=myuploadid&delimiter=mydelimiter&max-uploads=1000 +// - bucket is mandatory query parameter +// - rest are optional query parameters List upto maxKey objects that +// need healing in a given bucket matching the given prefix. +func (adminAPI adminAPIHandlers) ListUploadsHealHandler(w http.ResponseWriter, r *http.Request) { + // Get object layer instance. + objLayer := newObjectLayerFn() + if objLayer == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + // Validate request signature. + adminAPIErr := checkRequestAuthType(r, "", "", "") + if adminAPIErr != ErrNone { + writeErrorResponse(w, adminAPIErr, r.URL) + return + } + + // Validate query params. + vars := r.URL.Query() + bucket := vars.Get(string(mgmtBucket)) + prefix, keyMarker, uploadIDMarker, delimiter, maxUploads, _ := getBucketMultipartResources(r.URL.Query()) + + if err := checkListMultipartArgs(bucket, prefix, keyMarker, uploadIDMarker, delimiter, objLayer); err != nil { + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + if maxUploads <= 0 || maxUploads > maxUploadsList { + writeErrorResponse(w, ErrInvalidMaxUploads, r.URL) + return + } + + // Get the list objects to be healed. + listMultipartInfos, err := objLayer.ListUploadsHeal(bucket, prefix, + keyMarker, uploadIDMarker, delimiter, maxUploads) + if err != nil { + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + listResponse := generateListMultipartUploadsResponse(bucket, listMultipartInfos) + // Write success response. + writeSuccessResponseXML(w, encodeResponse(listResponse)) +} + +// extractListObjectsHealQuery - Validates query params for heal objects list management API. +func extractListObjectsHealQuery(vars url.Values) (string, string, string, string, int, APIErrorCode) { bucket := vars.Get(string(mgmtBucket)) prefix := vars.Get(string(mgmtPrefix)) marker := vars.Get(string(mgmtMarker)) @@ -418,10 +470,13 @@ func validateHealQueryParams(vars url.Values) (string, string, string, string, i return "", "", "", "", 0, ErrInvalidObjectName } - // check if maxKey is a valid integer. - maxKey, err := strconv.Atoi(maxKeyStr) - if err != nil { - return "", "", "", "", 0, ErrInvalidMaxKeys + // check if maxKey is a valid integer, if present. + var maxKey int + var err error + if maxKeyStr != "" { + if maxKey, err = strconv.Atoi(maxKeyStr); err != nil { + return "", "", "", "", 0, ErrInvalidMaxKeys + } } // Validate prefix, marker, delimiter and maxKey. @@ -454,7 +509,7 @@ func (adminAPI adminAPIHandlers) ListObjectsHealHandler(w http.ResponseWriter, r // Validate query params. vars := r.URL.Query() - bucket, prefix, marker, delimiter, maxKey, adminAPIErr := validateHealQueryParams(vars) + bucket, prefix, marker, delimiter, maxKey, adminAPIErr := extractListObjectsHealQuery(vars) if adminAPIErr != ErrNone { writeErrorResponse(w, adminAPIErr, r.URL) return diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index b3128cfc8..187c7c0a6 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -740,7 +740,7 @@ func TestValidateHealQueryParams(t *testing.T) { } for i, test := range testCases { vars := mkListObjectsQueryVal(test.bucket, test.prefix, test.marker, test.delimiter, test.maxKeys) - _, _, _, _, _, actualErr := validateHealQueryParams(vars) + _, _, _, _, _, actualErr := extractListObjectsHealQuery(vars) if actualErr != test.apiErr { t.Errorf("Test %d - Expected %v but received %v", i+1, getAPIError(test.apiErr), getAPIError(actualErr)) @@ -856,9 +856,6 @@ func TestListObjectsHealHandler(t *testing.T) { } for i, test := range testCases { - if i != 0 { - continue - } queryVal := mkListObjectsQueryVal(test.bucket, test.prefix, test.marker, test.delimiter, test.maxKeys) req, err := newTestRequest("GET", "/?"+queryVal.Encode(), 0, nil) if err != nil { @@ -1290,3 +1287,137 @@ func TestWriteSetConfigResponse(t *testing.T) { } } } + +// mkUploadsHealQuery - helper function to construct query values for +// listUploadsHeal. +func mkUploadsHealQuery(bucket, prefix, keyMarker, uploadIDMarker, delimiter, maxUploadsStr string) url.Values { + + queryVal := make(url.Values) + queryVal.Set("heal", "") + queryVal.Set(string(mgmtBucket), bucket) + queryVal.Set(string(mgmtPrefix), prefix) + queryVal.Set(string(mgmtKeyMarker), keyMarker) + queryVal.Set(string(mgmtUploadIDMarker), uploadIDMarker) + queryVal.Set(string(mgmtDelimiter), delimiter) + queryVal.Set(string(mgmtMaxUploads), maxUploadsStr) + return queryVal +} + +func TestListHealUploadsHandler(t *testing.T) { + adminTestBed, err := prepareAdminXLTestBed() + if err != nil { + t.Fatal("Failed to initialize a single node XL backend for admin handler tests.") + } + defer adminTestBed.TearDown() + + err = adminTestBed.objLayer.MakeBucket("mybucket") + if err != nil { + t.Fatalf("Failed to make bucket - %v", err) + } + + // Delete bucket after running all test cases. + defer adminTestBed.objLayer.DeleteBucket("mybucket") + + testCases := []struct { + bucket string + prefix string + keyMarker string + delimiter string + maxKeys string + statusCode int + }{ + // 1. Valid params. + { + bucket: "mybucket", + prefix: "prefix", + keyMarker: "prefix11", + delimiter: "/", + maxKeys: "10", + statusCode: http.StatusOK, + }, + // 2. Valid params with empty prefix. + { + bucket: "mybucket", + prefix: "", + keyMarker: "", + delimiter: "/", + maxKeys: "10", + statusCode: http.StatusOK, + }, + // 3. Invalid params with invalid bucket. + { + bucket: `invalid\\Bucket`, + prefix: "prefix", + keyMarker: "prefix11", + delimiter: "/", + maxKeys: "10", + statusCode: getAPIError(ErrInvalidBucketName).HTTPStatusCode, + }, + // 4. Invalid params with invalid prefix. + { + bucket: "mybucket", + prefix: `invalid\\Prefix`, + keyMarker: "prefix11", + delimiter: "/", + maxKeys: "10", + statusCode: getAPIError(ErrInvalidObjectName).HTTPStatusCode, + }, + // 5. Invalid params with invalid maxKeys. + { + bucket: "mybucket", + prefix: "prefix", + keyMarker: "prefix11", + delimiter: "/", + maxKeys: "-1", + statusCode: getAPIError(ErrInvalidMaxUploads).HTTPStatusCode, + }, + // 6. Invalid params with unsupported prefix marker combination. + { + bucket: "mybucket", + prefix: "prefix", + keyMarker: "notmatchingmarker", + delimiter: "/", + maxKeys: "10", + statusCode: getAPIError(ErrNotImplemented).HTTPStatusCode, + }, + // 7. Invalid params with unsupported delimiter. + { + bucket: "mybucket", + prefix: "prefix", + keyMarker: "notmatchingmarker", + delimiter: "unsupported", + maxKeys: "10", + statusCode: getAPIError(ErrNotImplemented).HTTPStatusCode, + }, + // 8. Invalid params with invalid max Keys + { + bucket: "mybucket", + prefix: "prefix", + keyMarker: "prefix11", + delimiter: "/", + maxKeys: "999999999999999999999999999", + statusCode: getAPIError(ErrInvalidMaxUploads).HTTPStatusCode, + }, + } + + for i, test := range testCases { + queryVal := mkUploadsHealQuery(test.bucket, test.prefix, test.keyMarker, "", test.delimiter, test.maxKeys) + + req, err := newTestRequest("GET", "/?"+queryVal.Encode(), 0, nil) + if err != nil { + t.Fatalf("Test %d - Failed to construct list uploads needing heal request - %v", i+1, err) + } + req.Header.Set(minioAdminOpHeader, "list-uploads") + + cred := serverConfig.GetCredential() + err = signRequestV4(req, cred.AccessKey, cred.SecretKey) + if err != nil { + t.Fatalf("Test %d - Failed to sign list uploads needing heal request - %v", i+1, err) + } + rec := httptest.NewRecorder() + adminTestBed.mux.ServeHTTP(rec, req) + if test.statusCode != rec.Code { + t.Errorf("Test %d - Expected HTTP status code %d but received %d", i+1, test.statusCode, rec.Code) + } + } +} diff --git a/cmd/admin-router.go b/cmd/admin-router.go index fa0b805b2..b65c4eda2 100644 --- a/cmd/admin-router.go +++ b/cmd/admin-router.go @@ -53,6 +53,8 @@ func registerAdminRouter(mux *router.Router) { // List Objects needing heal. adminRouter.Methods("GET").Queries("heal", "").Headers(minioAdminOpHeader, "list-objects").HandlerFunc(adminAPI.ListObjectsHealHandler) + // List Uploads needing heal. + adminRouter.Methods("GET").Queries("heal", "").Headers(minioAdminOpHeader, "list-uploads").HandlerFunc(adminAPI.ListUploadsHealHandler) // List Buckets needing heal. adminRouter.Methods("GET").Queries("heal", "").Headers(minioAdminOpHeader, "list-buckets").HandlerFunc(adminAPI.ListBucketsHealHandler) diff --git a/cmd/api-response.go b/cmd/api-response.go index 7f0641bb2..bc95cab60 100644 --- a/cmd/api-response.go +++ b/cmd/api-response.go @@ -166,12 +166,13 @@ type ListBucketsResponse struct { // Upload container for in progress multipart upload type Upload struct { - Key string - UploadID string `xml:"UploadId"` - Initiator Initiator - Owner Owner - StorageClass string - Initiated string + Key string + UploadID string `xml:"UploadId"` + Initiator Initiator + Owner Owner + StorageClass string + Initiated string + HealUploadInfo *HealObjectInfo `xml:"HealObjectInfo,omitempty"` } // CommonPrefix container for prefix response in ListObjectsResponse @@ -488,6 +489,7 @@ func generateListMultipartUploadsResponse(bucket string, multipartsInfo ListMult newUpload.UploadID = upload.UploadID newUpload.Key = upload.Object newUpload.Initiated = upload.Initiated.UTC().Format(timeFormatAMZLong) + newUpload.HealUploadInfo = upload.HealUploadInfo listMultipartUploadsResponse.Uploads[index] = newUpload } return listMultipartUploadsResponse diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index fc1cd2d1b..b9d59a1ac 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -827,3 +827,8 @@ func (fs fsObjects) ListObjectsHeal(bucket, prefix, marker, delimiter string, ma func (fs fsObjects) ListBucketsHeal() ([]BucketInfo, error) { return []BucketInfo{}, traceError(NotImplemented{}) } + +func (fs fsObjects) ListUploadsHeal(bucket, prefix, marker, uploadIDMarker, + delimiter string, maxUploads int) (ListMultipartsInfo, error) { + return ListMultipartsInfo{}, traceError(NotImplemented{}) +} diff --git a/cmd/object-api-datatypes.go b/cmd/object-api-datatypes.go index 307220f4d..17d8d9366 100644 --- a/cmd/object-api-datatypes.go +++ b/cmd/object-api-datatypes.go @@ -248,6 +248,8 @@ type uploadMetadata struct { Initiated time.Time StorageClass string // Not supported yet. + + HealUploadInfo *HealObjectInfo `xml:"HealUploadInfo,omitempty"` } // completePart - completed part container. diff --git a/cmd/object-api-interface.go b/cmd/object-api-interface.go index 4938af274..ca60e728c 100644 --- a/cmd/object-api-interface.go +++ b/cmd/object-api-interface.go @@ -52,4 +52,6 @@ type ObjectLayer interface { ListBucketsHeal() (buckets []BucketInfo, err error) HealObject(bucket, object string) error ListObjectsHeal(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) + ListUploadsHeal(bucket, prefix, marker, uploadIDMarker, + delimiter string, maxUploads int) (ListMultipartsInfo, error) } diff --git a/cmd/xl-v1-list-objects-heal.go b/cmd/xl-v1-list-objects-heal.go index d48470974..94362d75c 100644 --- a/cmd/xl-v1-list-objects-heal.go +++ b/cmd/xl-v1-list-objects-heal.go @@ -17,6 +17,7 @@ package cmd import ( + "path/filepath" "sort" "strings" ) @@ -205,3 +206,219 @@ func (xl xlObjects) ListObjectsHeal(bucket, prefix, marker, delimiter string, ma // Return error at the end. return ListObjectsInfo{}, toObjectErr(err, bucket, prefix) } + +// ListUploadsHeal - lists ongoing multipart uploads that require +// healing in one or more disks. +func (xl xlObjects) ListUploadsHeal(bucket, prefix, marker, uploadIDMarker, + delimiter string, maxUploads int) (ListMultipartsInfo, error) { + + // For delimiter and prefix as '/' we do not list anything at all + // since according to s3 spec we stop at the 'delimiter' along + // with the prefix. On a flat namespace with 'prefix' as '/' + // we don't have any entries, since all the keys are of form 'keyName/...' + if delimiter == slashSeparator && prefix == slashSeparator { + return ListMultipartsInfo{}, nil + } + + // Initiate a list operation. + listMultipartInfo, err := xl.listMultipartUploadsHeal(bucket, prefix, + marker, uploadIDMarker, delimiter, maxUploads) + if err != nil { + return ListMultipartsInfo{}, toObjectErr(err, bucket, prefix) + } + + // We got the entries successfully return. + return listMultipartInfo, nil +} + +// Fetches list of multipart uploadIDs given bucket, keyMarker, uploadIDMarker. +func fetchMultipartUploadIDs(bucket, keyMarker, uploadIDMarker string, + maxUploads int, disks []StorageAPI) (uploads []uploadMetadata, end bool, + err error) { + + // Hold a read lock on keyMarker path. + keyMarkerLock := globalNSMutex.NewNSLock(minioMetaMultipartBucket, + pathJoin(bucket, keyMarker)) + keyMarkerLock.RLock() + for _, disk := range disks { + if disk == nil { + continue + } + uploads, end, err = listMultipartUploadIDs(bucket, keyMarker, + uploadIDMarker, maxUploads, disk) + if err == nil || + !isErrIgnored(err, objMetadataOpIgnoredErrs...) { + break + } + } + keyMarkerLock.RUnlock() + return uploads, end, err +} + +// listMultipartUploadsHeal - Returns a list of incomplete multipart +// uploads that need to be healed. +func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker, + uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, error) { + + result := ListMultipartsInfo{ + IsTruncated: true, + MaxUploads: maxUploads, + KeyMarker: keyMarker, + Prefix: prefix, + Delimiter: delimiter, + } + + recursive := delimiter != slashSeparator + + var uploads []uploadMetadata + var err error + // List all upload ids for the given keyMarker, starting from + // uploadIDMarker. + if uploadIDMarker != "" { + uploads, _, err = fetchMultipartUploadIDs(bucket, keyMarker, + uploadIDMarker, maxUploads, xl.getLoadBalancedDisks()) + if err != nil { + return ListMultipartsInfo{}, err + } + maxUploads = maxUploads - len(uploads) + } + + // We can't use path.Join() as it strips off the trailing '/'. + multipartPrefixPath := pathJoin(bucket, prefix) + // multipartPrefixPath should have a trailing '/' when prefix = "". + if prefix == "" { + multipartPrefixPath += slashSeparator + } + + multipartMarkerPath := "" + if keyMarker != "" { + multipartMarkerPath = pathJoin(bucket, keyMarker) + } + + // `heal bool` is used to differentiate listing of incomplete + // uploads (and parts) from a regular listing of incomplete + // parts by client SDKs or mc-like commands, within a treewalk + // pool. + heal := true + // The listing is truncated if we have maxUploads entries and + // there are more entries to be listed. + truncated := true + var walkerCh chan treeWalkResult + var walkerDoneCh chan struct{} + // Check if we have room left to send more uploads. + if maxUploads > 0 { + walkerCh, walkerDoneCh = xl.listPool.Release(listParams{ + bucket: minioMetaMultipartBucket, + recursive: recursive, + marker: multipartMarkerPath, + prefix: multipartPrefixPath, + heal: heal, + }) + if walkerCh == nil { + walkerDoneCh = make(chan struct{}) + isLeaf := xl.isMultipartUpload + listDir := listDirFactory(isLeaf, xlTreeWalkIgnoredErrs, + xl.getLoadBalancedDisks()...) + walkerCh = startTreeWalk(minioMetaMultipartBucket, + multipartPrefixPath, multipartMarkerPath, + recursive, listDir, isLeaf, walkerDoneCh) + } + // Collect uploads until maxUploads limit is reached. + for walkResult := range walkerCh { + // Ignore errors like errDiskNotFound + // and errFileNotFound. + if isErrIgnored(walkResult.err, + xlTreeWalkIgnoredErrs...) { + continue + } + // For any error during tree walk we should + // return right away. + if walkResult.err != nil { + return ListMultipartsInfo{}, walkResult.err + } + + entry := strings.TrimPrefix(walkResult.entry, + retainSlash(bucket)) + // Skip entries that are not object directory. + if hasSuffix(walkResult.entry, slashSeparator) { + uploads = append(uploads, uploadMetadata{ + Object: entry, + }) + maxUploads-- + if maxUploads == 0 { + break + } + continue + } + + // For an object entry we get all its pending + // uploadIDs. + var newUploads []uploadMetadata + var end bool + uploadIDMarker = "" + newUploads, end, err = fetchMultipartUploadIDs(bucket, entry, uploadIDMarker, + maxUploads, xl.getLoadBalancedDisks()) + if err != nil { + return ListMultipartsInfo{}, err + } + uploads = append(uploads, newUploads...) + maxUploads -= len(newUploads) + if end && walkResult.end { + truncated = false + break + } + if maxUploads == 0 { + break + } + } + } + + // For all received uploads fill in the multiparts result. + for _, upload := range uploads { + var objectName string + var uploadID string + if hasSuffix(upload.Object, slashSeparator) { + // All directory entries are common + // prefixes. For common prefixes, upload ids + // are empty. + uploadID = "" + objectName = upload.Object + result.CommonPrefixes = append(result.CommonPrefixes, objectName) + } else { + // Check if upload needs healing. + uploadIDPath := filepath.Join(bucket, upload.Object, upload.UploadID) + partsMetadata, errs := readAllXLMetadata(xl.storageDisks, + minioMetaMultipartBucket, uploadIDPath) + if xlShouldHeal(partsMetadata, errs) { + healUploadInfo := xlHealStat(xl, partsMetadata, errs) + upload.HealUploadInfo = &healUploadInfo + result.Uploads = append(result.Uploads, upload) + } + uploadID = upload.UploadID + objectName = upload.Object + } + + result.NextKeyMarker = objectName + result.NextUploadIDMarker = uploadID + } + + if truncated { + // Put back the tree walk go-routine into the pool for + // subsequent use. + xl.listPool.Set(listParams{ + bucket: bucket, + recursive: recursive, + marker: result.NextKeyMarker, + prefix: prefix, + heal: heal, + }, walkerCh, walkerDoneCh) + } + + result.IsTruncated = truncated + // Result is not truncated, reset the markers. + if !result.IsTruncated { + result.NextKeyMarker = "" + result.NextUploadIDMarker = "" + } + return result, nil +} diff --git a/cmd/xl-v1-list-objects-heal_test.go b/cmd/xl-v1-list-objects-heal_test.go index fb515e325..af12060b2 100644 --- a/cmd/xl-v1-list-objects-heal_test.go +++ b/cmd/xl-v1-list-objects-heal_test.go @@ -18,6 +18,8 @@ package cmd import ( "bytes" + "path" + "path/filepath" "strconv" "testing" ) @@ -139,3 +141,78 @@ func TestListObjectsHeal(t *testing.T) { } } + +// Test for ListUploadsHeal API for XL. +func TestListUploadsHeal(t *testing.T) { + initNSLock(false) + + rootPath, err := newTestConfig(globalMinioDefaultRegion) + if err != nil { + t.Fatalf("Init Test config failed") + } + // Remove config directory after the test ends. + defer removeAll(rootPath) + + // Create an instance of XL backend. + xl, fsDirs, err := prepareXL() + if err != nil { + t.Fatal(err) + } + // Cleanup backend directories on function return. + defer removeRoots(fsDirs) + + bucketName := "bucket" + prefix := "prefix" + objName := path.Join(prefix, "obj") + + // Create test bucket. + err = xl.MakeBucket(bucketName) + if err != nil { + t.Fatal(err) + } + + // Create a new multipart upload. + uploadID, err := xl.NewMultipartUpload(bucketName, objName, nil) + if err != nil { + t.Fatal(err) + } + + // Upload a part. + data := bytes.Repeat([]byte("a"), 1024) + _, err = xl.PutObjectPart(bucketName, objName, uploadID, 1, + int64(len(data)), bytes.NewReader(data), "", "") + if err != nil { + t.Fatal(err) + } + + // Check if list uploads heal returns any uploads to be healed + // incorrectly. + listUploadsInfo, err := xl.ListUploadsHeal(bucketName, prefix, "", "", "", 1000) + if err != nil { + t.Fatal(err) + } + + // All uploads intact nothing to heal. + if len(listUploadsInfo.Uploads) != 0 { + t.Errorf("Expected no uploads but received %d", len(listUploadsInfo.Uploads)) + } + + // Delete the part from the first disk to make the upload (and + // its part) to appear in upload heal listing. + firstDisk := xl.(*xlObjects).storageDisks[0] + err = firstDisk.DeleteFile(minioMetaMultipartBucket, + filepath.Join(bucketName, objName, uploadID, xlMetaJSONFile)) + if err != nil { + t.Fatal(err) + } + + listUploadsInfo, err = xl.ListUploadsHeal(bucketName, prefix, "", "", "", 1000) + if err != nil { + t.Fatal(err) + } + + // One upload with missing xl.json on first disk. + if len(listUploadsInfo.Uploads) != 1 { + t.Errorf("Expected 1 upload but received %d", len(listUploadsInfo.Uploads)) + } +} diff --git a/pkg/madmin/API.md b/pkg/madmin/API.md index 8a6222bce..7d5ba2a5e 100644 --- a/pkg/madmin/API.md +++ b/pkg/madmin/API.md @@ -43,6 +43,7 @@ func main() { | | |[`HealBucket`](#HealBucket) ||| | | |[`HealObject`](#HealObject)||| | | |[`HealFormat`](#HealFormat)||| +| | |[`ListUploadsHeal`](#ListUploadsHeal)||| ## 1. Constructor @@ -353,3 +354,46 @@ __Example__ } log.Println("SetConfig: ", string(buf.Bytes())) ``` + + +### ListUploadsHeal(bucket, prefix string, recursive bool, doneCh <-chan struct{}) (<-chan UploadInfo, error) +List ongoing multipart uploads that need healing. + +| Param | Type | Description | +|---|---|---| +|`ui.Key` | _string_ | Name of the object being uploaded | +|`ui.UploadID` | _string_ | UploadID of the ongoing multipart upload | +|`ui.HealUploadInfo.Status` | _healStatus_| One of `Healthy`, `CanHeal`, `Corrupted`, `QuorumUnavailable`| +|`ui.Err`| _error_ | non-nil if fetching fetching healing information failed | + +__Example__ + +``` go + + // Set true if recursive listing is needed. + isRecursive := true + // List objects that need healing for a given bucket and + // prefix. + healUploadsCh, err := madmClnt.ListUploadsHeal(bucket, prefix, isRecursive, doneCh) + if err != nil { + log.Fatalln("Failed to get list of uploads to be healed: ", err) + } + + for upload := range healUploadsCh { + if upload.Err != nil { + log.Println("upload listing error: ", upload.Err) + } + + if upload.HealUploadInfo != nil { + switch healInfo := *upload.HealUploadInfo; healInfo.Status { + case madmin.CanHeal: + fmt.Println(upload.Key, " can be healed.") + case madmin.QuorumUnavailable: + fmt.Println(upload.Key, " can't be healed until quorum is available.") + case madmin.Corrupted: + fmt.Println(upload.Key, " can't be healed, not enough information.") + } + } + } + +``` diff --git a/pkg/madmin/examples/heal-uploads-list.go b/pkg/madmin/examples/heal-uploads-list.go new file mode 100644 index 000000000..08da11c02 --- /dev/null +++ b/pkg/madmin/examples/heal-uploads-list.go @@ -0,0 +1,74 @@ +// +build ignore + +package main + +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import ( + "fmt" + "log" + + "github.com/minio/minio/pkg/madmin" +) + +func main() { + + // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are + // dummy values, please replace them with original values. + + // API requests are secure (HTTPS) if secure=true and insecure (HTTPS) otherwise. + // New returns an Minio Admin client object. + madmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true) + if err != nil { + log.Fatalln(err) + } + + bucket := "mybucket" + prefix := "myprefix" + + // Create a done channel to control 'ListUploadsHeal' go routine. + doneCh := make(chan struct{}) + // Indicate to our routine to exit cleanly upon return. + defer close(doneCh) + + // Set true if recursive listing is needed. + isRecursive := true + // List objects that need healing for a given bucket and + // prefix. + healUploadsCh, err := madmClnt.ListUploadsHeal(bucket, prefix, isRecursive, doneCh) + if err != nil { + log.Fatalln("Failed to get list of uploads to be healed: ", err) + } + + for upload := range healUploadsCh { + if upload.Err != nil { + log.Println("upload listing error: ", upload.Err) + } + + if upload.HealUploadInfo != nil { + switch healInfo := *upload.HealUploadInfo; healInfo.Status { + case madmin.CanHeal: + fmt.Println(upload.Key, " can be healed.") + case madmin.QuorumUnavailable: + fmt.Println(upload.Key, " can't be healed until quorum is available.") + case madmin.Corrupted: + fmt.Println(upload.Key, " can't be healed, not enough information.") + } + } + } +} diff --git a/pkg/madmin/heal-commands.go b/pkg/madmin/heal-commands.go index 3dea72ccf..86042157c 100644 --- a/pkg/madmin/heal-commands.go +++ b/pkg/madmin/heal-commands.go @@ -3,6 +3,8 @@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. + + * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 @@ -25,6 +27,10 @@ import ( "time" ) +const ( + maxUploadsList = 1000 +) + // listBucketHealResult container for listObjects response. type listBucketHealResult struct { // A response can contain CommonPrefixes only if you have @@ -156,16 +162,75 @@ type ObjectInfo struct { HealObjectInfo *HealObjectInfo `json:"healObjectInfo,omitempty"` } +// UploadInfo - represents an ongoing upload that needs to be healed. +type UploadInfo struct { + Key string `json:"name"` // Name of the object being uploaded. + + UploadID string `json:"uploadId"` // UploadID + // Owner name. + Owner struct { + DisplayName string `json:"name"` + ID string `json:"id"` + } `json:"owner"` + + // The class of storage used to store the object. + StorageClass string `json:"storageClass"` + + Initiated time.Time `json:"initiated"` // Time at which upload was initiated. + + // Error + Err error `json:"-"` + HealUploadInfo *HealObjectInfo `json:"healObjectInfo,omitempty"` +} + +// Initiator - has same properties as Owner. +type Initiator Owner + +// upload - represents an ongoing multipart upload. +type upload struct { + Key string + UploadID string `xml:"UploadId"` + Initiator Initiator + Owner Owner + StorageClass string + Initiated time.Time + HealUploadInfo *HealObjectInfo `xml:"HealObjectInfo,omitempty"` +} + +// listUploadsHealResponse - represents ListUploadsHeal response. +type listUploadsHealResponse struct { + XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListMultipartUploadsResult" json:"-"` + + Bucket string + KeyMarker string + UploadIDMarker string `xml:"UploadIdMarker"` + NextKeyMarker string + NextUploadIDMarker string `xml:"NextUploadIdMarker"` + Delimiter string + Prefix string + EncodingType string `xml:"EncodingType,omitempty"` + MaxUploads int + IsTruncated bool + + // List of pending uploads. + Uploads []upload `xml:"Upload"` + + // Delimed common prefixes. + CommonPrefixes []commonPrefix +} + type healQueryKey string const ( - healBucket healQueryKey = "bucket" - healObject healQueryKey = "object" - healPrefix healQueryKey = "prefix" - healMarker healQueryKey = "marker" - healDelimiter healQueryKey = "delimiter" - healMaxKey healQueryKey = "max-key" - healDryRun healQueryKey = "dry-run" + healBucket healQueryKey = "bucket" + healObject healQueryKey = "object" + healPrefix healQueryKey = "prefix" + healMarker healQueryKey = "marker" + healDelimiter healQueryKey = "delimiter" + healMaxKey healQueryKey = "max-key" + healDryRun healQueryKey = "dry-run" + healUploadIDMarker healQueryKey = "upload-id-marker" + healMaxUpload healQueryKey = "max-uploads" ) // mkHealQueryVal - helper function to construct heal REST API query params. @@ -432,3 +497,139 @@ func (adm *AdminClient) HealFormat(dryrun bool) error { return nil } + +// mkUploadsHealQuery - helper function to construct query params for +// ListUploadsHeal API. +func mkUploadsHealQuery(bucket, prefix, marker, uploadIDMarker, delimiter, maxUploadsStr string) url.Values { + + queryVal := make(url.Values) + queryVal.Set("heal", "") + queryVal.Set(string(healBucket), bucket) + queryVal.Set(string(healPrefix), prefix) + queryVal.Set(string(healMarker), marker) + queryVal.Set(string(healUploadIDMarker), uploadIDMarker) + queryVal.Set(string(healDelimiter), delimiter) + queryVal.Set(string(healMaxUpload), maxUploadsStr) + return queryVal +} + +func (adm *AdminClient) listUploadsHeal(bucket, prefix, marker, uploadIDMarker, delimiter string, maxUploads int) (listUploadsHealResponse, error) { + // Construct query params. + maxUploadsStr := fmt.Sprintf("%d", maxUploads) + queryVal := mkUploadsHealQuery(bucket, prefix, marker, uploadIDMarker, delimiter, maxUploadsStr) + + hdrs := make(http.Header) + hdrs.Set(minioAdminOpHeader, "list-uploads") + + reqData := requestData{ + queryValues: queryVal, + customHeaders: hdrs, + } + + // Empty 'list' of objects to be healed. + toBeHealedUploads := listUploadsHealResponse{} + + // Execute GET on /?heal to list objects needing heal. + resp, err := adm.executeMethod("GET", reqData) + + defer closeResponse(resp) + if err != nil { + return listUploadsHealResponse{}, err + } + + if resp.StatusCode != http.StatusOK { + return toBeHealedUploads, httpRespToErrorResponse(resp) + + } + + err = xml.NewDecoder(resp.Body).Decode(&toBeHealedUploads) + if err != nil { + return listUploadsHealResponse{}, err + } + + return toBeHealedUploads, nil +} + +// ListUploadsHeal - issues list heal uploads API request +func (adm *AdminClient) ListUploadsHeal(bucket, prefix string, recursive bool, + doneCh <-chan struct{}) (<-chan UploadInfo, error) { + + // Default listing is delimited at "/" + delimiter := "/" + if recursive { + // If recursive we do not delimit. + delimiter = "" + } + + uploadIDMarker := "" + + // Allocate new list objects channel. + uploadStatCh := make(chan UploadInfo, maxUploadsList) + + // Initiate list objects goroutine here. + go func(uploadStatCh chan<- UploadInfo) { + defer close(uploadStatCh) + // Save marker for next request. + var marker string + for { + // Get list of objects a maximum of 1000 per request. + result, err := adm.listUploadsHeal(bucket, prefix, marker, + uploadIDMarker, delimiter, maxUploadsList) + if err != nil { + uploadStatCh <- UploadInfo{ + Err: err, + } + return + } + + // If contents are available loop through and + // send over channel. + for _, upload := range result.Uploads { + select { + // Send upload info. + case uploadStatCh <- UploadInfo{ + Key: upload.Key, + Initiated: upload.Initiated, + HealUploadInfo: upload.HealUploadInfo, + }: + // If receives done from the caller, return here. + case <-doneCh: + return + } + } + + // Send all common prefixes if any. NOTE: + // prefixes are only present if the request is + // delimited. + for _, prefix := range result.CommonPrefixes { + upload := UploadInfo{} + upload.Key = prefix.Prefix + select { + // Send object prefixes. + case uploadStatCh <- upload: + // If receives done from the caller, return here. + case <-doneCh: + return + } + } + + // If next uploadID marker is present, set it + // for the next request. + if result.NextUploadIDMarker != "" { + uploadIDMarker = result.NextUploadIDMarker + } + + // If next marker present, save it for next request. + if result.KeyMarker != "" { + marker = result.KeyMarker + } + + // Listing ends result is not truncated, + // return right here. + if !result.IsTruncated { + return + } + } + }(uploadStatCh) + return uploadStatCh, nil +} From 21d73a3eefc6ade7e65e761bcb0a789bda3ecb78 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Thu, 16 Mar 2017 12:46:06 +0530 Subject: [PATCH 90/94] Simplify credential usage. (#3893) --- cmd/admin-handlers.go | 8 +- cmd/auth-handler_test.go | 6 +- cmd/browser-peer-rpc.go | 7 +- cmd/browser-peer-rpc_test.go | 8 +- cmd/config-migrate.go | 11 ++- cmd/config-v14.go | 8 +- cmd/credential.go | 143 +++++++++++++++-------------------- cmd/credential_test.go | 101 +++++++++++++++++++++++++ cmd/jwt.go | 34 ++------- cmd/jwt_test.go | 4 +- cmd/server-main.go | 26 ++++++- cmd/server_test.go | 2 +- cmd/utils.go | 23 ------ cmd/web-handlers.go | 13 +--- 14 files changed, 225 insertions(+), 169 deletions(-) create mode 100644 cmd/credential_test.go diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index d549d81b9..816263c3a 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -165,18 +165,12 @@ func (adminAPI adminAPIHandlers) ServiceCredentialsHandler(w http.ResponseWriter return } - // Check passed credentials - err = validateAuthKeys(req.Username, req.Password) + creds, err := createCredential(req.Username, req.Password) if err != nil { writeErrorResponse(w, toAPIErrorCode(err), r.URL) return } - creds := credential{ - AccessKey: req.Username, - SecretKey: req.Password, - } - // Notify all other Minio peers to update credentials updateErrs := updateCredsOnPeers(creds) for peer, err := range updateErrs { diff --git a/cmd/auth-handler_test.go b/cmd/auth-handler_test.go index b67398bdf..bd6cafd8e 100644 --- a/cmd/auth-handler_test.go +++ b/cmd/auth-handler_test.go @@ -316,7 +316,11 @@ func TestIsReqAuthenticated(t *testing.T) { } defer removeAll(path) - creds := newCredentialWithKeys("myuser", "mypassword") + creds, err := createCredential("myuser", "mypassword") + if err != nil { + t.Fatalf("unable create credential, %s", err) + } + serverConfig.SetCredential(creds) // List of test cases for validating http request authentication. diff --git a/cmd/browser-peer-rpc.go b/cmd/browser-peer-rpc.go index f078c43d0..4602cba27 100644 --- a/cmd/browser-peer-rpc.go +++ b/cmd/browser-peer-rpc.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package cmd import ( + "fmt" "path" "sync" "time" @@ -63,8 +64,8 @@ func (br *browserPeerAPIHandlers) SetAuthPeer(args SetAuthPeerArgs, reply *AuthR return err } - if err := validateAuthKeys(args.Creds.AccessKey, args.Creds.SecretKey); err != nil { - return err + if !args.Creds.IsValid() { + return fmt.Errorf("Invalid credential passed") } // Update credentials in memory diff --git a/cmd/browser-peer-rpc_test.go b/cmd/browser-peer-rpc_test.go index ccf3301cf..2bea40e9c 100644 --- a/cmd/browser-peer-rpc_test.go +++ b/cmd/browser-peer-rpc_test.go @@ -63,9 +63,9 @@ func TestBrowserPeerRPC(t *testing.T) { // Tests for browser peer rpc. func (s *TestRPCBrowserPeerSuite) testBrowserPeerRPC(t *testing.T) { // Construct RPC call arguments. - creds := credential{ - AccessKey: "abcd1", - SecretKey: "abcd1234", + creds, err := createCredential("abcd1", "abcd1234") + if err != nil { + t.Fatalf("unable to create credential. %v", err) } // Validate for invalid token. @@ -73,7 +73,7 @@ func (s *TestRPCBrowserPeerSuite) testBrowserPeerRPC(t *testing.T) { args.AuthToken = "garbage" rclient := newRPCClient(s.testAuthConf.serverAddr, s.testAuthConf.serviceEndpoint, false) defer rclient.Close() - err := rclient.Call("BrowserPeer.SetAuthPeer", &args, &AuthRPCReply{}) + err = rclient.Call("BrowserPeer.SetAuthPeer", &args, &AuthRPCReply{}) if err != nil { if err.Error() != errInvalidToken.Error() { t.Fatal(err) diff --git a/cmd/config-migrate.go b/cmd/config-migrate.go index e45bdfae5..f75b2c18e 100644 --- a/cmd/config-migrate.go +++ b/cmd/config-migrate.go @@ -116,13 +116,16 @@ func migrateV2ToV3() error { if cv2.Version != "2" { return nil } + + cred, err := createCredential(cv2.Credentials.AccessKey, cv2.Credentials.SecretKey) + if err != nil { + return fmt.Errorf("Invalid credential in V2 configuration file. %v", err) + } + srvConfig := &configV3{} srvConfig.Version = "3" srvConfig.Addr = ":9000" - srvConfig.Credential = credential{ - AccessKey: cv2.Credentials.AccessKey, - SecretKey: cv2.Credentials.SecretKey, - } + srvConfig.Credential = cred srvConfig.Region = cv2.Credentials.Region if srvConfig.Region == "" { // Region needs to be set for AWS Signature V4. diff --git a/cmd/config-v14.go b/cmd/config-v14.go index 070b7cce5..a2986091e 100644 --- a/cmd/config-v14.go +++ b/cmd/config-v14.go @@ -57,7 +57,7 @@ func newServerConfigV14() *serverConfigV14 { Logger: &logger{}, Notify: ¬ifier{}, } - srvCfg.SetCredential(newCredential()) + srvCfg.SetCredential(mustGetNewCredential()) srvCfg.SetBrowser("on") // Enable console logger by default on a fresh run. srvCfg.Logger.Console = consoleLogger{ @@ -253,8 +253,8 @@ func validateConfig() error { } // Validate credential field - if err := srvCfg.Credential.Validate(); err != nil { - return err + if !srvCfg.Credential.IsValid() { + return errors.New("invalid credential") } // Validate logger field @@ -303,7 +303,7 @@ func (s *serverConfigV14) SetCredential(creds credential) { defer serverConfigMu.Unlock() // Set updated credential. - s.Credential = newCredentialWithKeys(creds.AccessKey, creds.SecretKey) + s.Credential = creds } // GetCredentials get current credentials. diff --git a/cmd/credential.go b/cmd/credential.go index c6f9953a4..db0cbf711 100644 --- a/cmd/credential.go +++ b/cmd/credential.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2015, 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import ( "crypto/rand" "encoding/base64" "errors" - "os" "github.com/minio/mc/pkg/console" @@ -37,27 +36,10 @@ const ( alphaNumericTableLen = byte(len(alphaNumericTable)) ) -func mustGetAccessKey() string { - keyBytes := make([]byte, accessKeyMaxLen) - if _, err := rand.Read(keyBytes); err != nil { - console.Fatalf("Unable to generate access key. Err: %s.\n", err) - } - - for i := 0; i < accessKeyMaxLen; i++ { - keyBytes[i] = alphaNumericTable[keyBytes[i]%alphaNumericTableLen] - } - - return string(keyBytes) -} - -func mustGetSecretKey() string { - keyBytes := make([]byte, secretKeyMaxLen) - if _, err := rand.Read(keyBytes); err != nil { - console.Fatalf("Unable to generate secret key. Err: %s.\n", err) - } - - return string([]byte(base64.StdEncoding.EncodeToString(keyBytes))[:secretKeyMaxLen]) -} +var ( + errInvalidAccessKeyLength = errors.New("Invalid access key, access key should be 5 to 20 characters in length") + errInvalidSecretKeyLength = errors.New("Invalid secret key, secret key should be 8 to 40 characters in length") +) // isAccessKeyValid - validate access key for right length. func isAccessKeyValid(accessKey string) bool { @@ -76,75 +58,72 @@ type credential struct { secretKeyHash []byte } -func (c *credential) Validate() error { - if !isAccessKeyValid(c.AccessKey) { - return errors.New("Invalid access key") - } - if !isSecretKeyValid(c.SecretKey) { - return errors.New("Invalid secret key") - } - return nil +// IsValid - returns whether credential is valid or not. +func (cred credential) IsValid() bool { + return isAccessKeyValid(cred.AccessKey) && isSecretKeyValid(cred.SecretKey) } -// Generate a bcrypt hashed key for input secret key. -func mustGetHashedSecretKey(secretKey string) []byte { - hashedSecretKey, err := bcrypt.GenerateFromPassword([]byte(secretKey), bcrypt.DefaultCost) - if err != nil { - console.Fatalf("Unable to generate secret hash for secret key. Err: %s.\n", err) +// Equals - returns whether two credentials are equal or not. +func (cred credential) Equal(ccred credential) bool { + if !ccred.IsValid() { + return false } - return hashedSecretKey + + if cred.secretKeyHash == nil { + secretKeyHash, err := bcrypt.GenerateFromPassword([]byte(cred.SecretKey), bcrypt.DefaultCost) + if err != nil { + errorIf(err, "Unable to generate hash of given password") + return false + } + + cred.secretKeyHash = secretKeyHash + } + + return (cred.AccessKey == ccred.AccessKey && + bcrypt.CompareHashAndPassword(cred.secretKeyHash, []byte(ccred.SecretKey)) == nil) +} + +func createCredential(accessKey, secretKey string) (cred credential, err error) { + if !isAccessKeyValid(accessKey) { + err = errInvalidAccessKeyLength + } else if !isSecretKeyValid(secretKey) { + err = errInvalidSecretKeyLength + } else { + var secretKeyHash []byte + secretKeyHash, err = bcrypt.GenerateFromPassword([]byte(secretKey), bcrypt.DefaultCost) + if err == nil { + cred.AccessKey = accessKey + cred.SecretKey = secretKey + cred.secretKeyHash = secretKeyHash + } + } + + return cred, err } // Initialize a new credential object -func newCredential() credential { - return newCredentialWithKeys(mustGetAccessKey(), mustGetSecretKey()) -} - -func newCredentialWithKeys(accessKey, secretKey string) credential { - secretHash := mustGetHashedSecretKey(secretKey) - return credential{accessKey, secretKey, secretHash} -} - -// Validate incoming auth keys. -func validateAuthKeys(accessKey, secretKey string) error { - // Validate the env values before proceeding. - if !isAccessKeyValid(accessKey) { - return errInvalidAccessKeyLength +func mustGetNewCredential() credential { + // Generate access key. + keyBytes := make([]byte, accessKeyMaxLen) + if _, err := rand.Read(keyBytes); err != nil { + console.Fatalln("Unable to generate access key.", err) } - if !isSecretKeyValid(secretKey) { - return errInvalidSecretKeyLength + for i := 0; i < accessKeyMaxLen; i++ { + keyBytes[i] = alphaNumericTable[keyBytes[i]%alphaNumericTableLen] } - return nil -} + accessKey := string(keyBytes) -// Variant of getCredentialFromEnv but upon error fails right here. -func mustGetCredentialFromEnv() credential { - creds, err := getCredentialFromEnv() + // Generate secret key. + keyBytes = make([]byte, secretKeyMaxLen) + if _, err := rand.Read(keyBytes); err != nil { + console.Fatalln("Unable to generate secret key.", err) + } + secretKey := string([]byte(base64.StdEncoding.EncodeToString(keyBytes))[:secretKeyMaxLen]) + + cred, err := createCredential(accessKey, secretKey) if err != nil { - console.Fatalf("Unable to load credentials from environment. Err: %s.\n", err) - } - return creds -} - -// Converts accessKey and secretKeys into credential object which -// contains bcrypt secret key hash for future validation. -func getCredentialFromEnv() (credential, error) { - // Fetch access keys from environment variables and update the config. - accessKey := os.Getenv("MINIO_ACCESS_KEY") - secretKey := os.Getenv("MINIO_SECRET_KEY") - - // Envs are set globally. - globalIsEnvCreds = accessKey != "" && secretKey != "" - - if globalIsEnvCreds { - // Validate the env values before proceeding. - if err := validateAuthKeys(accessKey, secretKey); err != nil { - return credential{}, err - } - - // Return credential object. - return newCredentialWithKeys(accessKey, secretKey), nil + console.Fatalln("Unable to generate new credential.", err) } - return credential{}, nil + return cred } diff --git a/cmd/credential_test.go b/cmd/credential_test.go new file mode 100644 index 000000000..4d30519d3 --- /dev/null +++ b/cmd/credential_test.go @@ -0,0 +1,101 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import "testing" + +func TestMustGetNewCredential(t *testing.T) { + cred := mustGetNewCredential() + if !cred.IsValid() { + t.Fatalf("Failed to get new valid credential") + } +} + +func TestCreateCredential(t *testing.T) { + cred := mustGetNewCredential() + testCases := []struct { + accessKey string + secretKey string + expectedResult bool + expectedErr error + }{ + // Access key too small. + {"user", "pass", false, errInvalidAccessKeyLength}, + // Access key too long. + {"user12345678901234567", "pass", false, errInvalidAccessKeyLength}, + // Access key contains unsuppported characters. + {"!@#$", "pass", false, errInvalidAccessKeyLength}, + // Secret key too small. + {"myuser", "pass", false, errInvalidSecretKeyLength}, + // Secret key too long. + {"myuser", "pass1234567890123456789012345678901234567", false, errInvalidSecretKeyLength}, + // Success when access key contains leading/trailing spaces. + {" user ", cred.SecretKey, true, nil}, + {"myuser", "mypassword", true, nil}, + {cred.AccessKey, cred.SecretKey, true, nil}, + } + + for _, testCase := range testCases { + cred, err := createCredential(testCase.accessKey, testCase.secretKey) + if testCase.expectedErr == nil { + if err != nil { + t.Fatalf("error: expected = , got = %v", err) + } + } else if err == nil { + t.Fatalf("error: expected = %v, got = ", testCase.expectedErr) + } else if testCase.expectedErr.Error() != err.Error() { + t.Fatalf("error: expected = %v, got = %v", testCase.expectedErr, err) + } + + if testCase.expectedResult != cred.IsValid() { + t.Fatalf("cred: expected: %v, got: %v", testCase.expectedResult, cred.IsValid()) + } + } +} + +func TestCredentialEqual(t *testing.T) { + cred := mustGetNewCredential() + testCases := []struct { + cred credential + ccred credential + expectedResult bool + }{ + // Empty compare credential + {cred, credential{}, false}, + // Empty credential + {credential{}, cred, false}, + // Two different credentials + {cred, mustGetNewCredential(), false}, + // Access key is different in compare credential. + {cred, credential{AccessKey: "myuser", SecretKey: cred.SecretKey}, false}, + // Secret key is different in compare credential. + {cred, credential{AccessKey: cred.AccessKey, SecretKey: "mypassword"}, false}, + // secretHashKey is missing in compare credential. + {cred, credential{AccessKey: cred.AccessKey, SecretKey: cred.SecretKey}, true}, + // secretHashKey is missing in credential. + {credential{AccessKey: cred.AccessKey, SecretKey: cred.SecretKey}, cred, true}, + // Same credentials. + {cred, cred, true}, + } + + for _, testCase := range testCases { + result := testCase.cred.Equal(testCase.ccred) + if result != testCase.expectedResult { + t.Fatalf("cred: expected: %v, got: %v", testCase.expectedResult, result) + } + } +} diff --git a/cmd/jwt.go b/cmd/jwt.go index 54f4668f7..430cada9f 100644 --- a/cmd/jwt.go +++ b/cmd/jwt.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +20,10 @@ import ( "errors" "fmt" "net/http" - "strings" "time" jwtgo "github.com/dgrijalva/jwt-go" jwtreq "github.com/dgrijalva/jwt-go/request" - "golang.org/x/crypto/bcrypt" ) const ( @@ -39,9 +37,6 @@ const ( ) var ( - errInvalidAccessKeyLength = errors.New("Invalid access key, access key should be 5 to 20 characters in length") - errInvalidSecretKeyLength = errors.New("Invalid secret key, secret key should be 8 to 40 characters in length") - errInvalidAccessKeyID = errors.New("The access key ID you provided does not exist in our records") errChangeCredNotAllowed = errors.New("Changing access key and secret key not allowed") errAuthentication = errors.New("Authentication failed, check your access credentials") @@ -49,34 +44,19 @@ var ( ) func authenticateJWT(accessKey, secretKey string, expiry time.Duration) (string, error) { - // Trim spaces. - accessKey = strings.TrimSpace(accessKey) - - if !isAccessKeyValid(accessKey) { - return "", errInvalidAccessKeyLength - } - if !isSecretKeyValid(secretKey) { - return "", errInvalidSecretKeyLength + passedCredential, err := createCredential(accessKey, secretKey) + if err != nil { + return "", err } serverCred := serverConfig.GetCredential() - // Validate access key. - if accessKey != serverCred.AccessKey { + if serverCred.AccessKey != passedCredential.AccessKey { return "", errInvalidAccessKeyID } - // Validate secret key. - // Using bcrypt to avoid timing attacks. - if serverCred.secretKeyHash != nil { - if bcrypt.CompareHashAndPassword(serverCred.secretKeyHash, []byte(secretKey)) != nil { - return "", errAuthentication - } - } else { - // Secret key hash not set then generate and validate. - if bcrypt.CompareHashAndPassword(mustGetHashedSecretKey(serverCred.SecretKey), []byte(secretKey)) != nil { - return "", errAuthentication - } + if !serverCred.Equal(passedCredential) { + return "", errAuthentication } utcNow := time.Now().UTC() diff --git a/cmd/jwt_test.go b/cmd/jwt_test.go index c8b531269..7a101252e 100644 --- a/cmd/jwt_test.go +++ b/cmd/jwt_test.go @@ -39,6 +39,8 @@ func testAuthenticate(authType string, t *testing.T) { {"user12345678901234567", "pass", errInvalidAccessKeyLength}, // Access key contains unsuppported characters. {"!@#$", "pass", errInvalidAccessKeyLength}, + // Success when access key contains leading/trailing spaces. + {" " + serverCred.AccessKey + " ", serverCred.SecretKey, errInvalidAccessKeyLength}, // Secret key too small. {"myuser", "pass", errInvalidSecretKeyLength}, // Secret key too long. @@ -49,8 +51,6 @@ func testAuthenticate(authType string, t *testing.T) { {serverCred.AccessKey, "mypassword", errAuthentication}, // Success. {serverCred.AccessKey, serverCred.SecretKey, nil}, - // Success when access key contains leading/trailing spaces. - {" " + serverCred.AccessKey + " ", serverCred.SecretKey, nil}, } // Run tests. diff --git a/cmd/server-main.go b/cmd/server-main.go index 5f91e4de3..b45c52e22 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -118,10 +118,32 @@ func enableLoggers() { // Initializes a new config if it doesn't exist, else migrates any old config // to newer config and finally loads the config to memory. func initConfig() { + accessKey := os.Getenv("MINIO_ACCESS_KEY") + secretKey := os.Getenv("MINIO_SECRET_KEY") + + var cred credential + var err error + if accessKey != "" && secretKey != "" { + if cred, err = createCredential(accessKey, secretKey); err != nil { + console.Fatalf("Invalid access/secret Key set in environment. Err: %s.\n", err) + } + + // Envs are set globally. + globalIsEnvCreds = true + } + + browser := os.Getenv("MINIO_BROWSER") + if browser != "" { + if !(strings.EqualFold(browser, "off") || strings.EqualFold(browser, "on")) { + console.Fatalf("Invalid value ‘%s’ in MINIO_BROWSER environment variable.", browser) + } + + globalIsEnvBrowser = strings.EqualFold(browser, "off") + } envs := envParams{ - creds: mustGetCredentialFromEnv(), - browser: mustGetBrowserFromEnv(), + creds: cred, + browser: browser, } // Config file does not exist, we create it fresh and return upon success. diff --git a/cmd/server_test.go b/cmd/server_test.go index 70fb9e6ce..3dffd14b2 100644 --- a/cmd/server_test.go +++ b/cmd/server_test.go @@ -94,7 +94,7 @@ func (s *TestSuiteCommon) TearDownSuite(c *C) { } func (s *TestSuiteCommon) TestAuth(c *C) { - cred := newCredential() + cred := mustGetNewCredential() c.Assert(len(cred.AccessKey), Equals, accessKeyMaxLen) c.Assert(len(cred.SecretKey), Equals, secretKeyMaxLen) diff --git a/cmd/utils.go b/cmd/utils.go index 4d8512408..d644731ed 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -29,7 +29,6 @@ import ( "encoding/json" humanize "github.com/dustin/go-humanize" - "github.com/minio/mc/pkg/console" "github.com/pkg/profile" ) @@ -255,28 +254,6 @@ func dumpRequest(r *http.Request) string { return string(jsonBytes) } -// Variant of getBrowserFromEnv but upon error fails right here. -func mustGetBrowserFromEnv() string { - browser, err := getBrowserFromEnv() - if err != nil { - console.Fatalf("Unable to load MINIO_BROWSER value from environment. Err: %s.\n", err) - } - return browser -} - -// -func getBrowserFromEnv() (string, error) { - b := os.Getenv("MINIO_BROWSER") - if strings.TrimSpace(b) == "" { - return "", nil - } - if !strings.EqualFold(b, "off") && !strings.EqualFold(b, "on") { - return "", errInvalidArgument - } - globalIsEnvBrowser = true - return strings.ToLower(b), nil -} - // isFile - returns whether given path is a file or not. func isFile(path string) bool { if fi, err := os.Stat(path); err == nil { diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index e5a189358..feccf9767 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -373,7 +373,7 @@ func (web webAPIHandlers) GenerateAuth(r *http.Request, args *WebGenericArgs, re if !isHTTPRequestValid(r) { return toJSONError(errAuthentication) } - cred := newCredential() + cred := mustGetNewCredential() reply.AccessKey = cred.AccessKey reply.SecretKey = cred.SecretKey reply.UIVersion = browser.UIVersion @@ -404,16 +404,11 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se return toJSONError(errChangeCredNotAllowed) } - // As we already validated the authentication, we save given access/secret keys. - if err := validateAuthKeys(args.AccessKey, args.SecretKey); err != nil { + creds, err := createCredential(args.AccessKey, args.SecretKey) + if err != nil { return toJSONError(err) } - creds := credential{ - AccessKey: args.AccessKey, - SecretKey: args.SecretKey, - } - // Notify all other Minio peers to update credentials errsMap := updateCredsOnPeers(creds) @@ -421,7 +416,7 @@ func (web *webAPIHandlers) SetAuth(r *http.Request, args *SetAuthArgs, reply *Se serverConfig.SetCredential(creds) // Persist updated credentials. - if err := serverConfig.Save(); err != nil { + if err = serverConfig.Save(); err != nil { errsMap[globalMinioAddr] = err } From 3edff1501ed59df87c78e5c9bd18c4638b531b06 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 16 Mar 2017 08:22:47 -0700 Subject: [PATCH 91/94] Vendor upstream redis library instead of our fork. (#3913) We forked the upstream to address a build issue on go 1.6 - that is long done and we don't need to manage our forks anymore. --- cmd/notify-redis.go | 2 +- .../redigo/internal}/commandinfo.go | 2 +- .../{minio => garyburd}/redigo/redis/conn.go | 50 ++++- .../{minio => garyburd}/redigo/redis/doc.go | 17 +- .../github.com/garyburd/redigo/redis/go17.go | 33 ++++ .../{minio => garyburd}/redigo/redis/log.go | 0 .../{minio => garyburd}/redigo/redis/pool.go | 97 ++++++---- .../garyburd/redigo/redis/pre_go17.go | 31 ++++ .../redigo/redis/pubsub.go | 0 .../{minio => garyburd}/redigo/redis/redis.go | 5 +- .../{minio => garyburd}/redigo/redis/reply.go | 0 .../{minio => garyburd}/redigo/redis/scan.go | 0 .../redigo/redis/script.go | 0 vendor/github.com/minio/redigo/LICENSE | 175 ------------------ vendor/vendor.json | 18 +- 15 files changed, 202 insertions(+), 228 deletions(-) rename vendor/github.com/{minio/redigo/redis => garyburd/redigo/internal}/commandinfo.go (95%) rename vendor/github.com/{minio => garyburd}/redigo/redis/conn.go (91%) rename vendor/github.com/{minio => garyburd}/redigo/redis/doc.go (91%) create mode 100644 vendor/github.com/garyburd/redigo/redis/go17.go rename vendor/github.com/{minio => garyburd}/redigo/redis/log.go (100%) rename vendor/github.com/{minio => garyburd}/redigo/redis/pool.go (81%) create mode 100644 vendor/github.com/garyburd/redigo/redis/pre_go17.go rename vendor/github.com/{minio => garyburd}/redigo/redis/pubsub.go (100%) rename vendor/github.com/{minio => garyburd}/redigo/redis/redis.go (83%) rename vendor/github.com/{minio => garyburd}/redigo/redis/reply.go (100%) rename vendor/github.com/{minio => garyburd}/redigo/redis/scan.go (100%) rename vendor/github.com/{minio => garyburd}/redigo/redis/script.go (100%) delete mode 100644 vendor/github.com/minio/redigo/LICENSE diff --git a/cmd/notify-redis.go b/cmd/notify-redis.go index b4730e404..ca2aca93b 100644 --- a/cmd/notify-redis.go +++ b/cmd/notify-redis.go @@ -21,7 +21,7 @@ import ( "time" "github.com/Sirupsen/logrus" - "github.com/minio/redigo/redis" + "github.com/garyburd/redigo/redis" ) // redisNotify to send logs to Redis server diff --git a/vendor/github.com/minio/redigo/redis/commandinfo.go b/vendor/github.com/garyburd/redigo/internal/commandinfo.go similarity index 95% rename from vendor/github.com/minio/redigo/redis/commandinfo.go rename to vendor/github.com/garyburd/redigo/internal/commandinfo.go index 0ad2af5df..11e584257 100644 --- a/vendor/github.com/minio/redigo/redis/commandinfo.go +++ b/vendor/github.com/garyburd/redigo/internal/commandinfo.go @@ -12,7 +12,7 @@ // License for the specific language governing permissions and limitations // under the License. -package redis +package internal // import "github.com/garyburd/redigo/internal" import ( "strings" diff --git a/vendor/github.com/minio/redigo/redis/conn.go b/vendor/github.com/garyburd/redigo/redis/conn.go similarity index 91% rename from vendor/github.com/minio/redigo/redis/conn.go rename to vendor/github.com/garyburd/redigo/redis/conn.go index ed358c601..6ccace078 100644 --- a/vendor/github.com/minio/redigo/redis/conn.go +++ b/vendor/github.com/garyburd/redigo/redis/conn.go @@ -17,6 +17,7 @@ package redis import ( "bufio" "bytes" + "crypto/tls" "errors" "fmt" "io" @@ -75,6 +76,9 @@ type dialOptions struct { dial func(network, addr string) (net.Conn, error) db int password string + dialTLS bool + skipVerify bool + tlsConfig *tls.Config } // DialReadTimeout specifies the timeout for reading a single command reply. @@ -123,6 +127,22 @@ func DialPassword(password string) DialOption { }} } +// DialTLSConfig specifies the config to use when a TLS connection is dialed. +// Has no effect when not dialing a TLS connection. +func DialTLSConfig(c *tls.Config) DialOption { + return DialOption{func(do *dialOptions) { + do.tlsConfig = c + }} +} + +// DialTLSSkipVerify to disable server name verification when connecting +// over TLS. Has no effect when not dialing a TLS connection. +func DialTLSSkipVerify(skip bool) DialOption { + return DialOption{func(do *dialOptions) { + do.skipVerify = skip + }} +} + // Dial connects to the Redis server at the given network and // address using the specified options. func Dial(network, address string, options ...DialOption) (Conn, error) { @@ -137,6 +157,26 @@ func Dial(network, address string, options ...DialOption) (Conn, error) { if err != nil { return nil, err } + + if do.dialTLS { + tlsConfig := cloneTLSClientConfig(do.tlsConfig, do.skipVerify) + if tlsConfig.ServerName == "" { + host, _, err := net.SplitHostPort(address) + if err != nil { + netConn.Close() + return nil, err + } + tlsConfig.ServerName = host + } + + tlsConn := tls.Client(netConn, tlsConfig) + if err := tlsConn.Handshake(); err != nil { + netConn.Close() + return nil, err + } + netConn = tlsConn + } + c := &conn{ conn: netConn, bw: bufio.NewWriter(netConn), @@ -162,6 +202,10 @@ func Dial(network, address string, options ...DialOption) (Conn, error) { return c, nil } +func dialTLS(do *dialOptions) { + do.dialTLS = true +} + var pathDBRegexp = regexp.MustCompile(`/(\d*)\z`) // DialURL connects to a Redis server at the given URL using the Redis @@ -173,7 +217,7 @@ func DialURL(rawurl string, options ...DialOption) (Conn, error) { return nil, err } - if u.Scheme != "redis" { + if u.Scheme != "redis" && u.Scheme != "rediss" { return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme) } @@ -213,6 +257,10 @@ func DialURL(rawurl string, options ...DialOption) (Conn, error) { return nil, fmt.Errorf("invalid database: %s", u.Path[1:]) } + if u.Scheme == "rediss" { + options = append([]DialOption{{dialTLS}}, options...) + } + return Dial("tcp", address, options...) } diff --git a/vendor/github.com/minio/redigo/redis/doc.go b/vendor/github.com/garyburd/redigo/redis/doc.go similarity index 91% rename from vendor/github.com/minio/redigo/redis/doc.go rename to vendor/github.com/garyburd/redigo/redis/doc.go index 6571c9de2..d4f489280 100644 --- a/vendor/github.com/minio/redigo/redis/doc.go +++ b/vendor/github.com/garyburd/redigo/redis/doc.go @@ -14,7 +14,7 @@ // Package redis is a client for the Redis database. // -// The Redigo FAQ (https://github.com/minio/redigo/wiki/FAQ) contains more +// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more // documentation about this package. // // Connections @@ -99,7 +99,7 @@ // // Concurrency // -// Connections support one concurrent caller to the Recieve method and one +// Connections support one concurrent caller to the Receive method and one // concurrent caller to the Send and Flush methods. No other concurrency is // supported including concurrent calls to the Do method. // @@ -127,7 +127,7 @@ // send and flush a subscription management command. The receive method // converts a pushed message to convenient types for use in a type switch. // -// psc := redis.PubSubConn{c} +// psc := redis.PubSubConn{Conn: c} // psc.Subscribe("example") // for { // switch v := psc.Receive().(type) { @@ -165,4 +165,13 @@ // if _, err := redis.Scan(reply, &value1, &value2); err != nil { // // handle error // } -package redis // import "github.com/minio/redigo/redis" +// +// Errors +// +// Connection methods return error replies from the server as type redis.Error. +// +// Call the connection Err() method to determine if the connection encountered +// non-recoverable error such as a network error or protocol parsing error. If +// Err() returns a non-nil value, then the connection is not usable and should +// be closed. +package redis // import "github.com/garyburd/redigo/redis" diff --git a/vendor/github.com/garyburd/redigo/redis/go17.go b/vendor/github.com/garyburd/redigo/redis/go17.go new file mode 100644 index 000000000..3f951e5ef --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/go17.go @@ -0,0 +1,33 @@ +// +build go1.7 + +package redis + +import "crypto/tls" + +// similar cloneTLSClientConfig in the stdlib, but also honor skipVerify for the nil case +func cloneTLSClientConfig(cfg *tls.Config, skipVerify bool) *tls.Config { + if cfg == nil { + return &tls.Config{InsecureSkipVerify: skipVerify} + } + return &tls.Config{ + Rand: cfg.Rand, + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled, + Renegotiation: cfg.Renegotiation, + } +} diff --git a/vendor/github.com/minio/redigo/redis/log.go b/vendor/github.com/garyburd/redigo/redis/log.go similarity index 100% rename from vendor/github.com/minio/redigo/redis/log.go rename to vendor/github.com/garyburd/redigo/redis/log.go diff --git a/vendor/github.com/minio/redigo/redis/pool.go b/vendor/github.com/garyburd/redigo/redis/pool.go similarity index 81% rename from vendor/github.com/minio/redigo/redis/pool.go rename to vendor/github.com/garyburd/redigo/redis/pool.go index 749d8a9c5..283a41d5a 100644 --- a/vendor/github.com/minio/redigo/redis/pool.go +++ b/vendor/github.com/garyburd/redigo/redis/pool.go @@ -24,6 +24,8 @@ import ( "strconv" "sync" "time" + + "github.com/garyburd/redigo/internal" ) var nowFunc = time.Now // for testing @@ -44,40 +46,26 @@ var ( // // The following example shows how to use a pool in a web application. The // application creates a pool at application startup and makes it available to -// request handlers using a global variable. +// request handlers using a package level variable. The pool configuration used +// here is an example, not a recommendation. // -// func newPool(server, password string) *redis.Pool { -// return &redis.Pool{ -// MaxIdle: 3, -// IdleTimeout: 240 * time.Second, -// Dial: func () (redis.Conn, error) { -// c, err := redis.Dial("tcp", server) -// if err != nil { -// return nil, err -// } -// if _, err := c.Do("AUTH", password); err != nil { -// c.Close() -// return nil, err -// } -// return c, err -// }, -// TestOnBorrow: func(c redis.Conn, t time.Time) error { -// _, err := c.Do("PING") -// return err -// }, -// } +// func newPool(addr string) *redis.Pool { +// return &redis.Pool{ +// MaxIdle: 3, +// IdleTimeout: 240 * time.Second, +// Dial: func () (redis.Conn, error) { return redis.Dial("tcp", addr) }, +// } // } // // var ( -// pool *redis.Pool -// redisServer = flag.String("redisServer", ":6379", "") -// redisPassword = flag.String("redisPassword", "", "") +// pool *redis.Pool +// redisServer = flag.String("redisServer", ":6379", "") // ) // // func main() { -// flag.Parse() -// pool = newPool(*redisServer, *redisPassword) -// ... +// flag.Parse() +// pool = newPool(*redisServer) +// ... // } // // A request handler gets a connection from the pool and closes the connection @@ -86,7 +74,44 @@ var ( // func serveHome(w http.ResponseWriter, r *http.Request) { // conn := pool.Get() // defer conn.Close() -// .... +// ... +// } +// +// Use the Dial function to authenticate connections with the AUTH command or +// select a database with the SELECT command: +// +// pool := &redis.Pool{ +// // Other pool configuration not shown in this example. +// Dial: func () (redis.Conn, error) { +// c, err := redis.Dial("tcp", server) +// if err != nil { +// return nil, err +// } +// if _, err := c.Do("AUTH", password); err != nil { +// c.Close() +// return nil, err +// } +// if _, err := c.Do("SELECT", db); err != nil { +// c.Close() +// return nil, err +// } +// return c, nil +// } +// } +// +// Use the TestOnBorrow function to check the health of an idle connection +// before the connection is returned to the application. This example PINGs +// connections that have been idle more than a minute: +// +// pool := &redis.Pool{ +// // Other pool configuration not shown in this example. +// TestOnBorrow: func(c redis.Conn, t time.Time) error { +// if time.Since(t) < time.Minute { +// return nil +// } +// _, err := c.Do("PING") +// return err +// }, // } // type Pool struct { @@ -326,14 +351,14 @@ func (pc *pooledConnection) Close() error { } pc.c = errorConnection{errConnClosed} - if pc.state&MultiState != 0 { + if pc.state&internal.MultiState != 0 { c.Send("DISCARD") - pc.state &^= (MultiState | WatchState) - } else if pc.state&WatchState != 0 { + pc.state &^= (internal.MultiState | internal.WatchState) + } else if pc.state&internal.WatchState != 0 { c.Send("UNWATCH") - pc.state &^= WatchState + pc.state &^= internal.WatchState } - if pc.state&SubscribeState != 0 { + if pc.state&internal.SubscribeState != 0 { c.Send("UNSUBSCRIBE") c.Send("PUNSUBSCRIBE") // To detect the end of the message stream, ask the server to echo @@ -347,7 +372,7 @@ func (pc *pooledConnection) Close() error { break } if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) { - pc.state &^= SubscribeState + pc.state &^= internal.SubscribeState break } } @@ -362,13 +387,13 @@ func (pc *pooledConnection) Err() error { } func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) { - ci := LookupCommandInfo(commandName) + ci := internal.LookupCommandInfo(commandName) pc.state = (pc.state | ci.Set) &^ ci.Clear return pc.c.Do(commandName, args...) } func (pc *pooledConnection) Send(commandName string, args ...interface{}) error { - ci := LookupCommandInfo(commandName) + ci := internal.LookupCommandInfo(commandName) pc.state = (pc.state | ci.Set) &^ ci.Clear return pc.c.Send(commandName, args...) } diff --git a/vendor/github.com/garyburd/redigo/redis/pre_go17.go b/vendor/github.com/garyburd/redigo/redis/pre_go17.go new file mode 100644 index 000000000..0212f60fb --- /dev/null +++ b/vendor/github.com/garyburd/redigo/redis/pre_go17.go @@ -0,0 +1,31 @@ +// +build !go1.7 + +package redis + +import "crypto/tls" + +// similar cloneTLSClientConfig in the stdlib, but also honor skipVerify for the nil case +func cloneTLSClientConfig(cfg *tls.Config, skipVerify bool) *tls.Config { + if cfg == nil { + return &tls.Config{InsecureSkipVerify: skipVerify} + } + return &tls.Config{ + Rand: cfg.Rand, + Time: cfg.Time, + Certificates: cfg.Certificates, + NameToCertificate: cfg.NameToCertificate, + GetCertificate: cfg.GetCertificate, + RootCAs: cfg.RootCAs, + NextProtos: cfg.NextProtos, + ServerName: cfg.ServerName, + ClientAuth: cfg.ClientAuth, + ClientCAs: cfg.ClientCAs, + InsecureSkipVerify: cfg.InsecureSkipVerify, + CipherSuites: cfg.CipherSuites, + PreferServerCipherSuites: cfg.PreferServerCipherSuites, + ClientSessionCache: cfg.ClientSessionCache, + MinVersion: cfg.MinVersion, + MaxVersion: cfg.MaxVersion, + CurvePreferences: cfg.CurvePreferences, + } +} diff --git a/vendor/github.com/minio/redigo/redis/pubsub.go b/vendor/github.com/garyburd/redigo/redis/pubsub.go similarity index 100% rename from vendor/github.com/minio/redigo/redis/pubsub.go rename to vendor/github.com/garyburd/redigo/redis/pubsub.go diff --git a/vendor/github.com/minio/redigo/redis/redis.go b/vendor/github.com/garyburd/redigo/redis/redis.go similarity index 83% rename from vendor/github.com/minio/redigo/redis/redis.go rename to vendor/github.com/garyburd/redigo/redis/redis.go index c90a48ed4..b7298298c 100644 --- a/vendor/github.com/minio/redigo/redis/redis.go +++ b/vendor/github.com/garyburd/redigo/redis/redis.go @@ -24,10 +24,7 @@ type Conn interface { // Close closes the connection. Close() error - // Err returns a non-nil value if the connection is broken. The returned - // value is either the first non-nil value returned from the underlying - // network connection or a protocol parsing error. Applications should - // close broken connections. + // Err returns a non-nil value when the connection is not usable. Err() error // Do sends a command to the server and returns the received reply. diff --git a/vendor/github.com/minio/redigo/redis/reply.go b/vendor/github.com/garyburd/redigo/redis/reply.go similarity index 100% rename from vendor/github.com/minio/redigo/redis/reply.go rename to vendor/github.com/garyburd/redigo/redis/reply.go diff --git a/vendor/github.com/minio/redigo/redis/scan.go b/vendor/github.com/garyburd/redigo/redis/scan.go similarity index 100% rename from vendor/github.com/minio/redigo/redis/scan.go rename to vendor/github.com/garyburd/redigo/redis/scan.go diff --git a/vendor/github.com/minio/redigo/redis/script.go b/vendor/github.com/garyburd/redigo/redis/script.go similarity index 100% rename from vendor/github.com/minio/redigo/redis/script.go rename to vendor/github.com/garyburd/redigo/redis/script.go diff --git a/vendor/github.com/minio/redigo/LICENSE b/vendor/github.com/minio/redigo/LICENSE deleted file mode 100644 index 67db85882..000000000 --- a/vendor/github.com/minio/redigo/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/vendor/vendor.json b/vendor/vendor.json index 645342f9c..5424a54b3 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -62,6 +62,18 @@ "revision": "42c364ba490082e4815b5222728711b3440603eb", "revisionTime": "2017-01-13T15:16:12Z" }, + { + "checksumSHA1": "2UmMbNHc8FBr98mJFN1k8ISOIHk=", + "path": "github.com/garyburd/redigo/internal", + "revision": "0d253a66e6e1349f4581d6d2b300ee434ee2da9f", + "revisionTime": "2017-02-16T21:49:44Z" + }, + { + "checksumSHA1": "81OSg/NapmTaRpSS+oYsPVE0b1Y=", + "path": "github.com/garyburd/redigo/redis", + "revision": "0d253a66e6e1349f4581d6d2b300ee434ee2da9f", + "revisionTime": "2017-02-16T21:49:44Z" + }, { "checksumSHA1": "3yco0089CSJ4qbyUccpbDC2+dPg=", "path": "github.com/gogo/protobuf/gogoproto", @@ -208,12 +220,6 @@ "revision": "9e734013294ab153b0bdbe182738bcddd46f1947", "revisionTime": "2016-08-18T00:31:20Z" }, - { - "checksumSHA1": "GOSe2XEQI4AYwrMoLZu8vtmzkJM=", - "path": "github.com/minio/redigo/redis", - "revision": "5e2117cd32d677a36dcd8c9c83776a065555653b", - "revisionTime": "2016-07-24T00:05:56Z" - }, { "checksumSHA1": "URVle4qtadmW9w9BulDRHY3kxnA=", "path": "github.com/minio/sha256-simd", From f3334159a486417bfdaf1e18c6b52b7f7a8e2b61 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 16 Mar 2017 11:06:17 -0700 Subject: [PATCH 92/94] config: Relax browser and region to be empty. (#3912) - If browser field is missing or empty then default to "on". - If region field is empty or missing then default to "us-east-1" (S3 spec behavior) --- cmd/config-v14.go | 28 +++++++++++++++++++++++---- cmd/config-v14_test.go | 43 +++++++++++++++++++++++------------------- cmd/server-main.go | 6 ++++-- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/cmd/config-v14.go b/cmd/config-v14.go index a2986091e..e17d2b787 100644 --- a/cmd/config-v14.go +++ b/cmd/config-v14.go @@ -18,6 +18,7 @@ package cmd import ( "errors" + "fmt" "io/ioutil" "os" "strings" @@ -244,12 +245,12 @@ func validateConfig() error { // Validate region field if srvCfg.GetRegion() == "" { - return errors.New("region config is empty") + return errors.New("Region config value cannot be empty") } // Validate browser field if b := strings.ToLower(srvCfg.GetBrowser()); b != "on" && b != "off" { - return errors.New("invalid browser config") + return fmt.Errorf("Browser config value %s is invalid", b) } // Validate credential field @@ -286,6 +287,10 @@ func (s *serverConfigV14) SetRegion(region string) { serverConfigMu.Lock() defer serverConfigMu.Unlock() + // Empty region means "us-east-1" by default from S3 spec. + if region == "" { + region = "us-east-1" + } s.Region = region } @@ -294,7 +299,12 @@ func (s serverConfigV14) GetRegion() string { serverConfigMu.RLock() defer serverConfigMu.RUnlock() - return s.Region + if s.Region != "" { + return s.Region + } // region empty + + // Empty region means "us-east-1" by default from S3 spec. + return "us-east-1" } // SetCredentials set new credentials. @@ -320,6 +330,11 @@ func (s *serverConfigV14) SetBrowser(v string) { defer serverConfigMu.Unlock() // Set browser param + if v == "" { + v = "on" // Browser is on by default. + } + + // Set the new value. s.Browser = v } @@ -328,7 +343,12 @@ func (s serverConfigV14) GetBrowser() string { serverConfigMu.RLock() defer serverConfigMu.RUnlock() - return s.Browser + if s.Browser != "" { + return s.Browser + } // empty browser. + + // Empty browser means "on" by default. + return "on" } // Save config. diff --git a/cmd/config-v14_test.go b/cmd/config-v14_test.go index eadb5966a..718b6276d 100644 --- a/cmd/config-v14_test.go +++ b/cmd/config-v14_test.go @@ -200,11 +200,13 @@ func TestCheckDupJSONKeys(t *testing.T) { } +// Tests config validator.. func TestValidateConfig(t *testing.T) { rootPath, err := newTestConfig(globalMinioDefaultRegion) if err != nil { t.Fatalf("Init Test config failed") } + // remove the root directory after the test ends. defer removeAll(rootPath) @@ -234,52 +236,55 @@ func TestValidateConfig(t *testing.T) { // Test 6 - missing secret key {`{"version": "` + v + `", "browser": "on", "credential" : {"accessKey":"minio", "secretKey":""}}`, false}, - // Test 7 - missing region - {`{"version": "` + v + `", "browser": "on", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, false}, + // Test 7 - missing region should pass, defaults to 'us-east-1'. + {`{"version": "` + v + `", "browser": "on", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, true}, - // Test 8 - success + // Test 8 - missing browser should pass, defaults to 'on'. + {`{"version": "` + v + `", "region": "us-east-1", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, true}, + + // Test 9 - success {`{"version": "` + v + `", "browser": "on", "region":"us-east-1", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, true}, - // Test 9 - duplicated json keys + // Test 10 - duplicated json keys {`{"version": "` + v + `", "browser": "on", "browser": "on", "region":"us-east-1", "credential" : {"accessKey":"minio", "secretKey":"minio123"}}`, false}, - // Test 10 - Wrong Console logger level + // Test 11 - Wrong Console logger level {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "logger": { "console": { "enable": true, "level": "foo" } }}`, false}, - // Test 11 - Wrong File logger level + // Test 12 - Wrong File logger level {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "logger": { "file": { "enable": true, "level": "foo" } }}`, false}, - // Test 12 - Test AMQP + // Test 13 - Test AMQP {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "amqp": { "1": { "enable": true, "url": "", "exchange": "", "routingKey": "", "exchangeType": "", "mandatory": false, "immediate": false, "durable": false, "internal": false, "noWait": false, "autoDeleted": false }}}}`, false}, - // Test 13 - Test NATS + // Test 14 - Test NATS {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "nats": { "1": { "enable": true, "address": "", "subject": "", "username": "", "password": "", "token": "", "secure": false, "pingInterval": 0, "streaming": { "enable": false, "clusterID": "", "clientID": "", "async": false, "maxPubAcksInflight": 0 } } }}}`, false}, - // Test 14 - Test ElasticSearch + // Test 15 - Test ElasticSearch {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "elasticsearch": { "1": { "enable": true, "url": "", "index": "" } }}}`, false}, - // Test 15 - Test Redis + // Test 16 - Test Redis {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "redis": { "1": { "enable": true, "address": "", "password": "", "key": "" } }}}`, false}, - // Test 16 - Test PostgreSQL + // Test 17 - Test PostgreSQL {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "postgresql": { "1": { "enable": true, "connectionString": "", "table": "", "host": "", "port": "", "user": "", "password": "", "database": "" }}}}`, false}, - // Test 17 - Test Kafka + // Test 18 - Test Kafka {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "kafka": { "1": { "enable": true, "brokers": null, "topic": "" } }}}`, false}, - // Test 18 - Test Webhook + // Test 19 - Test Webhook {`{"version": "` + v + `", "credential": { "accessKey": "minio", "secretKey": "minio123" }, "region": "us-east-1", "browser": "on", "notify": { "webhook": { "1": { "enable": true, "endpoint": "" } }}}`, false}, } for i, testCase := range testCases { - if err := ioutil.WriteFile(configPath, []byte(testCase.configData), 0700); err != nil { - t.Error(err) + if werr := ioutil.WriteFile(configPath, []byte(testCase.configData), 0700); werr != nil { + t.Fatal(werr) } - err := validateConfig() - if testCase.shouldPass && err != nil { - t.Errorf("Test %d, should pass but it failed with err = %v", i+1, err) + verr := validateConfig() + if testCase.shouldPass && verr != nil { + t.Errorf("Test %d, should pass but it failed with err = %v", i+1, verr) } - if !testCase.shouldPass && err == nil { + if !testCase.shouldPass && verr == nil { t.Errorf("Test %d, should fail but it succeed.", i+1) } } diff --git a/cmd/server-main.go b/cmd/server-main.go index b45c52e22..61223af23 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -128,7 +128,7 @@ func initConfig() { console.Fatalf("Invalid access/secret Key set in environment. Err: %s.\n", err) } - // Envs are set globally. + // credential Envs are set globally. globalIsEnvCreds = true } @@ -138,7 +138,9 @@ func initConfig() { console.Fatalf("Invalid value ‘%s’ in MINIO_BROWSER environment variable.", browser) } - globalIsEnvBrowser = strings.EqualFold(browser, "off") + // browser Envs are set globally, this doesn't represent + // if browser is turned off or on. + globalIsEnvBrowser = true } envs := envParams{ From 8426cf9aec468e67928c2d942ca2eadb12fb826e Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Thu, 16 Mar 2017 19:44:01 +0100 Subject: [PATCH 93/94] config: Accept more address format + unit test (#3915) checkURL() is a generic function to check if a passed address is valid. This commit adds support for addresses like `m1` and `172.16.3.1` which is needed in MySQL and NATS. This commit also adds tests. --- cmd/notify-amqp.go | 2 +- cmd/notify-elasticsearch.go | 2 +- cmd/notify-nats.go | 2 +- cmd/notify-postgresql.go | 2 +- cmd/notify-redis.go | 2 +- cmd/notify-webhook.go | 2 +- cmd/utils.go | 12 ++++++------ cmd/utils_test.go | 27 +++++++++++++++++++++++++++ 8 files changed, 39 insertions(+), 12 deletions(-) diff --git a/cmd/notify-amqp.go b/cmd/notify-amqp.go index 8e3b4652e..04965d954 100644 --- a/cmd/notify-amqp.go +++ b/cmd/notify-amqp.go @@ -44,7 +44,7 @@ func (a *amqpNotify) Validate() error { if !a.Enable { return nil } - if _, err := checkNetURL(a.URL); err != nil { + if _, err := checkURL(a.URL); err != nil { return err } return nil diff --git a/cmd/notify-elasticsearch.go b/cmd/notify-elasticsearch.go index 4773feaf2..e35eef0cd 100644 --- a/cmd/notify-elasticsearch.go +++ b/cmd/notify-elasticsearch.go @@ -37,7 +37,7 @@ func (e *elasticSearchNotify) Validate() error { if !e.Enable { return nil } - if _, err := checkNetURL(e.URL); err != nil { + if _, err := checkURL(e.URL); err != nil { return err } return nil diff --git a/cmd/notify-nats.go b/cmd/notify-nats.go index 8fe0654d7..1659eefc2 100644 --- a/cmd/notify-nats.go +++ b/cmd/notify-nats.go @@ -52,7 +52,7 @@ func (n *natsNotify) Validate() error { if !n.Enable { return nil } - if _, err := checkNetURL(n.Address); err != nil { + if _, err := checkURL(n.Address); err != nil { return err } return nil diff --git a/cmd/notify-postgresql.go b/cmd/notify-postgresql.go index 1ea092f5b..fadecd332 100644 --- a/cmd/notify-postgresql.go +++ b/cmd/notify-postgresql.go @@ -88,7 +88,7 @@ func (p *postgreSQLNotify) Validate() error { if !p.Enable { return nil } - if _, err := checkNetURL(p.Host); err != nil { + if _, err := checkURL(p.Host); err != nil { return err } return nil diff --git a/cmd/notify-redis.go b/cmd/notify-redis.go index ca2aca93b..1f385d472 100644 --- a/cmd/notify-redis.go +++ b/cmd/notify-redis.go @@ -36,7 +36,7 @@ func (r *redisNotify) Validate() error { if !r.Enable { return nil } - if _, err := checkNetURL(r.Addr); err != nil { + if _, err := checkURL(r.Addr); err != nil { return err } return nil diff --git a/cmd/notify-webhook.go b/cmd/notify-webhook.go index b028c8e4e..c64421996 100644 --- a/cmd/notify-webhook.go +++ b/cmd/notify-webhook.go @@ -36,7 +36,7 @@ func (w *webhookNotify) Validate() error { if !w.Enable { return nil } - if _, err := checkNetURL(w.Endpoint); err != nil { + if _, err := checkURL(w.Endpoint); err != nil { return err } return nil diff --git a/cmd/utils.go b/cmd/utils.go index d644731ed..744e7bd08 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -19,6 +19,7 @@ package cmd import ( "encoding/base64" "encoding/xml" + "errors" "fmt" "io" "net/http" @@ -263,15 +264,14 @@ func isFile(path string) bool { return false } -// checkNetURL - checks if passed address correspond -// to a network address (and not file system path) -func checkNetURL(address string) (*url.URL, error) { +// checkURL - checks if passed address correspond +func checkURL(address string) (*url.URL, error) { + if address == "" { + return nil, errors.New("Address cannot be empty") + } u, err := url.Parse(address) if err != nil { return nil, fmt.Errorf("`%s` invalid: %s", address, err.Error()) } - if u.Host == "" { - return nil, fmt.Errorf("`%s` invalid network URL", address) - } return u, nil } diff --git a/cmd/utils_test.go b/cmd/utils_test.go index d0d11c3f4..fa06e8e09 100644 --- a/cmd/utils_test.go +++ b/cmd/utils_test.go @@ -388,3 +388,30 @@ func TestLocalAddress(t *testing.T) { } } + +// TestCheckURL tests valid address +func TestCheckURL(t *testing.T) { + testCases := []struct { + addr string + shouldPass bool + }{ + {"", false}, + {":", false}, + {"localhost", true}, + {"127.0.0.1", true}, + {"http://localhost/", true}, + {"http://127.0.0.1/", true}, + {"proto://myhostname/path", true}, + } + + // Validates fetching local address. + for i, testCase := range testCases { + _, err := checkURL(testCase.addr) + if testCase.shouldPass && err != nil { + t.Errorf("Test %d: expected to pass but got an error: %v\n", i+1, err) + } + if !testCase.shouldPass && err == nil { + t.Errorf("Test %d: expected to fail but passed.", i+1) + } + } +} From cea4cfa3a8005a9504024179e8e6e53c42b69d23 Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Thu, 16 Mar 2017 12:21:58 -0700 Subject: [PATCH 94/94] Implement S3 Gateway to third party cloud storage providers. (#3756) Currently supported backend is Azure Blob Storage. ``` export MINIO_ACCESS_KEY=azureaccountname export MINIO_SECRET_KEY=azureaccountkey minio gateway azure ``` --- cmd/api-errors.go | 2 + cmd/api-errors_test.go | 4 + cmd/azure-anonymous.go | 185 ++ cmd/azure-unsupported.go | 43 + cmd/azure.go | 635 +++++++ cmd/azure_test.go | 142 ++ cmd/bucket-handlers.go | 4 + cmd/credential.go | 36 +- cmd/event-notifier.go | 3 + cmd/gateway-handlers.go | 703 ++++++++ cmd/gateway-main.go | 219 +++ cmd/gateway-router.go | 122 ++ cmd/gateway-startup-msg.go | 67 + cmd/gateway-startup-msg_test.go | 31 + cmd/globals.go | 4 + cmd/main.go | 1 + cmd/server-main.go | 25 +- cmd/server-startup-msg.go | 3 +- cmd/update-main.go | 24 +- cmd/update-main_test.go | 2 +- cmd/web-handlers.go | 8 +- cmd/web-handlers_test.go | 4 +- docs/gateway/README.md | 48 + docs/gateway/azure-limitations.md | 19 + .../github.com/Azure/azure-sdk-for-go/LICENSE | 202 +++ .../Azure/azure-sdk-for-go/storage/README.md | 5 + .../azure-sdk-for-go/storage/authorization.go | 223 +++ .../Azure/azure-sdk-for-go/storage/blob.go | 1539 +++++++++++++++++ .../Azure/azure-sdk-for-go/storage/client.go | 469 +++++ .../azure-sdk-for-go/storage/directory.go | 217 +++ .../Azure/azure-sdk-for-go/storage/file.go | 360 ++++ .../storage/fileserviceclient.go | 360 ++++ .../Azure/azure-sdk-for-go/storage/queue.go | 346 ++++ .../Azure/azure-sdk-for-go/storage/share.go | 186 ++ .../azure-sdk-for-go/storage/storagepolicy.go | 47 + .../Azure/azure-sdk-for-go/storage/table.go | 258 +++ .../storage/table_entities.go | 345 ++++ .../Azure/azure-sdk-for-go/storage/util.go | 85 + .../Azure/azure-sdk-for-go/storage/version.go | 5 + vendor/github.com/minio/cli/help.go | 55 +- vendor/vendor.json | 12 +- 41 files changed, 6983 insertions(+), 65 deletions(-) create mode 100644 cmd/azure-anonymous.go create mode 100644 cmd/azure-unsupported.go create mode 100644 cmd/azure.go create mode 100644 cmd/azure_test.go create mode 100644 cmd/gateway-handlers.go create mode 100644 cmd/gateway-main.go create mode 100644 cmd/gateway-router.go create mode 100644 cmd/gateway-startup-msg.go create mode 100644 cmd/gateway-startup-msg_test.go create mode 100644 docs/gateway/README.md create mode 100644 docs/gateway/azure-limitations.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/LICENSE create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/README.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/authorization.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/file.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/share.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/storagepolicy.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/table.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/util.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/storage/version.go diff --git a/cmd/api-errors.go b/cmd/api-errors.go index 81c69b784..7d061495e 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -692,6 +692,8 @@ func toAPIErrorCode(err error) (apiErr APIErrorCode) { apiErr = ErrEntityTooLarge case ObjectTooSmall: apiErr = ErrEntityTooSmall + case NotImplemented: + apiErr = ErrNotImplemented default: apiErr = ErrInternalError } diff --git a/cmd/api-errors_test.go b/cmd/api-errors_test.go index ca5f653ec..7a4b6fde0 100644 --- a/cmd/api-errors_test.go +++ b/cmd/api-errors_test.go @@ -103,6 +103,10 @@ func TestAPIErrCode(t *testing.T) { StorageFull{}, ErrStorageFull, }, + { + NotImplemented{}, + ErrNotImplemented, + }, { errSignatureMismatch, ErrSignatureDoesNotMatch, diff --git a/cmd/azure-anonymous.go b/cmd/azure-anonymous.go new file mode 100644 index 000000000..72bb6bc9b --- /dev/null +++ b/cmd/azure-anonymous.go @@ -0,0 +1,185 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/Azure/azure-sdk-for-go/storage" +) + +// AnonGetBucketInfo - Get bucket metadata from azure anonymously. +func (a AzureObjects) AnonGetBucketInfo(bucket string) (bucketInfo BucketInfo, err error) { + url, err := url.Parse(a.client.GetBlobURL(bucket, "")) + if err != nil { + return bucketInfo, azureToObjectError(traceError(err)) + } + url.RawQuery = "restype=container" + resp, err := http.Head(url.String()) + if err != nil { + return bucketInfo, azureToObjectError(traceError(err), bucket) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return bucketInfo, azureToObjectError(traceError(anonErrToObjectErr(resp.StatusCode, bucket)), bucket) + } + + t, err := time.Parse(time.RFC1123, resp.Header.Get("Last-Modified")) + if err != nil { + return bucketInfo, traceError(err) + } + bucketInfo = BucketInfo{ + Name: bucket, + Created: t, + } + return bucketInfo, nil +} + +// AnonGetObject - SendGET request without authentication. +// This is needed when clients send GET requests on objects that can be downloaded without auth. +func (a AzureObjects) AnonGetObject(bucket, object string, startOffset int64, length int64, writer io.Writer) (err error) { + url := a.client.GetBlobURL(bucket, object) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return azureToObjectError(traceError(err), bucket, object) + } + + if length > 0 && startOffset > 0 { + req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", startOffset, startOffset+length-1)) + } else if startOffset > 0 { + req.Header.Add("Range", fmt.Sprintf("bytes=%d-", startOffset)) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return azureToObjectError(traceError(err), bucket, object) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusPartialContent && resp.StatusCode != http.StatusOK { + return azureToObjectError(traceError(anonErrToObjectErr(resp.StatusCode, bucket, object)), bucket, object) + } + + _, err = io.Copy(writer, resp.Body) + return traceError(err) +} + +// AnonGetObjectInfo - Send HEAD request without authentication and convert the +// result to ObjectInfo. +func (a AzureObjects) AnonGetObjectInfo(bucket, object string) (objInfo ObjectInfo, err error) { + resp, err := http.Head(a.client.GetBlobURL(bucket, object)) + if err != nil { + return objInfo, azureToObjectError(traceError(err), bucket, object) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return objInfo, azureToObjectError(traceError(anonErrToObjectErr(resp.StatusCode, bucket, object)), bucket, object) + } + + var contentLength int64 + contentLengthStr := resp.Header.Get("Content-Length") + if contentLengthStr != "" { + contentLength, err = strconv.ParseInt(contentLengthStr, 0, 64) + if err != nil { + return objInfo, azureToObjectError(traceError(errUnexpected), bucket, object) + } + } + + t, err := time.Parse(time.RFC1123, resp.Header.Get("Last-Modified")) + if err != nil { + return objInfo, traceError(err) + } + + objInfo.ModTime = t + objInfo.Bucket = bucket + objInfo.UserDefined = make(map[string]string) + if resp.Header.Get("Content-Encoding") != "" { + objInfo.UserDefined["Content-Encoding"] = resp.Header.Get("Content-Encoding") + } + objInfo.UserDefined["Content-Type"] = resp.Header.Get("Content-Type") + objInfo.MD5Sum = resp.Header.Get("Etag") + objInfo.ModTime = t + objInfo.Name = object + objInfo.Size = contentLength + return +} + +// AnonListObjects - Use Azure equivalent ListBlobs. +func (a AzureObjects) AnonListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (result ListObjectsInfo, err error) { + params := storage.ListBlobsParameters{ + Prefix: prefix, + Marker: marker, + Delimiter: delimiter, + MaxResults: uint(maxKeys), + } + + q := azureListBlobsGetParameters(params) + q.Set("restype", "container") + q.Set("comp", "list") + + url, err := url.Parse(a.client.GetBlobURL(bucket, "")) + if err != nil { + return result, azureToObjectError(traceError(err)) + } + url.RawQuery = q.Encode() + + resp, err := http.Get(url.String()) + if err != nil { + return result, azureToObjectError(traceError(err)) + } + defer resp.Body.Close() + + var listResp storage.BlobListResponse + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return result, azureToObjectError(traceError(err)) + } + err = xml.Unmarshal(data, &listResp) + if err != nil { + return result, azureToObjectError(traceError(err)) + } + + result.IsTruncated = listResp.NextMarker != "" + result.NextMarker = listResp.NextMarker + for _, object := range listResp.Blobs { + t, e := time.Parse(time.RFC1123, object.Properties.LastModified) + if e != nil { + continue + } + result.Objects = append(result.Objects, ObjectInfo{ + Bucket: bucket, + Name: object.Name, + ModTime: t, + Size: object.Properties.ContentLength, + MD5Sum: object.Properties.Etag, + ContentType: object.Properties.ContentType, + ContentEncoding: object.Properties.ContentEncoding, + }) + } + result.Prefixes = listResp.BlobPrefixes + return result, nil +} diff --git a/cmd/azure-unsupported.go b/cmd/azure-unsupported.go new file mode 100644 index 000000000..a6d821dc4 --- /dev/null +++ b/cmd/azure-unsupported.go @@ -0,0 +1,43 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +// HealBucket - Not relevant. +func (a AzureObjects) HealBucket(bucket string) error { + return traceError(NotImplemented{}) +} + +// ListBucketsHeal - Not relevant. +func (a AzureObjects) ListBucketsHeal() (buckets []BucketInfo, err error) { + return nil, traceError(NotImplemented{}) +} + +// HealObject - Not relevant. +func (a AzureObjects) HealObject(bucket, object string) error { + return traceError(NotImplemented{}) +} + +// ListObjectsHeal - Not relevant. +func (a AzureObjects) ListObjectsHeal(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) { + return ListObjectsInfo{}, traceError(NotImplemented{}) +} + +// ListUploadsHeal - Not relevant. +func (a AzureObjects) ListUploadsHeal(bucket, prefix, marker, uploadIDMarker, + delimiter string, maxUploads int) (ListMultipartsInfo, error) { + return ListMultipartsInfo{}, traceError(NotImplemented{}) +} diff --git a/cmd/azure.go b/cmd/azure.go new file mode 100644 index 000000000..5b3eebb2e --- /dev/null +++ b/cmd/azure.go @@ -0,0 +1,635 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "encoding/base64" + "encoding/hex" + "fmt" + "hash" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "github.com/Azure/azure-sdk-for-go/storage" + "github.com/minio/minio-go/pkg/policy" + "github.com/minio/sha256-simd" +) + +const globalAzureAPIVersion = "2016-05-31" + +// To store metadata during NewMultipartUpload which will be used after +// CompleteMultipartUpload to call SetBlobMetadata. +type azureMultipartMetaInfo struct { + meta map[string]map[string]string + *sync.Mutex +} + +// Return metadata map of the multipart object. +func (a *azureMultipartMetaInfo) get(key string) map[string]string { + a.Lock() + defer a.Unlock() + return a.meta[key] +} + +// Set metadata map for the multipart object. +func (a *azureMultipartMetaInfo) set(key string, value map[string]string) { + a.Lock() + defer a.Unlock() + a.meta[key] = value +} + +// Delete metadata map for the multipart object. +func (a *azureMultipartMetaInfo) del(key string) { + a.Lock() + defer a.Unlock() + delete(a.meta, key) +} + +// AzureObjects - Implements Object layer for Azure blob storage. +type AzureObjects struct { + client storage.BlobStorageClient // Azure sdk client + metaInfo azureMultipartMetaInfo +} + +// Convert azure errors to minio object layer errors. +func azureToObjectError(err error, params ...string) error { + if err == nil { + return nil + } + + e, ok := err.(*Error) + if !ok { + // Code should be fixed if this function is called without doing traceError() + // Else handling different situations in this function makes this function complicated. + errorIf(err, "Expected type *Error") + return err + } + + err = e.e + bucket := "" + object := "" + if len(params) >= 1 { + bucket = params[0] + } + if len(params) == 2 { + object = params[1] + } + + azureErr, ok := err.(storage.AzureStorageServiceError) + if !ok { + // We don't interpret non Azure errors. As azure errors will + // have StatusCode to help to convert to object errors. + return e + } + + switch azureErr.Code { + case "ContainerAlreadyExists": + err = BucketExists{Bucket: bucket} + case "InvalidResourceName": + err = BucketNameInvalid{Bucket: bucket} + default: + switch azureErr.StatusCode { + case http.StatusNotFound: + if object != "" { + err = ObjectNotFound{bucket, object} + } else { + err = BucketNotFound{Bucket: bucket} + } + case http.StatusBadRequest: + err = BucketNameInvalid{Bucket: bucket} + } + } + e.e = err + return e +} + +// Inits azure blob storage client and returns AzureObjects. +func newAzureLayer(account, key string) (GatewayLayer, error) { + useHTTPS := true + c, err := storage.NewClient(account, key, storage.DefaultBaseURL, globalAzureAPIVersion, useHTTPS) + if err != nil { + return AzureObjects{}, err + } + return &AzureObjects{ + client: c.GetBlobService(), + metaInfo: azureMultipartMetaInfo{ + meta: make(map[string]map[string]string), + Mutex: &sync.Mutex{}, + }, + }, nil +} + +// Shutdown - save any gateway metadata to disk +// if necessary and reload upon next restart. +func (a AzureObjects) Shutdown() error { + // TODO + return nil +} + +// StorageInfo - Not relevant to Azure backend. +func (a AzureObjects) StorageInfo() StorageInfo { + return StorageInfo{} +} + +// MakeBucket - Create a new container on azure backend. +func (a AzureObjects) MakeBucket(bucket string) error { + err := a.client.CreateContainer(bucket, storage.ContainerAccessTypePrivate) + return azureToObjectError(traceError(err), bucket) +} + +// GetBucketInfo - Get bucket metadata.. +func (a AzureObjects) GetBucketInfo(bucket string) (BucketInfo, error) { + // Azure does not have an equivalent call, hence use ListContainers. + resp, err := a.client.ListContainers(storage.ListContainersParameters{ + Prefix: bucket, + }) + if err != nil { + return BucketInfo{}, azureToObjectError(traceError(err), bucket) + } + for _, container := range resp.Containers { + if container.Name == bucket { + t, e := time.Parse(time.RFC1123, container.Properties.LastModified) + if e == nil { + return BucketInfo{ + Name: bucket, + Created: t, + }, nil + } // else continue + } + } + return BucketInfo{}, traceError(BucketNotFound{Bucket: bucket}) +} + +// ListBuckets - Lists all azure containers, uses Azure equivalent ListContainers. +func (a AzureObjects) ListBuckets() (buckets []BucketInfo, err error) { + resp, err := a.client.ListContainers(storage.ListContainersParameters{}) + if err != nil { + return nil, azureToObjectError(traceError(err)) + } + for _, container := range resp.Containers { + t, e := time.Parse(time.RFC1123, container.Properties.LastModified) + if e != nil { + return nil, traceError(e) + } + buckets = append(buckets, BucketInfo{ + Name: container.Name, + Created: t, + }) + } + return buckets, nil +} + +// DeleteBucket - delete a container on azure, uses Azure equivalent DeleteContainer. +func (a AzureObjects) DeleteBucket(bucket string) error { + return azureToObjectError(traceError(a.client.DeleteContainer(bucket)), bucket) +} + +// ListObjects - lists all blobs on azure with in a container filtered by prefix +// and marker, uses Azure equivalent ListBlobs. +func (a AzureObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (result ListObjectsInfo, err error) { + resp, err := a.client.ListBlobs(bucket, storage.ListBlobsParameters{ + Prefix: prefix, + Marker: marker, + Delimiter: delimiter, + MaxResults: uint(maxKeys), + }) + if err != nil { + return result, azureToObjectError(traceError(err), bucket, prefix) + } + result.IsTruncated = resp.NextMarker != "" + result.NextMarker = resp.NextMarker + for _, object := range resp.Blobs { + t, e := time.Parse(time.RFC1123, object.Properties.LastModified) + if e != nil { + continue + } + result.Objects = append(result.Objects, ObjectInfo{ + Bucket: bucket, + Name: object.Name, + ModTime: t, + Size: object.Properties.ContentLength, + MD5Sum: canonicalizeETag(object.Properties.Etag), + ContentType: object.Properties.ContentType, + ContentEncoding: object.Properties.ContentEncoding, + }) + } + result.Prefixes = resp.BlobPrefixes + return result, nil +} + +// GetObject - reads an object from azure. Supports additional +// parameters like offset and length which are synonymous with +// HTTP Range requests. +// +// startOffset indicates the starting read location of the object. +// length indicates the total length of the object. +func (a AzureObjects) GetObject(bucket, object string, startOffset int64, length int64, writer io.Writer) error { + byteRange := fmt.Sprintf("%d-", startOffset) + if length > 0 && startOffset > 0 { + byteRange = fmt.Sprintf("%d-%d", startOffset, startOffset+length-1) + } + + var rc io.ReadCloser + var err error + if startOffset == 0 && length == 0 { + rc, err = a.client.GetBlob(bucket, object) + } else { + rc, err = a.client.GetBlobRange(bucket, object, byteRange, nil) + } + if err != nil { + return azureToObjectError(traceError(err), bucket, object) + } + _, err = io.Copy(writer, rc) + rc.Close() + return traceError(err) +} + +// GetObjectInfo - reads blob metadata properties and replies back ObjectInfo, +// uses zure equivalent GetBlobProperties. +func (a AzureObjects) GetObjectInfo(bucket, object string) (objInfo ObjectInfo, err error) { + prop, err := a.client.GetBlobProperties(bucket, object) + if err != nil { + return objInfo, azureToObjectError(traceError(err), bucket, object) + } + t, err := time.Parse(time.RFC1123, prop.LastModified) + if err != nil { + return objInfo, traceError(err) + } + objInfo = ObjectInfo{ + Bucket: bucket, + UserDefined: make(map[string]string), + MD5Sum: canonicalizeETag(prop.Etag), + ModTime: t, + Name: object, + Size: prop.ContentLength, + } + if prop.ContentEncoding != "" { + objInfo.UserDefined["Content-Encoding"] = prop.ContentEncoding + } + objInfo.UserDefined["Content-Type"] = prop.ContentType + return objInfo, nil +} + +// Canonicalize the metadata headers, without this azure-sdk calculates +// incorrect signature. This attempt to canonicalize is to convert +// any HTTP header which is of form say `accept-encoding` should be +// converted to `Accept-Encoding` in its canonical form. +func canonicalMetadata(metadata map[string]string) (canonical map[string]string) { + canonical = make(map[string]string) + for k, v := range metadata { + canonical[http.CanonicalHeaderKey(k)] = v + } + return canonical +} + +// PutObject - Create a new blob with the incoming data, +// uses Azure equivalent CreateBlockBlobFromReader. +func (a AzureObjects) PutObject(bucket, object string, size int64, data io.Reader, metadata map[string]string, sha256sum string) (objInfo ObjectInfo, err error) { + var sha256Writer hash.Hash + teeReader := data + if sha256sum != "" { + sha256Writer = sha256.New() + teeReader = io.TeeReader(data, sha256Writer) + } + + delete(metadata, "md5Sum") + + err = a.client.CreateBlockBlobFromReader(bucket, object, uint64(size), teeReader, canonicalMetadata(metadata)) + if err != nil { + return objInfo, azureToObjectError(traceError(err), bucket, object) + } + + if sha256sum != "" { + newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil)) + if newSHA256sum != sha256sum { + a.client.DeleteBlob(bucket, object, nil) + return ObjectInfo{}, traceError(SHA256Mismatch{}) + } + } + + return a.GetObjectInfo(bucket, object) +} + +// CopyObject - Copies a blob from source container to destination container. +// Uses Azure equivalent CopyBlob API. +func (a AzureObjects) CopyObject(srcBucket, srcObject, destBucket, destObject string, metadata map[string]string) (objInfo ObjectInfo, err error) { + err = a.client.CopyBlob(destBucket, destObject, a.client.GetBlobURL(srcBucket, srcObject)) + if err != nil { + return objInfo, azureToObjectError(traceError(err), srcBucket, srcObject) + } + return a.GetObjectInfo(destBucket, destObject) +} + +// DeleteObject - Deletes a blob on azure container, uses Azure +// equivalent DeleteBlob API. +func (a AzureObjects) DeleteObject(bucket, object string) error { + err := a.client.DeleteBlob(bucket, object, nil) + if err != nil { + return azureToObjectError(traceError(err), bucket, object) + } + return nil +} + +// ListMultipartUploads - Incomplete implementation, for now just return the prefix if it is an incomplete upload. +// FIXME: Full ListMultipartUploads is not supported yet. It is supported just enough to help our client libs to +// support re-uploads. a.client.ListBlobs() can be made to return entries which include uncommitted blobs using +// which we need to filter out the committed blobs to get the list of uncommitted blobs. +func (a AzureObjects) ListMultipartUploads(bucket, prefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (result ListMultipartsInfo, err error) { + result.MaxUploads = maxUploads + result.Prefix = prefix + result.Delimiter = delimiter + meta := a.metaInfo.get(prefix) + if meta == nil { + // In case minio was restarted after NewMultipartUpload and before CompleteMultipartUpload we expect + // the client to do a fresh upload so that any metadata like content-type are sent again in the + // NewMultipartUpload. + return result, nil + } + result.Uploads = []uploadMetadata{{prefix, prefix, time.Now().UTC(), "", nil}} + return result, nil +} + +// NewMultipartUpload - Use Azure equivalent CreateBlockBlob. +func (a AzureObjects) NewMultipartUpload(bucket, object string, metadata map[string]string) (uploadID string, err error) { + // Azure doesn't return a unique upload ID and we use object name in place of it. Azure allows multiple uploads to + // co-exist as long as the user keeps the blocks uploaded (in block blobs) unique amongst concurrent upload attempts. + // Each concurrent client, keeps its own blockID list which it can commit. + uploadID = object + if metadata == nil { + // Store an empty map as a placeholder else ListObjectParts/PutObjectPart will not work properly. + metadata = make(map[string]string) + } else { + metadata = canonicalMetadata(metadata) + } + a.metaInfo.set(uploadID, metadata) + return uploadID, nil +} + +// CopyObjectPart - Not implemented. +func (a AzureObjects) CopyObjectPart(srcBucket, srcObject, destBucket, destObject string, uploadID string, partID int, startOffset int64, length int64) (info PartInfo, err error) { + return info, traceError(NotImplemented{}) +} + +// Encode partID+md5Hex to a blockID. +func azureGetBlockID(partID int, md5Hex string) string { + return base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%.5d.%s", partID, md5Hex))) +} + +// Decode blockID to partID+md5Hex. +func azureParseBlockID(blockID string) (int, string, error) { + idByte, err := base64.StdEncoding.DecodeString(blockID) + if err != nil { + return 0, "", traceError(err) + } + idStr := string(idByte) + splitRes := strings.Split(idStr, ".") + if len(splitRes) != 2 { + return 0, "", traceError(errUnexpected) + } + partID, err := strconv.Atoi(splitRes[0]) + if err != nil { + return 0, "", traceError(err) + } + return partID, splitRes[1], nil +} + +// PutObjectPart - Use Azure equivalent PutBlockWithLength. +func (a AzureObjects) PutObjectPart(bucket, object, uploadID string, partID int, size int64, data io.Reader, md5Hex string, sha256sum string) (info PartInfo, err error) { + if meta := a.metaInfo.get(uploadID); meta == nil { + return info, traceError(InvalidUploadID{}) + } + var sha256Writer hash.Hash + if sha256sum != "" { + sha256Writer = sha256.New() + } + + teeReader := io.TeeReader(data, sha256Writer) + + id := azureGetBlockID(partID, md5Hex) + err = a.client.PutBlockWithLength(bucket, object, id, uint64(size), teeReader, nil) + if err != nil { + return info, azureToObjectError(traceError(err), bucket, object) + } + + if sha256sum != "" { + newSHA256sum := hex.EncodeToString(sha256Writer.Sum(nil)) + if newSHA256sum != sha256sum { + return PartInfo{}, traceError(SHA256Mismatch{}) + } + } + + info.PartNumber = partID + info.ETag = md5Hex + info.LastModified = time.Now().UTC() + info.Size = size + return info, nil +} + +// ListObjectParts - Use Azure equivalent GetBlockList. +func (a AzureObjects) ListObjectParts(bucket, object, uploadID string, partNumberMarker int, maxParts int) (result ListPartsInfo, err error) { + result.Bucket = bucket + result.Object = object + result.UploadID = uploadID + result.MaxParts = maxParts + + if meta := a.metaInfo.get(uploadID); meta == nil { + return result, nil + } + resp, err := a.client.GetBlockList(bucket, object, storage.BlockListTypeUncommitted) + if err != nil { + return result, azureToObjectError(traceError(err), bucket, object) + } + tmpMaxParts := 0 + partCount := 0 // Used for figuring out IsTruncated. + nextPartNumberMarker := 0 + for _, part := range resp.UncommittedBlocks { + if tmpMaxParts == maxParts { + // Also takes care of the case if maxParts = 0 + break + } + partCount++ + partID, md5Hex, err := azureParseBlockID(part.Name) + if err != nil { + return result, err + } + if partID <= partNumberMarker { + continue + } + result.Parts = append(result.Parts, PartInfo{ + partID, + time.Now().UTC(), + md5Hex, + part.Size, + }) + tmpMaxParts++ + nextPartNumberMarker = partID + } + if partCount < len(resp.UncommittedBlocks) { + result.IsTruncated = true + result.NextPartNumberMarker = nextPartNumberMarker + } + + return result, nil +} + +// AbortMultipartUpload - Not Implemented. +// There is no corresponding API in azure to abort an incomplete upload. The uncommmitted blocks +// gets deleted after one week. +func (a AzureObjects) AbortMultipartUpload(bucket, object, uploadID string) error { + a.metaInfo.del(uploadID) + return nil +} + +// CompleteMultipartUpload - Use Azure equivalent PutBlockList. +func (a AzureObjects) CompleteMultipartUpload(bucket, object, uploadID string, uploadedParts []completePart) (objInfo ObjectInfo, err error) { + meta := a.metaInfo.get(uploadID) + if meta == nil { + return objInfo, traceError(InvalidUploadID{uploadID}) + } + var blocks []storage.Block + for _, part := range uploadedParts { + blocks = append(blocks, storage.Block{ + ID: azureGetBlockID(part.PartNumber, part.ETag), + Status: storage.BlockStatusUncommitted, + }) + } + err = a.client.PutBlockList(bucket, object, blocks) + if err != nil { + return objInfo, azureToObjectError(traceError(err), bucket, object) + } + if len(meta) > 0 { + prop := storage.BlobHeaders{ + ContentMD5: meta["Content-Md5"], + ContentLanguage: meta["Content-Language"], + ContentEncoding: meta["Content-Encoding"], + ContentType: meta["Content-Type"], + CacheControl: meta["Cache-Control"], + } + err = a.client.SetBlobProperties(bucket, object, prop) + if err != nil { + return objInfo, azureToObjectError(traceError(err), bucket, object) + } + } + a.metaInfo.del(uploadID) + return a.GetObjectInfo(bucket, object) +} + +func anonErrToObjectErr(statusCode int, params ...string) error { + bucket := "" + object := "" + if len(params) >= 1 { + bucket = params[0] + } + if len(params) == 2 { + object = params[1] + } + + switch statusCode { + case http.StatusNotFound: + if object != "" { + return ObjectNotFound{bucket, object} + } + return BucketNotFound{Bucket: bucket} + case http.StatusBadRequest: + if object != "" { + return ObjectNameInvalid{bucket, object} + } + return BucketNameInvalid{Bucket: bucket} + } + return errUnexpected +} + +// Copied from github.com/Azure/azure-sdk-for-go/storage/blob.go +func azureListBlobsGetParameters(p storage.ListBlobsParameters) url.Values { + out := url.Values{} + + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } + if p.Delimiter != "" { + out.Set("delimiter", p.Delimiter) + } + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.Include != "" { + out.Set("include", p.Include) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +// SetBucketPolicies - Azure supports three types of container policies: +// storage.ContainerAccessTypeContainer - readonly in minio terminology +// storage.ContainerAccessTypeBlob - readonly without listing in minio terminology +// storage.ContainerAccessTypePrivate - none in minio terminology +// As the common denominator for minio and azure is readonly and none, we support +// these two policies at the bucket level. +func (a AzureObjects) SetBucketPolicies(bucket string, policies []BucketAccessPolicy) error { + prefix := bucket + "/*" // For all objects inside the bucket. + if len(policies) != 1 { + return traceError(NotImplemented{}) + } + if policies[0].Prefix != prefix { + return traceError(NotImplemented{}) + } + if policies[0].Policy != policy.BucketPolicyReadOnly { + return traceError(NotImplemented{}) + } + perm := storage.ContainerPermissions{ + AccessType: storage.ContainerAccessTypeContainer, + AccessPolicies: nil, + } + err := a.client.SetContainerPermissions(bucket, perm, 0, "") + return azureToObjectError(traceError(err), bucket) +} + +// GetBucketPolicies - Get the container ACL and convert it to canonical []bucketAccessPolicy +func (a AzureObjects) GetBucketPolicies(bucket string) ([]BucketAccessPolicy, error) { + perm, err := a.client.GetContainerPermissions(bucket, 0, "") + if err != nil { + return nil, azureToObjectError(traceError(err), bucket) + } + switch perm.AccessType { + case storage.ContainerAccessTypePrivate: + return nil, nil + case storage.ContainerAccessTypeContainer: + return []BucketAccessPolicy{{"", policy.BucketPolicyReadOnly}}, nil + } + return nil, azureToObjectError(traceError(NotImplemented{})) +} + +// DeleteBucketPolicies - Set the container ACL to "private" +func (a AzureObjects) DeleteBucketPolicies(bucket string) error { + perm := storage.ContainerPermissions{ + AccessType: storage.ContainerAccessTypePrivate, + AccessPolicies: nil, + } + err := a.client.SetContainerPermissions(bucket, perm, 0, "") + return azureToObjectError(traceError(err)) +} diff --git a/cmd/azure_test.go b/cmd/azure_test.go new file mode 100644 index 000000000..b7d99debe --- /dev/null +++ b/cmd/azure_test.go @@ -0,0 +1,142 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "net/http" + "reflect" + "testing" + + "github.com/Azure/azure-sdk-for-go/storage" +) + +// Test canonical metadata. +func TestCanonicalMetadata(t *testing.T) { + metadata := map[string]string{ + "accept-encoding": "gzip", + "content-encoding": "gzip", + } + expectedCanonicalM := map[string]string{ + "Accept-Encoding": "gzip", + "Content-Encoding": "gzip", + } + actualCanonicalM := canonicalMetadata(metadata) + if !reflect.DeepEqual(actualCanonicalM, expectedCanonicalM) { + t.Fatalf("Test failed, expected %#v, got %#v", expectedCanonicalM, actualCanonicalM) + } +} + +// Add tests for azure to object error. +func TestAzureToObjectError(t *testing.T) { + testCases := []struct { + actualErr error + expectedErr error + bucket, object string + }{ + { + nil, nil, "", "", + }, + { + traceError(errUnexpected), errUnexpected, "", "", + }, + { + traceError(errUnexpected), traceError(errUnexpected), "", "", + }, + { + traceError(storage.AzureStorageServiceError{ + Code: "ContainerAlreadyExists", + }), BucketExists{Bucket: "bucket"}, "bucket", "", + }, + { + traceError(storage.AzureStorageServiceError{ + Code: "InvalidResourceName", + }), BucketNameInvalid{Bucket: "bucket."}, "bucket.", "", + }, + { + traceError(storage.AzureStorageServiceError{ + StatusCode: http.StatusNotFound, + }), ObjectNotFound{ + Bucket: "bucket", + Object: "object", + }, "bucket", "object", + }, + { + traceError(storage.AzureStorageServiceError{ + StatusCode: http.StatusNotFound, + }), BucketNotFound{Bucket: "bucket"}, "bucket", "", + }, + { + traceError(storage.AzureStorageServiceError{ + StatusCode: http.StatusBadRequest, + }), BucketNameInvalid{Bucket: "bucket."}, "bucket.", "", + }, + } + for i, testCase := range testCases { + err := azureToObjectError(testCase.actualErr, testCase.bucket, testCase.object) + if err != nil { + if err.Error() != testCase.expectedErr.Error() { + t.Errorf("Test %d: Expected error %s, got %s", i+1, testCase.expectedErr, err) + } + } + } +} + +// Test azureGetBlockID(). +func TestAzureGetBlockID(t *testing.T) { + testCases := []struct { + partID int + md5 string + blockID string + }{ + {1, "d41d8cd98f00b204e9800998ecf8427e", "MDAwMDEuZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2U="}, + {2, "a7fb6b7b36ee4ed66b5546fac4690273", "MDAwMDIuYTdmYjZiN2IzNmVlNGVkNjZiNTU0NmZhYzQ2OTAyNzM="}, + } + for _, test := range testCases { + blockID := azureGetBlockID(test.partID, test.md5) + if blockID != test.blockID { + t.Fatalf("%s is not equal to %s", blockID, test.blockID) + } + } +} + +// Test azureParseBlockID(). +func TestAzureParseBlockID(t *testing.T) { + testCases := []struct { + partID int + md5 string + blockID string + }{ + {1, "d41d8cd98f00b204e9800998ecf8427e", "MDAwMDEuZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2U="}, + {2, "a7fb6b7b36ee4ed66b5546fac4690273", "MDAwMDIuYTdmYjZiN2IzNmVlNGVkNjZiNTU0NmZhYzQ2OTAyNzM="}, + } + for _, test := range testCases { + partID, md5, err := azureParseBlockID(test.blockID) + if err != nil { + t.Fatal(err) + } + if partID != test.partID { + t.Fatalf("%d not equal to %d", partID, test.partID) + } + if md5 != test.md5 { + t.Fatalf("%s not equal to %s", md5, test.md5) + } + } + _, _, err := azureParseBlockID("junk") + if err == nil { + t.Fatal("Expected azureParseBlockID() to return error") + } +} diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index a27552f69..eda75d76e 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -49,6 +49,10 @@ func enforceBucketPolicy(bucket, action, resource, referer string, queryParams u return ErrInternalError } + if globalBucketPolicies == nil { + return ErrAccessDenied + } + // Fetch bucket policy, if policy is not set return access denied. policy := globalBucketPolicies.GetBucketPolicy(bucket) if policy == nil { diff --git a/cmd/credential.go b/cmd/credential.go index db0cbf711..8b580b7e5 100644 --- a/cmd/credential.go +++ b/cmd/credential.go @@ -27,19 +27,41 @@ import ( ) const ( - accessKeyMinLen = 5 - accessKeyMaxLen = 20 - secretKeyMinLen = 8 - secretKeyMaxLen = 40 - - alphaNumericTable = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - alphaNumericTableLen = byte(len(alphaNumericTable)) + accessKeyMinLen = 5 + accessKeyMaxLen = 20 + secretKeyMinLen = 8 + secretKeyMaxLenAmazon = 40 + alphaNumericTable = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + alphaNumericTableLen = byte(len(alphaNumericTable)) ) var ( errInvalidAccessKeyLength = errors.New("Invalid access key, access key should be 5 to 20 characters in length") errInvalidSecretKeyLength = errors.New("Invalid secret key, secret key should be 8 to 40 characters in length") ) +var secretKeyMaxLen = secretKeyMaxLenAmazon + +func mustGetAccessKey() string { + keyBytes := make([]byte, accessKeyMaxLen) + if _, err := rand.Read(keyBytes); err != nil { + console.Fatalf("Unable to generate access key. Err: %s.\n", err) + } + + for i := 0; i < accessKeyMaxLen; i++ { + keyBytes[i] = alphaNumericTable[keyBytes[i]%alphaNumericTableLen] + } + + return string(keyBytes) +} + +func mustGetSecretKey() string { + keyBytes := make([]byte, secretKeyMaxLen) + if _, err := rand.Read(keyBytes); err != nil { + console.Fatalf("Unable to generate secret key. Err: %s.\n", err) + } + + return string([]byte(base64.StdEncoding.EncodeToString(keyBytes))[:secretKeyMaxLen]) +} // isAccessKeyValid - validate access key for right length. func isAccessKeyValid(accessKey string) bool { diff --git a/cmd/event-notifier.go b/cmd/event-notifier.go index 1aee1c626..f97cac51c 100644 --- a/cmd/event-notifier.go +++ b/cmd/event-notifier.go @@ -313,6 +313,9 @@ func eventNotifyForBucketListeners(eventType, objectName, bucketName string, // eventNotify notifies an event to relevant targets based on their // bucket configuration (notifications and listeners). func eventNotify(event eventData) { + if globalEventNotifier == nil { + return + } // Notifies a new event. // List of events reported through this function are // - s3:ObjectCreated:Put diff --git a/cmd/gateway-handlers.go b/cmd/gateway-handlers.go new file mode 100644 index 000000000..31a5ea06e --- /dev/null +++ b/cmd/gateway-handlers.go @@ -0,0 +1,703 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" + + "encoding/json" + "encoding/xml" + + router "github.com/gorilla/mux" + "github.com/minio/minio-go/pkg/policy" +) + +// GetObjectHandler - GET Object +// ---------- +// This implementation of the GET operation retrieves object. To use GET, +// you must have READ access to the object. +func (api gatewayAPIHandlers) GetObjectHandler(w http.ResponseWriter, r *http.Request) { + var object, bucket string + vars := router.Vars(r) + bucket = vars["bucket"] + object = vars["object"] + + // Fetch object stat info. + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + reqAuthType := getRequestAuthType(r) + + switch reqAuthType { + case authTypePresignedV2, authTypeSignedV2: + // Signature V2 validation. + s3Error := isReqAuthenticatedV2(r) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + case authTypeSigned, authTypePresigned: + s3Error := isReqAuthenticated(r, serverConfig.GetRegion()) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + } + + getObjectInfo := objectAPI.GetObjectInfo + if reqAuthType == authTypeAnonymous { + getObjectInfo = objectAPI.AnonGetObjectInfo + } + objInfo, err := getObjectInfo(bucket, object) + if err != nil { + errorIf(err, "Unable to fetch object info.") + apiErr := toAPIErrorCode(err) + if apiErr == ErrNoSuchKey { + apiErr = errAllowableObjectNotFound(bucket, r) + } + writeErrorResponse(w, apiErr, r.URL) + return + } + + // Get request range. + var hrange *httpRange + rangeHeader := r.Header.Get("Range") + if rangeHeader != "" { + if hrange, err = parseRequestRange(rangeHeader, objInfo.Size); err != nil { + // Handle only errInvalidRange + // Ignore other parse error and treat it as regular Get request like Amazon S3. + if err == errInvalidRange { + writeErrorResponse(w, ErrInvalidRange, r.URL) + return + } + + // log the error. + errorIf(err, "Invalid request range") + } + } + + // Validate pre-conditions if any. + if checkPreconditions(w, r, objInfo) { + return + } + + // Get the object. + var startOffset int64 + length := objInfo.Size + if hrange != nil { + startOffset = hrange.offsetBegin + length = hrange.getLength() + } + // Indicates if any data was written to the http.ResponseWriter + dataWritten := false + // io.Writer type which keeps track if any data was written. + writer := funcToWriter(func(p []byte) (int, error) { + if !dataWritten { + // Set headers on the first write. + // Set standard object headers. + setObjectHeaders(w, objInfo, hrange) + + // Set any additional requested response headers. + setGetRespHeaders(w, r.URL.Query()) + + dataWritten = true + } + return w.Write(p) + }) + + getObject := objectAPI.GetObject + if reqAuthType == authTypeAnonymous { + getObject = objectAPI.AnonGetObject + } + + // Reads the object at startOffset and writes to mw. + if err := getObject(bucket, object, startOffset, length, writer); err != nil { + errorIf(err, "Unable to write to client.") + if !dataWritten { + // Error response only if no data has been written to client yet. i.e if + // partial data has already been written before an error + // occurred then no point in setting StatusCode and + // sending error XML. + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + } + return + } + if !dataWritten { + // If ObjectAPI.GetObject did not return error and no data has + // been written it would mean that it is a 0-byte object. + // call wrter.Write(nil) to set appropriate headers. + writer.Write(nil) + } +} + +// HeadObjectHandler - HEAD Object +// ----------- +// The HEAD operation retrieves metadata from an object without returning the object itself. +func (api gatewayAPIHandlers) HeadObjectHandler(w http.ResponseWriter, r *http.Request) { + var object, bucket string + vars := router.Vars(r) + bucket = vars["bucket"] + object = vars["object"] + + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponseHeadersOnly(w, ErrServerNotInitialized) + return + } + + reqAuthType := getRequestAuthType(r) + + switch reqAuthType { + case authTypePresignedV2, authTypeSignedV2: + // Signature V2 validation. + s3Error := isReqAuthenticatedV2(r) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + case authTypeSigned, authTypePresigned: + s3Error := isReqAuthenticated(r, serverConfig.GetRegion()) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + } + + getObjectInfo := objectAPI.GetObjectInfo + if reqAuthType == authTypeAnonymous { + getObjectInfo = objectAPI.AnonGetObjectInfo + } + objInfo, err := getObjectInfo(bucket, object) + if err != nil { + errorIf(err, "Unable to fetch object info.") + apiErr := toAPIErrorCode(err) + if apiErr == ErrNoSuchKey { + apiErr = errAllowableObjectNotFound(bucket, r) + } + writeErrorResponse(w, apiErr, r.URL) + return + } + + // Validate pre-conditions if any. + if checkPreconditions(w, r, objInfo) { + return + } + + // Set standard object headers. + setObjectHeaders(w, objInfo, nil) + + // Successful response. + w.WriteHeader(http.StatusOK) +} + +// DeleteMultipleObjectsHandler - deletes multiple objects. +func (api gatewayAPIHandlers) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) { + vars := router.Vars(r) + bucket := vars["bucket"] + + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + if s3Error := checkRequestAuthType(r, bucket, "s3:DeleteObject", serverConfig.GetRegion()); s3Error != ErrNone { + writeErrorResponse(w, s3Error, r.URL) + return + } + + // Content-Length is required and should be non-zero + // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html + if r.ContentLength <= 0 { + writeErrorResponse(w, ErrMissingContentLength, r.URL) + return + } + + // Content-Md5 is requied should be set + // http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html + if _, ok := r.Header["Content-Md5"]; !ok { + writeErrorResponse(w, ErrMissingContentMD5, r.URL) + return + } + + // Allocate incoming content length bytes. + deleteXMLBytes := make([]byte, r.ContentLength) + + // Read incoming body XML bytes. + if _, err := io.ReadFull(r.Body, deleteXMLBytes); err != nil { + errorIf(err, "Unable to read HTTP body.") + writeErrorResponse(w, ErrInternalError, r.URL) + return + } + + // Unmarshal list of keys to be deleted. + deleteObjects := &DeleteObjectsRequest{} + if err := xml.Unmarshal(deleteXMLBytes, deleteObjects); err != nil { + errorIf(err, "Unable to unmarshal delete objects request XML.") + writeErrorResponse(w, ErrMalformedXML, r.URL) + return + } + + var dErrs = make([]error, len(deleteObjects.Objects)) + + // Delete all requested objects in parallel. + for index, object := range deleteObjects.Objects { + dErr := objectAPI.DeleteObject(bucket, object.ObjectName) + if dErr != nil { + dErrs[index] = dErr + } + } + + // Collect deleted objects and errors if any. + var deletedObjects []ObjectIdentifier + var deleteErrors []DeleteError + for index, err := range dErrs { + object := deleteObjects.Objects[index] + // Success deleted objects are collected separately. + if err == nil { + deletedObjects = append(deletedObjects, object) + continue + } + if _, ok := errorCause(err).(ObjectNotFound); ok { + // If the object is not found it should be + // accounted as deleted as per S3 spec. + deletedObjects = append(deletedObjects, object) + continue + } + errorIf(err, "Unable to delete object. %s", object.ObjectName) + // Error during delete should be collected separately. + deleteErrors = append(deleteErrors, DeleteError{ + Code: errorCodeResponse[toAPIErrorCode(err)].Code, + Message: errorCodeResponse[toAPIErrorCode(err)].Description, + Key: object.ObjectName, + }) + } + + // Generate response + response := generateMultiDeleteResponse(deleteObjects.Quiet, deletedObjects, deleteErrors) + encodedSuccessResponse := encodeResponse(response) + + // Write success response. + writeSuccessResponseXML(w, encodedSuccessResponse) +} + +// PutBucketPolicyHandler - PUT Bucket policy +// ----------------- +// This implementation of the PUT operation uses the policy +// subresource to add to or replace a policy on a bucket +func (api gatewayAPIHandlers) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + if s3Error := checkRequestAuthType(r, "", "", serverConfig.GetRegion()); s3Error != ErrNone { + writeErrorResponse(w, s3Error, r.URL) + return + } + + vars := router.Vars(r) + bucket := vars["bucket"] + + // Before proceeding validate if bucket exists. + _, err := objAPI.GetBucketInfo(bucket) + if err != nil { + errorIf(err, "Unable to find bucket info.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + // If Content-Length is unknown or zero, deny the + // request. PutBucketPolicy always needs a Content-Length. + if r.ContentLength == -1 || r.ContentLength == 0 { + writeErrorResponse(w, ErrMissingContentLength, r.URL) + return + } + // If Content-Length is greater than maximum allowed policy size. + if r.ContentLength > maxAccessPolicySize { + writeErrorResponse(w, ErrEntityTooLarge, r.URL) + return + } + + // Read access policy up to maxAccessPolicySize. + // http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html + // bucket policies are limited to 20KB in size, using a limit reader. + policyBytes, err := ioutil.ReadAll(io.LimitReader(r.Body, maxAccessPolicySize)) + if err != nil { + errorIf(err, "Unable to read from client.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + { + // FIXME: consolidate bucketPolicy and policy.BucketAccessPolicy so that + // the verification below is done on the same type. + // Parse bucket policy. + policyInfo := &bucketPolicy{} + err = parseBucketPolicy(bytes.NewReader(policyBytes), policyInfo) + if err != nil { + errorIf(err, "Unable to parse bucket policy.") + writeErrorResponse(w, ErrInvalidPolicyDocument, r.URL) + return + } + + // Parse check bucket policy. + if s3Error := checkBucketPolicyResources(bucket, policyInfo); s3Error != ErrNone { + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + } + policyInfo := &policy.BucketAccessPolicy{} + if err = json.Unmarshal(policyBytes, policyInfo); err != nil { + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + var policies []BucketAccessPolicy + for prefix, policy := range policy.GetPolicies(policyInfo.Statements, bucket) { + policies = append(policies, BucketAccessPolicy{ + Prefix: prefix, + Policy: policy, + }) + } + if err = objAPI.SetBucketPolicies(bucket, policies); err != nil { + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + // Success. + writeSuccessNoContent(w) +} + +// DeleteBucketPolicyHandler - DELETE Bucket policy +// ----------------- +// This implementation of the DELETE operation uses the policy +// subresource to add to remove a policy on a bucket. +func (api gatewayAPIHandlers) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + if s3Error := checkRequestAuthType(r, "", "", serverConfig.GetRegion()); s3Error != ErrNone { + writeErrorResponse(w, s3Error, r.URL) + return + } + + vars := router.Vars(r) + bucket := vars["bucket"] + + // Before proceeding validate if bucket exists. + _, err := objAPI.GetBucketInfo(bucket) + if err != nil { + errorIf(err, "Unable to find bucket info.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + // Delete bucket access policy, by passing an empty policy + // struct. + objAPI.DeleteBucketPolicies(bucket) + // Success. + writeSuccessNoContent(w) +} + +// GetBucketPolicyHandler - GET Bucket policy +// ----------------- +// This operation uses the policy +// subresource to return the policy of a specified bucket. +func (api gatewayAPIHandlers) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + if s3Error := checkRequestAuthType(r, "", "", serverConfig.GetRegion()); s3Error != ErrNone { + writeErrorResponse(w, s3Error, r.URL) + return + } + + vars := router.Vars(r) + bucket := vars["bucket"] + + // Before proceeding validate if bucket exists. + _, err := objAPI.GetBucketInfo(bucket) + if err != nil { + errorIf(err, "Unable to find bucket info.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + policies, err := objAPI.GetBucketPolicies(bucket) + if err != nil { + errorIf(err, "Unable to read bucket policy.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + policyInfo := policy.BucketAccessPolicy{Version: "2012-10-17"} + for _, p := range policies { + policyInfo.Statements = policy.SetPolicy(policyInfo.Statements, p.Policy, bucket, p.Prefix) + } + policyBytes, err := json.Marshal(&policyInfo) + if err != nil { + errorIf(err, "Unable to read bucket policy.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + // Write to client. + w.Write(policyBytes) +} + +// GetBucketNotificationHandler - This implementation of the GET +// operation uses the notification subresource to return the +// notification configuration of a bucket. If notifications are +// not enabled on the bucket, the operation returns an empty +// NotificationConfiguration element. +func (api gatewayAPIHandlers) GetBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { + writeErrorResponse(w, ErrNotImplemented, r.URL) +} + +// PutBucketNotificationHandler - Minio notification feature enables +// you to receive notifications when certain events happen in your bucket. +// Using this API, you can replace an existing notification configuration. +// The configuration is an XML file that defines the event types that you +// want Minio to publish and the destination where you want Minio to publish +// an event notification when it detects an event of the specified type. +// By default, your bucket has no event notifications configured. That is, +// the notification configuration will be an empty NotificationConfiguration. +func (api gatewayAPIHandlers) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { + writeErrorResponse(w, ErrNotImplemented, r.URL) +} + +// ListenBucketNotificationHandler - list bucket notifications. +func (api gatewayAPIHandlers) ListenBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { + writeErrorResponse(w, ErrNotImplemented, r.URL) +} + +// DeleteBucketHandler - Delete bucket +func (api gatewayAPIHandlers) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + // DeleteBucket does not have any bucket action. + if s3Error := checkRequestAuthType(r, "", "", serverConfig.GetRegion()); s3Error != ErrNone { + writeErrorResponse(w, s3Error, r.URL) + return + } + + vars := router.Vars(r) + bucket := vars["bucket"] + + // Attempt to delete bucket. + if err := objectAPI.DeleteBucket(bucket); err != nil { + errorIf(err, "Unable to delete a bucket.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + // Write success response. + writeSuccessNoContent(w) +} + +// ListObjectsV1Handler - GET Bucket (List Objects) Version 1. +// -------------------------- +// This implementation of the GET operation returns some or all (up to 1000) +// of the objects in a bucket. You can use the request parameters as selection +// criteria to return a subset of the objects in a bucket. +// +func (api gatewayAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) { + vars := router.Vars(r) + bucket := vars["bucket"] + + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + + reqAuthType := getRequestAuthType(r) + + switch reqAuthType { + case authTypePresignedV2, authTypeSignedV2: + // Signature V2 validation. + s3Error := isReqAuthenticatedV2(r) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + case authTypeSigned, authTypePresigned: + s3Error := isReqAuthenticated(r, serverConfig.GetRegion()) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + } + + // Extract all the litsObjectsV1 query params to their native values. + prefix, marker, delimiter, maxKeys, _ := getListObjectsV1Args(r.URL.Query()) + + // Validate all the query params before beginning to serve the request. + if s3Error := validateListObjectsArgs(prefix, marker, delimiter, maxKeys); s3Error != ErrNone { + writeErrorResponse(w, s3Error, r.URL) + return + } + + listObjects := objectAPI.ListObjects + if reqAuthType == authTypeAnonymous { + listObjects = objectAPI.AnonListObjects + } + // Inititate a list objects operation based on the input params. + // On success would return back ListObjectsInfo object to be + // marshalled into S3 compatible XML header. + listObjectsInfo, err := listObjects(bucket, prefix, marker, delimiter, maxKeys) + if err != nil { + errorIf(err, "Unable to list objects.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + response := generateListObjectsV1Response(bucket, prefix, marker, delimiter, maxKeys, listObjectsInfo) + + // Write success response. + writeSuccessResponseXML(w, encodeResponse(response)) +} + +// HeadBucketHandler - HEAD Bucket +// ---------- +// This operation is useful to determine if a bucket exists. +// The operation returns a 200 OK if the bucket exists and you +// have permission to access it. Otherwise, the operation might +// return responses such as 404 Not Found and 403 Forbidden. +func (api gatewayAPIHandlers) HeadBucketHandler(w http.ResponseWriter, r *http.Request) { + vars := router.Vars(r) + bucket := vars["bucket"] + + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponseHeadersOnly(w, ErrServerNotInitialized) + return + } + + reqAuthType := getRequestAuthType(r) + + switch reqAuthType { + case authTypePresignedV2, authTypeSignedV2: + // Signature V2 validation. + s3Error := isReqAuthenticatedV2(r) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + case authTypeSigned, authTypePresigned: + s3Error := isReqAuthenticated(r, serverConfig.GetRegion()) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + } + + getBucketInfo := objectAPI.GetBucketInfo + if reqAuthType == authTypeAnonymous { + getBucketInfo = objectAPI.AnonGetBucketInfo + } + + if _, err := getBucketInfo(bucket); err != nil { + errorIf(err, "Unable to fetch bucket info.") + writeErrorResponseHeadersOnly(w, toAPIErrorCode(err)) + return + } + + writeSuccessResponseHeadersOnly(w) +} + +// GetBucketLocationHandler - GET Bucket location. +// ------------------------- +// This operation returns bucket location. +func (api gatewayAPIHandlers) GetBucketLocationHandler(w http.ResponseWriter, r *http.Request) { + vars := router.Vars(r) + bucket := vars["bucket"] + + objectAPI := api.ObjectAPI() + if objectAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL) + return + } + reqAuthType := getRequestAuthType(r) + + switch reqAuthType { + case authTypePresignedV2, authTypeSignedV2: + // Signature V2 validation. + s3Error := isReqAuthenticatedV2(r) + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + case authTypeSigned, authTypePresigned: + s3Error := isReqAuthenticated(r, globalMinioDefaultRegion) + if s3Error == ErrInvalidRegion { + // Clients like boto3 send getBucketLocation() call signed with region that is configured. + s3Error = isReqAuthenticated(r, serverConfig.GetRegion()) + } + if s3Error != ErrNone { + errorIf(errSignatureMismatch, dumpRequest(r)) + writeErrorResponse(w, s3Error, r.URL) + return + } + } + + getBucketInfo := objectAPI.GetBucketInfo + if reqAuthType == authTypeAnonymous { + getBucketInfo = objectAPI.AnonGetBucketInfo + } + + if _, err := getBucketInfo(bucket); err != nil { + errorIf(err, "Unable to fetch bucket info.") + writeErrorResponse(w, toAPIErrorCode(err), r.URL) + return + } + + // Generate response. + encodedSuccessResponse := encodeResponse(LocationResponse{}) + // Get current region. + region := serverConfig.GetRegion() + if region != globalMinioDefaultRegion { + encodedSuccessResponse = encodeResponse(LocationResponse{ + Location: region, + }) + } + + // Write success response. + writeSuccessResponseXML(w, encodedSuccessResponse) +} diff --git a/cmd/gateway-main.go b/cmd/gateway-main.go new file mode 100644 index 000000000..a38759ec4 --- /dev/null +++ b/cmd/gateway-main.go @@ -0,0 +1,219 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "fmt" + "os" + + "github.com/gorilla/mux" + "github.com/minio/cli" + "github.com/minio/mc/pkg/console" +) + +var gatewayTemplate = `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} {{if .VisibleFlags}}[FLAGS]{{end}} BACKEND +{{if .VisibleFlags}} +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}}{{end}} +ENVIRONMENT VARIABLES: + ACCESS: + MINIO_ACCESS_KEY: Username or access key of your storage backend. + MINIO_SECRET_KEY: Password or secret key of your storage backend. + +EXAMPLES: + 1. Start minio gateway server for Azure Blob Storage backend. + $ {{.HelpName}} azure + + 2. Start minio gateway server bound to a specific ADDRESS:PORT. + $ {{.HelpName}} --address 192.168.1.101:9000 azure +` + +var gatewayCmd = cli.Command{ + Name: "gateway", + Usage: "Start object storage gateway server.", + Action: gatewayMain, + CustomHelpTemplate: gatewayTemplate, + Flags: append(serverFlags, cli.BoolFlag{ + Name: "quiet", + Usage: "Disable startup banner.", + }), + HideHelpCommand: true, +} + +// Represents the type of the gateway backend. +type gatewayBackend string + +const ( + azureBackend gatewayBackend = "azure" + // Add more backends here. +) + +// Returns access and secretkey set from environment variables. +func mustGetGatewayCredsFromEnv() (accessKey, secretKey string) { + // Fetch access keys from environment variables. + accessKey = os.Getenv("MINIO_ACCESS_KEY") + secretKey = os.Getenv("MINIO_SECRET_KEY") + if accessKey == "" || secretKey == "" { + console.Fatalln("Access and secret keys are mandatory to run Minio gateway server.") + } + return accessKey, secretKey +} + +// Initialize gateway layer depending on the backend type. +// Supported backend types are +// +// - Azure Blob Storage. +// - Add your favorite backend here. +func newGatewayLayer(backendType, accessKey, secretKey string) (GatewayLayer, error) { + if gatewayBackend(backendType) != azureBackend { + return nil, fmt.Errorf("Unrecognized backend type %s", backendType) + } + return newAzureLayer(accessKey, secretKey) +} + +// Initialize a new gateway config. +// +// DO NOT save this config, this is meant to be +// only used in memory. +func newGatewayConfig(accessKey, secretKey, region string) error { + // Initialize server config. + srvCfg := newServerConfigV14() + + // If env is set for a fresh start, save them to config file. + srvCfg.SetCredential(credential{ + AccessKey: accessKey, + SecretKey: secretKey, + }) + + // Set default printing to console. + srvCfg.Logger.SetConsole(consoleLogger{true, "error"}) + + // Set custom region. + srvCfg.SetRegion(region) + + // Create certs path for SSL configuration. + if err := createConfigDir(); err != nil { + return err + } + + // hold the mutex lock before a new config is assigned. + // Save the new config globally. + // unlock the mutex. + serverConfigMu.Lock() + serverConfig = srvCfg + serverConfigMu.Unlock() + + return nil +} + +// Handler for 'minio gateway'. +func gatewayMain(ctx *cli.Context) { + if !ctx.Args().Present() || ctx.Args().First() == "help" { + cli.ShowCommandHelpAndExit(ctx, "gateway", 1) + } + + // Fetch access and secret key from env. + accessKey, secretKey := mustGetGatewayCredsFromEnv() + + // Initialize new gateway config. + // + // TODO: add support for custom region when we add + // support for S3 backend storage, currently this can + // default to "us-east-1" + err := newGatewayConfig(accessKey, secretKey, "us-east-1") + if err != nil { + console.Fatalf("Unable to initialize gateway config. Error: %s", err) + } + + // Enable console logging. + enableConsoleLogger() + + // Get quiet flag from command line argument. + quietFlag := ctx.Bool("quiet") || ctx.GlobalBool("quiet") + + // First argument is selected backend type. + backendType := ctx.Args().First() + + newObject, err := newGatewayLayer(backendType, accessKey, secretKey) + if err != nil { + console.Fatalf("Unable to initialize gateway layer. Error: %s", err) + } + + initNSLock(false) // Enable local namespace lock. + + router := mux.NewRouter().SkipClean(true) + registerGatewayAPIRouter(router, newObject) + + var handlerFns = []HandlerFunc{ + // Limits all requests size to a maximum fixed limit + setRequestSizeLimitHandler, + // Adds 'crossdomain.xml' policy handler to serve legacy flash clients. + setCrossDomainPolicy, + // Validates all incoming requests to have a valid date header. + setTimeValidityHandler, + // CORS setting for all browser API requests. + setCorsHandler, + // Validates all incoming URL resources, for invalid/unsupported + // resources client receives a HTTP error. + setIgnoreResourcesHandler, + // Auth handler verifies incoming authorization headers and + // routes them accordingly. Client receives a HTTP error for + // invalid/unsupported signatures. + setAuthHandler, + } + + apiServer := NewServerMux(ctx.String("address"), registerHandlers(router, handlerFns...)) + + // Set if we are SSL enabled S3 gateway. + globalIsSSL = isSSL() + + // Start server, automatically configures TLS if certs are available. + go func() { + cert, key := "", "" + if globalIsSSL { + cert, key = getPublicCertFile(), getPrivateKeyFile() + } + if aerr := apiServer.ListenAndServe(cert, key); aerr != nil { + console.Fatalf("Failed to start minio server. Error: %s\n", aerr) + } + }() + + apiEndPoints, err := finalizeAPIEndpoints(apiServer.Addr) + fatalIf(err, "Unable to finalize API endpoints for %s", apiServer.Addr) + + // Once endpoints are finalized, initialize the new object api. + globalObjLayerMutex.Lock() + globalObjectAPI = newObject + globalObjLayerMutex.Unlock() + + // Prints the formatted startup message once object layer is initialized. + if !quietFlag { + mode := "" + if gatewayBackend(backendType) == azureBackend { + mode = globalMinioModeGatewayAzure + } + checkUpdate(mode) + printGatewayStartupMessage(apiEndPoints, accessKey, secretKey, backendType) + } + + <-globalServiceDoneCh +} diff --git a/cmd/gateway-router.go b/cmd/gateway-router.go new file mode 100644 index 000000000..6ff0f1913 --- /dev/null +++ b/cmd/gateway-router.go @@ -0,0 +1,122 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "io" + + router "github.com/gorilla/mux" +) + +// GatewayLayer - Interface to implement gateway mode. +type GatewayLayer interface { + ObjectLayer + AnonGetObject(bucket, object string, startOffset int64, length int64, writer io.Writer) (err error) + AnonGetObjectInfo(bucket, object string) (objInfo ObjectInfo, err error) + SetBucketPolicies(string, []BucketAccessPolicy) error + GetBucketPolicies(string) ([]BucketAccessPolicy, error) + DeleteBucketPolicies(string) error + AnonListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (result ListObjectsInfo, err error) + AnonGetBucketInfo(bucket string) (bucketInfo BucketInfo, err error) +} + +// Implements and provides http handlers for S3 API. +// Overrides GetObject HeadObject and Policy related handlers. +type gatewayAPIHandlers struct { + objectAPIHandlers + ObjectAPI func() GatewayLayer +} + +// registerAPIRouter - registers S3 compatible APIs. +func registerGatewayAPIRouter(mux *router.Router, gw GatewayLayer) { + // Initialize API. + api := gatewayAPIHandlers{ + ObjectAPI: func() GatewayLayer { return gw }, + objectAPIHandlers: objectAPIHandlers{ + ObjectAPI: newObjectLayerFn, + }, + } + + // API Router + apiRouter := mux.NewRoute().PathPrefix("/").Subrouter() + + // Bucket router + bucket := apiRouter.PathPrefix("/{bucket}").Subrouter() + + /// Object operations + + // HeadObject + bucket.Methods("HEAD").Path("/{object:.+}").HandlerFunc(api.HeadObjectHandler) + // CopyObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(api.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // PutObjectPart + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(api.PutObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}") + // ListObjectPxarts + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(api.ListObjectPartsHandler).Queries("uploadId", "{uploadId:.*}") + // CompleteMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(api.CompleteMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + // NewMultipartUpload + bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(api.NewMultipartUploadHandler).Queries("uploads", "") + // AbortMultipartUpload + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(api.AbortMultipartUploadHandler).Queries("uploadId", "{uploadId:.*}") + // GetObject + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(api.GetObjectHandler) + // CopyObject + bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(api.CopyObjectHandler) + // PutObject + bucket.Methods("PUT").Path("/{object:.+}").HandlerFunc(api.PutObjectHandler) + // DeleteObject + bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(api.DeleteObjectHandler) + + /// Bucket operations + + // GetBucketLocation + bucket.Methods("GET").HandlerFunc(api.GetBucketLocationHandler).Queries("location", "") + // GetBucketPolicy + bucket.Methods("GET").HandlerFunc(api.GetBucketPolicyHandler).Queries("policy", "") + // GetBucketNotification + bucket.Methods("GET").HandlerFunc(api.GetBucketNotificationHandler).Queries("notification", "") + // ListenBucketNotification + bucket.Methods("GET").HandlerFunc(api.ListenBucketNotificationHandler).Queries("events", "{events:.*}") + // ListMultipartUploads + bucket.Methods("GET").HandlerFunc(api.ListMultipartUploadsHandler).Queries("uploads", "") + // ListObjectsV2 + bucket.Methods("GET").HandlerFunc(api.ListObjectsV2Handler).Queries("list-type", "2") + // ListObjectsV1 (Legacy) + bucket.Methods("GET").HandlerFunc(api.ListObjectsV1Handler) + // PutBucketPolicy + bucket.Methods("PUT").HandlerFunc(api.PutBucketPolicyHandler).Queries("policy", "") + // PutBucketNotification + bucket.Methods("PUT").HandlerFunc(api.PutBucketNotificationHandler).Queries("notification", "") + // PutBucket + bucket.Methods("PUT").HandlerFunc(api.PutBucketHandler) + // HeadBucket + bucket.Methods("HEAD").HandlerFunc(api.HeadBucketHandler) + // PostPolicy + bucket.Methods("POST").HeadersRegexp("Content-Type", "multipart/form-data*").HandlerFunc(api.PostPolicyBucketHandler) + // DeleteMultipleObjects + bucket.Methods("POST").HandlerFunc(api.DeleteMultipleObjectsHandler) + // DeleteBucketPolicy + bucket.Methods("DELETE").HandlerFunc(api.DeleteBucketPolicyHandler).Queries("policy", "") + // DeleteBucket + bucket.Methods("DELETE").HandlerFunc(api.DeleteBucketHandler) + + /// Root operation + + // ListBuckets + apiRouter.Methods("GET").HandlerFunc(api.ListBucketsHandler) +} diff --git a/cmd/gateway-startup-msg.go b/cmd/gateway-startup-msg.go new file mode 100644 index 000000000..ade9c451d --- /dev/null +++ b/cmd/gateway-startup-msg.go @@ -0,0 +1,67 @@ +/* + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "fmt" + "runtime" + "strings" + + "github.com/minio/mc/pkg/console" +) + +// Prints the formatted startup message. +func printGatewayStartupMessage(apiEndPoints []string, accessKey, secretKey, backendType string) { + // Prints credential. + printGatewayCommonMsg(apiEndPoints, accessKey, secretKey) + + // Prints `mc` cli configuration message chooses + // first endpoint as default. + endPoint := apiEndPoints[0] + + // Configure 'mc', following block prints platform specific information for minio client. + console.Println(colorBlue("\nCommand-line Access: ") + mcQuickStartGuide) + if runtime.GOOS == globalWindowsOSName { + mcMessage := fmt.Sprintf("$ mc.exe config host add my%s %s %s %s", backendType, endPoint, accessKey, secretKey) + console.Println(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) + } else { + mcMessage := fmt.Sprintf("$ mc config host add my%s %s %s %s", backendType, endPoint, accessKey, secretKey) + console.Println(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) + } + + // Prints documentation message. + printObjectAPIMsg() + + // SSL is configured reads certification chain, prints + // authority and expiry. + if globalIsSSL { + certs, err := readCertificateChain() + if err != nil { + console.Fatalf("Unable to read certificate chain. Error: %s", err) + } + printCertificateMsg(certs) + } +} + +// Prints common server startup message. Prints credential, region and browser access. +func printGatewayCommonMsg(apiEndpoints []string, accessKey, secretKey string) { + apiEndpointStr := strings.Join(apiEndpoints, " ") + // Colorize the message and print. + console.Println(colorBlue("\nEndpoint: ") + colorBold(fmt.Sprintf(getFormatStr(len(apiEndpointStr), 1), apiEndpointStr))) + console.Println(colorBlue("AccessKey: ") + colorBold(fmt.Sprintf("%s ", accessKey))) + console.Println(colorBlue("SecretKey: ") + colorBold(fmt.Sprintf("%s ", secretKey))) +} diff --git a/cmd/gateway-startup-msg_test.go b/cmd/gateway-startup-msg_test.go new file mode 100644 index 000000000..c3bf2e6cb --- /dev/null +++ b/cmd/gateway-startup-msg_test.go @@ -0,0 +1,31 @@ +/* + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import "testing" + +// Test printing Gateway common message. +func TestPrintGatewayCommonMessage(t *testing.T) { + apiEndpoints := []string{"127.0.0.1:9000"} + printGatewayCommonMsg(apiEndpoints, "abcd1", "abcd123") +} + +// Test print gateway startup message. +func TestPrintGatewayStartupMessage(t *testing.T) { + apiEndpoints := []string{"127.0.0.1:9000"} + printGatewayStartupMessage(apiEndpoints, "abcd1", "abcd123", "azure") +} diff --git a/cmd/globals.go b/cmd/globals.go index 13f8253ec..ba3f3f286 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -36,6 +36,10 @@ const ( globalWindowsOSName = "windows" globalNetBSDOSName = "netbsd" globalSolarisOSName = "solaris" + globalMinioModeFS = "mode-server-fs" + globalMinioModeXL = "mode-server-xl" + globalMinioModeDistXL = "mode-server-distributed-xl" + globalMinioModeGatewayAzure = "mode-gateway-azure" // Add new global values here. ) diff --git a/cmd/main.go b/cmd/main.go index 6811a451d..659dfac27 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -98,6 +98,7 @@ func newApp() *cli.App { registerCommand(serverCmd) registerCommand(versionCmd) registerCommand(updateCmd) + registerCommand(gatewayCmd) // Set up app. cli.HelpFlag = cli.BoolFlag{ diff --git a/cmd/server-main.go b/cmd/server-main.go index 61223af23..a8293cc0f 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -48,10 +48,10 @@ var serverCmd = cli.Command{ Flags: append(serverFlags, globalFlags...), Action: serverMain, CustomHelpTemplate: `NAME: - {{.HelpName}} - {{.Usage}} + {{.HelpName}} - {{.Usage}} USAGE: - {{.HelpName}} {{if .VisibleFlags}}[FLAGS] {{end}}PATH [PATH...] + {{.HelpName}} {{if .VisibleFlags}}[FLAGS] {{end}}PATH [PATH...] {{if .VisibleFlags}} FLAGS: {{range .VisibleFlags}}{{.}} @@ -85,9 +85,9 @@ EXAMPLES: } // Check for updates and print a notification message -func checkUpdate() { +func checkUpdate(mode string) { // Its OK to ignore any errors during getUpdateInfo() here. - if older, downloadURL, err := getUpdateInfo(1 * time.Second); err == nil { + if older, downloadURL, err := getUpdateInfo(1*time.Second, mode); err == nil { if older > time.Duration(0) { console.Println(colorizeUpdateMessage(downloadURL, older)) } @@ -485,11 +485,6 @@ func serverMain(c *cli.Context) { // Initializes server config, certs, logging and system settings. initServerConfig(c) - // Check for new updates from dl.minio.io. - if !quietFlag { - checkUpdate() - } - // Server address. serverAddr := c.String("address") @@ -538,6 +533,18 @@ func serverMain(c *cli.Context) { globalIsXL = true } + if !quietFlag { + // Check for new updates from dl.minio.io. + mode := globalMinioModeFS + if globalIsXL { + mode = globalMinioModeXL + } + if globalIsDistXL { + mode = globalMinioModeDistXL + } + checkUpdate(mode) + } + // Initialize name space lock. initNSLock(globalIsDistXL) diff --git a/cmd/server-startup-msg.go b/cmd/server-startup-msg.go index dbdecdca6..a51ca7ceb 100644 --- a/cmd/server-startup-msg.go +++ b/cmd/server-startup-msg.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016, 2017, 2017 Minio, Inc. + * Minio Cloud Storage, (C) 2016, 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -175,4 +175,5 @@ func getCertificateChainMsg(certs []*x509.Certificate) string { // Prints the certificate expiry message. func printCertificateMsg(certs []*x509.Certificate) { console.Println(getCertificateChainMsg(certs)) + } diff --git a/cmd/update-main.go b/cmd/update-main.go index 21498679d..d41bed83f 100644 --- a/cmd/update-main.go +++ b/cmd/update-main.go @@ -133,8 +133,11 @@ func IsSourceBuild() bool { // Minio (; [; docker][; source]) Minio/ Minio/ Minio/ // // For any change here should be discussed by openning an issue at https://github.com/minio/minio/issues. -func getUserAgent() string { +func getUserAgent(mode string) string { userAgent := "Minio (" + runtime.GOOS + "; " + runtime.GOARCH + if mode != "" { + userAgent += "; " + mode + } if IsDocker() { userAgent += "; docker" } @@ -146,12 +149,12 @@ func getUserAgent() string { return userAgent } -func downloadReleaseData(releaseChecksumURL string, timeout time.Duration) (data string, err error) { +func downloadReleaseData(releaseChecksumURL string, timeout time.Duration, mode string) (data string, err error) { req, err := http.NewRequest("GET", releaseChecksumURL, nil) if err != nil { return data, err } - req.Header.Set("User-Agent", getUserAgent()) + req.Header.Set("User-Agent", getUserAgent(mode)) client := &http.Client{ Timeout: timeout, @@ -184,8 +187,8 @@ func downloadReleaseData(releaseChecksumURL string, timeout time.Duration) (data } // DownloadReleaseData - downloads release data from minio official server. -func DownloadReleaseData(timeout time.Duration) (data string, err error) { - return downloadReleaseData(minioReleaseURL+"minio.shasum", timeout) +func DownloadReleaseData(timeout time.Duration, mode string) (data string, err error) { + return downloadReleaseData(minioReleaseURL+"minio.shasum", timeout, mode) } func parseReleaseData(data string) (releaseTime time.Time, err error) { @@ -214,8 +217,8 @@ func parseReleaseData(data string) (releaseTime time.Time, err error) { return releaseTime, err } -func getLatestReleaseTime(timeout time.Duration) (releaseTime time.Time, err error) { - data, err := DownloadReleaseData(timeout) +func getLatestReleaseTime(timeout time.Duration, mode string) (releaseTime time.Time, err error) { + data, err := DownloadReleaseData(timeout, mode) if err != nil { return releaseTime, err } @@ -235,13 +238,13 @@ func getDownloadURL() (downloadURL string) { return minioReleaseURL + "minio" } -func getUpdateInfo(timeout time.Duration) (older time.Duration, downloadURL string, err error) { +func getUpdateInfo(timeout time.Duration, mode string) (older time.Duration, downloadURL string, err error) { currentReleaseTime, err := GetCurrentReleaseTime() if err != nil { return older, downloadURL, err } - latestReleaseTime, err := getLatestReleaseTime(timeout) + latestReleaseTime, err := getLatestReleaseTime(timeout, mode) if err != nil { return older, downloadURL, err } @@ -266,7 +269,8 @@ func mainUpdate(ctx *cli.Context) { } } - older, downloadURL, err := getUpdateInfo(10 * time.Second) + minioMode := "" + older, downloadURL, err := getUpdateInfo(10*time.Second, minioMode) if err != nil { quietPrintln(err) os.Exit(-1) diff --git a/cmd/update-main_test.go b/cmd/update-main_test.go index dc0b7be7e..0a3a746ea 100644 --- a/cmd/update-main_test.go +++ b/cmd/update-main_test.go @@ -260,7 +260,7 @@ func TestDownloadReleaseData(t *testing.T) { } for _, testCase := range testCases { - result, err := downloadReleaseData(testCase.releaseChecksumURL, 1*time.Second) + result, err := downloadReleaseData(testCase.releaseChecksumURL, 1*time.Second, "") if testCase.expectedErr == nil { if err != nil { t.Fatalf("error: expected: %v, got: %v", testCase.expectedErr, err) diff --git a/cmd/web-handlers.go b/cmd/web-handlers.go index feccf9767..4c7bc8754 100644 --- a/cmd/web-handlers.go +++ b/cmd/web-handlers.go @@ -708,8 +708,8 @@ type ListAllBucketPoliciesArgs struct { BucketName string `json:"bucketName"` } -// Collection of canned bucket policy at a given prefix. -type bucketAccessPolicy struct { +// BucketAccessPolicy - Collection of canned bucket policy at a given prefix. +type BucketAccessPolicy struct { Prefix string `json:"prefix"` Policy policy.BucketPolicy `json:"policy"` } @@ -717,7 +717,7 @@ type bucketAccessPolicy struct { // ListAllBucketPoliciesRep - get all bucket policy reply. type ListAllBucketPoliciesRep struct { UIVersion string `json:"uiVersion"` - Policies []bucketAccessPolicy `json:"policies"` + Policies []BucketAccessPolicy `json:"policies"` } // GetllBucketPolicy - get all bucket policy. @@ -738,7 +738,7 @@ func (web *webAPIHandlers) ListAllBucketPolicies(r *http.Request, args *ListAllB reply.UIVersion = browser.UIVersion for prefix, policy := range policy.GetPolicies(policyInfo.Statements, args.BucketName) { - reply.Policies = append(reply.Policies, bucketAccessPolicy{ + reply.Policies = append(reply.Policies, BucketAccessPolicy{ Prefix: prefix, Policy: policy, }) diff --git a/cmd/web-handlers_test.go b/cmd/web-handlers_test.go index 64b24fa31..ffe9c9bed 100644 --- a/cmd/web-handlers_test.go +++ b/cmd/web-handlers_test.go @@ -1136,13 +1136,13 @@ func testWebListAllBucketPoliciesHandler(obj ObjectLayer, instanceType string, t t.Fatal("Unexpected error: ", err) } - testCaseResult1 := []bucketAccessPolicy{{ + testCaseResult1 := []BucketAccessPolicy{{ Prefix: bucketName + "/hello*", Policy: policy.BucketPolicyReadWrite, }} testCases := []struct { bucketName string - expectedResult []bucketAccessPolicy + expectedResult []BucketAccessPolicy }{ {bucketName, testCaseResult1}, } diff --git a/docs/gateway/README.md b/docs/gateway/README.md new file mode 100644 index 000000000..51f54e583 --- /dev/null +++ b/docs/gateway/README.md @@ -0,0 +1,48 @@ +# Minio Gateway [![Slack](https://slack.minio.io/slack?type=svg)](https://slack.minio.io) + +Minio gateway adds Amazon S3 compatibility to third party cloud storage providers. Supported providers are: + +- Azure Blob Storage + +## Run Minio Gateway for Azure Blob Storage + +### Using Docker + +``` +docker run -p 9000:9000 --name azure-s3 \ + -e "MINIO_ACCESS_KEY=azureaccountname" \ + -e "MINIO_SECRET_KEY=azureaccountkey" \ + minio/minio gateway azure +``` + +### Using Binary + +``` +export MINIO_ACCESS_KEY=azureaccountname +export MINIO_SECRET_KEY=azureaccountkey +minio gateway azure +``` + +## Test using Minio Client `mc` +`mc` provides a modern alternative to UNIX commands such as ls, cat, cp, mirror, diff etc. It supports filesystems and Amazon S3 compatible cloud storage services. + +### Configure `mc` + +``` +mc config host add myazure http://gateway-ip:9000 azureaccountname azureaccountkey +``` + +### List containers on Azure + +``` +mc ls myazure +[2017-02-22 01:50:43 PST] 0B ferenginar/ +[2017-02-26 21:43:51 PST] 0B my-container/ +[2017-02-26 22:10:11 PST] 0B test-container1/ +``` + +## Explore Further +- [`mc` command-line interface](https://docs.minio.io/docs/minio-client-quickstart-guide) +- [`aws` command-line interface](https://docs.minio.io/docs/aws-cli-with-minio) +- [`minfs` filesystem interface](http://docs.minio.io/docs/minfs-quickstart-guide) +- [`minio-go` Go SDK](https://docs.minio.io/docs/golang-client-quickstart-guide) diff --git a/docs/gateway/azure-limitations.md b/docs/gateway/azure-limitations.md new file mode 100644 index 000000000..7108bafa3 --- /dev/null +++ b/docs/gateway/azure-limitations.md @@ -0,0 +1,19 @@ +## Minio Azure Gateway Limitations + +Gateway inherits the following Azure limitations: + +- Maximum Multipart part size is 100MB. +- Maximum Multipart object size is 10000*100 MB = 1TB +- No support for prefix based bucket policies. Only top level bucket policy is supported. +- Gateway restart implies all the ongoing multipart uploads must be restarted. + i.e clients must again start with NewMultipartUpload + This is because S3 clients send metadata in NewMultipartUpload but Azure expects metadata to + be set during CompleteMultipartUpload (PutBlockList in Azure terminology). We store the metadata + sent by the client during NewMultipartUpload in memory so that it can be set on Azure later during + CompleteMultipartUpload. When the gateway is restarted this information is lost. +- Bucket names with "." in the bucket name is not supported. +- Non-empty buckets get removed on a DeleteBucket() call. + +Other limitations: +- Current implementation of ListMultipartUploads is incomplete. Right now it returns if the object with name "prefix" has any uploaded parts. +- Bucket notification not supported. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/LICENSE b/vendor/github.com/Azure/azure-sdk-for-go/LICENSE new file mode 100644 index 000000000..af39a91e7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 Microsoft Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md new file mode 100644 index 000000000..0ab099848 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/README.md @@ -0,0 +1,5 @@ +# Azure Storage SDK for Go + +The `github.com/Azure/azure-sdk-for-go/storage` package is used to perform operations in Azure Storage Service. To manage your storage accounts (Azure Resource Manager / ARM), use the [github.com/Azure/azure-sdk-for-go/arm/storage](../arm/storage) package. For your classic storage accounts (Azure Service Management / ASM), use [github.com/Azure/azure-sdk-for-go/management/storageservice](../management/storageservice) package. + +This package includes support for [Azure Storage Emulator](https://azure.microsoft.com/documentation/articles/storage-use-emulator/) \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/authorization.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/authorization.go new file mode 100644 index 000000000..89a0d0b3c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/authorization.go @@ -0,0 +1,223 @@ +// Package storage provides clients for Microsoft Azure Storage Services. +package storage + +import ( + "bytes" + "fmt" + "net/url" + "sort" + "strings" +) + +// See: https://docs.microsoft.com/rest/api/storageservices/fileservices/authentication-for-the-azure-storage-services + +type authentication string + +const ( + sharedKey authentication = "sharedKey" + sharedKeyForTable authentication = "sharedKeyTable" + sharedKeyLite authentication = "sharedKeyLite" + sharedKeyLiteForTable authentication = "sharedKeyLiteTable" + + // headers + headerAuthorization = "Authorization" + headerContentLength = "Content-Length" + headerDate = "Date" + headerXmsDate = "x-ms-date" + headerXmsVersion = "x-ms-version" + headerContentEncoding = "Content-Encoding" + headerContentLanguage = "Content-Language" + headerContentType = "Content-Type" + headerContentMD5 = "Content-MD5" + headerIfModifiedSince = "If-Modified-Since" + headerIfMatch = "If-Match" + headerIfNoneMatch = "If-None-Match" + headerIfUnmodifiedSince = "If-Unmodified-Since" + headerRange = "Range" +) + +func (c *Client) addAuthorizationHeader(verb, url string, headers map[string]string, auth authentication) (map[string]string, error) { + authHeader, err := c.getSharedKey(verb, url, headers, auth) + if err != nil { + return nil, err + } + headers[headerAuthorization] = authHeader + return headers, nil +} + +func (c *Client) getSharedKey(verb, url string, headers map[string]string, auth authentication) (string, error) { + canRes, err := c.buildCanonicalizedResource(url, auth) + if err != nil { + return "", err + } + + canString, err := buildCanonicalizedString(verb, headers, canRes, auth) + if err != nil { + return "", err + } + return c.createAuthorizationHeader(canString, auth), nil +} + +func (c *Client) buildCanonicalizedResource(uri string, auth authentication) (string, error) { + errMsg := "buildCanonicalizedResource error: %s" + u, err := url.Parse(uri) + if err != nil { + return "", fmt.Errorf(errMsg, err.Error()) + } + + cr := bytes.NewBufferString("/") + cr.WriteString(c.getCanonicalizedAccountName()) + + if len(u.Path) > 0 { + // Any portion of the CanonicalizedResource string that is derived from + // the resource's URI should be encoded exactly as it is in the URI. + // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx + cr.WriteString(u.EscapedPath()) + } + + params, err := url.ParseQuery(u.RawQuery) + if err != nil { + return "", fmt.Errorf(errMsg, err.Error()) + } + + // See https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Core/Util/AuthenticationUtility.cs#L277 + if auth == sharedKey { + if len(params) > 0 { + cr.WriteString("\n") + + keys := []string{} + for key := range params { + keys = append(keys, key) + } + sort.Strings(keys) + + completeParams := []string{} + for _, key := range keys { + if len(params[key]) > 1 { + sort.Strings(params[key]) + } + + completeParams = append(completeParams, fmt.Sprintf("%s:%s", key, strings.Join(params[key], ","))) + } + cr.WriteString(strings.Join(completeParams, "\n")) + } + } else { + // search for "comp" parameter, if exists then add it to canonicalizedresource + if v, ok := params["comp"]; ok { + cr.WriteString("?comp=" + v[0]) + } + } + + return string(cr.Bytes()), nil +} + +func (c *Client) getCanonicalizedAccountName() string { + // since we may be trying to access a secondary storage account, we need to + // remove the -secondary part of the storage name + return strings.TrimSuffix(c.accountName, "-secondary") +} + +func buildCanonicalizedString(verb string, headers map[string]string, canonicalizedResource string, auth authentication) (string, error) { + contentLength := headers[headerContentLength] + if contentLength == "0" { + contentLength = "" + } + date := headers[headerDate] + if v, ok := headers[headerXmsDate]; ok { + if auth == sharedKey || auth == sharedKeyLite { + date = "" + } else { + date = v + } + } + var canString string + switch auth { + case sharedKey: + canString = strings.Join([]string{ + verb, + headers[headerContentEncoding], + headers[headerContentLanguage], + contentLength, + headers[headerContentMD5], + headers[headerContentType], + date, + headers[headerIfModifiedSince], + headers[headerIfMatch], + headers[headerIfNoneMatch], + headers[headerIfUnmodifiedSince], + headers[headerRange], + buildCanonicalizedHeader(headers), + canonicalizedResource, + }, "\n") + case sharedKeyForTable: + canString = strings.Join([]string{ + verb, + headers[headerContentMD5], + headers[headerContentType], + date, + canonicalizedResource, + }, "\n") + case sharedKeyLite: + canString = strings.Join([]string{ + verb, + headers[headerContentMD5], + headers[headerContentType], + date, + buildCanonicalizedHeader(headers), + canonicalizedResource, + }, "\n") + case sharedKeyLiteForTable: + canString = strings.Join([]string{ + date, + canonicalizedResource, + }, "\n") + default: + return "", fmt.Errorf("%s authentication is not supported yet", auth) + } + return canString, nil +} + +func buildCanonicalizedHeader(headers map[string]string) string { + cm := make(map[string]string) + + for k, v := range headers { + headerName := strings.TrimSpace(strings.ToLower(k)) + if strings.HasPrefix(headerName, "x-ms-") { + cm[headerName] = v + } + } + + if len(cm) == 0 { + return "" + } + + keys := []string{} + for key := range cm { + keys = append(keys, key) + } + + sort.Strings(keys) + + ch := bytes.NewBufferString("") + + for _, key := range keys { + ch.WriteString(key) + ch.WriteRune(':') + ch.WriteString(cm[key]) + ch.WriteRune('\n') + } + + return strings.TrimSuffix(string(ch.Bytes()), "\n") +} + +func (c *Client) createAuthorizationHeader(canonicalizedString string, auth authentication) string { + signature := c.computeHmac256(canonicalizedString) + var key string + switch auth { + case sharedKey, sharedKeyForTable: + key = "SharedKey" + case sharedKeyLite, sharedKeyLiteForTable: + key = "SharedKeyLite" + } + return fmt.Sprintf("%s %s:%s", key, c.getCanonicalizedAccountName(), signature) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go new file mode 100644 index 000000000..e33de1031 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/blob.go @@ -0,0 +1,1539 @@ +package storage + +import ( + "bytes" + "encoding/xml" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "time" +) + +// BlobStorageClient contains operations for Microsoft Azure Blob Storage +// Service. +type BlobStorageClient struct { + client Client + auth authentication +} + +// A Container is an entry in ContainerListResponse. +type Container struct { + Name string `xml:"Name"` + Properties ContainerProperties `xml:"Properties"` + // TODO (ahmetalpbalkan) Metadata +} + +// ContainerProperties contains various properties of a container returned from +// various endpoints like ListContainers. +type ContainerProperties struct { + LastModified string `xml:"Last-Modified"` + Etag string `xml:"Etag"` + LeaseStatus string `xml:"LeaseStatus"` + LeaseState string `xml:"LeaseState"` + LeaseDuration string `xml:"LeaseDuration"` + // TODO (ahmetalpbalkan) remaining fields +} + +// ContainerListResponse contains the response fields from +// ListContainers call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +type ContainerListResponse struct { + XMLName xml.Name `xml:"EnumerationResults"` + Xmlns string `xml:"xmlns,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + NextMarker string `xml:"NextMarker"` + MaxResults int64 `xml:"MaxResults"` + Containers []Container `xml:"Containers>Container"` +} + +// A Blob is an entry in BlobListResponse. +type Blob struct { + Name string `xml:"Name"` + Properties BlobProperties `xml:"Properties"` + Metadata BlobMetadata `xml:"Metadata"` +} + +// BlobMetadata is a set of custom name/value pairs. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179404.aspx +type BlobMetadata map[string]string + +type blobMetadataEntries struct { + Entries []blobMetadataEntry `xml:",any"` +} +type blobMetadataEntry struct { + XMLName xml.Name + Value string `xml:",chardata"` +} + +// UnmarshalXML converts the xml:Metadata into Metadata map +func (bm *BlobMetadata) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + var entries blobMetadataEntries + if err := d.DecodeElement(&entries, &start); err != nil { + return err + } + for _, entry := range entries.Entries { + if *bm == nil { + *bm = make(BlobMetadata) + } + (*bm)[strings.ToLower(entry.XMLName.Local)] = entry.Value + } + return nil +} + +// MarshalXML implements the xml.Marshaler interface. It encodes +// metadata name/value pairs as they would appear in an Azure +// ListBlobs response. +func (bm BlobMetadata) MarshalXML(enc *xml.Encoder, start xml.StartElement) error { + entries := make([]blobMetadataEntry, 0, len(bm)) + for k, v := range bm { + entries = append(entries, blobMetadataEntry{ + XMLName: xml.Name{Local: http.CanonicalHeaderKey(k)}, + Value: v, + }) + } + return enc.EncodeElement(blobMetadataEntries{ + Entries: entries, + }, start) +} + +// BlobProperties contains various properties of a blob +// returned in various endpoints like ListBlobs or GetBlobProperties. +type BlobProperties struct { + LastModified string `xml:"Last-Modified"` + Etag string `xml:"Etag"` + ContentMD5 string `xml:"Content-MD5"` + ContentLength int64 `xml:"Content-Length"` + ContentType string `xml:"Content-Type"` + ContentEncoding string `xml:"Content-Encoding"` + CacheControl string `xml:"Cache-Control"` + ContentLanguage string `xml:"Cache-Language"` + BlobType BlobType `xml:"x-ms-blob-blob-type"` + SequenceNumber int64 `xml:"x-ms-blob-sequence-number"` + CopyID string `xml:"CopyId"` + CopyStatus string `xml:"CopyStatus"` + CopySource string `xml:"CopySource"` + CopyProgress string `xml:"CopyProgress"` + CopyCompletionTime string `xml:"CopyCompletionTime"` + CopyStatusDescription string `xml:"CopyStatusDescription"` + LeaseStatus string `xml:"LeaseStatus"` + LeaseState string `xml:"LeaseState"` +} + +// BlobHeaders contains various properties of a blob and is an entry +// in SetBlobProperties +type BlobHeaders struct { + ContentMD5 string `header:"x-ms-blob-content-md5"` + ContentLanguage string `header:"x-ms-blob-content-language"` + ContentEncoding string `header:"x-ms-blob-content-encoding"` + ContentType string `header:"x-ms-blob-content-type"` + CacheControl string `header:"x-ms-blob-cache-control"` +} + +// BlobListResponse contains the response fields from ListBlobs call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx +type BlobListResponse struct { + XMLName xml.Name `xml:"EnumerationResults"` + Xmlns string `xml:"xmlns,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + NextMarker string `xml:"NextMarker"` + MaxResults int64 `xml:"MaxResults"` + Blobs []Blob `xml:"Blobs>Blob"` + + // BlobPrefix is used to traverse blobs as if it were a file system. + // It is returned if ListBlobsParameters.Delimiter is specified. + // The list here can be thought of as "folders" that may contain + // other folders or blobs. + BlobPrefixes []string `xml:"Blobs>BlobPrefix>Name"` + + // Delimiter is used to traverse blobs as if it were a file system. + // It is returned if ListBlobsParameters.Delimiter is specified. + Delimiter string `xml:"Delimiter"` +} + +// ListContainersParameters defines the set of customizable parameters to make a +// List Containers call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +type ListContainersParameters struct { + Prefix string + Marker string + Include string + MaxResults uint + Timeout uint +} + +func (p ListContainersParameters) getParameters() url.Values { + out := url.Values{} + + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.Include != "" { + out.Set("include", p.Include) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +// ListBlobsParameters defines the set of customizable +// parameters to make a List Blobs call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx +type ListBlobsParameters struct { + Prefix string + Delimiter string + Marker string + Include string + MaxResults uint + Timeout uint +} + +func (p ListBlobsParameters) getParameters() url.Values { + out := url.Values{} + + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } + if p.Delimiter != "" { + out.Set("delimiter", p.Delimiter) + } + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.Include != "" { + out.Set("include", p.Include) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +// BlobType defines the type of the Azure Blob. +type BlobType string + +// Types of page blobs +const ( + BlobTypeBlock BlobType = "BlockBlob" + BlobTypePage BlobType = "PageBlob" + BlobTypeAppend BlobType = "AppendBlob" +) + +// PageWriteType defines the type updates that are going to be +// done on the page blob. +type PageWriteType string + +// Types of operations on page blobs +const ( + PageWriteTypeUpdate PageWriteType = "update" + PageWriteTypeClear PageWriteType = "clear" +) + +const ( + blobCopyStatusPending = "pending" + blobCopyStatusSuccess = "success" + blobCopyStatusAborted = "aborted" + blobCopyStatusFailed = "failed" +) + +// lease constants. +const ( + leaseHeaderPrefix = "x-ms-lease-" + headerLeaseID = "x-ms-lease-id" + leaseAction = "x-ms-lease-action" + leaseBreakPeriod = "x-ms-lease-break-period" + leaseDuration = "x-ms-lease-duration" + leaseProposedID = "x-ms-proposed-lease-id" + leaseTime = "x-ms-lease-time" + + acquireLease = "acquire" + renewLease = "renew" + changeLease = "change" + releaseLease = "release" + breakLease = "break" +) + +// BlockListType is used to filter out types of blocks in a Get Blocks List call +// for a block blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx for all +// block types. +type BlockListType string + +// Filters for listing blocks in block blobs +const ( + BlockListTypeAll BlockListType = "all" + BlockListTypeCommitted BlockListType = "committed" + BlockListTypeUncommitted BlockListType = "uncommitted" +) + +// ContainerAccessType defines the access level to the container from a public +// request. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx and "x-ms- +// blob-public-access" header. +type ContainerAccessType string + +// Access options for containers +const ( + ContainerAccessTypePrivate ContainerAccessType = "" + ContainerAccessTypeBlob ContainerAccessType = "blob" + ContainerAccessTypeContainer ContainerAccessType = "container" +) + +// ContainerAccessPolicyDetails are used for SETTING container policies +type ContainerAccessPolicyDetails struct { + ID string + StartTime time.Time + ExpiryTime time.Time + CanRead bool + CanWrite bool + CanDelete bool +} + +// ContainerPermissions is used when setting permissions and Access Policies for containers. +type ContainerPermissions struct { + AccessType ContainerAccessType + AccessPolicies []ContainerAccessPolicyDetails +} + +// ContainerAccessHeader references header used when setting/getting container ACL +const ( + ContainerAccessHeader string = "x-ms-blob-public-access" +) + +// Maximum sizes (per REST API) for various concepts +const ( + MaxBlobBlockSize = 4 * 1024 * 1024 + MaxBlobPageSize = 4 * 1024 * 1024 +) + +// BlockStatus defines states a block for a block blob can +// be in. +type BlockStatus string + +// List of statuses that can be used to refer to a block in a block list +const ( + BlockStatusUncommitted BlockStatus = "Uncommitted" + BlockStatusCommitted BlockStatus = "Committed" + BlockStatusLatest BlockStatus = "Latest" +) + +// Block is used to create Block entities for Put Block List +// call. +type Block struct { + ID string + Status BlockStatus +} + +// BlockListResponse contains the response fields from Get Block List call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx +type BlockListResponse struct { + XMLName xml.Name `xml:"BlockList"` + CommittedBlocks []BlockResponse `xml:"CommittedBlocks>Block"` + UncommittedBlocks []BlockResponse `xml:"UncommittedBlocks>Block"` +} + +// BlockResponse contains the block information returned +// in the GetBlockListCall. +type BlockResponse struct { + Name string `xml:"Name"` + Size int64 `xml:"Size"` +} + +// GetPageRangesResponse contains the response fields from +// Get Page Ranges call. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +type GetPageRangesResponse struct { + XMLName xml.Name `xml:"PageList"` + PageList []PageRange `xml:"PageRange"` +} + +// PageRange contains information about a page of a page blob from +// Get Pages Range call. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +type PageRange struct { + Start int64 `xml:"Start"` + End int64 `xml:"End"` +} + +var ( + errBlobCopyAborted = errors.New("storage: blob copy is aborted") + errBlobCopyIDMismatch = errors.New("storage: blob copy id is a mismatch") +) + +// ListContainers returns the list of containers in a storage account along with +// pagination token and other response details. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +func (b BlobStorageClient) ListContainers(params ListContainersParameters) (ContainerListResponse, error) { + q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}}) + uri := b.client.getEndpoint(blobServiceName, "", q) + headers := b.client.getStandardHeaders() + + var out ContainerListResponse + resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// CreateContainer creates a blob container within the storage account +// with given name and access level. Returns error if container already exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx +func (b BlobStorageClient) CreateContainer(name string, access ContainerAccessType) error { + resp, err := b.createContainer(name, access) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// CreateContainerIfNotExists creates a blob container if it does not exist. Returns +// true if container is newly created or false if container already exists. +func (b BlobStorageClient) CreateContainerIfNotExists(name string, access ContainerAccessType) (bool, error) { + resp, err := b.createContainer(name, access) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { + return resp.statusCode == http.StatusCreated, nil + } + } + return false, err +} + +func (b BlobStorageClient) createContainer(name string, access ContainerAccessType) (*storageResponse, error) { + uri := b.client.getEndpoint(blobServiceName, pathForContainer(name), url.Values{"restype": {"container"}}) + + headers := b.client.getStandardHeaders() + if access != "" { + headers[ContainerAccessHeader] = string(access) + } + return b.client.exec(http.MethodPut, uri, headers, nil, b.auth) +} + +// ContainerExists returns true if a container with given name exists +// on the storage account, otherwise returns false. +func (b BlobStorageClient) ContainerExists(name string) (bool, error) { + uri := b.client.getEndpoint(blobServiceName, pathForContainer(name), url.Values{"restype": {"container"}}) + headers := b.client.getStandardHeaders() + + resp, err := b.client.exec(http.MethodHead, uri, headers, nil, b.auth) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusOK, nil + } + } + return false, err +} + +// SetContainerPermissions sets up container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179391.aspx +func (b BlobStorageClient) SetContainerPermissions(container string, containerPermissions ContainerPermissions, timeout int, leaseID string) (err error) { + params := url.Values{ + "restype": {"container"}, + "comp": {"acl"}, + } + + if timeout > 0 { + params.Add("timeout", strconv.Itoa(timeout)) + } + + uri := b.client.getEndpoint(blobServiceName, pathForContainer(container), params) + headers := b.client.getStandardHeaders() + if containerPermissions.AccessType != "" { + headers[ContainerAccessHeader] = string(containerPermissions.AccessType) + } + + if leaseID != "" { + headers[headerLeaseID] = leaseID + } + + body, length, err := generateContainerACLpayload(containerPermissions.AccessPolicies) + headers["Content-Length"] = strconv.Itoa(length) + resp, err := b.client.exec(http.MethodPut, uri, headers, body, b.auth) + + if err != nil { + return err + } + + if resp != nil { + defer resp.body.Close() + + if resp.statusCode != http.StatusOK { + return errors.New("Unable to set permissions") + } + } + return nil +} + +// GetContainerPermissions gets the container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179469.aspx +// If timeout is 0 then it will not be passed to Azure +// leaseID will only be passed to Azure if populated +// Returns permissionResponse which is combined permissions and AccessPolicy +func (b BlobStorageClient) GetContainerPermissions(container string, timeout int, leaseID string) (*ContainerPermissions, error) { + params := url.Values{"restype": {"container"}, + "comp": {"acl"}} + + if timeout > 0 { + params.Add("timeout", strconv.Itoa(timeout)) + } + + uri := b.client.getEndpoint(blobServiceName, pathForContainer(container), params) + headers := b.client.getStandardHeaders() + + if leaseID != "" { + headers[headerLeaseID] = leaseID + } + + resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + var out AccessPolicy + err = xmlUnmarshal(resp.body, &out.SignedIdentifiersList) + if err != nil { + return nil, err + } + + permissionResponse := updateContainerAccessPolicy(out, &resp.headers) + return &permissionResponse, nil +} + +func updateContainerAccessPolicy(ap AccessPolicy, headers *http.Header) ContainerPermissions { + // containerAccess. Blob, Container, empty + containerAccess := headers.Get(http.CanonicalHeaderKey(ContainerAccessHeader)) + + var cp ContainerPermissions + cp.AccessType = ContainerAccessType(containerAccess) + for _, policy := range ap.SignedIdentifiersList.SignedIdentifiers { + capd := ContainerAccessPolicyDetails{ + ID: policy.ID, + StartTime: policy.AccessPolicy.StartTime, + ExpiryTime: policy.AccessPolicy.ExpiryTime, + } + capd.CanRead = updatePermissions(policy.AccessPolicy.Permission, "r") + capd.CanWrite = updatePermissions(policy.AccessPolicy.Permission, "w") + capd.CanDelete = updatePermissions(policy.AccessPolicy.Permission, "d") + + cp.AccessPolicies = append(cp.AccessPolicies, capd) + } + + return cp +} + +// DeleteContainer deletes the container with given name on the storage +// account. If the container does not exist returns error. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx +func (b BlobStorageClient) DeleteContainer(name string) error { + resp, err := b.deleteContainer(name) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) +} + +// DeleteContainerIfExists deletes the container with given name on the storage +// account if it exists. Returns true if container is deleted with this call, or +// false if the container did not exist at the time of the Delete Container +// operation. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx +func (b BlobStorageClient) DeleteContainerIfExists(name string) (bool, error) { + resp, err := b.deleteContainer(name) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } + } + return false, err +} + +func (b BlobStorageClient) deleteContainer(name string) (*storageResponse, error) { + uri := b.client.getEndpoint(blobServiceName, pathForContainer(name), url.Values{"restype": {"container"}}) + + headers := b.client.getStandardHeaders() + return b.client.exec(http.MethodDelete, uri, headers, nil, b.auth) +} + +// ListBlobs returns an object that contains list of blobs in the container, +// pagination token and other information in the response of List Blobs call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx +func (b BlobStorageClient) ListBlobs(container string, params ListBlobsParameters) (BlobListResponse, error) { + q := mergeParams(params.getParameters(), url.Values{ + "restype": {"container"}, + "comp": {"list"}}) + uri := b.client.getEndpoint(blobServiceName, pathForContainer(container), q) + headers := b.client.getStandardHeaders() + + var out BlobListResponse + resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// BlobExists returns true if a blob with given name exists on the specified +// container of the storage account. +func (b BlobStorageClient) BlobExists(container, name string) (bool, error) { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + headers := b.client.getStandardHeaders() + resp, err := b.client.exec(http.MethodHead, uri, headers, nil, b.auth) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusOK, nil + } + } + return false, err +} + +// GetBlobURL gets the canonical URL to the blob with the specified name in the +// specified container. This method does not create a publicly accessible URL if +// the blob or container is private and this method does not check if the blob +// exists. +func (b BlobStorageClient) GetBlobURL(container, name string) string { + if container == "" { + container = "$root" + } + return b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) +} + +// GetBlob returns a stream to read the blob. Caller must call Close() the +// reader to close on the underlying connection. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx +func (b BlobStorageClient) GetBlob(container, name string) (io.ReadCloser, error) { + resp, err := b.getBlobRange(container, name, "", nil) + if err != nil { + return nil, err + } + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + return resp.body, nil +} + +// GetBlobRange reads the specified range of a blob to a stream. The bytesRange +// string must be in a format like "0-", "10-100" as defined in HTTP 1.1 spec. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx +func (b BlobStorageClient) GetBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (io.ReadCloser, error) { + resp, err := b.getBlobRange(container, name, bytesRange, extraHeaders) + if err != nil { + return nil, err + } + + if err := checkRespCode(resp.statusCode, []int{http.StatusPartialContent}); err != nil { + return nil, err + } + return resp.body, nil +} + +func (b BlobStorageClient) getBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (*storageResponse, error) { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + if bytesRange != "" { + headers["Range"] = fmt.Sprintf("bytes=%s", bytesRange) + } + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + if err != nil { + return nil, err + } + return resp, err +} + +// leasePut is common PUT code for the various acquire/release/break etc functions. +func (b BlobStorageClient) leaseCommonPut(container string, name string, headers map[string]string, expectedStatus int) (http.Header, error) { + params := url.Values{"comp": {"lease"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{expectedStatus}); err != nil { + return nil, err + } + + return resp.headers, nil +} + +// SnapshotBlob creates a snapshot for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691971.aspx +func (b BlobStorageClient) SnapshotBlob(container string, name string, timeout int, extraHeaders map[string]string) (snapshotTimestamp *time.Time, err error) { + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + params := url.Values{"comp": {"snapshot"}} + + if timeout > 0 { + params.Add("timeout", strconv.Itoa(timeout)) + } + + for k, v := range extraHeaders { + headers[k] = v + } + + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return nil, err + } + + if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { + return nil, err + } + + snapshotResponse := resp.headers.Get(http.CanonicalHeaderKey("x-ms-snapshot")) + if snapshotResponse != "" { + snapshotTimestamp, err := time.Parse(time.RFC3339, snapshotResponse) + if err != nil { + return nil, err + } + + return &snapshotTimestamp, nil + } + + return nil, errors.New("Snapshot not created") +} + +// AcquireLease creates a lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx +// returns leaseID acquired +func (b BlobStorageClient) AcquireLease(container string, name string, leaseTimeInSeconds int, proposedLeaseID string) (returnedLeaseID string, err error) { + headers := b.client.getStandardHeaders() + headers[leaseAction] = acquireLease + + if leaseTimeInSeconds > 0 { + headers[leaseDuration] = strconv.Itoa(leaseTimeInSeconds) + } + + if proposedLeaseID != "" { + headers[leaseProposedID] = proposedLeaseID + } + + respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusCreated) + if err != nil { + return "", err + } + + returnedLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) + + if returnedLeaseID != "" { + return returnedLeaseID, nil + } + + return "", errors.New("LeaseID not returned") +} + +// BreakLease breaks the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx +// Returns the timeout remaining in the lease in seconds +func (b BlobStorageClient) BreakLease(container string, name string) (breakTimeout int, err error) { + headers := b.client.getStandardHeaders() + headers[leaseAction] = breakLease + return b.breakLeaseCommon(container, name, headers) +} + +// BreakLeaseWithBreakPeriod breaks the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx +// breakPeriodInSeconds is used to determine how long until new lease can be created. +// Returns the timeout remaining in the lease in seconds +func (b BlobStorageClient) BreakLeaseWithBreakPeriod(container string, name string, breakPeriodInSeconds int) (breakTimeout int, err error) { + headers := b.client.getStandardHeaders() + headers[leaseAction] = breakLease + headers[leaseBreakPeriod] = strconv.Itoa(breakPeriodInSeconds) + return b.breakLeaseCommon(container, name, headers) +} + +// breakLeaseCommon is common code for both version of BreakLease (with and without break period) +func (b BlobStorageClient) breakLeaseCommon(container string, name string, headers map[string]string) (breakTimeout int, err error) { + + respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusAccepted) + if err != nil { + return 0, err + } + + breakTimeoutStr := respHeaders.Get(http.CanonicalHeaderKey(leaseTime)) + if breakTimeoutStr != "" { + breakTimeout, err = strconv.Atoi(breakTimeoutStr) + if err != nil { + return 0, err + } + } + + return breakTimeout, nil +} + +// ChangeLease changes a lease ID for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx +// Returns the new LeaseID acquired +func (b BlobStorageClient) ChangeLease(container string, name string, currentLeaseID string, proposedLeaseID string) (newLeaseID string, err error) { + headers := b.client.getStandardHeaders() + headers[leaseAction] = changeLease + headers[headerLeaseID] = currentLeaseID + headers[leaseProposedID] = proposedLeaseID + + respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusOK) + if err != nil { + return "", err + } + + newLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) + if newLeaseID != "" { + return newLeaseID, nil + } + + return "", errors.New("LeaseID not returned") +} + +// ReleaseLease releases the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx +func (b BlobStorageClient) ReleaseLease(container string, name string, currentLeaseID string) error { + headers := b.client.getStandardHeaders() + headers[leaseAction] = releaseLease + headers[headerLeaseID] = currentLeaseID + + _, err := b.leaseCommonPut(container, name, headers, http.StatusOK) + if err != nil { + return err + } + + return nil +} + +// RenewLease renews the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx +func (b BlobStorageClient) RenewLease(container string, name string, currentLeaseID string) error { + headers := b.client.getStandardHeaders() + headers[leaseAction] = renewLease + headers[headerLeaseID] = currentLeaseID + + _, err := b.leaseCommonPut(container, name, headers, http.StatusOK) + if err != nil { + return err + } + + return nil +} + +// GetBlobProperties provides various information about the specified +// blob. See https://msdn.microsoft.com/en-us/library/azure/dd179394.aspx +func (b BlobStorageClient) GetBlobProperties(container, name string) (*BlobProperties, error) { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + + headers := b.client.getStandardHeaders() + resp, err := b.client.exec(http.MethodHead, uri, headers, nil, b.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + var contentLength int64 + contentLengthStr := resp.headers.Get("Content-Length") + if contentLengthStr != "" { + contentLength, err = strconv.ParseInt(contentLengthStr, 0, 64) + if err != nil { + return nil, err + } + } + + var sequenceNum int64 + sequenceNumStr := resp.headers.Get("x-ms-blob-sequence-number") + if sequenceNumStr != "" { + sequenceNum, err = strconv.ParseInt(sequenceNumStr, 0, 64) + if err != nil { + return nil, err + } + } + + return &BlobProperties{ + LastModified: resp.headers.Get("Last-Modified"), + Etag: resp.headers.Get("Etag"), + ContentMD5: resp.headers.Get("Content-MD5"), + ContentLength: contentLength, + ContentEncoding: resp.headers.Get("Content-Encoding"), + ContentType: resp.headers.Get("Content-Type"), + CacheControl: resp.headers.Get("Cache-Control"), + ContentLanguage: resp.headers.Get("Content-Language"), + SequenceNumber: sequenceNum, + CopyCompletionTime: resp.headers.Get("x-ms-copy-completion-time"), + CopyStatusDescription: resp.headers.Get("x-ms-copy-status-description"), + CopyID: resp.headers.Get("x-ms-copy-id"), + CopyProgress: resp.headers.Get("x-ms-copy-progress"), + CopySource: resp.headers.Get("x-ms-copy-source"), + CopyStatus: resp.headers.Get("x-ms-copy-status"), + BlobType: BlobType(resp.headers.Get("x-ms-blob-type")), + LeaseStatus: resp.headers.Get("x-ms-lease-status"), + LeaseState: resp.headers.Get("x-ms-lease-state"), + }, nil +} + +// SetBlobProperties replaces the BlobHeaders for the specified blob. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetBlobProperties. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691966.aspx +func (b BlobStorageClient) SetBlobProperties(container, name string, blobHeaders BlobHeaders) error { + params := url.Values{"comp": {"properties"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + + extraHeaders := headersFromStruct(blobHeaders) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// SetBlobMetadata replaces the metadata for the specified blob. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetBlobMetadata. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx +func (b BlobStorageClient) SetBlobMetadata(container, name string, metadata map[string]string, extraHeaders map[string]string) error { + params := url.Values{"comp": {"metadata"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + metadata = b.client.protectUserAgent(metadata) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + for k, v := range metadata { + headers[userDefinedMetadataHeaderPrefix+k] = v + } + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// GetBlobMetadata returns all user-defined metadata for the specified blob. +// +// All metadata keys will be returned in lower case. (HTTP header +// names are case-insensitive.) +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx +func (b BlobStorageClient) GetBlobMetadata(container, name string) (map[string]string, error) { + params := url.Values{"comp": {"metadata"}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + + resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + metadata := make(map[string]string) + for k, v := range resp.headers { + // Can't trust CanonicalHeaderKey() to munge case + // reliably. "_" is allowed in identifiers: + // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx + // https://msdn.microsoft.com/library/aa664670(VS.71).aspx + // http://tools.ietf.org/html/rfc7230#section-3.2 + // ...but "_" is considered invalid by + // CanonicalMIMEHeaderKey in + // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 + // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". + k = strings.ToLower(k) + if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { + continue + } + // metadata["foo"] = content of the last X-Ms-Meta-Foo header + k = k[len(userDefinedMetadataHeaderPrefix):] + metadata[k] = v[len(v)-1] + } + return metadata, nil +} + +// CreateBlockBlob initializes an empty block blob with no blocks. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) CreateBlockBlob(container, name string) error { + return b.CreateBlockBlobFromReader(container, name, 0, nil, nil) +} + +// CreateBlockBlobFromReader initializes a block blob using data from +// reader. Size must be the number of bytes read from reader. To +// create an empty blob, use size==0 and reader==nil. +// +// The API rejects requests with size > 64 MiB (but this limit is not +// checked by the SDK). To write a larger blob, use CreateBlockBlob, +// PutBlock, and PutBlockList. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) CreateBlockBlobFromReader(container, name string, size uint64, blob io.Reader, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeBlock) + headers["Content-Length"] = fmt.Sprintf("%d", size) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, blob, b.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutBlock saves the given data chunk to the specified block blob with +// given ID. +// +// The API rejects chunks larger than 4 MiB (but this limit is not +// checked by the SDK). +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx +func (b BlobStorageClient) PutBlock(container, name, blockID string, chunk []byte) error { + return b.PutBlockWithLength(container, name, blockID, uint64(len(chunk)), bytes.NewReader(chunk), nil) +} + +// PutBlockWithLength saves the given data stream of exactly specified size to +// the block blob with given ID. It is an alternative to PutBlocks where data +// comes as stream but the length is known in advance. +// +// The API rejects requests with size > 4 MiB (but this limit is not +// checked by the SDK). +// +// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx +func (b BlobStorageClient) PutBlockWithLength(container, name, blockID string, size uint64, blob io.Reader, extraHeaders map[string]string) error { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"block"}, "blockid": {blockID}}) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeBlock) + headers["Content-Length"] = fmt.Sprintf("%v", size) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, blob, b.auth) + if err != nil { + return err + } + + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutBlockList saves list of blocks to the specified block blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179467.aspx +func (b BlobStorageClient) PutBlockList(container, name string, blocks []Block) error { + blockListXML := prepareBlockListRequest(blocks) + + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"blocklist"}}) + headers := b.client.getStandardHeaders() + headers["Content-Length"] = fmt.Sprintf("%v", len(blockListXML)) + + resp, err := b.client.exec(http.MethodPut, uri, headers, strings.NewReader(blockListXML), b.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// GetBlockList retrieves list of blocks in the specified block blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx +func (b BlobStorageClient) GetBlockList(container, name string, blockType BlockListType) (BlockListResponse, error) { + params := url.Values{"comp": {"blocklist"}, "blocklisttype": {string(blockType)}} + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + + var out BlockListResponse + resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + if err != nil { + return out, err + } + defer resp.body.Close() + + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// PutPageBlob initializes an empty page blob with specified name and maximum +// size in bytes (size must be aligned to a 512-byte boundary). A page blob must +// be created using this method before writing pages. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) PutPageBlob(container, name string, size int64, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypePage) + headers["x-ms-blob-content-length"] = fmt.Sprintf("%v", size) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// PutPage writes a range of pages to a page blob or clears the given range. +// In case of 'clear' writes, given chunk is discarded. Ranges must be aligned +// with 512-byte boundaries and chunk must be of size multiplies by 512. +// +// See https://msdn.microsoft.com/en-us/library/ee691975.aspx +func (b BlobStorageClient) PutPage(container, name string, startByte, endByte int64, writeType PageWriteType, chunk []byte, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"page"}}) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypePage) + headers["x-ms-page-write"] = string(writeType) + headers["x-ms-range"] = fmt.Sprintf("bytes=%v-%v", startByte, endByte) + for k, v := range extraHeaders { + headers[k] = v + } + var contentLength int64 + var data io.Reader + if writeType == PageWriteTypeClear { + contentLength = 0 + data = bytes.NewReader([]byte{}) + } else { + contentLength = int64(len(chunk)) + data = bytes.NewReader(chunk) + } + headers["Content-Length"] = fmt.Sprintf("%v", contentLength) + + resp, err := b.client.exec(http.MethodPut, uri, headers, data, b.auth) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// GetPageRanges returns the list of valid page ranges for a page blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx +func (b BlobStorageClient) GetPageRanges(container, name string) (GetPageRangesResponse, error) { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"pagelist"}}) + headers := b.client.getStandardHeaders() + + var out GetPageRangesResponse + resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) + if err != nil { + return out, err + } + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return out, err + } + err = xmlUnmarshal(resp.body, &out) + return out, err +} + +// PutAppendBlob initializes an empty append blob with specified name. An +// append blob must be created using this method before appending blocks. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx +func (b BlobStorageClient) PutAppendBlob(container, name string, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeAppend) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// AppendBlock appends a block to an append blob. +// +// See https://msdn.microsoft.com/en-us/library/azure/mt427365.aspx +func (b BlobStorageClient) AppendBlock(container, name string, chunk []byte, extraHeaders map[string]string) error { + path := fmt.Sprintf("%s/%s", container, name) + uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"appendblock"}}) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + headers["x-ms-blob-type"] = string(BlobTypeAppend) + headers["Content-Length"] = fmt.Sprintf("%v", len(chunk)) + + for k, v := range extraHeaders { + headers[k] = v + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, bytes.NewReader(chunk), b.auth) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// CopyBlob starts a blob copy operation and waits for the operation to +// complete. sourceBlob parameter must be a canonical URL to the blob (can be +// obtained using GetBlobURL method.) There is no SLA on blob copy and therefore +// this helper method works faster on smaller files. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx +func (b BlobStorageClient) CopyBlob(container, name, sourceBlob string) error { + copyID, err := b.StartBlobCopy(container, name, sourceBlob) + if err != nil { + return err + } + + return b.WaitForBlobCopy(container, name, copyID) +} + +// StartBlobCopy starts a blob copy operation. +// sourceBlob parameter must be a canonical URL to the blob (can be +// obtained using GetBlobURL method.) +// +// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx +func (b BlobStorageClient) StartBlobCopy(container, name, sourceBlob string) (string, error) { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + + headers := b.client.getStandardHeaders() + headers["x-ms-copy-source"] = sourceBlob + + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return "", err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil { + return "", err + } + + copyID := resp.headers.Get("x-ms-copy-id") + if copyID == "" { + return "", errors.New("Got empty copy id header") + } + return copyID, nil +} + +// AbortBlobCopy aborts a BlobCopy which has already been triggered by the StartBlobCopy function. +// copyID is generated from StartBlobCopy function. +// currentLeaseID is required IF the destination blob has an active lease on it. +// As defined in https://msdn.microsoft.com/en-us/library/azure/jj159098.aspx +func (b BlobStorageClient) AbortBlobCopy(container, name, copyID, currentLeaseID string, timeout int) error { + params := url.Values{"comp": {"copy"}, "copyid": {copyID}} + if timeout > 0 { + params.Add("timeout", strconv.Itoa(timeout)) + } + + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) + headers := b.client.getStandardHeaders() + headers["x-ms-copy-action"] = "abort" + + if currentLeaseID != "" { + headers[headerLeaseID] = currentLeaseID + } + + resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + + return nil +} + +// WaitForBlobCopy loops until a BlobCopy operation is completed (or fails with error) +func (b BlobStorageClient) WaitForBlobCopy(container, name, copyID string) error { + for { + props, err := b.GetBlobProperties(container, name) + if err != nil { + return err + } + + if props.CopyID != copyID { + return errBlobCopyIDMismatch + } + + switch props.CopyStatus { + case blobCopyStatusSuccess: + return nil + case blobCopyStatusPending: + continue + case blobCopyStatusAborted: + return errBlobCopyAborted + case blobCopyStatusFailed: + return fmt.Errorf("storage: blob copy failed. Id=%s Description=%s", props.CopyID, props.CopyStatusDescription) + default: + return fmt.Errorf("storage: unhandled blob copy status: '%s'", props.CopyStatus) + } + } +} + +// DeleteBlob deletes the given blob from the specified container. +// If the blob does not exists at the time of the Delete Blob operation, it +// returns error. See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx +func (b BlobStorageClient) DeleteBlob(container, name string, extraHeaders map[string]string) error { + resp, err := b.deleteBlob(container, name, extraHeaders) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) +} + +// DeleteBlobIfExists deletes the given blob from the specified container If the +// blob is deleted with this call, returns true. Otherwise returns false. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx +func (b BlobStorageClient) DeleteBlobIfExists(container, name string, extraHeaders map[string]string) (bool, error) { + resp, err := b.deleteBlob(container, name, extraHeaders) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } + } + return false, err +} + +func (b BlobStorageClient) deleteBlob(container, name string, extraHeaders map[string]string) (*storageResponse, error) { + uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) + extraHeaders = b.client.protectUserAgent(extraHeaders) + headers := b.client.getStandardHeaders() + for k, v := range extraHeaders { + headers[k] = v + } + + return b.client.exec(http.MethodDelete, uri, headers, nil, b.auth) +} + +// helper method to construct the path to a container given its name +func pathForContainer(name string) string { + return fmt.Sprintf("/%s", name) +} + +// helper method to construct the path to a blob given its container and blob +// name +func pathForBlob(container, name string) string { + return fmt.Sprintf("/%s/%s", container, name) +} + +// GetBlobSASURIWithSignedIPAndProtocol creates an URL to the specified blob which contains the Shared +// Access Signature with specified permissions and expiration time. Also includes signedIPRange and allowed protocols. +// If old API version is used but no signedIP is passed (ie empty string) then this should still work. +// We only populate the signedIP when it non-empty. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx +func (b BlobStorageClient) GetBlobSASURIWithSignedIPAndProtocol(container, name string, expiry time.Time, permissions string, signedIPRange string, HTTPSOnly bool) (string, error) { + var ( + signedPermissions = permissions + blobURL = b.GetBlobURL(container, name) + ) + canonicalizedResource, err := b.client.buildCanonicalizedResource(blobURL, b.auth) + if err != nil { + return "", err + } + + // "The canonicalizedresouce portion of the string is a canonical path to the signed resource. + // It must include the service name (blob, table, queue or file) for version 2015-02-21 or + // later, the storage account name, and the resource name, and must be URL-decoded. + // -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + + // We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component). + canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1) + canonicalizedResource, err = url.QueryUnescape(canonicalizedResource) + if err != nil { + return "", err + } + + signedExpiry := expiry.UTC().Format(time.RFC3339) + signedResource := "b" + + protocols := "https,http" + if HTTPSOnly { + protocols = "https" + } + stringToSign, err := blobSASStringToSign(b.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions, signedIPRange, protocols) + if err != nil { + return "", err + } + + sig := b.client.computeHmac256(stringToSign) + sasParams := url.Values{ + "sv": {b.client.apiVersion}, + "se": {signedExpiry}, + "sr": {signedResource}, + "sp": {signedPermissions}, + "sig": {sig}, + } + + if b.client.apiVersion >= "2015-04-05" { + sasParams.Add("spr", protocols) + if signedIPRange != "" { + sasParams.Add("sip", signedIPRange) + } + } + + sasURL, err := url.Parse(blobURL) + if err != nil { + return "", err + } + sasURL.RawQuery = sasParams.Encode() + return sasURL.String(), nil +} + +// GetBlobSASURI creates an URL to the specified blob which contains the Shared +// Access Signature with specified permissions and expiration time. +// +// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx +func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Time, permissions string) (string, error) { + url, err := b.GetBlobSASURIWithSignedIPAndProtocol(container, name, expiry, permissions, "", false) + return url, err +} + +func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string, signedIP string, protocols string) (string, error) { + var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string + + if signedVersion >= "2015-02-21" { + canonicalizedResource = "/blob" + canonicalizedResource + } + + // https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx#Anchor_12 + if signedVersion >= "2015-04-05" { + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedIP, protocols, signedVersion, rscc, rscd, rsce, rscl, rsct), nil + } + + // reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + if signedVersion >= "2013-08-15" { + return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion, rscc, rscd, rsce, rscl, rsct), nil + } + + return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15") +} + +func generateContainerACLpayload(policies []ContainerAccessPolicyDetails) (io.Reader, int, error) { + sil := SignedIdentifiers{ + SignedIdentifiers: []SignedIdentifier{}, + } + for _, capd := range policies { + permission := capd.generateContainerPermissions() + signedIdentifier := convertAccessPolicyToXMLStructs(capd.ID, capd.StartTime, capd.ExpiryTime, permission) + sil.SignedIdentifiers = append(sil.SignedIdentifiers, signedIdentifier) + } + return xmlMarshal(sil) +} + +func (capd *ContainerAccessPolicyDetails) generateContainerPermissions() (permissions string) { + // generate the permissions string (rwd). + // still want the end user API to have bool flags. + permissions = "" + + if capd.CanRead { + permissions += "r" + } + + if capd.CanWrite { + permissions += "w" + } + + if capd.CanDelete { + permissions += "d" + } + + return permissions +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go new file mode 100644 index 000000000..817f934c5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/client.go @@ -0,0 +1,469 @@ +// Package storage provides clients for Microsoft Azure Storage Services. +package storage + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "runtime" + "strconv" + "strings" +) + +const ( + // DefaultBaseURL is the domain name used for storage requests when a + // default client is created. + DefaultBaseURL = "core.windows.net" + + // DefaultAPIVersion is the Azure Storage API version string used when a + // basic client is created. + DefaultAPIVersion = "2015-02-21" + + defaultUseHTTPS = true + + // StorageEmulatorAccountName is the fixed storage account used by Azure Storage Emulator + StorageEmulatorAccountName = "devstoreaccount1" + + // StorageEmulatorAccountKey is the the fixed storage account used by Azure Storage Emulator + StorageEmulatorAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" + + blobServiceName = "blob" + tableServiceName = "table" + queueServiceName = "queue" + fileServiceName = "file" + + storageEmulatorBlob = "127.0.0.1:10000" + storageEmulatorTable = "127.0.0.1:10002" + storageEmulatorQueue = "127.0.0.1:10001" + + userAgentHeader = "User-Agent" +) + +// Client is the object that needs to be constructed to perform +// operations on the storage account. +type Client struct { + // HTTPClient is the http.Client used to initiate API + // requests. If it is nil, http.DefaultClient is used. + HTTPClient *http.Client + + accountName string + accountKey []byte + useHTTPS bool + UseSharedKeyLite bool + baseURL string + apiVersion string + userAgent string +} + +type storageResponse struct { + statusCode int + headers http.Header + body io.ReadCloser +} + +type odataResponse struct { + storageResponse + odata odataErrorMessage +} + +// AzureStorageServiceError contains fields of the error response from +// Azure Storage Service REST API. See https://msdn.microsoft.com/en-us/library/azure/dd179382.aspx +// Some fields might be specific to certain calls. +type AzureStorageServiceError struct { + Code string `xml:"Code"` + Message string `xml:"Message"` + AuthenticationErrorDetail string `xml:"AuthenticationErrorDetail"` + QueryParameterName string `xml:"QueryParameterName"` + QueryParameterValue string `xml:"QueryParameterValue"` + Reason string `xml:"Reason"` + StatusCode int + RequestID string +} + +type odataErrorMessageMessage struct { + Lang string `json:"lang"` + Value string `json:"value"` +} + +type odataErrorMessageInternal struct { + Code string `json:"code"` + Message odataErrorMessageMessage `json:"message"` +} + +type odataErrorMessage struct { + Err odataErrorMessageInternal `json:"odata.error"` +} + +// UnexpectedStatusCodeError is returned when a storage service responds with neither an error +// nor with an HTTP status code indicating success. +type UnexpectedStatusCodeError struct { + allowed []int + got int +} + +func (e UnexpectedStatusCodeError) Error() string { + s := func(i int) string { return fmt.Sprintf("%d %s", i, http.StatusText(i)) } + + got := s(e.got) + expected := []string{} + for _, v := range e.allowed { + expected = append(expected, s(v)) + } + return fmt.Sprintf("storage: status code from service response is %s; was expecting %s", got, strings.Join(expected, " or ")) +} + +// Got is the actual status code returned by Azure. +func (e UnexpectedStatusCodeError) Got() int { + return e.got +} + +// NewBasicClient constructs a Client with given storage service name and +// key. +func NewBasicClient(accountName, accountKey string) (Client, error) { + if accountName == StorageEmulatorAccountName { + return NewEmulatorClient() + } + return NewClient(accountName, accountKey, DefaultBaseURL, DefaultAPIVersion, defaultUseHTTPS) + +} + +//NewEmulatorClient contructs a Client intended to only work with Azure +//Storage Emulator +func NewEmulatorClient() (Client, error) { + return NewClient(StorageEmulatorAccountName, StorageEmulatorAccountKey, DefaultBaseURL, DefaultAPIVersion, false) +} + +// NewClient constructs a Client. This should be used if the caller wants +// to specify whether to use HTTPS, a specific REST API version or a custom +// storage endpoint than Azure Public Cloud. +func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, useHTTPS bool) (Client, error) { + var c Client + if accountName == "" { + return c, fmt.Errorf("azure: account name required") + } else if accountKey == "" { + return c, fmt.Errorf("azure: account key required") + } else if blobServiceBaseURL == "" { + return c, fmt.Errorf("azure: base storage service url required") + } + + key, err := base64.StdEncoding.DecodeString(accountKey) + if err != nil { + return c, fmt.Errorf("azure: malformed storage account key: %v", err) + } + + c = Client{ + accountName: accountName, + accountKey: key, + useHTTPS: useHTTPS, + baseURL: blobServiceBaseURL, + apiVersion: apiVersion, + UseSharedKeyLite: false, + } + c.userAgent = c.getDefaultUserAgent() + return c, nil +} + +func (c Client) getDefaultUserAgent() string { + return fmt.Sprintf("Go/%s (%s-%s) Azure-SDK-For-Go/%s storage-dataplane/%s", + runtime.Version(), + runtime.GOARCH, + runtime.GOOS, + sdkVersion, + c.apiVersion, + ) +} + +// AddToUserAgent adds an extension to the current user agent +func (c *Client) AddToUserAgent(extension string) error { + if extension != "" { + c.userAgent = fmt.Sprintf("%s %s", c.userAgent, extension) + return nil + } + return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.userAgent) +} + +// protectUserAgent is used in funcs that include extraheaders as a parameter. +// It prevents the User-Agent header to be overwritten, instead if it happens to +// be present, it gets added to the current User-Agent. Use it before getStandardHeaders +func (c *Client) protectUserAgent(extraheaders map[string]string) map[string]string { + if v, ok := extraheaders[userAgentHeader]; ok { + c.AddToUserAgent(v) + delete(extraheaders, userAgentHeader) + } + return extraheaders +} + +func (c Client) getBaseURL(service string) string { + scheme := "http" + if c.useHTTPS { + scheme = "https" + } + host := "" + if c.accountName == StorageEmulatorAccountName { + switch service { + case blobServiceName: + host = storageEmulatorBlob + case tableServiceName: + host = storageEmulatorTable + case queueServiceName: + host = storageEmulatorQueue + } + } else { + host = fmt.Sprintf("%s.%s.%s", c.accountName, service, c.baseURL) + } + + u := &url.URL{ + Scheme: scheme, + Host: host} + return u.String() +} + +func (c Client) getEndpoint(service, path string, params url.Values) string { + u, err := url.Parse(c.getBaseURL(service)) + if err != nil { + // really should not be happening + panic(err) + } + + // API doesn't accept path segments not starting with '/' + if !strings.HasPrefix(path, "/") { + path = fmt.Sprintf("/%v", path) + } + + if c.accountName == StorageEmulatorAccountName { + path = fmt.Sprintf("/%v%v", StorageEmulatorAccountName, path) + } + + u.Path = path + u.RawQuery = params.Encode() + return u.String() +} + +// GetBlobService returns a BlobStorageClient which can operate on the blob +// service of the storage account. +func (c Client) GetBlobService() BlobStorageClient { + b := BlobStorageClient{ + client: c, + } + b.client.AddToUserAgent(blobServiceName) + b.auth = sharedKey + if c.UseSharedKeyLite { + b.auth = sharedKeyLite + } + return b +} + +// GetQueueService returns a QueueServiceClient which can operate on the queue +// service of the storage account. +func (c Client) GetQueueService() QueueServiceClient { + q := QueueServiceClient{ + client: c, + } + q.client.AddToUserAgent(queueServiceName) + q.auth = sharedKey + if c.UseSharedKeyLite { + q.auth = sharedKeyLite + } + return q +} + +// GetTableService returns a TableServiceClient which can operate on the table +// service of the storage account. +func (c Client) GetTableService() TableServiceClient { + t := TableServiceClient{ + client: c, + } + t.client.AddToUserAgent(tableServiceName) + t.auth = sharedKeyForTable + if c.UseSharedKeyLite { + t.auth = sharedKeyLiteForTable + } + return t +} + +// GetFileService returns a FileServiceClient which can operate on the file +// service of the storage account. +func (c Client) GetFileService() FileServiceClient { + f := FileServiceClient{ + client: c, + } + f.client.AddToUserAgent(fileServiceName) + f.auth = sharedKey + if c.UseSharedKeyLite { + f.auth = sharedKeyLite + } + return f +} + +func (c Client) getStandardHeaders() map[string]string { + return map[string]string{ + userAgentHeader: c.userAgent, + "x-ms-version": c.apiVersion, + "x-ms-date": currentTimeRfc1123Formatted(), + } +} + +func (c Client) exec(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*storageResponse, error) { + headers, err := c.addAuthorizationHeader(verb, url, headers, auth) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(verb, url, body) + if err != nil { + return nil, errors.New("azure/storage: error creating request: " + err.Error()) + } + + if clstr, ok := headers["Content-Length"]; ok { + // content length header is being signed, but completely ignored by golang. + // instead we have to use the ContentLength property on the request struct + // (see https://golang.org/src/net/http/request.go?s=18140:18370#L536 and + // https://golang.org/src/net/http/transfer.go?s=1739:2467#L49) + req.ContentLength, err = strconv.ParseInt(clstr, 10, 64) + if err != nil { + return nil, err + } + } + for k, v := range headers { + req.Header.Add(k, v) + } + + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + resp, err := httpClient.Do(req) + if err != nil { + return nil, err + } + + statusCode := resp.StatusCode + if statusCode >= 400 && statusCode <= 505 { + var respBody []byte + respBody, err = readResponseBody(resp) + if err != nil { + return nil, err + } + + requestID := resp.Header.Get("x-ms-request-id") + if len(respBody) == 0 { + // no error in response body, might happen in HEAD requests + err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, requestID) + } else { + // response contains storage service error object, unmarshal + storageErr, errIn := serviceErrFromXML(respBody, resp.StatusCode, requestID) + if err != nil { // error unmarshaling the error response + err = errIn + } + err = storageErr + } + return &storageResponse{ + statusCode: resp.StatusCode, + headers: resp.Header, + body: ioutil.NopCloser(bytes.NewReader(respBody)), /* restore the body */ + }, err + } + + return &storageResponse{ + statusCode: resp.StatusCode, + headers: resp.Header, + body: resp.Body}, nil +} + +func (c Client) execInternalJSON(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*odataResponse, error) { + headers, err := c.addAuthorizationHeader(verb, url, headers, auth) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(verb, url, body) + for k, v := range headers { + req.Header.Add(k, v) + } + + httpClient := c.HTTPClient + if httpClient == nil { + httpClient = http.DefaultClient + } + + resp, err := httpClient.Do(req) + if err != nil { + return nil, err + } + + respToRet := &odataResponse{} + respToRet.body = resp.Body + respToRet.statusCode = resp.StatusCode + respToRet.headers = resp.Header + + statusCode := resp.StatusCode + if statusCode >= 400 && statusCode <= 505 { + var respBody []byte + respBody, err = readResponseBody(resp) + if err != nil { + return nil, err + } + + if len(respBody) == 0 { + // no error in response body, might happen in HEAD requests + err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, resp.Header.Get("x-ms-request-id")) + return respToRet, err + } + // try unmarshal as odata.error json + err = json.Unmarshal(respBody, &respToRet.odata) + return respToRet, err + } + + return respToRet, nil +} + +func readResponseBody(resp *http.Response) ([]byte, error) { + defer resp.Body.Close() + out, err := ioutil.ReadAll(resp.Body) + if err == io.EOF { + err = nil + } + return out, err +} + +func serviceErrFromXML(body []byte, statusCode int, requestID string) (AzureStorageServiceError, error) { + var storageErr AzureStorageServiceError + if err := xml.Unmarshal(body, &storageErr); err != nil { + return storageErr, err + } + storageErr.StatusCode = statusCode + storageErr.RequestID = requestID + return storageErr, nil +} + +func serviceErrFromStatusCode(code int, status string, requestID string) AzureStorageServiceError { + return AzureStorageServiceError{ + StatusCode: code, + Code: status, + RequestID: requestID, + Message: "no response body was available for error status code", + } +} + +func (e AzureStorageServiceError) Error() string { + return fmt.Sprintf("storage: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=%s, RequestId=%s, QueryParameterName=%s, QueryParameterValue=%s", + e.StatusCode, e.Code, e.Message, e.RequestID, e.QueryParameterName, e.QueryParameterValue) +} + +// checkRespCode returns UnexpectedStatusError if the given response code is not +// one of the allowed status codes; otherwise nil. +func checkRespCode(respCode int, allowed []int) error { + for _, v := range allowed { + if respCode == v { + return nil + } + } + return UnexpectedStatusCodeError{allowed, respCode} +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go new file mode 100644 index 000000000..d07e0af1c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/directory.go @@ -0,0 +1,217 @@ +package storage + +import ( + "encoding/xml" + "net/http" + "net/url" +) + +// Directory represents a directory on a share. +type Directory struct { + fsc *FileServiceClient + Metadata map[string]string + Name string `xml:"Name"` + parent *Directory + Properties DirectoryProperties + share *Share +} + +// DirectoryProperties contains various properties of a directory. +type DirectoryProperties struct { + LastModified string `xml:"Last-Modified"` + Etag string `xml:"Etag"` +} + +// ListDirsAndFilesParameters defines the set of customizable parameters to +// make a List Files and Directories call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx +type ListDirsAndFilesParameters struct { + Marker string + MaxResults uint + Timeout uint +} + +// DirsAndFilesListResponse contains the response fields from +// a List Files and Directories call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx +type DirsAndFilesListResponse struct { + XMLName xml.Name `xml:"EnumerationResults"` + Xmlns string `xml:"xmlns,attr"` + Marker string `xml:"Marker"` + MaxResults int64 `xml:"MaxResults"` + Directories []Directory `xml:"Entries>Directory"` + Files []File `xml:"Entries>File"` + NextMarker string `xml:"NextMarker"` +} + +// builds the complete directory path for this directory object. +func (d *Directory) buildPath() string { + path := "" + current := d + for current.Name != "" { + path = "/" + current.Name + path + current = current.parent + } + return d.share.buildPath() + path +} + +// Create this directory in the associated share. +// If a directory with the same name already exists, the operation fails. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166993.aspx +func (d *Directory) Create() error { + // if this is the root directory exit early + if d.parent == nil { + return nil + } + + headers, err := d.fsc.createResource(d.buildPath(), resourceDirectory, mergeMDIntoExtraHeaders(d.Metadata, nil)) + if err != nil { + return err + } + + d.updateEtagAndLastModified(headers) + return nil +} + +// CreateIfNotExists creates this directory under the associated share if the +// directory does not exists. Returns true if the directory is newly created or +// false if the directory already exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166993.aspx +func (d *Directory) CreateIfNotExists() (bool, error) { + // if this is the root directory exit early + if d.parent == nil { + return false, nil + } + + resp, err := d.fsc.createResourceNoClose(d.buildPath(), resourceDirectory, nil) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { + if resp.statusCode == http.StatusCreated { + d.updateEtagAndLastModified(resp.headers) + return true, nil + } + + return false, d.FetchAttributes() + } + } + + return false, err +} + +// Delete removes this directory. It must be empty in order to be deleted. +// If the directory does not exist the operation fails. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166969.aspx +func (d *Directory) Delete() error { + return d.fsc.deleteResource(d.buildPath(), resourceDirectory) +} + +// DeleteIfExists removes this directory if it exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166969.aspx +func (d *Directory) DeleteIfExists() (bool, error) { + resp, err := d.fsc.deleteResourceNoClose(d.buildPath(), resourceDirectory) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } + } + return false, err +} + +// Exists returns true if this directory exists. +func (d *Directory) Exists() (bool, error) { + exists, headers, err := d.fsc.resourceExists(d.buildPath(), resourceDirectory) + if exists { + d.updateEtagAndLastModified(headers) + } + return exists, err +} + +// FetchAttributes retrieves metadata for this directory. +func (d *Directory) FetchAttributes() error { + headers, err := d.fsc.getResourceHeaders(d.buildPath(), compNone, resourceDirectory, http.MethodHead) + if err != nil { + return err + } + + d.updateEtagAndLastModified(headers) + d.Metadata = getMetadataFromHeaders(headers) + + return nil +} + +// GetDirectoryReference returns a child Directory object for this directory. +func (d *Directory) GetDirectoryReference(name string) *Directory { + return &Directory{ + fsc: d.fsc, + Name: name, + parent: d, + share: d.share, + } +} + +// GetFileReference returns a child File object for this directory. +func (d *Directory) GetFileReference(name string) *File { + return &File{ + fsc: d.fsc, + Name: name, + parent: d, + share: d.share, + } +} + +// ListDirsAndFiles returns a list of files and directories under this directory. +// It also contains a pagination token and other response details. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx +func (d *Directory) ListDirsAndFiles(params ListDirsAndFilesParameters) (*DirsAndFilesListResponse, error) { + q := mergeParams(params.getParameters(), getURLInitValues(compList, resourceDirectory)) + + resp, err := d.fsc.listContent(d.buildPath(), q, nil) + if err != nil { + return nil, err + } + + defer resp.body.Close() + var out DirsAndFilesListResponse + err = xmlUnmarshal(resp.body, &out) + return &out, err +} + +// SetMetadata replaces the metadata for this directory. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetDirectoryMetadata. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/mt427370.aspx +func (d *Directory) SetMetadata() error { + headers, err := d.fsc.setResourceHeaders(d.buildPath(), compMetadata, resourceDirectory, mergeMDIntoExtraHeaders(d.Metadata, nil)) + if err != nil { + return err + } + + d.updateEtagAndLastModified(headers) + return nil +} + +// updates Etag and last modified date +func (d *Directory) updateEtagAndLastModified(headers http.Header) { + d.Properties.Etag = headers.Get("Etag") + d.Properties.LastModified = headers.Get("Last-Modified") +} + +// URL gets the canonical URL to this directory. +// This method does not create a publicly accessible URL if the directory +// is private and this method does not check if the directory exists. +func (d *Directory) URL() string { + return d.fsc.client.getEndpoint(fileServiceName, d.buildPath(), url.Values{}) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go new file mode 100644 index 000000000..575f3f726 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go @@ -0,0 +1,360 @@ +package storage + +import ( + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" +) + +const fourMB = uint64(4194304) +const oneTB = uint64(1099511627776) + +// File represents a file on a share. +type File struct { + fsc *FileServiceClient + Metadata map[string]string + Name string `xml:"Name"` + parent *Directory + Properties FileProperties `xml:"Properties"` + share *Share +} + +// FileProperties contains various properties of a file. +type FileProperties struct { + CacheControl string `header:"x-ms-cache-control"` + Disposition string `header:"x-ms-content-disposition"` + Encoding string `header:"x-ms-content-encoding"` + Etag string + Language string `header:"x-ms-content-language"` + LastModified string + Length uint64 `xml:"Content-Length"` + MD5 string `header:"x-ms-content-md5"` + Type string `header:"x-ms-content-type"` +} + +// FileCopyState contains various properties of a file copy operation. +type FileCopyState struct { + CompletionTime string + ID string + Progress string + Source string + Status string + StatusDesc string +} + +// FileStream contains file data returned from a call to GetFile. +type FileStream struct { + Body io.ReadCloser + ContentMD5 string +} + +// FileRanges contains a list of file range information for a file. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx +type FileRanges struct { + ContentLength uint64 + LastModified string + ETag string + FileRanges []FileRange `xml:"Range"` +} + +// FileRange contains range information for a file. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx +type FileRange struct { + Start uint64 `xml:"Start"` + End uint64 `xml:"End"` +} + +func (fr FileRange) String() string { + return fmt.Sprintf("bytes=%d-%d", fr.Start, fr.End) +} + +// builds the complete file path for this file object +func (f *File) buildPath() string { + return f.parent.buildPath() + "/" + f.Name +} + +// ClearRange releases the specified range of space in a file. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn194276.aspx +func (f *File) ClearRange(fileRange FileRange) error { + headers, err := f.modifyRange(nil, fileRange, nil) + if err != nil { + return err + } + + f.updateEtagAndLastModified(headers) + return nil +} + +// Create creates a new file or replaces an existing one. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn194271.aspx +func (f *File) Create(maxSize uint64) error { + if maxSize > oneTB { + return fmt.Errorf("max file size is 1TB") + } + + extraHeaders := map[string]string{ + "x-ms-content-length": strconv.FormatUint(maxSize, 10), + "x-ms-type": "file", + } + + headers, err := f.fsc.createResource(f.buildPath(), resourceFile, mergeMDIntoExtraHeaders(f.Metadata, extraHeaders)) + if err != nil { + return err + } + + f.Properties.Length = maxSize + f.updateEtagAndLastModified(headers) + return nil +} + +// Delete immediately removes this file from the storage account. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn689085.aspx +func (f *File) Delete() error { + return f.fsc.deleteResource(f.buildPath(), resourceFile) +} + +// DeleteIfExists removes this file if it exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn689085.aspx +func (f *File) DeleteIfExists() (bool, error) { + resp, err := f.fsc.deleteResourceNoClose(f.buildPath(), resourceFile) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } + } + return false, err +} + +// DownloadRangeToStream operation downloads the specified range of this file with optional MD5 hash. +// +// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-file +func (f *File) DownloadRangeToStream(fileRange FileRange, getContentMD5 bool) (fs FileStream, err error) { + if getContentMD5 && isRangeTooBig(fileRange) { + return fs, fmt.Errorf("must specify a range less than or equal to 4MB when getContentMD5 is true") + } + + extraHeaders := map[string]string{ + "Range": fileRange.String(), + } + if getContentMD5 == true { + extraHeaders["x-ms-range-get-content-md5"] = "true" + } + + resp, err := f.fsc.getResourceNoClose(f.buildPath(), compNone, resourceFile, http.MethodGet, extraHeaders) + if err != nil { + return fs, err + } + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK, http.StatusPartialContent}); err != nil { + resp.body.Close() + return fs, err + } + + fs.Body = resp.body + if getContentMD5 { + fs.ContentMD5 = resp.headers.Get("Content-MD5") + } + return fs, nil +} + +// Exists returns true if this file exists. +func (f *File) Exists() (bool, error) { + exists, headers, err := f.fsc.resourceExists(f.buildPath(), resourceFile) + if exists { + f.updateEtagAndLastModified(headers) + f.updateProperties(headers) + } + return exists, err +} + +// FetchAttributes updates metadata and properties for this file. +func (f *File) FetchAttributes() error { + headers, err := f.fsc.getResourceHeaders(f.buildPath(), compNone, resourceFile, http.MethodHead) + if err != nil { + return err + } + + f.updateEtagAndLastModified(headers) + f.updateProperties(headers) + f.Metadata = getMetadataFromHeaders(headers) + return nil +} + +// returns true if the range is larger than 4MB +func isRangeTooBig(fileRange FileRange) bool { + if fileRange.End-fileRange.Start > fourMB { + return true + } + + return false +} + +// ListRanges returns the list of valid ranges for this file. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx +func (f *File) ListRanges(listRange *FileRange) (*FileRanges, error) { + params := url.Values{"comp": {"rangelist"}} + + // add optional range to list + var headers map[string]string + if listRange != nil { + headers = make(map[string]string) + headers["Range"] = listRange.String() + } + + resp, err := f.fsc.listContent(f.buildPath(), params, headers) + if err != nil { + return nil, err + } + + defer resp.body.Close() + var cl uint64 + cl, err = strconv.ParseUint(resp.headers.Get("x-ms-content-length"), 10, 64) + if err != nil { + return nil, err + } + + var out FileRanges + out.ContentLength = cl + out.ETag = resp.headers.Get("ETag") + out.LastModified = resp.headers.Get("Last-Modified") + + err = xmlUnmarshal(resp.body, &out) + return &out, err +} + +// modifies a range of bytes in this file +func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, contentMD5 *string) (http.Header, error) { + if err := f.fsc.checkForStorageEmulator(); err != nil { + return nil, err + } + if fileRange.End < fileRange.Start { + return nil, errors.New("the value for rangeEnd must be greater than or equal to rangeStart") + } + if bytes != nil && isRangeTooBig(fileRange) { + return nil, errors.New("range cannot exceed 4MB in size") + } + + uri := f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), url.Values{"comp": {"range"}}) + + // default to clear + write := "clear" + cl := uint64(0) + + // if bytes is not nil then this is an update operation + if bytes != nil { + write = "update" + cl = (fileRange.End - fileRange.Start) + 1 + } + + extraHeaders := map[string]string{ + "Content-Length": strconv.FormatUint(cl, 10), + "Range": fileRange.String(), + "x-ms-write": write, + } + + if contentMD5 != nil { + extraHeaders["Content-MD5"] = *contentMD5 + } + + headers := mergeHeaders(f.fsc.client.getStandardHeaders(), extraHeaders) + resp, err := f.fsc.client.exec(http.MethodPut, uri, headers, bytes, f.fsc.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// SetMetadata replaces the metadata for this file. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetFileMetadata. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn689097.aspx +func (f *File) SetMetadata() error { + headers, err := f.fsc.setResourceHeaders(f.buildPath(), compMetadata, resourceFile, mergeMDIntoExtraHeaders(f.Metadata, nil)) + if err != nil { + return err + } + + f.updateEtagAndLastModified(headers) + return nil +} + +// SetProperties sets system properties on this file. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by SetFileProperties. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn166975.aspx +func (f *File) SetProperties() error { + headers, err := f.fsc.setResourceHeaders(f.buildPath(), compProperties, resourceFile, headersFromStruct(f.Properties)) + if err != nil { + return err + } + + f.updateEtagAndLastModified(headers) + return nil +} + +// updates Etag and last modified date +func (f *File) updateEtagAndLastModified(headers http.Header) { + f.Properties.Etag = headers.Get("Etag") + f.Properties.LastModified = headers.Get("Last-Modified") +} + +// updates file properties from the specified HTTP header +func (f *File) updateProperties(header http.Header) { + size, err := strconv.ParseUint(header.Get("Content-Length"), 10, 64) + if err == nil { + f.Properties.Length = size + } + + f.updateEtagAndLastModified(header) + f.Properties.CacheControl = header.Get("Cache-Control") + f.Properties.Disposition = header.Get("Content-Disposition") + f.Properties.Encoding = header.Get("Content-Encoding") + f.Properties.Language = header.Get("Content-Language") + f.Properties.MD5 = header.Get("Content-MD5") + f.Properties.Type = header.Get("Content-Type") +} + +// URL gets the canonical URL to this file. +// This method does not create a publicly accessible URL if the file +// is private and this method does not check if the file exists. +func (f *File) URL() string { + return f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), url.Values{}) +} + +// WriteRange writes a range of bytes to this file with an optional MD5 hash of the content. +// Note that the length of bytes must match (rangeEnd - rangeStart) + 1 with a maximum size of 4MB. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn194276.aspx +func (f *File) WriteRange(bytes io.Reader, fileRange FileRange, contentMD5 *string) error { + if bytes == nil { + return errors.New("bytes cannot be nil") + } + + headers, err := f.modifyRange(bytes, fileRange, contentMD5) + if err != nil { + return err + } + + f.updateEtagAndLastModified(headers) + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go new file mode 100644 index 000000000..81e094f00 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/fileserviceclient.go @@ -0,0 +1,360 @@ +package storage + +import ( + "encoding/xml" + "fmt" + "net/http" + "net/url" + "strings" +) + +// FileServiceClient contains operations for Microsoft Azure File Service. +type FileServiceClient struct { + client Client + auth authentication +} + +// ListSharesParameters defines the set of customizable parameters to make a +// List Shares call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx +type ListSharesParameters struct { + Prefix string + Marker string + Include string + MaxResults uint + Timeout uint +} + +// ShareListResponse contains the response fields from +// ListShares call. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx +type ShareListResponse struct { + XMLName xml.Name `xml:"EnumerationResults"` + Xmlns string `xml:"xmlns,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + NextMarker string `xml:"NextMarker"` + MaxResults int64 `xml:"MaxResults"` + Shares []Share `xml:"Shares>Share"` +} + +type compType string + +const ( + compNone compType = "" + compList compType = "list" + compMetadata compType = "metadata" + compProperties compType = "properties" + compRangeList compType = "rangelist" +) + +func (ct compType) String() string { + return string(ct) +} + +type resourceType string + +const ( + resourceDirectory resourceType = "directory" + resourceFile resourceType = "" + resourceShare resourceType = "share" +) + +func (rt resourceType) String() string { + return string(rt) +} + +func (p ListSharesParameters) getParameters() url.Values { + out := url.Values{} + + if p.Prefix != "" { + out.Set("prefix", p.Prefix) + } + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.Include != "" { + out.Set("include", p.Include) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +func (p ListDirsAndFilesParameters) getParameters() url.Values { + out := url.Values{} + + if p.Marker != "" { + out.Set("marker", p.Marker) + } + if p.MaxResults != 0 { + out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) + } + if p.Timeout != 0 { + out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) + } + + return out +} + +// returns url.Values for the specified types +func getURLInitValues(comp compType, res resourceType) url.Values { + values := url.Values{} + if comp != compNone { + values.Set("comp", comp.String()) + } + if res != resourceFile { + values.Set("restype", res.String()) + } + return values +} + +// GetShareReference returns a Share object for the specified share name. +func (f FileServiceClient) GetShareReference(name string) Share { + return Share{ + fsc: &f, + Name: name, + Properties: ShareProperties{ + Quota: -1, + }, + } +} + +// ListShares returns the list of shares in a storage account along with +// pagination token and other response details. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx +func (f FileServiceClient) ListShares(params ListSharesParameters) (*ShareListResponse, error) { + q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}}) + + var out ShareListResponse + resp, err := f.listContent("", q, nil) + if err != nil { + return nil, err + } + defer resp.body.Close() + err = xmlUnmarshal(resp.body, &out) + + // assign our client to the newly created Share objects + for i := range out.Shares { + out.Shares[i].fsc = &f + } + return &out, err +} + +// retrieves directory or share content +func (f FileServiceClient) listContent(path string, params url.Values, extraHeaders map[string]string) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + + uri := f.client.getEndpoint(fileServiceName, path, params) + extraHeaders = f.client.protectUserAgent(extraHeaders) + headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) + + resp, err := f.client.exec(http.MethodGet, uri, headers, nil, f.auth) + if err != nil { + return nil, err + } + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + resp.body.Close() + return nil, err + } + + return resp, nil +} + +// returns true if the specified resource exists +func (f FileServiceClient) resourceExists(path string, res resourceType) (bool, http.Header, error) { + if err := f.checkForStorageEmulator(); err != nil { + return false, nil, err + } + + uri := f.client.getEndpoint(fileServiceName, path, getURLInitValues(compNone, res)) + headers := f.client.getStandardHeaders() + + resp, err := f.client.exec(http.MethodHead, uri, headers, nil, f.auth) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusOK, resp.headers, nil + } + } + return false, nil, err +} + +// creates a resource depending on the specified resource type +func (f FileServiceClient) createResource(path string, res resourceType, extraHeaders map[string]string) (http.Header, error) { + resp, err := f.createResourceNoClose(path, res, extraHeaders) + if err != nil { + return nil, err + } + defer resp.body.Close() + return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// creates a resource depending on the specified resource type, doesn't close the response body +func (f FileServiceClient) createResourceNoClose(path string, res resourceType, extraHeaders map[string]string) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + + values := getURLInitValues(compNone, res) + uri := f.client.getEndpoint(fileServiceName, path, values) + extraHeaders = f.client.protectUserAgent(extraHeaders) + headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) + + return f.client.exec(http.MethodPut, uri, headers, nil, f.auth) +} + +// returns HTTP header data for the specified directory or share +func (f FileServiceClient) getResourceHeaders(path string, comp compType, res resourceType, verb string) (http.Header, error) { + resp, err := f.getResourceNoClose(path, comp, res, verb, nil) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + return resp.headers, nil +} + +// gets the specified resource, doesn't close the response body +func (f FileServiceClient) getResourceNoClose(path string, comp compType, res resourceType, verb string, extraHeaders map[string]string) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + + params := getURLInitValues(comp, res) + uri := f.client.getEndpoint(fileServiceName, path, params) + extraHeaders = f.client.protectUserAgent(extraHeaders) + headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) + + return f.client.exec(verb, uri, headers, nil, f.auth) +} + +// deletes the resource and returns the response +func (f FileServiceClient) deleteResource(path string, res resourceType) error { + resp, err := f.deleteResourceNoClose(path, res) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) +} + +// deletes the resource and returns the response, doesn't close the response body +func (f FileServiceClient) deleteResourceNoClose(path string, res resourceType) (*storageResponse, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + + values := getURLInitValues(compNone, res) + uri := f.client.getEndpoint(fileServiceName, path, values) + return f.client.exec(http.MethodDelete, uri, f.client.getStandardHeaders(), nil, f.auth) +} + +// merges metadata into extraHeaders and returns extraHeaders +func mergeMDIntoExtraHeaders(metadata, extraHeaders map[string]string) map[string]string { + if metadata == nil && extraHeaders == nil { + return nil + } + if extraHeaders == nil { + extraHeaders = make(map[string]string) + } + for k, v := range metadata { + extraHeaders[userDefinedMetadataHeaderPrefix+k] = v + } + return extraHeaders +} + +// merges extraHeaders into headers and returns headers +func mergeHeaders(headers, extraHeaders map[string]string) map[string]string { + for k, v := range extraHeaders { + headers[k] = v + } + return headers +} + +// sets extra header data for the specified resource +func (f FileServiceClient) setResourceHeaders(path string, comp compType, res resourceType, extraHeaders map[string]string) (http.Header, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + + params := getURLInitValues(comp, res) + uri := f.client.getEndpoint(fileServiceName, path, params) + extraHeaders = f.client.protectUserAgent(extraHeaders) + headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) + + resp, err := f.client.exec(http.MethodPut, uri, headers, nil, f.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// gets metadata for the specified resource +func (f FileServiceClient) getMetadata(path string, res resourceType) (map[string]string, error) { + if err := f.checkForStorageEmulator(); err != nil { + return nil, err + } + + headers, err := f.getResourceHeaders(path, compMetadata, res, http.MethodGet) + if err != nil { + return nil, err + } + + return getMetadataFromHeaders(headers), nil +} + +// returns a map of custom metadata values from the specified HTTP header +func getMetadataFromHeaders(header http.Header) map[string]string { + metadata := make(map[string]string) + for k, v := range header { + // Can't trust CanonicalHeaderKey() to munge case + // reliably. "_" is allowed in identifiers: + // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx + // https://msdn.microsoft.com/library/aa664670(VS.71).aspx + // http://tools.ietf.org/html/rfc7230#section-3.2 + // ...but "_" is considered invalid by + // CanonicalMIMEHeaderKey in + // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 + // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". + k = strings.ToLower(k) + if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { + continue + } + // metadata["foo"] = content of the last X-Ms-Meta-Foo header + k = k[len(userDefinedMetadataHeaderPrefix):] + metadata[k] = v[len(v)-1] + } + + if len(metadata) == 0 { + return nil + } + + return metadata +} + +//checkForStorageEmulator determines if the client is setup for use with +//Azure Storage Emulator, and returns a relevant error +func (f FileServiceClient) checkForStorageEmulator() error { + if f.client.accountName == StorageEmulatorAccountName { + return fmt.Errorf("Error: File service is not currently supported by Azure Storage Emulator") + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go new file mode 100644 index 000000000..4dbb67733 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/queue.go @@ -0,0 +1,346 @@ +package storage + +import ( + "encoding/xml" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" +) + +const ( + // casing is per Golang's http.Header canonicalizing the header names. + approximateMessagesCountHeader = "X-Ms-Approximate-Messages-Count" + userDefinedMetadataHeaderPrefix = "X-Ms-Meta-" +) + +// QueueServiceClient contains operations for Microsoft Azure Queue Storage +// Service. +type QueueServiceClient struct { + client Client + auth authentication +} + +func pathForQueue(queue string) string { return fmt.Sprintf("/%s", queue) } +func pathForQueueMessages(queue string) string { return fmt.Sprintf("/%s/messages", queue) } +func pathForMessage(queue, name string) string { return fmt.Sprintf("/%s/messages/%s", queue, name) } + +type putMessageRequest struct { + XMLName xml.Name `xml:"QueueMessage"` + MessageText string `xml:"MessageText"` +} + +// PutMessageParameters is the set of options can be specified for Put Messsage +// operation. A zero struct does not use any preferences for the request. +type PutMessageParameters struct { + VisibilityTimeout int + MessageTTL int +} + +func (p PutMessageParameters) getParameters() url.Values { + out := url.Values{} + if p.VisibilityTimeout != 0 { + out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) + } + if p.MessageTTL != 0 { + out.Set("messagettl", strconv.Itoa(p.MessageTTL)) + } + return out +} + +// GetMessagesParameters is the set of options can be specified for Get +// Messsages operation. A zero struct does not use any preferences for the +// request. +type GetMessagesParameters struct { + NumOfMessages int + VisibilityTimeout int +} + +func (p GetMessagesParameters) getParameters() url.Values { + out := url.Values{} + if p.NumOfMessages != 0 { + out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) + } + if p.VisibilityTimeout != 0 { + out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) + } + return out +} + +// PeekMessagesParameters is the set of options can be specified for Peek +// Messsage operation. A zero struct does not use any preferences for the +// request. +type PeekMessagesParameters struct { + NumOfMessages int +} + +func (p PeekMessagesParameters) getParameters() url.Values { + out := url.Values{"peekonly": {"true"}} // Required for peek operation + if p.NumOfMessages != 0 { + out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) + } + return out +} + +// UpdateMessageParameters is the set of options can be specified for Update Messsage +// operation. A zero struct does not use any preferences for the request. +type UpdateMessageParameters struct { + PopReceipt string + VisibilityTimeout int +} + +func (p UpdateMessageParameters) getParameters() url.Values { + out := url.Values{} + if p.PopReceipt != "" { + out.Set("popreceipt", p.PopReceipt) + } + if p.VisibilityTimeout != 0 { + out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) + } + return out +} + +// GetMessagesResponse represents a response returned from Get Messages +// operation. +type GetMessagesResponse struct { + XMLName xml.Name `xml:"QueueMessagesList"` + QueueMessagesList []GetMessageResponse `xml:"QueueMessage"` +} + +// GetMessageResponse represents a QueueMessage object returned from Get +// Messages operation response. +type GetMessageResponse struct { + MessageID string `xml:"MessageId"` + InsertionTime string `xml:"InsertionTime"` + ExpirationTime string `xml:"ExpirationTime"` + PopReceipt string `xml:"PopReceipt"` + TimeNextVisible string `xml:"TimeNextVisible"` + DequeueCount int `xml:"DequeueCount"` + MessageText string `xml:"MessageText"` +} + +// PeekMessagesResponse represents a response returned from Get Messages +// operation. +type PeekMessagesResponse struct { + XMLName xml.Name `xml:"QueueMessagesList"` + QueueMessagesList []PeekMessageResponse `xml:"QueueMessage"` +} + +// PeekMessageResponse represents a QueueMessage object returned from Peek +// Messages operation response. +type PeekMessageResponse struct { + MessageID string `xml:"MessageId"` + InsertionTime string `xml:"InsertionTime"` + ExpirationTime string `xml:"ExpirationTime"` + DequeueCount int `xml:"DequeueCount"` + MessageText string `xml:"MessageText"` +} + +// QueueMetadataResponse represents user defined metadata and queue +// properties on a specific queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx +type QueueMetadataResponse struct { + ApproximateMessageCount int + UserDefinedMetadata map[string]string +} + +// SetMetadata operation sets user-defined metadata on the specified queue. +// Metadata is associated with the queue as name-value pairs. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179348.aspx +func (c QueueServiceClient) SetMetadata(name string, metadata map[string]string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) + metadata = c.client.protectUserAgent(metadata) + headers := c.client.getStandardHeaders() + for k, v := range metadata { + headers[userDefinedMetadataHeaderPrefix+k] = v + } + + resp, err := c.client.exec(http.MethodPut, uri, headers, nil, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// GetMetadata operation retrieves user-defined metadata and queue +// properties on the specified queue. Metadata is associated with +// the queue as name-values pairs. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx +// +// Because the way Golang's http client (and http.Header in particular) +// canonicalize header names, the returned metadata names would always +// be all lower case. +func (c QueueServiceClient) GetMetadata(name string) (QueueMetadataResponse, error) { + qm := QueueMetadataResponse{} + qm.UserDefinedMetadata = make(map[string]string) + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) + headers := c.client.getStandardHeaders() + resp, err := c.client.exec(http.MethodGet, uri, headers, nil, c.auth) + if err != nil { + return qm, err + } + defer resp.body.Close() + + for k, v := range resp.headers { + if len(v) != 1 { + return qm, fmt.Errorf("Unexpected number of values (%d) in response header '%s'", len(v), k) + } + + value := v[0] + + if k == approximateMessagesCountHeader { + qm.ApproximateMessageCount, err = strconv.Atoi(value) + if err != nil { + return qm, fmt.Errorf("Unexpected value in response header '%s': '%s' ", k, value) + } + } else if strings.HasPrefix(k, userDefinedMetadataHeaderPrefix) { + name := strings.TrimPrefix(k, userDefinedMetadataHeaderPrefix) + qm.UserDefinedMetadata[strings.ToLower(name)] = value + } + } + + return qm, checkRespCode(resp.statusCode, []int{http.StatusOK}) +} + +// CreateQueue operation creates a queue under the given account. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179342.aspx +func (c QueueServiceClient) CreateQueue(name string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) + headers := c.client.getStandardHeaders() + resp, err := c.client.exec(http.MethodPut, uri, headers, nil, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// DeleteQueue operation permanently deletes the specified queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179436.aspx +func (c QueueServiceClient) DeleteQueue(name string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) + resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// QueueExists returns true if a queue with given name exists. +func (c QueueServiceClient) QueueExists(name string) (bool, error) { + uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": {"metadata"}}) + resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) + if resp != nil && (resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound) { + return resp.statusCode == http.StatusOK, nil + } + + return false, err +} + +// PutMessage operation adds a new message to the back of the message queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179346.aspx +func (c QueueServiceClient) PutMessage(queue string, message string, params PutMessageParameters) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) + req := putMessageRequest{MessageText: message} + body, nn, err := xmlMarshal(req) + if err != nil { + return err + } + headers := c.client.getStandardHeaders() + headers["Content-Length"] = strconv.Itoa(nn) + resp, err := c.client.exec(http.MethodPost, uri, headers, body, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusCreated}) +} + +// ClearMessages operation deletes all messages from the specified queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179454.aspx +func (c QueueServiceClient) ClearMessages(queue string) error { + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), url.Values{}) + resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// GetMessages operation retrieves one or more messages from the front of the +// queue. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179474.aspx +func (c QueueServiceClient) GetMessages(queue string, params GetMessagesParameters) (GetMessagesResponse, error) { + var r GetMessagesResponse + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) + resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) + if err != nil { + return r, err + } + defer resp.body.Close() + err = xmlUnmarshal(resp.body, &r) + return r, err +} + +// PeekMessages retrieves one or more messages from the front of the queue, but +// does not alter the visibility of the message. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179472.aspx +func (c QueueServiceClient) PeekMessages(queue string, params PeekMessagesParameters) (PeekMessagesResponse, error) { + var r PeekMessagesResponse + uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) + resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) + if err != nil { + return r, err + } + defer resp.body.Close() + err = xmlUnmarshal(resp.body, &r) + return r, err +} + +// DeleteMessage operation deletes the specified message. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179347.aspx +func (c QueueServiceClient) DeleteMessage(queue, messageID, popReceipt string) error { + uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), url.Values{ + "popreceipt": {popReceipt}}) + resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} + +// UpdateMessage operation deletes the specified message. +// +// See https://msdn.microsoft.com/en-us/library/azure/hh452234.aspx +func (c QueueServiceClient) UpdateMessage(queue string, messageID string, message string, params UpdateMessageParameters) error { + uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), params.getParameters()) + req := putMessageRequest{MessageText: message} + body, nn, err := xmlMarshal(req) + if err != nil { + return err + } + headers := c.client.getStandardHeaders() + headers["Content-Length"] = fmt.Sprintf("%d", nn) + resp, err := c.client.exec(http.MethodPut, uri, headers, body, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/share.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/share.go new file mode 100644 index 000000000..8423aedcc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/share.go @@ -0,0 +1,186 @@ +package storage + +import ( + "fmt" + "net/http" + "net/url" + "strconv" +) + +// Share represents an Azure file share. +type Share struct { + fsc *FileServiceClient + Name string `xml:"Name"` + Properties ShareProperties `xml:"Properties"` + Metadata map[string]string +} + +// ShareProperties contains various properties of a share. +type ShareProperties struct { + LastModified string `xml:"Last-Modified"` + Etag string `xml:"Etag"` + Quota int `xml:"Quota"` +} + +// builds the complete path for this share object. +func (s *Share) buildPath() string { + return fmt.Sprintf("/%s", s.Name) +} + +// Create this share under the associated account. +// If a share with the same name already exists, the operation fails. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx +func (s *Share) Create() error { + headers, err := s.fsc.createResource(s.buildPath(), resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil)) + if err != nil { + return err + } + + s.updateEtagAndLastModified(headers) + return nil +} + +// CreateIfNotExists creates this share under the associated account if +// it does not exist. Returns true if the share is newly created or false if +// the share already exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx +func (s *Share) CreateIfNotExists() (bool, error) { + resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, nil) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { + if resp.statusCode == http.StatusCreated { + s.updateEtagAndLastModified(resp.headers) + return true, nil + } + return false, s.FetchAttributes() + } + } + + return false, err +} + +// Delete marks this share for deletion. The share along with any files +// and directories contained within it are later deleted during garbage +// collection. If the share does not exist the operation fails +// +// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx +func (s *Share) Delete() error { + return s.fsc.deleteResource(s.buildPath(), resourceShare) +} + +// DeleteIfExists operation marks this share for deletion if it exists. +// +// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx +func (s *Share) DeleteIfExists() (bool, error) { + resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare) + if resp != nil { + defer resp.body.Close() + if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { + return resp.statusCode == http.StatusAccepted, nil + } + } + return false, err +} + +// Exists returns true if this share already exists +// on the storage account, otherwise returns false. +func (s *Share) Exists() (bool, error) { + exists, headers, err := s.fsc.resourceExists(s.buildPath(), resourceShare) + if exists { + s.updateEtagAndLastModified(headers) + s.updateQuota(headers) + } + return exists, err +} + +// FetchAttributes retrieves metadata and properties for this share. +func (s *Share) FetchAttributes() error { + headers, err := s.fsc.getResourceHeaders(s.buildPath(), compNone, resourceShare, http.MethodHead) + if err != nil { + return err + } + + s.updateEtagAndLastModified(headers) + s.updateQuota(headers) + s.Metadata = getMetadataFromHeaders(headers) + + return nil +} + +// GetRootDirectoryReference returns a Directory object at the root of this share. +func (s *Share) GetRootDirectoryReference() *Directory { + return &Directory{ + fsc: s.fsc, + share: s, + } +} + +// ServiceClient returns the FileServiceClient associated with this share. +func (s *Share) ServiceClient() *FileServiceClient { + return s.fsc +} + +// SetMetadata replaces the metadata for this share. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by GetShareMetadata. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx +func (s *Share) SetMetadata() error { + headers, err := s.fsc.setResourceHeaders(s.buildPath(), compMetadata, resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil)) + if err != nil { + return err + } + + s.updateEtagAndLastModified(headers) + return nil +} + +// SetProperties sets system properties for this share. +// +// Some keys may be converted to Camel-Case before sending. All keys +// are returned in lower case by SetShareProperties. HTTP header names +// are case-insensitive so case munging should not matter to other +// applications either. +// +// See https://msdn.microsoft.com/en-us/library/azure/mt427368.aspx +func (s *Share) SetProperties() error { + if s.Properties.Quota < 1 || s.Properties.Quota > 5120 { + return fmt.Errorf("invalid value %v for quota, valid values are [1, 5120]", s.Properties.Quota) + } + + headers, err := s.fsc.setResourceHeaders(s.buildPath(), compProperties, resourceShare, map[string]string{ + "x-ms-share-quota": strconv.Itoa(s.Properties.Quota), + }) + if err != nil { + return err + } + + s.updateEtagAndLastModified(headers) + return nil +} + +// updates Etag and last modified date +func (s *Share) updateEtagAndLastModified(headers http.Header) { + s.Properties.Etag = headers.Get("Etag") + s.Properties.LastModified = headers.Get("Last-Modified") +} + +// updates quota value +func (s *Share) updateQuota(headers http.Header) { + quota, err := strconv.Atoi(headers.Get("x-ms-share-quota")) + if err == nil { + s.Properties.Quota = quota + } +} + +// URL gets the canonical URL to this share. This method does not create a publicly accessible +// URL if the share is private and this method does not check if the share exists. +func (s *Share) URL() string { + return s.fsc.client.getEndpoint(fileServiceName, s.buildPath(), url.Values{}) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/storagepolicy.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/storagepolicy.go new file mode 100644 index 000000000..bee1c31ad --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/storagepolicy.go @@ -0,0 +1,47 @@ +package storage + +import ( + "strings" + "time" +) + +// AccessPolicyDetailsXML has specifics about an access policy +// annotated with XML details. +type AccessPolicyDetailsXML struct { + StartTime time.Time `xml:"Start"` + ExpiryTime time.Time `xml:"Expiry"` + Permission string `xml:"Permission"` +} + +// SignedIdentifier is a wrapper for a specific policy +type SignedIdentifier struct { + ID string `xml:"Id"` + AccessPolicy AccessPolicyDetailsXML `xml:"AccessPolicy"` +} + +// SignedIdentifiers part of the response from GetPermissions call. +type SignedIdentifiers struct { + SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` +} + +// AccessPolicy is the response type from the GetPermissions call. +type AccessPolicy struct { + SignedIdentifiersList SignedIdentifiers `xml:"SignedIdentifiers"` +} + +// convertAccessPolicyToXMLStructs converts between AccessPolicyDetails which is a struct better for API usage to the +// AccessPolicy struct which will get converted to XML. +func convertAccessPolicyToXMLStructs(id string, startTime time.Time, expiryTime time.Time, permissions string) SignedIdentifier { + return SignedIdentifier{ + ID: id, + AccessPolicy: AccessPolicyDetailsXML{ + StartTime: startTime.UTC().Round(time.Second), + ExpiryTime: expiryTime.UTC().Round(time.Second), + Permission: permissions, + }, + } +} + +func updatePermissions(permissions, permission string) bool { + return strings.Contains(permissions, permission) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go new file mode 100644 index 000000000..5cbc13ff1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/table.go @@ -0,0 +1,258 @@ +package storage + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "time" +) + +// TableServiceClient contains operations for Microsoft Azure Table Storage +// Service. +type TableServiceClient struct { + client Client + auth authentication +} + +// AzureTable is the typedef of the Azure Table name +type AzureTable string + +const ( + tablesURIPath = "/Tables" +) + +type createTableRequest struct { + TableName string `json:"TableName"` +} + +// TableAccessPolicy are used for SETTING table policies +type TableAccessPolicy struct { + ID string + StartTime time.Time + ExpiryTime time.Time + CanRead bool + CanAppend bool + CanUpdate bool + CanDelete bool +} + +func pathForTable(table AzureTable) string { return fmt.Sprintf("%s", table) } + +func (c *TableServiceClient) getStandardHeaders() map[string]string { + return map[string]string{ + "x-ms-version": "2015-02-21", + "x-ms-date": currentTimeRfc1123Formatted(), + "Accept": "application/json;odata=nometadata", + "Accept-Charset": "UTF-8", + "Content-Type": "application/json", + userAgentHeader: c.client.userAgent, + } +} + +// QueryTables returns the tables created in the +// *TableServiceClient storage account. +func (c *TableServiceClient) QueryTables() ([]AzureTable, error) { + uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) + + headers := c.getStandardHeaders() + headers["Content-Length"] = "0" + + resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + buf := new(bytes.Buffer) + if _, err := buf.ReadFrom(resp.body); err != nil { + return nil, err + } + + var respArray queryTablesResponse + if err := json.Unmarshal(buf.Bytes(), &respArray); err != nil { + return nil, err + } + + s := make([]AzureTable, len(respArray.TableName)) + for i, elem := range respArray.TableName { + s[i] = AzureTable(elem.TableName) + } + + return s, nil +} + +// CreateTable creates the table given the specific +// name. This function fails if the name is not compliant +// with the specification or the tables already exists. +func (c *TableServiceClient) CreateTable(table AzureTable) error { + uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) + + headers := c.getStandardHeaders() + + req := createTableRequest{TableName: string(table)} + buf := new(bytes.Buffer) + + if err := json.NewEncoder(buf).Encode(req); err != nil { + return err + } + + headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) + + resp, err := c.client.execInternalJSON(http.MethodPost, uri, headers, buf, c.auth) + + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { + return err + } + + return nil +} + +// DeleteTable deletes the table given the specific +// name. This function fails if the table is not present. +// Be advised: DeleteTable deletes all the entries +// that may be present. +func (c *TableServiceClient) DeleteTable(table AzureTable) error { + uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) + uri += fmt.Sprintf("('%s')", string(table)) + + headers := c.getStandardHeaders() + + headers["Content-Length"] = "0" + + resp, err := c.client.execInternalJSON(http.MethodDelete, uri, headers, nil, c.auth) + + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + + } + return nil +} + +// SetTablePermissions sets up table ACL permissions as per REST details https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Table-ACL +func (c *TableServiceClient) SetTablePermissions(table AzureTable, policies []TableAccessPolicy, timeout uint) (err error) { + params := url.Values{"comp": {"acl"}} + + if timeout > 0 { + params.Add("timeout", fmt.Sprint(timeout)) + } + + uri := c.client.getEndpoint(tableServiceName, string(table), params) + headers := c.client.getStandardHeaders() + + body, length, err := generateTableACLPayload(policies) + if err != nil { + return err + } + headers["Content-Length"] = fmt.Sprintf("%v", length) + + resp, err := c.client.execInternalJSON(http.MethodPut, uri, headers, body, c.auth) + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + return nil +} + +func generateTableACLPayload(policies []TableAccessPolicy) (io.Reader, int, error) { + sil := SignedIdentifiers{ + SignedIdentifiers: []SignedIdentifier{}, + } + for _, tap := range policies { + permission := generateTablePermissions(&tap) + signedIdentifier := convertAccessPolicyToXMLStructs(tap.ID, tap.StartTime, tap.ExpiryTime, permission) + sil.SignedIdentifiers = append(sil.SignedIdentifiers, signedIdentifier) + } + return xmlMarshal(sil) +} + +// GetTablePermissions gets the table ACL permissions, as per REST details https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-acl +func (c *TableServiceClient) GetTablePermissions(table AzureTable, timeout int) (permissionResponse []TableAccessPolicy, err error) { + params := url.Values{"comp": {"acl"}} + + if timeout > 0 { + params.Add("timeout", strconv.Itoa(timeout)) + } + + uri := c.client.getEndpoint(tableServiceName, string(table), params) + headers := c.client.getStandardHeaders() + resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) + if err != nil { + return nil, err + } + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, err + } + + var ap AccessPolicy + err = xmlUnmarshal(resp.body, &ap.SignedIdentifiersList) + if err != nil { + return nil, err + } + out := updateTableAccessPolicy(ap) + return out, nil +} + +func updateTableAccessPolicy(ap AccessPolicy) []TableAccessPolicy { + out := []TableAccessPolicy{} + for _, policy := range ap.SignedIdentifiersList.SignedIdentifiers { + tap := TableAccessPolicy{ + ID: policy.ID, + StartTime: policy.AccessPolicy.StartTime, + ExpiryTime: policy.AccessPolicy.ExpiryTime, + } + tap.CanRead = updatePermissions(policy.AccessPolicy.Permission, "r") + tap.CanAppend = updatePermissions(policy.AccessPolicy.Permission, "a") + tap.CanUpdate = updatePermissions(policy.AccessPolicy.Permission, "u") + tap.CanDelete = updatePermissions(policy.AccessPolicy.Permission, "d") + + out = append(out, tap) + } + return out +} + +func generateTablePermissions(tap *TableAccessPolicy) (permissions string) { + // generate the permissions string (raud). + // still want the end user API to have bool flags. + permissions = "" + + if tap.CanRead { + permissions += "r" + } + + if tap.CanAppend { + permissions += "a" + } + + if tap.CanUpdate { + permissions += "u" + } + + if tap.CanDelete { + permissions += "d" + } + return permissions +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go new file mode 100644 index 000000000..1758d9f3e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/table_entities.go @@ -0,0 +1,345 @@ +package storage + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "reflect" +) + +// Annotating as secure for gas scanning +/* #nosec */ +const ( + partitionKeyNode = "PartitionKey" + rowKeyNode = "RowKey" + tag = "table" + tagIgnore = "-" + continuationTokenPartitionKeyHeader = "X-Ms-Continuation-Nextpartitionkey" + continuationTokenRowHeader = "X-Ms-Continuation-Nextrowkey" + maxTopParameter = 1000 +) + +type queryTablesResponse struct { + TableName []struct { + TableName string `json:"TableName"` + } `json:"value"` +} + +const ( + tableOperationTypeInsert = iota + tableOperationTypeUpdate = iota + tableOperationTypeMerge = iota + tableOperationTypeInsertOrReplace = iota + tableOperationTypeInsertOrMerge = iota +) + +type tableOperation int + +// TableEntity interface specifies +// the functions needed to support +// marshaling and unmarshaling into +// Azure Tables. The struct must only contain +// simple types because Azure Tables do not +// support hierarchy. +type TableEntity interface { + PartitionKey() string + RowKey() string + SetPartitionKey(string) error + SetRowKey(string) error +} + +// ContinuationToken is an opaque (ie not useful to inspect) +// struct that Get... methods can return if there are more +// entries to be returned than the ones already +// returned. Just pass it to the same function to continue +// receiving the remaining entries. +type ContinuationToken struct { + NextPartitionKey string + NextRowKey string +} + +type getTableEntriesResponse struct { + Elements []map[string]interface{} `json:"value"` +} + +// QueryTableEntities queries the specified table and returns the unmarshaled +// entities of type retType. +// top parameter limits the returned entries up to top. Maximum top +// allowed by Azure API is 1000. In case there are more than top entries to be +// returned the function will return a non nil *ContinuationToken. You can call the +// same function again passing the received ContinuationToken as previousContToken +// parameter in order to get the following entries. The query parameter +// is the odata query. To retrieve all the entries pass the empty string. +// The function returns a pointer to a TableEntity slice, the *ContinuationToken +// if there are more entries to be returned and an error in case something went +// wrong. +// +// Example: +// entities, cToken, err = tSvc.QueryTableEntities("table", cToken, reflect.TypeOf(entity), 20, "") +func (c *TableServiceClient) QueryTableEntities(tableName AzureTable, previousContToken *ContinuationToken, retType reflect.Type, top int, query string) ([]TableEntity, *ContinuationToken, error) { + if top > maxTopParameter { + return nil, nil, fmt.Errorf("top accepts at maximum %d elements. Requested %d instead", maxTopParameter, top) + } + + uri := c.client.getEndpoint(tableServiceName, pathForTable(tableName), url.Values{}) + uri += fmt.Sprintf("?$top=%d", top) + if query != "" { + uri += fmt.Sprintf("&$filter=%s", url.QueryEscape(query)) + } + + if previousContToken != nil { + uri += fmt.Sprintf("&NextPartitionKey=%s&NextRowKey=%s", previousContToken.NextPartitionKey, previousContToken.NextRowKey) + } + + headers := c.getStandardHeaders() + + headers["Content-Length"] = "0" + + resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) + + if err != nil { + return nil, nil, err + } + + contToken := extractContinuationTokenFromHeaders(resp.headers) + + defer resp.body.Close() + + if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { + return nil, contToken, err + } + + retEntries, err := deserializeEntity(retType, resp.body) + if err != nil { + return nil, contToken, err + } + + return retEntries, contToken, nil +} + +// InsertEntity inserts an entity in the specified table. +// The function fails if there is an entity with the same +// PartitionKey and RowKey in the table. +func (c *TableServiceClient) InsertEntity(table AzureTable, entity TableEntity) error { + if sc, err := c.execTable(table, entity, false, http.MethodPost); err != nil { + return checkRespCode(sc, []int{http.StatusCreated}) + } + + return nil +} + +func (c *TableServiceClient) execTable(table AzureTable, entity TableEntity, specifyKeysInURL bool, method string) (int, error) { + uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) + if specifyKeysInURL { + uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) + } + + headers := c.getStandardHeaders() + + var buf bytes.Buffer + + if err := injectPartitionAndRowKeys(entity, &buf); err != nil { + return 0, err + } + + headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) + + resp, err := c.client.execInternalJSON(method, uri, headers, &buf, c.auth) + + if err != nil { + return 0, err + } + + defer resp.body.Close() + + return resp.statusCode, nil +} + +// UpdateEntity updates the contents of an entity with the +// one passed as parameter. The function fails if there is no entity +// with the same PartitionKey and RowKey in the table. +func (c *TableServiceClient) UpdateEntity(table AzureTable, entity TableEntity) error { + if sc, err := c.execTable(table, entity, true, http.MethodPut); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return nil +} + +// MergeEntity merges the contents of an entity with the +// one passed as parameter. +// The function fails if there is no entity +// with the same PartitionKey and RowKey in the table. +func (c *TableServiceClient) MergeEntity(table AzureTable, entity TableEntity) error { + if sc, err := c.execTable(table, entity, true, "MERGE"); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return nil +} + +// DeleteEntityWithoutCheck deletes the entity matching by +// PartitionKey and RowKey. There is no check on IfMatch +// parameter so the entity is always deleted. +// The function fails if there is no entity +// with the same PartitionKey and RowKey in the table. +func (c *TableServiceClient) DeleteEntityWithoutCheck(table AzureTable, entity TableEntity) error { + return c.DeleteEntity(table, entity, "*") +} + +// DeleteEntity deletes the entity matching by +// PartitionKey, RowKey and ifMatch field. +// The function fails if there is no entity +// with the same PartitionKey and RowKey in the table or +// the ifMatch is different. +func (c *TableServiceClient) DeleteEntity(table AzureTable, entity TableEntity, ifMatch string) error { + uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) + uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) + + headers := c.getStandardHeaders() + + headers["Content-Length"] = "0" + headers["If-Match"] = ifMatch + + resp, err := c.client.execInternalJSON(http.MethodDelete, uri, headers, nil, c.auth) + + if err != nil { + return err + } + defer resp.body.Close() + + if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { + return err + } + + return nil +} + +// InsertOrReplaceEntity inserts an entity in the specified table +// or replaced the existing one. +func (c *TableServiceClient) InsertOrReplaceEntity(table AzureTable, entity TableEntity) error { + if sc, err := c.execTable(table, entity, true, http.MethodPut); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return nil +} + +// InsertOrMergeEntity inserts an entity in the specified table +// or merges the existing one. +func (c *TableServiceClient) InsertOrMergeEntity(table AzureTable, entity TableEntity) error { + if sc, err := c.execTable(table, entity, true, "MERGE"); err != nil { + return checkRespCode(sc, []int{http.StatusNoContent}) + } + return nil +} + +func injectPartitionAndRowKeys(entity TableEntity, buf *bytes.Buffer) error { + if err := json.NewEncoder(buf).Encode(entity); err != nil { + return err + } + + dec := make(map[string]interface{}) + if err := json.NewDecoder(buf).Decode(&dec); err != nil { + return err + } + + // Inject PartitionKey and RowKey + dec[partitionKeyNode] = entity.PartitionKey() + dec[rowKeyNode] = entity.RowKey() + + // Remove tagged fields + // The tag is defined in the const section + // This is useful to avoid storing the PartitionKey and RowKey twice. + numFields := reflect.ValueOf(entity).Elem().NumField() + for i := 0; i < numFields; i++ { + f := reflect.ValueOf(entity).Elem().Type().Field(i) + + if f.Tag.Get(tag) == tagIgnore { + // we must look for its JSON name in the dictionary + // as the user can rename it using a tag + jsonName := f.Name + if f.Tag.Get("json") != "" { + jsonName = f.Tag.Get("json") + } + delete(dec, jsonName) + } + } + + buf.Reset() + + if err := json.NewEncoder(buf).Encode(&dec); err != nil { + return err + } + + return nil +} + +func deserializeEntity(retType reflect.Type, reader io.Reader) ([]TableEntity, error) { + buf := new(bytes.Buffer) + + var ret getTableEntriesResponse + if err := json.NewDecoder(reader).Decode(&ret); err != nil { + return nil, err + } + + tEntries := make([]TableEntity, len(ret.Elements)) + + for i, entry := range ret.Elements { + + buf.Reset() + if err := json.NewEncoder(buf).Encode(entry); err != nil { + return nil, err + } + + dec := make(map[string]interface{}) + if err := json.NewDecoder(buf).Decode(&dec); err != nil { + return nil, err + } + + var pKey, rKey string + // strip pk and rk + for key, val := range dec { + switch key { + case partitionKeyNode: + pKey = val.(string) + case rowKeyNode: + rKey = val.(string) + } + } + + delete(dec, partitionKeyNode) + delete(dec, rowKeyNode) + + buf.Reset() + if err := json.NewEncoder(buf).Encode(dec); err != nil { + return nil, err + } + + // Create a empty retType instance + tEntries[i] = reflect.New(retType.Elem()).Interface().(TableEntity) + // Popolate it with the values + if err := json.NewDecoder(buf).Decode(&tEntries[i]); err != nil { + return nil, err + } + + // Reset PartitionKey and RowKey + if err := tEntries[i].SetPartitionKey(pKey); err != nil { + return nil, err + } + if err := tEntries[i].SetRowKey(rKey); err != nil { + return nil, err + } + } + + return tEntries, nil +} + +func extractContinuationTokenFromHeaders(h http.Header) *ContinuationToken { + ct := ContinuationToken{h.Get(continuationTokenPartitionKeyHeader), h.Get(continuationTokenRowHeader)} + + if ct.NextPartitionKey != "" && ct.NextRowKey != "" { + return &ct + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go new file mode 100644 index 000000000..57ca1b6d9 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/util.go @@ -0,0 +1,85 @@ +package storage + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "time" +) + +func (c Client) computeHmac256(message string) string { + h := hmac.New(sha256.New, c.accountKey) + h.Write([]byte(message)) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func currentTimeRfc1123Formatted() string { + return timeRfc1123Formatted(time.Now().UTC()) +} + +func timeRfc1123Formatted(t time.Time) string { + return t.Format(http.TimeFormat) +} + +func mergeParams(v1, v2 url.Values) url.Values { + out := url.Values{} + for k, v := range v1 { + out[k] = v + } + for k, v := range v2 { + vals, ok := out[k] + if ok { + vals = append(vals, v...) + out[k] = vals + } else { + out[k] = v + } + } + return out +} + +func prepareBlockListRequest(blocks []Block) string { + s := `` + for _, v := range blocks { + s += fmt.Sprintf("<%s>%s", v.Status, v.ID, v.Status) + } + s += `` + return s +} + +func xmlUnmarshal(body io.Reader, v interface{}) error { + data, err := ioutil.ReadAll(body) + if err != nil { + return err + } + return xml.Unmarshal(data, v) +} + +func xmlMarshal(v interface{}) (io.Reader, int, error) { + b, err := xml.Marshal(v) + if err != nil { + return nil, 0, err + } + return bytes.NewReader(b), len(b), nil +} + +func headersFromStruct(v interface{}) map[string]string { + headers := make(map[string]string) + value := reflect.ValueOf(v) + for i := 0; i < value.NumField(); i++ { + key := value.Type().Field(i).Tag.Get("header") + val := value.Field(i).String() + if key != "" && val != "" { + headers[key] = val + } + } + return headers +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/version.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/version.go new file mode 100644 index 000000000..d52ebfdb2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/version.go @@ -0,0 +1,5 @@ +package storage + +var ( + sdkVersion = "8.0.0-beta" +) diff --git a/vendor/github.com/minio/cli/help.go b/vendor/github.com/minio/cli/help.go index c42f9c9a7..ff35ea110 100644 --- a/vendor/github.com/minio/cli/help.go +++ b/vendor/github.com/minio/cli/help.go @@ -13,69 +13,68 @@ import ( // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var AppHelpTemplate = `NAME: - {{.Name}}{{if .Usage}} - {{.Usage}}{{end}} + {{.Name}}{{if .Usage}} - {{.Usage}}{{end}} USAGE: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} + {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} VERSION: - {{.Version}}{{end}}{{end}}{{if .Description}} + {{.Version}}{{end}}{{end}}{{if .Description}} DESCRIPTION: - {{.Description}}{{end}}{{if len .Authors}} + {{.Description}}{{end}}{{if len .Authors}} AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: - {{range $index, $author := .Authors}}{{if $index}} - {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}} + {{range $index, $author := .Authors}}{{if $index}} + {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}} COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{end}}{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} + {{.Name}}:{{end}}{{range .VisibleCommands}} + {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} -GLOBAL OPTIONS: - {{range $index, $option := .VisibleFlags}}{{if $index}} - {{end}}{{$option}}{{end}}{{end}}{{if .Copyright}} +GLOBAL FLAGS: + {{range $index, $option := .VisibleFlags}}{{if $index}} + {{end}}{{$option}}{{end}}{{end}}{{if .Copyright}} COPYRIGHT: - {{.Copyright}}{{end}} + {{.Copyright}}{{end}} ` // CommandHelpTemplate is the text template for the command help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var CommandHelpTemplate = `NAME: - {{.HelpName}} - {{.Usage}} + {{.HelpName}} - {{.Usage}} USAGE: - {{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}} + {{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}} CATEGORY: - {{.Category}}{{end}}{{if .Description}} + {{.Category}}{{end}}{{if .Description}} DESCRIPTION: - {{.Description}}{{end}}{{if .VisibleFlags}} + {{.Description}}{{end}}{{if .VisibleFlags}} -OPTIONS: - {{range .VisibleFlags}}{{.}} - {{end}}{{end}} +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}}{{end}} ` // SubcommandHelpTemplate is the text template for the subcommand help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var SubcommandHelpTemplate = `NAME: - {{.HelpName}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}} + {{.HelpName}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}} USAGE: - {{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} + {{.HelpName}} COMMAND{{if .VisibleFlags}} [COMMAND FLAGS | -h]{{end}} [ARGUMENTS...] -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{end}}{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}} -{{end}}{{if .VisibleFlags}} -OPTIONS: - {{range .VisibleFlags}}{{.}} - {{end}}{{end}} +COMMANDS: + {{range .VisibleCommands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}} + {{end}}{{if .VisibleFlags}} +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}}{{end}} ` var helpCommand = Command{ diff --git a/vendor/vendor.json b/vendor/vendor.json index 5424a54b3..cc9aa0322 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -2,6 +2,12 @@ "comment": "", "ignore": "test", "package": [ + { + "checksumSHA1": "rK3ght7KTtHGdm0V4+U7fv9+tUU=", + "path": "github.com/Azure/azure-sdk-for-go/storage", + "revision": "8e625d1702a32d01cef05a9252198d231c4af113", + "revisionTime": "2017-02-08T01:01:20Z" + }, { "path": "github.com/Sirupsen/logrus", "revision": "32055c351ea8b00b96d70f28db48d9840feaf0ec", @@ -175,10 +181,10 @@ "revisionTime": "2016-07-23T06:10:19Z" }, { - "checksumSHA1": "7PcmjItrQSx/1sZ6Q395LCzT+iw=", + "checksumSHA1": "fUWokilZyc1QDKnIgCDJE8n1S9U=", "path": "github.com/minio/cli", - "revision": "06bb2061ef1493532baf0444818eb5fb4c83caac", - "revisionTime": "2017-02-20T03:57:28Z" + "revision": "b8ae5507c0ceceecc22d5dbd386b58fbd4fdce72", + "revisionTime": "2017-02-27T07:32:28Z" }, { "checksumSHA1": "NBGyq2+iTtJvJ+ElG4FzHLe1WSY=",