From 52d0524fbbfc24d733bb88410e091962dbf18617 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Thu, 13 Aug 2020 17:14:49 -0700 Subject: [PATCH 1/5] saving lint work Signed-off-by: Sugu Sougoumarane --- go/vt/orchestrator/agent/agent_dao.go | 14 ++--- go/vt/orchestrator/app/cli.go | 61 ++++++++----------- go/vt/orchestrator/app/command_help.go | 3 +- .../orchestrator/attributes/attributes_dao.go | 21 ------- go/vt/orchestrator/collection/collection.go | 4 +- go/vt/orchestrator/config/config.go | 23 ------- go/vt/orchestrator/db/db.go | 12 +--- 7 files changed, 39 insertions(+), 99 deletions(-) diff --git a/go/vt/orchestrator/agent/agent_dao.go b/go/vt/orchestrator/agent/agent_dao.go index 52cc53cf223..bbeabedbee3 100644 --- a/go/vt/orchestrator/agent/agent_dao.go +++ b/go/vt/orchestrator/agent/agent_dao.go @@ -359,7 +359,7 @@ func GetAgent(hostname string) (Agent, error) { mySQLRunningUri := fmt.Sprintf("%s/mysql-status?token=%s", uri, token) body, err := readResponse(httpGet(mySQLRunningUri)) if err == nil { - err = json.Unmarshal(body, &agent.MySQLRunning) + _ = json.Unmarshal(body, &agent.MySQLRunning) } // Actually an error is OK here since "status" returns with non-zero exit code when MySQL not running } @@ -702,8 +702,8 @@ func executeSeed(seedId int64, targetHostname string, sourceHostname string) err if err != nil { return updateSeedStateEntry(seedStateId, err) } - sourceAgent, err = GetAgent(sourceHostname) - seedStateId, _ = submitSeedStateEntry(seedId, fmt.Sprintf("MySQL data volume on source host %s is %d bytes", sourceHostname, sourceAgent.MountPoint.MySQLDiskUsage), "") + sourceAgent, _ = GetAgent(sourceHostname) + _, _ = submitSeedStateEntry(seedId, fmt.Sprintf("MySQL data volume on source host %s is %d bytes", sourceHostname, sourceAgent.MountPoint.MySQLDiskUsage), "") seedStateId, _ = submitSeedStateEntry(seedId, fmt.Sprintf("Erasing MySQL data on %s", targetHostname), "") _, err = deleteMySQLDatadir(targetHostname) @@ -723,10 +723,10 @@ func executeSeed(seedId int64, targetHostname string, sourceHostname string) err } // ... - seedStateId, _ = submitSeedStateEntry(seedId, fmt.Sprintf("%s will now receive data in background", targetHostname), "") + _, _ = submitSeedStateEntry(seedId, fmt.Sprintf("%s will now receive data in background", targetHostname), "") ReceiveMySQLSeedData(targetHostname, seedId) - seedStateId, _ = submitSeedStateEntry(seedId, fmt.Sprintf("Waiting %d seconds for %s to start listening for incoming data", config.Config.SeedWaitSecondsBeforeSend, targetHostname), "") + _, _ = submitSeedStateEntry(seedId, fmt.Sprintf("Waiting %d seconds for %s to start listening for incoming data", config.Config.SeedWaitSecondsBeforeSend, targetHostname), "") time.Sleep(time.Duration(config.Config.SeedWaitSecondsBeforeSend) * time.Second) seedStateId, _ = submitSeedStateEntry(seedId, fmt.Sprintf("%s will now send data to %s in background", sourceHostname, targetHostname), "") @@ -795,10 +795,10 @@ func executeSeed(seedId int64, targetHostname string, sourceHostname string) err return updateSeedStateEntry(seedStateId, err) } - seedStateId, _ = submitSeedStateEntry(seedId, fmt.Sprintf("Submitting MySQL instance for discovery: %s", targetHostname), "") + _, _ = submitSeedStateEntry(seedId, fmt.Sprintf("Submitting MySQL instance for discovery: %s", targetHostname), "") SeededAgents <- &targetAgent - seedStateId, _ = submitSeedStateEntry(seedId, "Done", "") + _, _ = submitSeedStateEntry(seedId, "Done", "") return nil } diff --git a/go/vt/orchestrator/app/cli.go b/go/vt/orchestrator/app/cli.go index 7afa2f13b6d..b6f42460d9d 100644 --- a/go/vt/orchestrator/app/cli.go +++ b/go/vt/orchestrator/app/cli.go @@ -120,11 +120,6 @@ func getClusterName(clusterAlias string, instanceKey *inst.InstanceKey) (cluster return clusterName } -func assignThisInstanceKey() *inst.InstanceKey { - log.Debugf("Assuming instance is this machine, %+v", thisInstanceKey) - return thisInstanceKey -} - func validateInstanceIsFound(instanceKey *inst.InstanceKey) (instance *inst.Instance) { instance, _, err := inst.ReadInstance(instanceKey) if err != nil { @@ -227,7 +222,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), destinationKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), destinationKey.DisplayString()) } case registerCliCommand("relocate-replicas", "Smart relocation", `Relocates all or part of the replicas of a given instance under another instance`): { @@ -274,8 +269,8 @@ func Cli(command string, strict bool, instance string, destination string, owner if promotedReplica == nil { log.Fatalf("Could not regroup replicas of %+v; error: %+v", *instanceKey, err) } - fmt.Println(fmt.Sprintf("%s lost: %d, trivial: %d, pseudo-gtid: %d", - promotedReplica.Key.DisplayString(), len(lostReplicas), len(equalReplicas), len(aheadReplicas))) + fmt.Printf("%s lost: %d, trivial: %d, pseudo-gtid: %d\n", + promotedReplica.Key.DisplayString(), len(lostReplicas), len(equalReplicas), len(aheadReplicas)) if err != nil { log.Fatale(err) } @@ -289,7 +284,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), instance.MasterKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), instance.MasterKey.DisplayString()) } case registerCliCommand("move-up-replicas", "Classic file:pos relocation", `Moves replicas of the given instance one level up the topology`): { @@ -320,7 +315,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), destinationKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), destinationKey.DisplayString()) } case registerCliCommand("move-equivalent", "Classic file:pos relocation", `Moves a replica beneath another server, based on previously recorded "equivalence coordinates"`): { @@ -332,7 +327,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), destinationKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), destinationKey.DisplayString()) } case registerCliCommand("repoint", "Classic file:pos relocation", `Make the given instance replicate from another instance without changing the binglog coordinates. Use with care`): { @@ -342,7 +337,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), instance.MasterKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), instance.MasterKey.DisplayString()) } case registerCliCommand("repoint-replicas", "Classic file:pos relocation", `Repoint all replicas of given instance to replicate back from the instance. Use with care`): { @@ -355,7 +350,7 @@ func Cli(command string, strict bool, instance string, destination string, owner log.Errore(e) } for _, replica := range repointedReplicas { - fmt.Println(fmt.Sprintf("%s<%s", replica.Key.DisplayString(), instanceKey.DisplayString())) + fmt.Printf("%s<%s\n", replica.Key.DisplayString(), instanceKey.DisplayString()) } } } @@ -422,7 +417,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), destinationKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), destinationKey.DisplayString()) } case registerCliCommand("move-replicas-gtid", "GTID relocation", `Moves all replicas of a given instance under another (destination) instance using GTID`): { @@ -456,8 +451,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if promotedReplica == nil { log.Fatalf("Could not regroup replicas of %+v; error: %+v", *instanceKey, err) } - fmt.Println(fmt.Sprintf("%s lost: %d, moved: %d", - promotedReplica.Key.DisplayString(), len(lostReplicas), len(movedReplicas))) + fmt.Printf("%s lost: %d, moved: %d\n", promotedReplica.Key.DisplayString(), len(lostReplicas), len(movedReplicas)) if err != nil { log.Fatale(err) } @@ -473,7 +467,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), destinationKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), destinationKey.DisplayString()) } case registerCliCommand("match-up", "Pseudo-GTID relocation", `Transport the replica one level up the hierarchy, making it child of its grandparent, using Pseudo-GTID`): { @@ -482,7 +476,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), instance.MasterKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), instance.MasterKey.DisplayString()) } case registerCliCommand("rematch", "Pseudo-GTID relocation", `Reconnect a replica onto its master, via PSeudo-GTID.`): { @@ -491,7 +485,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%s<%s", instanceKey.DisplayString(), instance.MasterKey.DisplayString())) + fmt.Printf("%s<%s\n", instanceKey.DisplayString(), instance.MasterKey.DisplayString()) } case registerCliCommand("match-replicas", "Pseudo-GTID relocation", `Matches all replicas of a given instance under another (destination) instance using Pseudo-GTID`): { @@ -550,8 +544,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if promotedReplica == nil { log.Fatalf("Could not regroup replicas of %+v; error: %+v", *instanceKey, err) } - fmt.Println(fmt.Sprintf("%s lost: %d, trivial: %d, pseudo-gtid: %d", - promotedReplica.Key.DisplayString(), len(lostReplicas), len(equalReplicas), len(aheadReplicas))) + fmt.Printf("%s lost: %d, trivial: %d, pseudo-gtid: %d\n", promotedReplica.Key.DisplayString(), len(lostReplicas), len(equalReplicas), len(aheadReplicas)) if err != nil { log.Fatale(err) } @@ -844,7 +837,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%+v:%s", *coordinates, text)) + fmt.Printf("%+v:%s\n", *coordinates, text) } case registerCliCommand("locate-gtid-errant", "Binary logs", `List binary logs containing errant GTIDs`): { @@ -881,7 +874,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%+v:%d", *binlogEvent, binlogEvent.NextEventPos)) + fmt.Printf("%+v:%d\n", *binlogEvent, binlogEvent.NextEventPos) } case registerCliCommand("correlate-relaylog-pos", "Binary logs", `Given an instance (-i) and relaylog coordinates (--binlog=file:pos), find the correlated coordinates in another instance's relay logs (-d)`): { @@ -917,7 +910,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%+v;%+v;%+v", *instanceCoordinates, *correlatedCoordinates, *nextCoordinates)) + fmt.Printf("%+v;%+v;%+v\n", *instanceCoordinates, *correlatedCoordinates, *nextCoordinates) } case registerCliCommand("find-binlog-entry", "Binary logs", `Get binlog file:pos of entry given by --pattern (exact full match, not a regular expression) in a given instance`): { @@ -939,7 +932,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%+v", *coordinates)) + fmt.Printf("%+v\n", *coordinates) } case registerCliCommand("correlate-binlog-pos", "Binary logs", `Given an instance (-i) and binlog coordinates (--binlog=file:pos), find the correlated coordinates in another instance (-d)`): { @@ -980,7 +973,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%+v", *coordinates)) + fmt.Printf("%+v\n", *coordinates) } // Pool case registerCliCommand("submit-pool-instances", "Pools", `Submit a pool name with a list of instances in that pool`): @@ -1000,7 +993,7 @@ func Cli(command string, strict bool, instance string, destination string, owner log.Fatale(err) } for _, clusterPoolInstance := range clusterPoolInstances { - fmt.Println(fmt.Sprintf("%s\t%s\t%s\t%s:%d", clusterPoolInstance.ClusterName, clusterPoolInstance.ClusterAlias, clusterPoolInstance.Pool, clusterPoolInstance.Hostname, clusterPoolInstance.Port)) + fmt.Printf("%s\t%s\t%s\t%s:%d\n", clusterPoolInstance.ClusterName, clusterPoolInstance.ClusterAlias, clusterPoolInstance.Pool, clusterPoolInstance.Hostname, clusterPoolInstance.Port) } } case registerCliCommand("which-heuristic-cluster-pool-instances", "Pools", `List instances of a given cluster which are in either any pool or in a specific pool`): @@ -1060,7 +1053,7 @@ func Cli(command string, strict bool, instance string, destination string, owner log.Fatale(err) } for _, cluster := range clusters { - fmt.Println(fmt.Sprintf("%s\t%s", cluster.ClusterName, cluster.ClusterAlias)) + fmt.Printf("%s\t%s\n", cluster.ClusterName, cluster.ClusterAlias) } } case registerCliCommand("all-clusters-masters", "Information", `List of writeable masters, one per cluster`): @@ -1272,7 +1265,7 @@ func Cli(command string, strict bool, instance string, destination string, owner log.Fatale(err) } for _, kvPair := range kvPairs { - fmt.Println(fmt.Sprintf("%s:%s", kvPair.Key, kvPair.Value)) + fmt.Printf("%s:%s\n", kvPair.Key, kvPair.Value) } } @@ -1544,7 +1537,7 @@ func Cli(command string, strict bool, instance string, destination string, owner log.Fatale(err) } for _, entry := range analysis { - fmt.Println(fmt.Sprintf("%s (cluster %s): %s", entry.AnalyzedInstanceKey.DisplayString(), entry.ClusterDetails.ClusterName, entry.AnalysisString())) + fmt.Printf("%s (cluster %s): %s\n", entry.AnalyzedInstanceKey.DisplayString(), entry.ClusterDetails.ClusterName, entry.AnalysisString()) } } case registerCliCommand("ack-all-recoveries", "Recovery", `Acknowledge all recoveries; this unblocks pending future recoveries`): @@ -1556,7 +1549,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%d recoveries acknowldged", countRecoveries)) + fmt.Printf("%d recoveries acknowldged\n", countRecoveries) } case registerCliCommand("ack-cluster-recoveries", "Recovery", `Acknowledge recoveries for a given cluster; this unblocks pending future recoveries`): { @@ -1568,7 +1561,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%d recoveries acknowldged", countRecoveries)) + fmt.Printf("%d recoveries acknowldged\n", countRecoveries) } case registerCliCommand("ack-instance-recoveries", "Recovery", `Acknowledge recoveries for a given instance; this unblocks pending future recoveries`): { @@ -1581,7 +1574,7 @@ func Cli(command string, strict bool, instance string, destination string, owner if err != nil { log.Fatale(err) } - fmt.Println(fmt.Sprintf("%d recoveries acknowldged", countRecoveries)) + fmt.Printf("%d recoveries acknowldged\n", countRecoveries) } // Instance meta case registerCliCommand("register-candidate", "Instance, meta", `Indicate that a specific instance is a preferred candidate for master promotion`): @@ -1787,7 +1780,7 @@ func Cli(command string, strict bool, instance string, destination string, owner // Help case "help": { - fmt.Fprintf(os.Stderr, availableCommandsUsage()) + fmt.Fprint(os.Stderr, availableCommandsUsage()) } default: log.Fatalf("Unknown command: \"%s\". %s", command, availableCommandsUsage()) diff --git a/go/vt/orchestrator/app/command_help.go b/go/vt/orchestrator/app/command_help.go index 2c04a0ceda1..97e80010219 100644 --- a/go/vt/orchestrator/app/command_help.go +++ b/go/vt/orchestrator/app/command_help.go @@ -902,6 +902,5 @@ func init() { } func HelpCommand(command string) { - fmt.Println( - fmt.Sprintf("%s:\n%s", command, CommandHelp[command])) + fmt.Printf("%s:\n%s\n", command, CommandHelp[command]) } diff --git a/go/vt/orchestrator/attributes/attributes_dao.go b/go/vt/orchestrator/attributes/attributes_dao.go index 2b49b8cc818..7d69788602a 100644 --- a/go/vt/orchestrator/attributes/attributes_dao.go +++ b/go/vt/orchestrator/attributes/attributes_dao.go @@ -17,10 +17,7 @@ package attributes import ( - "errors" "fmt" - "io/ioutil" - "net/http" "strings" "vitess.io/vitess/go/vt/orchestrator/db" @@ -28,24 +25,6 @@ import ( "vitess.io/vitess/go/vt/orchestrator/external/golib/sqlutils" ) -func readResponse(res *http.Response, err error) ([]byte, error) { - if err != nil { - return nil, err - } - - defer res.Body.Close() - body, err := ioutil.ReadAll(res.Body) - if err != nil { - return nil, err - } - - if res.Status == "500" { - return body, errors.New("Response Status 500") - } - - return body, nil -} - // SetHostAttributes func SetHostAttributes(hostname string, attributeName string, attributeValue string) error { _, err := db.ExecOrchestrator(` diff --git a/go/vt/orchestrator/collection/collection.go b/go/vt/orchestrator/collection/collection.go index 599e67ff9cc..044f63f405e 100644 --- a/go/vt/orchestrator/collection/collection.go +++ b/go/vt/orchestrator/collection/collection.go @@ -280,8 +280,8 @@ func (c *Collection) Append(m Metric) error { if c == nil { return errors.New("Collection.Append: c == nil") } - c.Lock() - defer c.Unlock() + c.Lock() //nolint SA5011: possible nil pointer dereference + defer c.Unlock() //nolint SA5011: possible nil pointer dereference // we don't want to add nil metrics if c == nil { return errors.New("Collection.Append: c == nil") diff --git a/go/vt/orchestrator/config/config.go b/go/vt/orchestrator/config/config.go index 093d1b893b6..81c14aea867 100644 --- a/go/vt/orchestrator/config/config.go +++ b/go/vt/orchestrator/config/config.go @@ -62,26 +62,6 @@ const ( SelectTrueQuery = "select 1" ) -var deprecatedConfigurationVariables = []string{ - "DatabaselessMode__experimental", - "BufferBinlogEvents", - "BinlogFileHistoryDays", - "MaintenanceOwner", - "ReadLongRunningQueries", - "DiscoveryPollSeconds", - "ActiveNodeExpireSeconds", - "AuditPageSize", - "SlaveStartPostWaitMilliseconds", - "MySQLTopologyMaxPoolConnections", - "MaintenancePurgeDays", - "MaintenanceExpireMinutes", - "HttpTimeoutSeconds", - "AgentAutoDiscover", - "PseudoGTIDCoordinatesHistoryHeuristicMinutes", - "PseudoGTIDPreferIndependentMultiMatch", - "MaxOutdatedKeysToShow", -} - // Configuration makes for orchestrator configuration input, which can be provided by user via JSON formatted file. // Some of the parameteres have reasonable default values, and some (like database credentials) are // strictly expected from user. @@ -547,9 +527,6 @@ func (this *Configuration) postReadAdjustments() error { if this.IsSQLite() && this.SQLite3DataFile == "" { return fmt.Errorf("SQLite3DataFile must be set when BackendDB is sqlite3") } - if this.IsSQLite() { - // this.HostnameResolveMethod = "none" - } if this.RaftEnabled && this.RaftDataDir == "" { return fmt.Errorf("RaftDataDir must be defined since raft is enabled (RaftEnabled)") } diff --git a/go/vt/orchestrator/db/db.go b/go/vt/orchestrator/db/db.go index 47b1786320b..8472840569b 100644 --- a/go/vt/orchestrator/db/db.go +++ b/go/vt/orchestrator/db/db.go @@ -125,10 +125,6 @@ func IsSQLite() bool { return config.Config.IsSQLite() } -func isInMemorySQLite() bool { - return config.Config.IsSQLite() && strings.Contains(config.Config.SQLite3DataFile, ":memory:") -} - // OpenTopology returns the DB instance for the orchestrator backed database func OpenOrchestrator() (db *sql.DB, err error) { var fromCache bool @@ -248,7 +244,7 @@ func deployStatements(db *sql.DB, queries []string) error { // My bad. originalSqlMode := "" if config.Config.IsMySQL() { - err = tx.QueryRow(`select @@session.sql_mode`).Scan(&originalSqlMode) + _ = tx.QueryRow(`select @@session.sql_mode`).Scan(&originalSqlMode) if _, err := tx.Exec(`set @@session.sql_mode=REPLACE(@@session.sql_mode, 'NO_ZERO_DATE', '')`); err != nil { log.Fatale(err) } @@ -256,11 +252,7 @@ func deployStatements(db *sql.DB, queries []string) error { log.Fatale(err) } } - for i, query := range queries { - if i == 0 { - //log.Debugf("sql_mode is: %+v", originalSqlMode) - } - + for _, query := range queries { query, err := translateStatement(query) if err != nil { return log.Fatalf("Cannot initiate orchestrator: %+v; query=%+v", err, query) From 412789194aebc56bec49b6c82116e4178273b1b3 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Thu, 13 Aug 2020 21:28:19 -0700 Subject: [PATCH 2/5] more golint Signed-off-by: Sugu Sougoumarane --- .../external/golib/sqlutils/sqlutils.go | 12 +-- .../orchestrator/external/golib/util/text.go | 9 +-- .../external/raft/file_snapshot.go | 2 +- .../external/raft/file_snapshot_test.go | 6 +- .../orchestrator/external/raft/integ_test.go | 4 +- .../external/raft/net_transport.go | 2 +- .../external/raft/net_transport_test.go | 22 +++--- go/vt/orchestrator/external/raft/raft.go | 9 +-- go/vt/orchestrator/external/raft/raft_test.go | 8 +- .../external/raft/transport_test.go | 20 ++--- go/vt/orchestrator/external/raft/util_test.go | 4 +- go/vt/orchestrator/external/zk/zk.go | 13 +--- go/vt/orchestrator/http/api.go | 49 ++++++------ go/vt/orchestrator/http/httpbase.go | 9 +-- go/vt/orchestrator/inst/analysis.go | 74 +++++++++---------- go/vt/orchestrator/inst/analysis_dao.go | 31 -------- .../inst/candidate_database_instance_dao.go | 6 +- go/vt/orchestrator/inst/downtime.go | 2 +- go/vt/orchestrator/inst/instance.go | 7 +- go/vt/orchestrator/inst/instance_binlog.go | 2 +- .../orchestrator/inst/instance_binlog_dao.go | 5 +- go/vt/orchestrator/inst/instance_dao.go | 10 +-- go/vt/orchestrator/inst/instance_key.go | 10 +-- go/vt/orchestrator/inst/instance_test.go | 1 - go/vt/orchestrator/inst/instance_topology.go | 51 ++++++------- .../inst/instance_topology_dao.go | 5 +- go/vt/orchestrator/inst/pool_dao.go | 2 +- .../inst/replication_thread_state.go | 6 +- go/vt/orchestrator/inst/resolve_dao.go | 31 +------- go/vt/orchestrator/inst/tag.go | 2 +- go/vt/orchestrator/inst/tag_dao.go | 4 +- go/vt/orchestrator/inst/tag_test.go | 1 + 32 files changed, 162 insertions(+), 257 deletions(-) diff --git a/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go b/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go index a61d0c06e3a..e6b0ffd7b8d 100644 --- a/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go +++ b/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go @@ -19,7 +19,6 @@ package sqlutils import ( "database/sql" "encoding/json" - "errors" "fmt" "strconv" "strings" @@ -69,7 +68,7 @@ type RowData []CellData // MarshalJSON will marshal this map as JSON func (this *RowData) MarshalJSON() ([]byte, error) { - cells := make([](*CellData), len(*this), len(*this)) + cells := make([](*CellData), len(*this)) for i, val := range *this { d := CellData(val) cells[i] = &d @@ -279,16 +278,17 @@ func QueryRowsMap(db *sql.DB, query string, on_row func(RowMap) error, args ...i func queryResultData(db *sql.DB, query string, retrieveColumns bool, args ...interface{}) (resultData ResultData, columns []string, err error) { defer func() { if derr := recover(); derr != nil { - err = errors.New(fmt.Sprintf("QueryRowsMap unexpected error: %+v", derr)) + err = fmt.Errorf("QueryRowsMap unexpected error: %+v", derr) } }() var rows *sql.Rows rows, err = db.Query(query, args...) - defer rows.Close() if err != nil && err != sql.ErrNoRows { return EmptyResultData, columns, log.Errore(err) } + defer rows.Close() + if retrieveColumns { // Don't pay if you don't want to columns, _ = rows.Columns() @@ -335,7 +335,7 @@ func QueryRowsMapBuffered(db *sql.DB, query string, on_row func(RowMap) error, a func ExecNoPrepare(db *sql.DB, query string, args ...interface{}) (res sql.Result, err error) { defer func() { if derr := recover(); derr != nil { - err = errors.New(fmt.Sprintf("ExecNoPrepare unexpected error: %+v", derr)) + err = fmt.Errorf("ExecNoPrepare unexpected error: %+v", derr) } }() @@ -351,7 +351,7 @@ func ExecNoPrepare(db *sql.DB, query string, args ...interface{}) (res sql.Resul func execInternal(silent bool, db *sql.DB, query string, args ...interface{}) (res sql.Result, err error) { defer func() { if derr := recover(); derr != nil { - err = errors.New(fmt.Sprintf("execInternal unexpected error: %+v", derr)) + err = fmt.Errorf("execInternal unexpected error: %+v", derr) } }() var stmt *sql.Stmt diff --git a/go/vt/orchestrator/external/golib/util/text.go b/go/vt/orchestrator/external/golib/util/text.go index 2b0ae9a7e8b..419a5a5ef3a 100644 --- a/go/vt/orchestrator/external/golib/util/text.go +++ b/go/vt/orchestrator/external/golib/util/text.go @@ -17,7 +17,6 @@ package util import ( - "errors" "fmt" "regexp" "strconv" @@ -52,21 +51,15 @@ func SimpleTimeToSeconds(simpleTime string) (int, error) { i, _ := strconv.Atoi(simpleTime[0 : len(simpleTime)-1]) return i * 60 * 60 * 24 * 7, nil } - return 0, errors.New(fmt.Sprintf("Cannot parse simple time: %s", simpleTime)) + return 0, fmt.Errorf("Cannot parse simple time: %s", simpleTime) } func Tabulate(lines []string, separator string, outputSeparator string, directionFlags ...int) (result []string) { tokens := make([][]string, 0) - widths := make([][]int, 0) countColumns := 0 for _, line := range lines { lineTokens := strings.Split(line, separator) - lineWidths := make([]int, len(lineTokens)) - for i := range lineTokens { - lineWidths[i] = len(lineTokens[i]) - } tokens = append(tokens, lineTokens) - widths = append(widths, lineWidths) if len(lineTokens) > countColumns { countColumns = len(lineTokens) } diff --git a/go/vt/orchestrator/external/raft/file_snapshot.go b/go/vt/orchestrator/external/raft/file_snapshot.go index 4d841ba8dec..aa6d7e83297 100644 --- a/go/vt/orchestrator/external/raft/file_snapshot.go +++ b/go/vt/orchestrator/external/raft/file_snapshot.go @@ -304,7 +304,7 @@ func (f *FileSnapshotStore) Open(id string) (*SnapshotMeta, io.ReadCloser, error // Verify the hash computed := stateHash.Sum(nil) - if bytes.Compare(meta.CRC, computed) != 0 { + if !bytes.Equal(meta.CRC, computed) { f.logger.Printf("[ERR] snapshot: CRC checksum failed (stored: %v computed: %v)", meta.CRC, computed) fh.Close() diff --git a/go/vt/orchestrator/external/raft/file_snapshot_test.go b/go/vt/orchestrator/external/raft/file_snapshot_test.go index fcd2ef4b8b3..1fee98920ac 100644 --- a/go/vt/orchestrator/external/raft/file_snapshot_test.go +++ b/go/vt/orchestrator/external/raft/file_snapshot_test.go @@ -133,7 +133,7 @@ func TestFileSS_CreateSnapshot(t *testing.T) { if latest.Term != 3 { t.Fatalf("bad snapshot: %v", *latest) } - if bytes.Compare(latest.Peers, peers) != 0 { + if !bytes.Equal(latest.Peers, peers) { t.Fatalf("bad snapshot: %v", *latest) } if latest.Size != 13 { @@ -156,7 +156,7 @@ func TestFileSS_CreateSnapshot(t *testing.T) { } // Ensure a match - if bytes.Compare(buf.Bytes(), []byte("first\nsecond\n")) != 0 { + if !bytes.Equal(buf.Bytes(), []byte("first\nsecond\n")) { t.Fatalf("content mismatch") } } @@ -263,7 +263,7 @@ func TestFileSS_BadPerm(t *testing.T) { if err := os.Chmod(dir2, 000); err != nil { t.Fatalf("err: %s", err) } - defer os.Chmod(dir2, 777) // Set perms back for delete + defer os.Chmod(dir2, 0777) // Set perms back for delete // Should fail if _, err := NewFileSnapshotStore(dir2, 3, nil); err == nil { diff --git a/go/vt/orchestrator/external/raft/integ_test.go b/go/vt/orchestrator/external/raft/integ_test.go index c4bf67a7acf..89520882568 100644 --- a/go/vt/orchestrator/external/raft/integ_test.go +++ b/go/vt/orchestrator/external/raft/integ_test.go @@ -146,7 +146,7 @@ CHECK: } for idx, log := range first.fsm.logs { other := env.fsm.logs[idx] - if bytes.Compare(log, other) != 0 { + if !bytes.Equal(log, other) { err = fmt.Errorf("log %d mismatch %v %v", idx, log, other) goto ERR } @@ -252,7 +252,7 @@ func TestRaft_Integ(t *testing.T) { time.Sleep(3 * conf.HeartbeatTimeout) // Wait for a leader - leader, err = WaitForAny(Leader, envs) + _, err = WaitForAny(Leader, envs) NoErr(err, t) allEnvs := append([]*RaftEnv{env1}, envs...) diff --git a/go/vt/orchestrator/external/raft/net_transport.go b/go/vt/orchestrator/external/raft/net_transport.go index 3597f9df3ff..7f3e74450f7 100644 --- a/go/vt/orchestrator/external/raft/net_transport.go +++ b/go/vt/orchestrator/external/raft/net_transport.go @@ -249,7 +249,7 @@ func (n *NetworkTransport) returnConn(conn *netConn) { defer n.connPoolLock.Unlock() key := conn.target - conns, _ := n.connPool[key] + conns := n.connPool[key] if !n.IsShutdown() && len(conns) < n.maxPool { n.connPool[key] = append(conns, conn) diff --git a/go/vt/orchestrator/external/raft/net_transport_test.go b/go/vt/orchestrator/external/raft/net_transport_test.go index 88b04c2d84d..bef03512c6c 100644 --- a/go/vt/orchestrator/external/raft/net_transport_test.go +++ b/go/vt/orchestrator/external/raft/net_transport_test.go @@ -108,13 +108,13 @@ func TestNetworkTransport_AppendEntries(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -174,12 +174,12 @@ func TestNetworkTransport_AppendEntriesPipeline(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } } }() @@ -246,13 +246,13 @@ func TestNetworkTransport_RequestVote(t *testing.T) { // Verify the command req := rpc.Command.(*RequestVoteRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -304,7 +304,7 @@ func TestNetworkTransport_InstallSnapshot(t *testing.T) { // Verify the command req := rpc.Command.(*InstallSnapshotRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } // Try to read the bytes @@ -312,14 +312,14 @@ func TestNetworkTransport_InstallSnapshot(t *testing.T) { rpc.Reader.Read(buf) // Compare - if bytes.Compare(buf, []byte("0123456789")) != 0 { - t.Fatalf("bad buf %v", buf) + if !bytes.Equal(buf, []byte("0123456789")) { + t.Errorf("bad buf %v", buf) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -399,7 +399,7 @@ func TestNetworkTransport_PooledConn(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } rpc.Respond(&resp, nil) diff --git a/go/vt/orchestrator/external/raft/raft.go b/go/vt/orchestrator/external/raft/raft.go index bd630a495db..3d16452a81d 100644 --- a/go/vt/orchestrator/external/raft/raft.go +++ b/go/vt/orchestrator/external/raft/raft.go @@ -515,7 +515,7 @@ func (r *Raft) Stats() map[string]string { } else if r.getState() == Leader { s["last_contact"] = "0" } else { - s["last_contact"] = fmt.Sprintf("%v", time.Now().Sub(last)) + s["last_contact"] = fmt.Sprintf("%v", time.Since(last)) } return s } @@ -671,7 +671,7 @@ func (r *Raft) runFollower() { // Check if we have had a successful contact lastContact := r.LastContact() - if time.Now().Sub(lastContact) < r.conf.HeartbeatTimeout { + if time.Since(lastContact) < r.conf.HeartbeatTimeout { continue } @@ -1440,7 +1440,6 @@ func (r *Raft) appendEntries(rpc RPC, a *AppendEntriesRequest) { // Everything went well, set success resp.Success = true r.setLastContact() - return } // requestVote is invoked when we get an request vote RPC call. @@ -1495,7 +1494,7 @@ func (r *Raft) requestVote(rpc RPC, req *RequestVoteRequest) { // Check if we've voted in this election before if lastVoteTerm == req.Term && lastVoteCandBytes != nil { r.logger.Printf("[INFO] raft: Duplicate RequestVote for same term: %d", req.Term) - if bytes.Compare(lastVoteCandBytes, req.Candidate) == 0 { + if bytes.Equal(lastVoteCandBytes, req.Candidate) { r.logger.Printf("[WARN] raft: Duplicate RequestVote from candidate: %s", req.Candidate) resp.Granted = true } @@ -1524,7 +1523,6 @@ func (r *Raft) requestVote(rpc RPC, req *RequestVoteRequest) { resp.Granted = true r.setLastContact() - return } // installSnapshot is invoked when we get a InstallSnapshot RPC call. @@ -1629,7 +1627,6 @@ func (r *Raft) installSnapshot(rpc RPC, req *InstallSnapshotRequest) { r.logger.Printf("[INFO] raft: Installed remote snapshot") resp.Success = true r.setLastContact() - return } // setLastContact is used to set the last contact time to now diff --git a/go/vt/orchestrator/external/raft/raft_test.go b/go/vt/orchestrator/external/raft/raft_test.go index 5eb660aede8..442df637af4 100644 --- a/go/vt/orchestrator/external/raft/raft_test.go +++ b/go/vt/orchestrator/external/raft/raft_test.go @@ -464,7 +464,7 @@ CHECK: } for idx := 0; idx < len(first.logs); idx++ { - if bytes.Compare(first.logs[idx], fsm.logs[idx]) != 0 { + if !bytes.Equal(first.logs[idx], fsm.logs[idx]) { fsm.Unlock() if time.Now().After(limit) { c.FailNowf("[ERR] FSM log mismatch at index %d", idx) @@ -742,7 +742,7 @@ func TestRaft_LeaderFail(t *testing.T) { } // Ensure the term is greater - if newLead.getCurrentTerm() <= leaderTerm { + if newLead.getCurrentTerm() <= leaderTerm { //nolint SA5011: possible nil pointer dereference c.FailNowf("[ERR] expected newer term! %d %d (%v, %v)", newLead.getCurrentTerm(), leaderTerm, newLead, leader) } @@ -775,10 +775,10 @@ func TestRaft_LeaderFail(t *testing.T) { if len(fsm.logs) != 2 { c.FailNowf("[ERR] did not apply both to FSM! %v", fsm.logs) } - if bytes.Compare(fsm.logs[0], []byte("test")) != 0 { + if !bytes.Equal(fsm.logs[0], []byte("test")) { c.FailNowf("[ERR] first entry should be 'test'") } - if bytes.Compare(fsm.logs[1], []byte("apply")) != 0 { + if !bytes.Equal(fsm.logs[1], []byte("apply")) { c.FailNowf("[ERR] second entry should be 'apply'") } fsm.Unlock() diff --git a/go/vt/orchestrator/external/raft/transport_test.go b/go/vt/orchestrator/external/raft/transport_test.go index b89c3c90dd7..2e375d612a4 100644 --- a/go/vt/orchestrator/external/raft/transport_test.go +++ b/go/vt/orchestrator/external/raft/transport_test.go @@ -67,12 +67,12 @@ func TestTransport_AppendEntries(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -130,12 +130,12 @@ func TestTransport_AppendEntriesPipeline(t *testing.T) { // Verify the command req := rpc.Command.(*AppendEntriesRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } } }() @@ -200,13 +200,13 @@ func TestTransport_RequestVote(t *testing.T) { // Verify the command req := rpc.Command.(*RequestVoteRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() @@ -256,7 +256,7 @@ func TestTransport_InstallSnapshot(t *testing.T) { // Verify the command req := rpc.Command.(*InstallSnapshotRequest) if !reflect.DeepEqual(req, &args) { - t.Fatalf("command mismatch: %#v %#v", *req, args) + t.Errorf("command mismatch: %#v %#v", *req, args) } // Try to read the bytes @@ -264,14 +264,14 @@ func TestTransport_InstallSnapshot(t *testing.T) { rpc.Reader.Read(buf) // Compare - if bytes.Compare(buf, []byte("0123456789")) != 0 { - t.Fatalf("bad buf %v", buf) + if !bytes.Equal(buf, []byte("0123456789")) { + t.Errorf("bad buf %v", buf) } rpc.Respond(&resp, nil) case <-time.After(200 * time.Millisecond): - t.Fatalf("timeout") + t.Errorf("timeout") } }() diff --git a/go/vt/orchestrator/external/raft/util_test.go b/go/vt/orchestrator/external/raft/util_test.go index 88b93211f42..be637bc29b6 100644 --- a/go/vt/orchestrator/external/raft/util_test.go +++ b/go/vt/orchestrator/external/raft/util_test.go @@ -13,7 +13,7 @@ func TestRandomTimeout(t *testing.T) { select { case <-timeout: - diff := time.Now().Sub(start) + diff := time.Since(start) if diff < time.Millisecond { t.Fatalf("fired early") } @@ -72,7 +72,7 @@ func TestGenerateUUID(t *testing.T) { t.Fatalf("Should get a new ID!") } - matched, err := regexp.MatchString( + matched, err := regexp.MatchString( //nolint SA6000: calling regexp.MatchString in a loop has poor performance `[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}`, id) if !matched || err != nil { t.Fatalf("expected match %s %v %s", id, matched, err) diff --git a/go/vt/orchestrator/external/zk/zk.go b/go/vt/orchestrator/external/zk/zk.go index 894df772c5c..70bf5f8157b 100644 --- a/go/vt/orchestrator/external/zk/zk.go +++ b/go/vt/orchestrator/external/zk/zk.go @@ -174,7 +174,7 @@ func (zook *ZooKeeper) childrenRecursiveInternal(connection *zk.Conn, path strin if err != nil { return children, err } - sort.Sort(sort.StringSlice(children)) + sort.Strings(children) recursiveChildren := []string{} for _, child := range children { incrementalChild := gopath.Join(incrementalPath, child) @@ -221,12 +221,11 @@ func (zook *ZooKeeper) createInternal(connection *zk.Conn, path string, data []b if parentPath == path { return returnValue, err } - returnValue, err = zook.createInternal(connection, parentPath, []byte("zookeepercli auto-generated"), acl, force) + _, _ = zook.createInternal(connection, parentPath, []byte("zookeepercli auto-generated"), acl, force) } else { return returnValue, err } } - return "", nil } // createInternalWithACL: create a new path with acl @@ -241,12 +240,11 @@ func (zook *ZooKeeper) createInternalWithACL(connection *zk.Conn, path string, d returnValue, err := connection.Create(path, data, zook.flags, perms) log.Debugf("create status for %s: %s, %+v", path, returnValue, err) if err != nil && force && attempts < 2 { - returnValue, err = zook.createInternalWithACL(connection, gopath.Dir(path), []byte("zookeepercli auto-generated"), force, perms) + _, _ = zook.createInternalWithACL(connection, gopath.Dir(path), []byte("zookeepercli auto-generated"), force, perms) } else { return returnValue, err } } - return "", nil } // Create will create a new path, or exit with error should the path exist. @@ -350,19 +348,14 @@ func (zook *ZooKeeper) parsePermsString(permstr string) (perms int32, err error) switch rune { case "r": perms |= zk.PermRead - break case "w": perms |= zk.PermWrite - break case "c": perms |= zk.PermCreate - break case "d": perms |= zk.PermDelete - break case "a": perms |= zk.PermAdmin - break default: err = errors.New("invalid ACL string specified") } diff --git a/go/vt/orchestrator/http/api.go b/go/vt/orchestrator/http/api.go index 4e43bebb6d8..171ca1ecc26 100644 --- a/go/vt/orchestrator/http/api.go +++ b/go/vt/orchestrator/http/api.go @@ -723,7 +723,7 @@ func (this *HttpAPI) LocateErrantGTID(params martini.Params, r render.Render, re Respond(r, &APIResponse{Code: ERROR, Message: err.Error()}) return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("located errant GTID"), Details: errantBinlogs}) + Respond(r, &APIResponse{Code: OK, Message: "located errant GTID", Details: errantBinlogs}) } // ErrantGTIDResetMaster removes errant transactions on a server by way of RESET MASTER @@ -1625,7 +1625,7 @@ func (this *HttpAPI) KillQuery(params martini.Params, r render.Render, req *http Respond(r, &APIResponse{Code: ERROR, Message: "Unauthorized"}) return } - instanceKey, err := this.getInstanceKey(params["host"], params["port"]) + instanceKey, _ := this.getInstanceKey(params["host"], params["port"]) processId, err := strconv.ParseInt(params["process"], 10, 0) if err != nil { Respond(r, &APIResponse{Code: ERROR, Message: err.Error()}) @@ -2308,7 +2308,7 @@ func (this *HttpAPI) DiscoveryMetricsRaw(params martini.Params, r render.Render, // DiscoveryMetricsAggregated will return a single set of aggregated metrics for raw values collected since the // specified time. func (this *HttpAPI) DiscoveryMetricsAggregated(params martini.Params, r render.Render, req *http.Request, user auth.User) { - seconds, err := strconv.Atoi(params["seconds"]) + seconds, _ := strconv.Atoi(params["seconds"]) refTime := time.Now().Add(-time.Duration(seconds) * time.Second) aggregated, err := discovery.AggregatedSince(discoveryMetrics, refTime) @@ -2691,7 +2691,7 @@ func (this *HttpAPI) AgentSeedDetails(params martini.Params, r render.Render, re return } - seedId, err := strconv.ParseInt(params["seedId"], 10, 0) + seedId, _ := strconv.ParseInt(params["seedId"], 10, 0) output, err := agent.AgentSeedDetails(seedId) if err != nil { @@ -2713,7 +2713,7 @@ func (this *HttpAPI) AgentSeedStates(params martini.Params, r render.Render, req return } - seedId, err := strconv.ParseInt(params["seedId"], 10, 0) + seedId, _ := strconv.ParseInt(params["seedId"], 10, 0) output, err := agent.ReadSeedStates(seedId) if err != nil { @@ -2756,8 +2756,8 @@ func (this *HttpAPI) AbortSeed(params martini.Params, r render.Render, req *http return } - seedId, err := strconv.ParseInt(params["seedId"], 10, 0) - err = agent.AbortSeed(seedId) + seedId, _ := strconv.ParseInt(params["seedId"], 10, 0) + err := agent.AbortSeed(seedId) if err != nil { Respond(r, &APIResponse{Code: ERROR, Message: fmt.Sprintf("%+v", err)}) @@ -2780,7 +2780,7 @@ func (this *HttpAPI) Health(params martini.Params, r render.Render, req *http.Re return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Application node is healthy"), Details: health}) + Respond(r, &APIResponse{Code: OK, Message: "Application node is healthy", Details: health}) } @@ -2814,7 +2814,7 @@ func (this *HttpAPI) StatusCheck(params martini.Params, r render.Render, req *ht r.JSON(500, &APIResponse{Code: ERROR, Message: fmt.Sprintf("Application node is unhealthy %+v", err), Details: health}) return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Application node is healthy"), Details: health}) + Respond(r, &APIResponse{Code: OK, Message: "Application node is healthy", Details: health}) } // GrabElection forcibly grabs leadership. Use with care!! @@ -2829,7 +2829,7 @@ func (this *HttpAPI) GrabElection(params martini.Params, r render.Render, req *h return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Node elected as leader")}) + Respond(r, &APIResponse{Code: OK, Message: "Node elected as leader"}) } // Reelect causes re-elections for an active node @@ -2844,7 +2844,7 @@ func (this *HttpAPI) Reelect(params martini.Params, r render.Render, req *http.R return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Set re-elections")}) + Respond(r, &APIResponse{Code: OK, Message: "Set re-elections"}) } // RaftAddPeer adds a new node to the raft cluster @@ -2898,7 +2898,7 @@ func (this *HttpAPI) RaftYield(params martini.Params, r render.Render, req *http return } orcraft.PublishYield(params["node"]) - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Asynchronously yielded")}) + Respond(r, &APIResponse{Code: OK, Message: "Asynchronously yielded"}) } // RaftYieldHint yields to a host whose name contains given hint (e.g. DC) @@ -3039,7 +3039,7 @@ func (this *HttpAPI) ReloadConfiguration(params martini.Params, r render.Render, config.Reload(extraConfigFile) inst.AuditOperation("reload-configuration", nil, "Triggered via API") - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Config reloaded"), Details: extraConfigFile}) + Respond(r, &APIResponse{Code: OK, Message: "Config reloaded", Details: extraConfigFile}) } // ReplicationAnalysis retuens list of issues @@ -3060,7 +3060,7 @@ func (this *HttpAPI) replicationAnalysis(clusterName string, instanceKey *inst.I analysis = filtered } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Analysis"), Details: analysis}) + Respond(r, &APIResponse{Code: OK, Message: "Analysis", Details: analysis}) } // ReplicationAnalysis retuens list of issues @@ -3070,8 +3070,7 @@ func (this *HttpAPI) ReplicationAnalysis(params martini.Params, r render.Render, // ReplicationAnalysis retuens list of issues func (this *HttpAPI) ReplicationAnalysisForCluster(params martini.Params, r render.Render, req *http.Request) { - clusterName := params["clusterName"] - + var clusterName string var err error if clusterName, err = inst.DeduceClusterName(params["clusterName"]); err != nil { Respond(r, &APIResponse{Code: ERROR, Message: fmt.Sprintf("Cannot get analysis: %+v", err)}) @@ -3271,7 +3270,7 @@ func (this *HttpAPI) AutomatedRecoveryFilters(params martini.Params, r render.Re automatedRecoveryMap["RecoverIntermediateMasterClusterFilters"] = config.Config.RecoverIntermediateMasterClusterFilters automatedRecoveryMap["RecoveryIgnoreHostnameFilters"] = config.Config.RecoveryIgnoreHostnameFilters - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Automated recovery configuration details"), Details: automatedRecoveryMap}) + Respond(r, &APIResponse{Code: OK, Message: "Automated recovery configuration details", Details: automatedRecoveryMap}) } // AuditFailureDetection provides list of topology_failure_detection entries @@ -3414,7 +3413,7 @@ func (this *HttpAPI) AcknowledgeClusterRecoveries(params martini.Params, r rende comment := strings.TrimSpace(req.URL.Query().Get("comment")) if comment == "" { - Respond(r, &APIResponse{Code: ERROR, Message: fmt.Sprintf("No acknowledge comment given")}) + Respond(r, &APIResponse{Code: ERROR, Message: "No acknowledge comment given"}) return } userId := getUserId(req, user) @@ -3433,7 +3432,7 @@ func (this *HttpAPI) AcknowledgeClusterRecoveries(params martini.Params, r rende return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Acknowledged cluster recoveries"), Details: clusterName}) + Respond(r, &APIResponse{Code: OK, Message: "Acknowledged cluster recoveries", Details: clusterName}) } // ClusterInfo provides details of a given cluster @@ -3451,7 +3450,7 @@ func (this *HttpAPI) AcknowledgeInstanceRecoveries(params martini.Params, r rend comment := strings.TrimSpace(req.URL.Query().Get("comment")) if comment == "" { - Respond(r, &APIResponse{Code: ERROR, Message: fmt.Sprintf("No acknowledge comment given")}) + Respond(r, &APIResponse{Code: ERROR, Message: "No acknowledge comment given"}) return } userId := getUserId(req, user) @@ -3470,7 +3469,7 @@ func (this *HttpAPI) AcknowledgeInstanceRecoveries(params martini.Params, r rend return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Acknowledged instance recoveries"), Details: instanceKey}) + Respond(r, &APIResponse{Code: OK, Message: "Acknowledged instance recoveries", Details: instanceKey}) } // ClusterInfo provides details of a given cluster @@ -3497,7 +3496,7 @@ func (this *HttpAPI) AcknowledgeRecovery(params martini.Params, r render.Render, } comment := strings.TrimSpace(req.URL.Query().Get("comment")) if comment == "" { - Respond(r, &APIResponse{Code: ERROR, Message: fmt.Sprintf("No acknowledge comment given")}) + Respond(r, &APIResponse{Code: ERROR, Message: "No acknowledge comment given"}) return } userId := getUserId(req, user) @@ -3522,7 +3521,7 @@ func (this *HttpAPI) AcknowledgeRecovery(params martini.Params, r render.Render, return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Acknowledged recovery"), Details: idParam}) + Respond(r, &APIResponse{Code: OK, Message: "Acknowledged recovery", Details: idParam}) } // ClusterInfo provides details of a given cluster @@ -3534,7 +3533,7 @@ func (this *HttpAPI) AcknowledgeAllRecoveries(params martini.Params, r render.Re comment := strings.TrimSpace(req.URL.Query().Get("comment")) if comment == "" { - Respond(r, &APIResponse{Code: ERROR, Message: fmt.Sprintf("No acknowledge comment given")}) + Respond(r, &APIResponse{Code: ERROR, Message: "No acknowledge comment given"}) return } userId := getUserId(req, user) @@ -3554,7 +3553,7 @@ func (this *HttpAPI) AcknowledgeAllRecoveries(params martini.Params, r render.Re return } - Respond(r, &APIResponse{Code: OK, Message: fmt.Sprintf("Acknowledged all recoveries"), Details: comment}) + Respond(r, &APIResponse{Code: OK, Message: "Acknowledged all recoveries", Details: comment}) } // BlockedRecoveries reads list of currently blocked recoveries, optionally filtered by cluster name diff --git a/go/vt/orchestrator/http/httpbase.go b/go/vt/orchestrator/http/httpbase.go index f2106561df4..7d34278e053 100644 --- a/go/vt/orchestrator/http/httpbase.go +++ b/go/vt/orchestrator/http/httpbase.go @@ -56,14 +56,7 @@ func isAuthorizedForAction(req *http.Request, user auth.User) bool { return true } case "multi": - { - if string(user) == "readonly" { - // read only - return false - } - // passed authentication ==> writeable - return true - } + return string(user) != "readonly" case "proxy": { authUser := getProxyAuthUser(req) diff --git a/go/vt/orchestrator/inst/analysis.go b/go/vt/orchestrator/inst/analysis.go index 8ebe39ee178..3b1ea3d5b79 100644 --- a/go/vt/orchestrator/inst/analysis.go +++ b/go/vt/orchestrator/inst/analysis.go @@ -29,47 +29,47 @@ type StructureAnalysisCode string const ( NoProblem AnalysisCode = "NoProblem" - DeadMasterWithoutReplicas = "DeadMasterWithoutReplicas" - DeadMaster = "DeadMaster" - DeadMasterAndReplicas = "DeadMasterAndReplicas" - DeadMasterAndSomeReplicas = "DeadMasterAndSomeReplicas" - UnreachableMasterWithLaggingReplicas = "UnreachableMasterWithLaggingReplicas" - UnreachableMaster = "UnreachableMaster" - MasterSingleReplicaNotReplicating = "MasterSingleReplicaNotReplicating" - MasterSingleReplicaDead = "MasterSingleReplicaDead" - AllMasterReplicasNotReplicating = "AllMasterReplicasNotReplicating" - AllMasterReplicasNotReplicatingOrDead = "AllMasterReplicasNotReplicatingOrDead" - LockedSemiSyncMasterHypothesis = "LockedSemiSyncMasterHypothesis" - LockedSemiSyncMaster = "LockedSemiSyncMaster" - MasterWithoutReplicas = "MasterWithoutReplicas" - DeadCoMaster = "DeadCoMaster" - DeadCoMasterAndSomeReplicas = "DeadCoMasterAndSomeReplicas" - UnreachableCoMaster = "UnreachableCoMaster" - AllCoMasterReplicasNotReplicating = "AllCoMasterReplicasNotReplicating" - DeadIntermediateMaster = "DeadIntermediateMaster" - DeadIntermediateMasterWithSingleReplica = "DeadIntermediateMasterWithSingleReplica" - DeadIntermediateMasterWithSingleReplicaFailingToConnect = "DeadIntermediateMasterWithSingleReplicaFailingToConnect" - DeadIntermediateMasterAndSomeReplicas = "DeadIntermediateMasterAndSomeReplicas" - DeadIntermediateMasterAndReplicas = "DeadIntermediateMasterAndReplicas" - UnreachableIntermediateMasterWithLaggingReplicas = "UnreachableIntermediateMasterWithLaggingReplicas" - UnreachableIntermediateMaster = "UnreachableIntermediateMaster" - AllIntermediateMasterReplicasFailingToConnectOrDead = "AllIntermediateMasterReplicasFailingToConnectOrDead" - AllIntermediateMasterReplicasNotReplicating = "AllIntermediateMasterReplicasNotReplicating" - FirstTierReplicaFailingToConnectToMaster = "FirstTierReplicaFailingToConnectToMaster" - BinlogServerFailingToConnectToMaster = "BinlogServerFailingToConnectToMaster" + DeadMasterWithoutReplicas AnalysisCode = "DeadMasterWithoutReplicas" + DeadMaster AnalysisCode = "DeadMaster" + DeadMasterAndReplicas AnalysisCode = "DeadMasterAndReplicas" + DeadMasterAndSomeReplicas AnalysisCode = "DeadMasterAndSomeReplicas" + UnreachableMasterWithLaggingReplicas AnalysisCode = "UnreachableMasterWithLaggingReplicas" + UnreachableMaster AnalysisCode = "UnreachableMaster" + MasterSingleReplicaNotReplicating AnalysisCode = "MasterSingleReplicaNotReplicating" + MasterSingleReplicaDead AnalysisCode = "MasterSingleReplicaDead" + AllMasterReplicasNotReplicating AnalysisCode = "AllMasterReplicasNotReplicating" + AllMasterReplicasNotReplicatingOrDead AnalysisCode = "AllMasterReplicasNotReplicatingOrDead" + LockedSemiSyncMasterHypothesis AnalysisCode = "LockedSemiSyncMasterHypothesis" + LockedSemiSyncMaster AnalysisCode = "LockedSemiSyncMaster" + MasterWithoutReplicas AnalysisCode = "MasterWithoutReplicas" + DeadCoMaster AnalysisCode = "DeadCoMaster" + DeadCoMasterAndSomeReplicas AnalysisCode = "DeadCoMasterAndSomeReplicas" + UnreachableCoMaster AnalysisCode = "UnreachableCoMaster" + AllCoMasterReplicasNotReplicating AnalysisCode = "AllCoMasterReplicasNotReplicating" + DeadIntermediateMaster AnalysisCode = "DeadIntermediateMaster" + DeadIntermediateMasterWithSingleReplica AnalysisCode = "DeadIntermediateMasterWithSingleReplica" + DeadIntermediateMasterWithSingleReplicaFailingToConnect AnalysisCode = "DeadIntermediateMasterWithSingleReplicaFailingToConnect" + DeadIntermediateMasterAndSomeReplicas AnalysisCode = "DeadIntermediateMasterAndSomeReplicas" + DeadIntermediateMasterAndReplicas AnalysisCode = "DeadIntermediateMasterAndReplicas" + UnreachableIntermediateMasterWithLaggingReplicas AnalysisCode = "UnreachableIntermediateMasterWithLaggingReplicas" + UnreachableIntermediateMaster AnalysisCode = "UnreachableIntermediateMaster" + AllIntermediateMasterReplicasFailingToConnectOrDead AnalysisCode = "AllIntermediateMasterReplicasFailingToConnectOrDead" + AllIntermediateMasterReplicasNotReplicating AnalysisCode = "AllIntermediateMasterReplicasNotReplicating" + FirstTierReplicaFailingToConnectToMaster AnalysisCode = "FirstTierReplicaFailingToConnectToMaster" + BinlogServerFailingToConnectToMaster AnalysisCode = "BinlogServerFailingToConnectToMaster" ) const ( StatementAndMixedLoggingReplicasStructureWarning StructureAnalysisCode = "StatementAndMixedLoggingReplicasStructureWarning" - StatementAndRowLoggingReplicasStructureWarning = "StatementAndRowLoggingReplicasStructureWarning" - MixedAndRowLoggingReplicasStructureWarning = "MixedAndRowLoggingReplicasStructureWarning" - MultipleMajorVersionsLoggingReplicasStructureWarning = "MultipleMajorVersionsLoggingReplicasStructureWarning" - NoLoggingReplicasStructureWarning = "NoLoggingReplicasStructureWarning" - DifferentGTIDModesStructureWarning = "DifferentGTIDModesStructureWarning" - ErrantGTIDStructureWarning = "ErrantGTIDStructureWarning" - NoFailoverSupportStructureWarning = "NoFailoverSupportStructureWarning" - NoWriteableMasterStructureWarning = "NoWriteableMasterStructureWarning" - NotEnoughValidSemiSyncReplicasStructureWarning = "NotEnoughValidSemiSyncReplicasStructureWarning" + StatementAndRowLoggingReplicasStructureWarning StructureAnalysisCode = "StatementAndRowLoggingReplicasStructureWarning" + MixedAndRowLoggingReplicasStructureWarning StructureAnalysisCode = "MixedAndRowLoggingReplicasStructureWarning" + MultipleMajorVersionsLoggingReplicasStructureWarning StructureAnalysisCode = "MultipleMajorVersionsLoggingReplicasStructureWarning" + NoLoggingReplicasStructureWarning StructureAnalysisCode = "NoLoggingReplicasStructureWarning" + DifferentGTIDModesStructureWarning StructureAnalysisCode = "DifferentGTIDModesStructureWarning" + ErrantGTIDStructureWarning StructureAnalysisCode = "ErrantGTIDStructureWarning" + NoFailoverSupportStructureWarning StructureAnalysisCode = "NoFailoverSupportStructureWarning" + NoWriteableMasterStructureWarning StructureAnalysisCode = "NoWriteableMasterStructureWarning" + NotEnoughValidSemiSyncReplicasStructureWarning StructureAnalysisCode = "NotEnoughValidSemiSyncReplicasStructureWarning" ) type InstanceAnalysis struct { diff --git a/go/vt/orchestrator/inst/analysis_dao.go b/go/vt/orchestrator/inst/analysis_dao.go index 33fdd8548de..70e14e4b123 100644 --- a/go/vt/orchestrator/inst/analysis_dao.go +++ b/go/vt/orchestrator/inst/analysis_dao.go @@ -24,7 +24,6 @@ import ( "vitess.io/vitess/go/vt/orchestrator/config" "vitess.io/vitess/go/vt/orchestrator/db" "vitess.io/vitess/go/vt/orchestrator/process" - orcraft "vitess.io/vitess/go/vt/orchestrator/raft" "vitess.io/vitess/go/vt/orchestrator/util" "github.com/patrickmn/go-cache" @@ -699,36 +698,6 @@ func GetReplicationAnalysis(clusterName string, hints *ReplicationAnalysisHints) return result, log.Errore(err) } -func getConcensusReplicationAnalysis(analysisEntries []ReplicationAnalysis) ([]ReplicationAnalysis, error) { - if !orcraft.IsRaftEnabled() { - return analysisEntries, nil - } - if !config.Config.ExpectFailureAnalysisConcensus { - return analysisEntries, nil - } - concensusAnalysisEntries := []ReplicationAnalysis{} - peerAnalysisMap, err := ReadPeerAnalysisMap() - if err != nil { - return analysisEntries, err - } - quorumSize, err := orcraft.QuorumSize() - if err != nil { - return analysisEntries, err - } - - for _, analysisEntry := range analysisEntries { - instanceAnalysis := NewInstanceAnalysis(&analysisEntry.AnalyzedInstanceKey, analysisEntry.Analysis) - analysisKey := instanceAnalysis.String() - - peerAnalysisCount := peerAnalysisMap[analysisKey] - if 1+peerAnalysisCount >= quorumSize { - // this node and enough other nodes in agreement - concensusAnalysisEntries = append(concensusAnalysisEntries, analysisEntry) - } - } - return concensusAnalysisEntries, nil -} - // auditInstanceAnalysisInChangelog will write down an instance's analysis in the database_instance_analysis_changelog table. // To not repeat recurring analysis code, the database_instance_last_analysis table is used, so that only changes to // analysis codes are written. diff --git a/go/vt/orchestrator/inst/candidate_database_instance_dao.go b/go/vt/orchestrator/inst/candidate_database_instance_dao.go index 0bcc5e8e950..d0d108bd9db 100644 --- a/go/vt/orchestrator/inst/candidate_database_instance_dao.go +++ b/go/vt/orchestrator/inst/candidate_database_instance_dao.go @@ -17,8 +17,6 @@ package inst import ( - "fmt" - "vitess.io/vitess/go/vt/orchestrator/external/golib/log" "vitess.io/vitess/go/vt/orchestrator/external/golib/sqlutils" @@ -33,7 +31,7 @@ func RegisterCandidateInstance(candidate *CandidateDatabaseInstance) error { } args := sqlutils.Args(candidate.Hostname, candidate.Port, string(candidate.PromotionRule), candidate.LastSuggestedString) - query := fmt.Sprintf(` + query := ` insert into candidate_database_instance ( hostname, port, @@ -44,7 +42,7 @@ func RegisterCandidateInstance(candidate *CandidateDatabaseInstance) error { ) on duplicate key update last_suggested=values(last_suggested), promotion_rule=values(promotion_rule) - `) + ` writeFunc := func() error { _, err := db.ExecOrchestrator(query, args...) AuditOperation("register-candidate", candidate.Key(), string(candidate.PromotionRule)) diff --git a/go/vt/orchestrator/inst/downtime.go b/go/vt/orchestrator/inst/downtime.go index 90ab2ece22c..7110df1e60b 100644 --- a/go/vt/orchestrator/inst/downtime.go +++ b/go/vt/orchestrator/inst/downtime.go @@ -48,5 +48,5 @@ func (downtime *Downtime) Ended() bool { } func (downtime *Downtime) EndsIn() time.Duration { - return downtime.EndsAt.Sub(time.Now()) + return time.Until(downtime.EndsAt) } diff --git a/go/vt/orchestrator/inst/instance.go b/go/vt/orchestrator/inst/instance.go index 7bd2638934c..71531c00e30 100644 --- a/go/vt/orchestrator/inst/instance.go +++ b/go/vt/orchestrator/inst/instance.go @@ -264,10 +264,7 @@ func (this *Instance) IsReplicationGroupSecondary() bool { // IsBinlogServer checks whether this is any type of a binlog server (currently only maxscale) func (this *Instance) IsBinlogServer() bool { - if this.isMaxScale() { - return true - } - return false + return this.isMaxScale() } // IsOracleMySQL checks whether this is an Oracle MySQL distribution @@ -636,6 +633,6 @@ func (this *Instance) HumanReadableDescription() string { // TabulatedDescription returns a simple tabulated string of various properties func (this *Instance) TabulatedDescription(separator string) string { tokens := this.descriptionTokens() - description := fmt.Sprintf("%s", strings.Join(tokens, separator)) + description := strings.Join(tokens, separator) return description } diff --git a/go/vt/orchestrator/inst/instance_binlog.go b/go/vt/orchestrator/inst/instance_binlog.go index 267cfd7ba08..ec39f9ddaf0 100644 --- a/go/vt/orchestrator/inst/instance_binlog.go +++ b/go/vt/orchestrator/inst/instance_binlog.go @@ -169,7 +169,7 @@ func (this *BinlogEventCursor) nextRealEvent(recursionLevel int) (*BinlogEvent, return this.nextRealEvent(recursionLevel + 1) } for _, skipSubstring := range config.Config.SkipBinlogEventsContaining { - if strings.Index(event.Info, skipSubstring) >= 0 { + if strings.Contains(event.Info, skipSubstring) { // Recursion might go deeper here. return this.nextRealEvent(recursionLevel + 1) } diff --git a/go/vt/orchestrator/inst/instance_binlog_dao.go b/go/vt/orchestrator/inst/instance_binlog_dao.go index 2dcf1f1e1db..cd390e1a8cf 100644 --- a/go/vt/orchestrator/inst/instance_binlog_dao.go +++ b/go/vt/orchestrator/inst/instance_binlog_dao.go @@ -31,7 +31,6 @@ import ( ) const maxEmptyBinlogFiles int = 10 -const maxEventInfoDisplayLength int = 200 var instanceBinlogEntryCache *cache.Cache @@ -521,7 +520,7 @@ func SearchEntryInInstanceBinlogs(instance *Instance, entryText string, monotoni } } var resultCoordinates BinlogCoordinates - var found bool = false + var found bool resultCoordinates, found, err = SearchEntryInBinlog(pseudoGTIDRegexp, &instance.Key, currentBinlog.LogFile, entryText, monotonicPseudoGTIDEntries, minBinlogCoordinates) if err != nil { break @@ -660,7 +659,7 @@ const anonymousGTIDNextEvent = "SET @@SESSION.GTID_NEXT= 'ANONYMOUS'" // check if the event is one we want to skip. func specialEventToSkip(event *BinlogEvent) bool { - if event != nil && strings.Index(event.Info, anonymousGTIDNextEvent) >= 0 { + if event != nil && strings.Contains(event.Info, anonymousGTIDNextEvent) { return true } return false diff --git a/go/vt/orchestrator/inst/instance_dao.go b/go/vt/orchestrator/inst/instance_dao.go index 5e0f2ce2664..e0fb3bdeacb 100644 --- a/go/vt/orchestrator/inst/instance_dao.go +++ b/go/vt/orchestrator/inst/instance_dao.go @@ -126,7 +126,7 @@ func initializeInstanceDao() { clusterInjectedPseudoGTIDCache = cache.New(time.Minute, time.Second) // spin off instance write buffer flushing go func() { - flushTick := time.Tick(time.Duration(config.Config.InstanceFlushIntervalMilliseconds) * time.Millisecond) + flushTick := time.Tick(time.Duration(config.Config.InstanceFlushIntervalMilliseconds) * time.Millisecond) //nolint SA1015: using time.Tick leaks the underlying ticker for { // it is time to flush select { @@ -1353,7 +1353,7 @@ func ReadInstance(instanceKey *InstanceKey) (*Instance, bool, error) { // ReadClusterInstances reads all instances of a given cluster func ReadClusterInstances(clusterName string) ([](*Instance), error) { - if strings.Index(clusterName, "'") >= 0 { + if strings.Contains(clusterName, "'") { return [](*Instance){}, log.Errorf("Invalid cluster name: %s", clusterName) } condition := `cluster_name = ?` @@ -1655,10 +1655,10 @@ func filterOSCInstances(instances [](*Instance)) [](*Instance) { // GetClusterOSCReplicas returns a heuristic list of replicas which are fit as controll replicas for an OSC operation. // These would be intermediate masters func GetClusterOSCReplicas(clusterName string) ([](*Instance), error) { - intermediateMasters := [](*Instance){} + var intermediateMasters [](*Instance) result := [](*Instance){} var err error - if strings.Index(clusterName, "'") >= 0 { + if strings.Contains(clusterName, "'") { return [](*Instance){}, log.Errorf("Invalid cluster name: %s", clusterName) } { @@ -2538,7 +2538,7 @@ func mkInsertOdkuForInstances(instances []*Instance, instanceWasActuallyFound bo "replication_group_primary_port", } - var values []string = make([]string, len(columns), len(columns)) + var values []string = make([]string, len(columns)) for i := range columns { values[i] = "?" } diff --git a/go/vt/orchestrator/inst/instance_key.go b/go/vt/orchestrator/inst/instance_key.go index 3714f7db77b..1530b397881 100644 --- a/go/vt/orchestrator/inst/instance_key.go +++ b/go/vt/orchestrator/inst/instance_key.go @@ -32,11 +32,11 @@ type InstanceKey struct { } var ( - ipv4Regexp = regexp.MustCompile("^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$") - ipv4HostPortRegexp = regexp.MustCompile("^([^:]+):([0-9]+)$") - ipv4HostRegexp = regexp.MustCompile("^([^:]+)$") - ipv6HostPortRegexp = regexp.MustCompile("^\\[([:0-9a-fA-F]+)\\]:([0-9]+)$") // e.g. [2001:db8:1f70::999:de8:7648:6e8]:3308 - ipv6HostRegexp = regexp.MustCompile("^([:0-9a-fA-F]+)$") // e.g. 2001:db8:1f70::999:de8:7648:6e8 + ipv4Regexp = regexp.MustCompile(`^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$`) + ipv4HostPortRegexp = regexp.MustCompile(`^([^:]+):([0-9]+)$`) + ipv4HostRegexp = regexp.MustCompile(`^([^:]+)$`) + ipv6HostPortRegexp = regexp.MustCompile(`^\[([:0-9a-fA-F]+)\]:([0-9]+)$`) // e.g. [2001:db8:1f70::999:de8:7648:6e8]:3308 + ipv6HostRegexp = regexp.MustCompile(`^([:0-9a-fA-F]+)$`) // e.g. 2001:db8:1f70::999:de8:7648:6e8 ) const detachHint = "//" diff --git a/go/vt/orchestrator/inst/instance_test.go b/go/vt/orchestrator/inst/instance_test.go index e47c745860b..c775a9e876f 100644 --- a/go/vt/orchestrator/inst/instance_test.go +++ b/go/vt/orchestrator/inst/instance_test.go @@ -32,7 +32,6 @@ func init() { var instance1 = Instance{Key: key1} var instance2 = Instance{Key: key2} -var instance3 = Instance{Key: key3} func TestIsSmallerMajorVersion(t *testing.T) { i55 := Instance{Version: "5.5"} diff --git a/go/vt/orchestrator/inst/instance_topology.go b/go/vt/orchestrator/inst/instance_topology.go index fd43900f78c..f2f787c54f0 100644 --- a/go/vt/orchestrator/inst/instance_topology.go +++ b/go/vt/orchestrator/inst/instance_topology.go @@ -36,8 +36,8 @@ type StopReplicationMethod string const ( NoStopReplication StopReplicationMethod = "NoStopReplication" - StopReplicationNormal = "StopReplicationNormal" - StopReplicationNice = "StopReplicationNice" + StopReplicationNormal StopReplicationMethod = "StopReplicationNormal" + StopReplicationNice StopReplicationMethod = "StopReplicationNice" ) var ReplicationNotRunningError = fmt.Errorf("Replication not running") @@ -249,7 +249,7 @@ func MoveEquivalent(instanceKey, otherKey *InstanceKey) (*Instance, error) { err = fmt.Errorf("MoveEquivalent(): ExecBinlogCoordinates changed after stopping replication on %+v; aborting", instance.Key) goto Cleanup } - instance, err = ChangeMasterTo(instanceKey, otherKey, binlogCoordinates, false, GTIDHintNeutral) + _, err = ChangeMasterTo(instanceKey, otherKey, binlogCoordinates, false, GTIDHintNeutral) Cleanup: instance, _ = StartReplication(instanceKey) @@ -286,7 +286,7 @@ func MoveUp(instanceKey *InstanceKey) (*Instance, error) { return instance, fmt.Errorf("master is not a replica itself: %+v", master.Key) } - if canReplicate, err := instance.CanReplicateFrom(master); canReplicate == false { + if canReplicate, err := instance.CanReplicateFrom(master); !canReplicate { return instance, err } if master.IsBinlogServer() { @@ -322,14 +322,14 @@ func MoveUp(instanceKey *InstanceKey) (*Instance, error) { } if !instance.UsingMariaDBGTID { - instance, err = StartReplicationUntilMasterCoordinates(instanceKey, &master.SelfBinlogCoordinates) + _, err = StartReplicationUntilMasterCoordinates(instanceKey, &master.SelfBinlogCoordinates) if err != nil { goto Cleanup } } // We can skip hostname unresolve; we just copy+paste whatever our master thinks of its master. - instance, err = ChangeMasterTo(instanceKey, &master.MasterKey, &master.ExecBinlogCoordinates, true, GTIDHintDeny) + _, err = ChangeMasterTo(instanceKey, &master.MasterKey, &master.ExecBinlogCoordinates, true, GTIDHintDeny) if err != nil { goto Cleanup } @@ -416,7 +416,7 @@ func MoveUpReplicas(instanceKey *InstanceKey, pattern string) ([](*Instance), *I var replicaErr error ExecuteOnTopology(func() { - if canReplicate, err := replica.CanReplicateFrom(instance); canReplicate == false || err != nil { + if canReplicate, err := replica.CanReplicateFrom(instance); !canReplicate || err != nil { replicaErr = err return } @@ -542,7 +542,7 @@ func MoveBelow(instanceKey, siblingKey *InstanceKey) (*Instance, error) { goto Cleanup } if instance.ExecBinlogCoordinates.SmallerThan(&sibling.ExecBinlogCoordinates) { - instance, err = StartReplicationUntilMasterCoordinates(instanceKey, &sibling.ExecBinlogCoordinates) + _, err = StartReplicationUntilMasterCoordinates(instanceKey, &sibling.ExecBinlogCoordinates) if err != nil { goto Cleanup } @@ -554,14 +554,14 @@ func MoveBelow(instanceKey, siblingKey *InstanceKey) (*Instance, error) { } // At this point both siblings have executed exact same statements and are identical - instance, err = ChangeMasterTo(instanceKey, &sibling.Key, &sibling.SelfBinlogCoordinates, false, GTIDHintDeny) + _, err = ChangeMasterTo(instanceKey, &sibling.Key, &sibling.SelfBinlogCoordinates, false, GTIDHintDeny) if err != nil { goto Cleanup } Cleanup: instance, _ = StartReplication(instanceKey) - sibling, _ = StartReplication(siblingKey) + _, _ = StartReplication(siblingKey) if err != nil { return instance, log.Errore(err) @@ -635,12 +635,12 @@ func moveInstanceBelowViaGTID(instance, otherInstance *Instance) (*Instance, err defer EndMaintenance(maintenanceToken) } - instance, err = StopReplication(instanceKey) + _, err = StopReplication(instanceKey) if err != nil { goto Cleanup } - instance, err = ChangeMasterTo(instanceKey, &otherInstance.Key, &otherInstance.SelfBinlogCoordinates, false, GTIDHintForce) + _, err = ChangeMasterTo(instanceKey, &otherInstance.Key, &otherInstance.SelfBinlogCoordinates, false, GTIDHintForce) if err != nil { goto Cleanup } @@ -831,7 +831,7 @@ func Repoint(instanceKey *InstanceKey, masterKey *InstanceKey, gtidHint Operatio if instance.ExecBinlogCoordinates.IsEmpty() { instance.ExecBinlogCoordinates.LogFile = "orchestrator-unknown-log-file" } - instance, err = ChangeMasterTo(instanceKey, masterKey, &instance.ExecBinlogCoordinates, !masterIsAccessible, gtidHint) + _, err = ChangeMasterTo(instanceKey, masterKey, &instance.ExecBinlogCoordinates, !masterIsAccessible, gtidHint) if err != nil { goto Cleanup } @@ -1062,13 +1062,13 @@ func ResetReplicationOperation(instanceKey *InstanceKey) (*Instance, error) { } if instance.IsReplica() { - instance, err = StopReplication(instanceKey) + _, err = StopReplication(instanceKey) if err != nil { goto Cleanup } } - instance, err = ResetReplication(instanceKey) + _, err = ResetReplication(instanceKey) if err != nil { goto Cleanup } @@ -1114,7 +1114,7 @@ func DetachReplicaMasterHost(instanceKey *InstanceKey) (*Instance, error) { goto Cleanup } - instance, err = ChangeMasterTo(instanceKey, detachedMasterKey, &instance.ExecBinlogCoordinates, true, GTIDHintNeutral) + _, err = ChangeMasterTo(instanceKey, detachedMasterKey, &instance.ExecBinlogCoordinates, true, GTIDHintNeutral) if err != nil { goto Cleanup } @@ -1159,7 +1159,7 @@ func ReattachReplicaMasterHost(instanceKey *InstanceKey) (*Instance, error) { goto Cleanup } - instance, err = ChangeMasterTo(instanceKey, reattachedMasterKey, &instance.ExecBinlogCoordinates, true, GTIDHintNeutral) + _, err = ChangeMasterTo(instanceKey, reattachedMasterKey, &instance.ExecBinlogCoordinates, true, GTIDHintNeutral) if err != nil { goto Cleanup } @@ -1476,7 +1476,7 @@ func CorrelateBinlogCoordinates(instance *Instance, binlogCoordinates *BinlogCoo return nil, 0, err } entriesMonotonic := (config.Config.PseudoGTIDMonotonicHint != "") && strings.Contains(instancePseudoGtidText, config.Config.PseudoGTIDMonotonicHint) - minBinlogCoordinates, _, err := GetHeuristiclyRecentCoordinatesForInstance(&otherInstance.Key) + minBinlogCoordinates, _, _ := GetHeuristiclyRecentCoordinatesForInstance(&otherInstance.Key) otherInstancePseudoGtidCoordinates, err := SearchEntryInInstanceBinlogs(otherInstance, instancePseudoGtidText, entriesMonotonic, minBinlogCoordinates) if err != nil { return nil, 0, err @@ -1605,7 +1605,7 @@ func MatchBelow(instanceKey, otherKey *InstanceKey, requireInstanceMaintenance b goto Cleanup } - nextBinlogCoordinatesToMatch, countMatchedEvents, err = CorrelateBinlogCoordinates(instance, nil, otherInstance) + nextBinlogCoordinatesToMatch, countMatchedEvents, _ = CorrelateBinlogCoordinates(instance, nil, otherInstance) if countMatchedEvents == 0 { err = fmt.Errorf("Unexpected: 0 events processed while iterating logs. Something went wrong; aborting. nextBinlogCoordinatesToMatch: %+v", nextBinlogCoordinatesToMatch) @@ -1614,7 +1614,7 @@ func MatchBelow(instanceKey, otherKey *InstanceKey, requireInstanceMaintenance b log.Debugf("%+v will match below %+v at %+v; validated events: %d", *instanceKey, *otherKey, *nextBinlogCoordinatesToMatch, countMatchedEvents) // Drum roll... - instance, err = ChangeMasterTo(instanceKey, otherKey, nextBinlogCoordinatesToMatch, false, GTIDHintDeny) + _, err = ChangeMasterTo(instanceKey, otherKey, nextBinlogCoordinatesToMatch, false, GTIDHintDeny) if err != nil { goto Cleanup } @@ -1730,8 +1730,8 @@ func TakeMasterHook(successor *Instance, demoted *Instance) { env = append(env, fmt.Sprintf("ORC_SUCCESSOR_HOST=%s", successorKey)) env = append(env, fmt.Sprintf("ORC_FAILED_HOST=%s", demotedKey)) - successorStr := fmt.Sprintf("%s", successorKey) - demotedStr := fmt.Sprintf("%s", demotedKey) + successorStr := fmt.Sprintf("%v", successorKey) + demotedStr := fmt.Sprintf("%v", demotedKey) processCount := len(config.Config.PostTakeMasterProcesses) for i, command := range config.Config.PostTakeMasterProcesses { @@ -1773,7 +1773,7 @@ func TakeMaster(instanceKey *InstanceKey, allowTakingCoMaster bool) (*Instance, } log.Debugf("TakeMaster: will attempt making %+v take its master %+v, now resolved as %+v", *instanceKey, instance.MasterKey, masterInstance.Key) - if canReplicate, err := masterInstance.CanReplicateFrom(instance); canReplicate == false { + if canReplicate, err := masterInstance.CanReplicateFrom(instance); !canReplicate { return instance, err } // We begin @@ -2830,11 +2830,6 @@ func relocateReplicasInternal(replicas [](*Instance), instance, other *Instance) return pseudoGTIDReplicas, err, errs } - // Normal binlog file:pos - if InstanceIsMasterOf(other, instance) { - // MoveUpReplicas -- but not supporting "replicas" argument at this time. - } - // Too complex return nil, log.Errorf("Relocating %+v replicas of %+v below %+v turns to be too complex; please do it manually", len(replicas), instance.Key, other.Key), errs } diff --git a/go/vt/orchestrator/inst/instance_topology_dao.go b/go/vt/orchestrator/inst/instance_topology_dao.go index faa3b2f4898..956d7b5e78d 100644 --- a/go/vt/orchestrator/inst/instance_topology_dao.go +++ b/go/vt/orchestrator/inst/instance_topology_dao.go @@ -41,8 +41,8 @@ type OperationGTIDHint string const ( GTIDHintDeny OperationGTIDHint = "NoGTID" - GTIDHintNeutral = "GTIDHintNeutral" - GTIDHintForce = "GTIDHintForce" + GTIDHintNeutral OperationGTIDHint = "GTIDHintNeutral" + GTIDHintForce OperationGTIDHint = "GTIDHintForce" ) const ( @@ -524,7 +524,6 @@ func WaitForExecBinlogCoordinatesToReach(instanceKey *InstanceKey, coordinates * return instance, false, nil } } - return instance, exactMatch, err } // StartReplicationUntilMasterCoordinates issuesa START SLAVE UNTIL... statement on given instance diff --git a/go/vt/orchestrator/inst/pool_dao.go b/go/vt/orchestrator/inst/pool_dao.go index c8fd337db22..3d87d52d5c5 100644 --- a/go/vt/orchestrator/inst/pool_dao.go +++ b/go/vt/orchestrator/inst/pool_dao.go @@ -32,7 +32,7 @@ func writePoolInstances(pool string, instanceKeys [](*InstanceKey)) error { if err != nil { return log.Errore(err) } - tx, err := dbh.Begin() + tx, _ := dbh.Begin() if _, err := tx.Exec(`delete from database_instance_pool where pool = ?`, pool); err != nil { tx.Rollback() return log.Errore(err) diff --git a/go/vt/orchestrator/inst/replication_thread_state.go b/go/vt/orchestrator/inst/replication_thread_state.go index 2259aa74550..4a63d2deb05 100644 --- a/go/vt/orchestrator/inst/replication_thread_state.go +++ b/go/vt/orchestrator/inst/replication_thread_state.go @@ -20,9 +20,9 @@ type ReplicationThreadState int const ( ReplicationThreadStateNoThread ReplicationThreadState = -1 - ReplicationThreadStateStopped = 0 - ReplicationThreadStateRunning = 1 - ReplicationThreadStateOther = 2 + ReplicationThreadStateStopped ReplicationThreadState = 0 + ReplicationThreadStateRunning ReplicationThreadState = 1 + ReplicationThreadStateOther ReplicationThreadState = 2 ) func ReplicationThreadStateFromStatus(status string) ReplicationThreadState { diff --git a/go/vt/orchestrator/inst/resolve_dao.go b/go/vt/orchestrator/inst/resolve_dao.go index 19a8f19f7d1..94644c91088 100644 --- a/go/vt/orchestrator/inst/resolve_dao.go +++ b/go/vt/orchestrator/inst/resolve_dao.go @@ -57,7 +57,7 @@ func WriteResolvedHostname(hostname string, resolvedHostname string) error { } if hostname != resolvedHostname { // history is only interesting when there's actually something to resolve... - _, err = db.ExecOrchestrator(` + _, _ = db.ExecOrchestrator(` insert into hostname_resolve_history (hostname, resolved_hostname, resolved_timestamp) values @@ -182,33 +182,6 @@ func readUnresolvedHostname(hostname string) (string, error) { return unresolvedHostname, err } -// readMissingHostnamesToResolve gets those (unresolved, e.g. VIP) hostnames that *should* be present in -// the hostname_resolve table, but aren't. -func readMissingKeysToResolve() (result InstanceKeyMap, err error) { - query := ` - select - hostname_unresolve.unresolved_hostname, - database_instance.port - from - database_instance - join hostname_unresolve on (database_instance.hostname = hostname_unresolve.hostname) - left join hostname_resolve on (database_instance.hostname = hostname_resolve.resolved_hostname) - where - hostname_resolve.hostname is null - ` - - err = db.QueryOrchestratorRowsMap(query, func(m sqlutils.RowMap) error { - instanceKey := InstanceKey{Hostname: m.GetString("unresolved_hostname"), Port: m.GetInt("port")} - result.AddKey(instanceKey) - return nil - }) - - if err != nil { - log.Errore(err) - } - return result, err -} - // WriteHostnameUnresolve upserts an entry in hostname_unresolve func WriteHostnameUnresolve(instanceKey *InstanceKey, unresolvedHostname string) error { writeFunc := func() error { @@ -226,7 +199,7 @@ func WriteHostnameUnresolve(instanceKey *InstanceKey, unresolvedHostname string) if err != nil { return log.Errore(err) } - _, err = db.ExecOrchestrator(` + _, _ = db.ExecOrchestrator(` replace into hostname_unresolve_history ( hostname, unresolved_hostname, diff --git a/go/vt/orchestrator/inst/tag.go b/go/vt/orchestrator/inst/tag.go index 5d54d46cdb4..c6eee576e9a 100644 --- a/go/vt/orchestrator/inst/tag.go +++ b/go/vt/orchestrator/inst/tag.go @@ -80,7 +80,7 @@ func (tag *Tag) String() string { func (tag *Tag) Display() string { if tag.TagValue == "" { - return fmt.Sprintf("%s", tag.TagName) + return tag.TagName } else { return fmt.Sprintf("%s=%s", tag.TagName, tag.TagValue) } diff --git a/go/vt/orchestrator/inst/tag_dao.go b/go/vt/orchestrator/inst/tag_dao.go index fb5fea18992..cf301788f16 100644 --- a/go/vt/orchestrator/inst/tag_dao.go +++ b/go/vt/orchestrator/inst/tag_dao.go @@ -54,7 +54,7 @@ func Untag(instanceKey *InstanceKey, tag *Tag) (tagged *InstanceKeyMap, err erro if instanceKey == nil && !tag.HasValue { return nil, log.Errorf("Untag: either indicate an instance or a tag value. Will not delete on-valued tag across instances") } - clause := `` + var clause string args := sqlutils.Args() if tag.HasValue { clause = `tag_name=? and tag_value=?` @@ -79,7 +79,7 @@ func Untag(instanceKey *InstanceKey, tag *Tag) (tagged *InstanceKeyMap, err erro order by hostname, port `, clause, ) - err = db.QueryOrchestrator(query, args, func(m sqlutils.RowMap) error { + _ = db.QueryOrchestrator(query, args, func(m sqlutils.RowMap) error { key, _ := NewResolveInstanceKey(m.GetString("hostname"), m.GetInt("port")) tagged.AddKey(*key) return nil diff --git a/go/vt/orchestrator/inst/tag_test.go b/go/vt/orchestrator/inst/tag_test.go index 8551cd7b707..5ad9943fa83 100644 --- a/go/vt/orchestrator/inst/tag_test.go +++ b/go/vt/orchestrator/inst/tag_test.go @@ -6,6 +6,7 @@ import ( test "vitess.io/vitess/go/vt/orchestrator/external/golib/tests" ) +//nolint:staticcheck func TestParseTag(t *testing.T) { { tag, err := ParseTag("") From 2b876f1de5433f09898e01392a7450233f27e429 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Fri, 14 Aug 2020 12:11:41 -0700 Subject: [PATCH 3/5] orc: lint part 3 Signed-off-by: Sugu Sougoumarane --- go/vt/orchestrator/app/http.go | 2 +- go/vt/orchestrator/kv/consul.go | 12 +++-- go/vt/orchestrator/logic/orchestrator.go | 5 +- go/vt/orchestrator/logic/topology_recovery.go | 52 +++++++++---------- .../logic/topology_recovery_dao.go | 8 +-- go/vt/orchestrator/process/election_dao.go | 2 +- go/vt/orchestrator/process/health.go | 4 +- go/vt/orchestrator/raft/file_snapshot.go | 5 +- go/vt/orchestrator/raft/raft.go | 1 + go/vt/orchestrator/ssl/ssl.go | 2 +- 10 files changed, 47 insertions(+), 46 deletions(-) diff --git a/go/vt/orchestrator/app/http.go b/go/vt/orchestrator/app/http.go index 21693fe2ded..8a81794807d 100644 --- a/go/vt/orchestrator/app/http.go +++ b/go/vt/orchestrator/app/http.go @@ -47,7 +47,7 @@ var discoveryMetrics *collection.Collection // Http starts serving func Http(continuousDiscovery bool) { promptForSSLPasswords() - process.ContinuousRegistration(process.OrchestratorExecutionHttpMode, "") + process.ContinuousRegistration(string(process.OrchestratorExecutionHttpMode), "") martini.Env = martini.Prod if config.Config.ServeAgentsHttp { diff --git a/go/vt/orchestrator/kv/consul.go b/go/vt/orchestrator/kv/consul.go index 36d2e3fea9d..a5f5e916f74 100644 --- a/go/vt/orchestrator/kv/consul.go +++ b/go/vt/orchestrator/kv/consul.go @@ -33,10 +33,9 @@ import ( // A Consul store based on config's `ConsulAddress`, `ConsulScheme`, and `ConsulKVPrefix` type consulStore struct { - client *consulapi.Client - kvCache *cache.Cache - pairsDistributionSuccessMutex sync.Mutex - distributionReentry int64 + client *consulapi.Client + kvCache *cache.Cache + distributionReentry int64 } // NewConsulStore creates a new consul store. It is possible that the client for this store is nil, @@ -83,7 +82,10 @@ func (this *consulStore) GetKeyValue(key string) (value string, found bool, err if err != nil { return value, found, err } - return string(pair.Value), (pair != nil), nil + if pair == nil { + return "", false, err + } + return string(pair.Value), true, nil } func (this *consulStore) DistributePairs(kvPairs [](*KVPair)) (err error) { diff --git a/go/vt/orchestrator/logic/orchestrator.go b/go/vt/orchestrator/logic/orchestrator.go index 6a2b3560ccc..b44017fac2a 100644 --- a/go/vt/orchestrator/logic/orchestrator.go +++ b/go/vt/orchestrator/logic/orchestrator.go @@ -226,7 +226,7 @@ func DiscoverInstance(instanceKey inst.InstanceKey) { } latency.Start("backend") - instance, found, err := inst.ReadInstance(&instanceKey) + instance, found, _ := inst.ReadInstance(&instanceKey) latency.Stop("backend") if found && instance.IsUpToDate && instance.IsLastCheckValid { // we've already discovered this one. Skip! @@ -236,7 +236,7 @@ func DiscoverInstance(instanceKey inst.InstanceKey) { discoveriesCounter.Inc(1) // First we've ever heard of this instance. Continue investigation: - instance, err = inst.ReadTopologyInstanceBufferable(&instanceKey, config.Config.BufferInstanceWrites, latency) + instance, err := inst.ReadTopologyInstanceBufferable(&instanceKey, config.Config.BufferInstanceWrites, latency) // panic can occur (IO stuff). Therefore it may happen // that instance is nil. Check it, but first get the timing metrics. totalLatency := latency.Elapsed("total") @@ -476,6 +476,7 @@ func injectSeeds(seedOnce *sync.Once) { // ContinuousDiscovery starts an asynchronuous infinite discovery process where instances are // periodically investigated and their status captured, and long since unseen instances are // purged and forgotten. +//nolint SA1015: using time.Tick leaks the underlying ticker func ContinuousDiscovery() { log.Infof("continuous discovery: setting up") continuousDiscoveryStartTime := time.Now() diff --git a/go/vt/orchestrator/logic/topology_recovery.go b/go/vt/orchestrator/logic/topology_recovery.go index 858c989d6b2..27e871ff1ae 100644 --- a/go/vt/orchestrator/logic/topology_recovery.go +++ b/go/vt/orchestrator/logic/topology_recovery.go @@ -46,8 +46,8 @@ type RecoveryType string const ( MasterRecovery RecoveryType = "MasterRecovery" - CoMasterRecovery = "CoMasterRecovery" - IntermediateMasterRecovery = "IntermediateMasterRecovery" + CoMasterRecovery RecoveryType = "CoMasterRecovery" + IntermediateMasterRecovery RecoveryType = "IntermediateMasterRecovery" ) type RecoveryAcknowledgement struct { @@ -158,9 +158,9 @@ type MasterRecoveryType string const ( NotMasterRecovery MasterRecoveryType = "NotMasterRecovery" - MasterRecoveryGTID = "MasterRecoveryGTID" - MasterRecoveryPseudoGTID = "MasterRecoveryPseudoGTID" - MasterRecoveryBinlogServer = "MasterRecoveryBinlogServer" + MasterRecoveryGTID MasterRecoveryType = "MasterRecoveryGTID" + MasterRecoveryPseudoGTID MasterRecoveryType = "MasterRecoveryPseudoGTID" + MasterRecoveryBinlogServer MasterRecoveryType = "MasterRecoveryBinlogServer" ) var emergencyReadTopologyInstanceMap *cache.Cache @@ -531,17 +531,17 @@ func recoverDeadMaster(topologyRecovery *TopologyRecovery, candidateInstanceKey switch topologyRecovery.RecoveryType { case MasterRecoveryGTID: { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("RecoverDeadMaster: regrouping replicas via GTID")) + AuditTopologyRecovery(topologyRecovery, "RecoverDeadMaster: regrouping replicas via GTID") lostReplicas, _, cannotReplicateReplicas, promotedReplica, err = inst.RegroupReplicasGTID(failedInstanceKey, true, nil, &topologyRecovery.PostponedFunctionsContainer, promotedReplicaIsIdeal) } case MasterRecoveryPseudoGTID: { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("RecoverDeadMaster: regrouping replicas via Pseudo-GTID")) + AuditTopologyRecovery(topologyRecovery, "RecoverDeadMaster: regrouping replicas via Pseudo-GTID") lostReplicas, _, _, cannotReplicateReplicas, promotedReplica, err = inst.RegroupReplicasPseudoGTIDIncludingSubReplicasOfBinlogServers(failedInstanceKey, true, nil, &topologyRecovery.PostponedFunctionsContainer, promotedReplicaIsIdeal) } case MasterRecoveryBinlogServer: { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("RecoverDeadMaster: recovering via binlog servers")) + AuditTopologyRecovery(topologyRecovery, "RecoverDeadMaster: recovering via binlog servers") promotedReplica, err = recoverDeadMasterInBinlogServerTopology(topologyRecovery) } } @@ -622,9 +622,9 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de // Maybe we promoted a "prefer_not" // Maybe we promoted a server in a different DC than the master // There's many options. We may wish to replace the server we promoted with a better one. - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("checking if should replace promoted replica with a better candidate")) + AuditTopologyRecovery(topologyRecovery, "checking if should replace promoted replica with a better candidate") if candidateInstanceKey == nil { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ checking if promoted replica is the ideal candidate")) + AuditTopologyRecovery(topologyRecovery, "+ checking if promoted replica is the ideal candidate") if deadInstance != nil { for _, candidateReplica := range candidateReplicas { if promotedReplica.Key.Equals(&candidateReplica.Key) && @@ -640,7 +640,7 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de // We didn't pick the ideal candidate; let's see if we can replace with a candidate from same DC and ENV if candidateInstanceKey == nil { // Try a candidate replica that is in same DC & env as the dead instance - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ searching for an ideal candidate")) + AuditTopologyRecovery(topologyRecovery, "+ searching for an ideal candidate") if deadInstance != nil { for _, candidateReplica := range candidateReplicas { if canTakeOverPromotedServerAsMaster(candidateReplica, promotedReplica) && @@ -655,7 +655,7 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de } if candidateInstanceKey == nil { // We cannot find a candidate in same DC and ENV as dead master - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ checking if promoted replica is an OK candidate")) + AuditTopologyRecovery(topologyRecovery, "+ checking if promoted replica is an OK candidate") for _, candidateReplica := range candidateReplicas { if promotedReplica.Key.Equals(&candidateReplica.Key) { // Seems like we promoted a candidate replica (though not in same DC and ENV as dead master) @@ -672,7 +672,7 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de // Still nothing? if candidateInstanceKey == nil { // Try a candidate replica that is in same DC & env as the promoted replica (our promoted replica is not an "is_candidate") - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ searching for a candidate")) + AuditTopologyRecovery(topologyRecovery, "+ searching for a candidate") for _, candidateReplica := range candidateReplicas { if canTakeOverPromotedServerAsMaster(candidateReplica, promotedReplica) && promotedReplica.DataCenter == candidateReplica.DataCenter && @@ -686,7 +686,7 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de // Still nothing? if candidateInstanceKey == nil { // Try a candidate replica (our promoted replica is not an "is_candidate") - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ searching for a candidate")) + AuditTopologyRecovery(topologyRecovery, "+ searching for a candidate") for _, candidateReplica := range candidateReplicas { if canTakeOverPromotedServerAsMaster(candidateReplica, promotedReplica) { if satisfied, reason := MasterFailoverGeographicConstraintSatisfied(&topologyRecovery.AnalysisEntry, candidateReplica); satisfied { @@ -713,7 +713,7 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de if candidateInstanceKey == nil { // Still nothing? Then we didn't find a replica marked as "candidate". OK, further down the stream we have: // find neutral instance in same dv&env as dead master - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ searching for a neutral server to replace promoted server, in same DC and env as dead master")) + AuditTopologyRecovery(topologyRecovery, "+ searching for a neutral server to replace promoted server, in same DC and env as dead master") for _, neutralReplica := range neutralReplicas { if canTakeOverPromotedServerAsMaster(neutralReplica, promotedReplica) && deadInstance.DataCenter == neutralReplica.DataCenter && @@ -725,7 +725,7 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de } if candidateInstanceKey == nil { // find neutral instance in same dv&env as promoted replica - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ searching for a neutral server to replace promoted server, in same DC and env as promoted replica")) + AuditTopologyRecovery(topologyRecovery, "+ searching for a neutral server to replace promoted server, in same DC and env as promoted replica") for _, neutralReplica := range neutralReplicas { if canTakeOverPromotedServerAsMaster(neutralReplica, promotedReplica) && promotedReplica.DataCenter == neutralReplica.DataCenter && @@ -736,7 +736,7 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de } } if candidateInstanceKey == nil { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ searching for a neutral server to replace a prefer_not")) + AuditTopologyRecovery(topologyRecovery, "+ searching for a neutral server to replace a prefer_not") for _, neutralReplica := range neutralReplicas { if canTakeOverPromotedServerAsMaster(neutralReplica, promotedReplica) { if satisfied, reason := MasterFailoverGeographicConstraintSatisfied(&topologyRecovery.AnalysisEntry, neutralReplica); satisfied { @@ -754,12 +754,12 @@ func SuggestReplacementForPromotedReplica(topologyRecovery *TopologyRecovery, de // So do we have a candidate? if candidateInstanceKey == nil { // Found nothing. Stick with promoted replica - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ found no server to promote on top promoted replica")) + AuditTopologyRecovery(topologyRecovery, "+ found no server to promote on top promoted replica") return promotedReplica, false, nil } if promotedReplica.Key.Equals(candidateInstanceKey) { // Sanity. It IS the candidate, nothing to promote... - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("+ sanity check: found our very own server to promote; doing nothing")) + AuditTopologyRecovery(topologyRecovery, "+ sanity check: found our very own server to promote; doing nothing") return promotedReplica, false, nil } replacement, _, err = inst.ReadInstance(candidateInstanceKey) @@ -880,7 +880,7 @@ func checkAndRecoverDeadMaster(analysisEntry inst.ReplicationAnalysis, candidate if config.Config.ApplyMySQLPromotionAfterMasterFailover || analysisEntry.CommandHint == inst.GracefulMasterTakeoverCommandHint { // on GracefulMasterTakeoverCommandHint it makes utter sense to RESET SLAVE ALL and read_only=0, and there is no sense in not doing so. - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: will apply MySQL changes to promoted master")) + AuditTopologyRecovery(topologyRecovery, "- RecoverDeadMaster: will apply MySQL changes to promoted master") { _, err := inst.ResetReplicationOperation(&promotedReplica.Key) if err != nil { @@ -926,7 +926,7 @@ func checkAndRecoverDeadMaster(analysisEntry inst.ReplicationAnalysis, candidate } if config.Config.MasterFailoverDetachReplicaMasterHost { postponedFunction := func() error { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: detaching master host on promoted master")) + AuditTopologyRecovery(topologyRecovery, "- RecoverDeadMaster: detaching master host on promoted master") inst.DetachReplicaMasterHost(&promotedReplica.Key) return nil } @@ -1144,7 +1144,7 @@ func RecoverDeadIntermediateMaster(topologyRecovery *TopologyRecovery, skipProce relocateReplicasToCandidateSibling() } if !recoveryResolved { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadIntermediateMaster: will next attempt regrouping of replicas")) + AuditTopologyRecovery(topologyRecovery, "- RecoverDeadIntermediateMaster: will next attempt regrouping of replicas") // Plan B: regroup (we wish to reduce cross-DC replication streams) lostReplicas, _, _, _, regroupPromotedReplica, regroupError := inst.RegroupReplicas(failedInstanceKey, true, nil, nil) if regroupError != nil { @@ -1162,7 +1162,7 @@ func RecoverDeadIntermediateMaster(topologyRecovery *TopologyRecovery, skipProce } // Plan C: try replacement intermediate master in other DC... if candidateSiblingOfIntermediateMaster != nil && candidateSiblingOfIntermediateMaster.DataCenter != intermediateMasterInstance.DataCenter { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadIntermediateMaster: will next attempt relocating to another DC server")) + AuditTopologyRecovery(topologyRecovery, "- RecoverDeadIntermediateMaster: will next attempt relocating to another DC server") relocateReplicasToCandidateSibling() } } @@ -1175,7 +1175,7 @@ func RecoverDeadIntermediateMaster(topologyRecovery *TopologyRecovery, skipProce // So, match up all that's left, plan D AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadIntermediateMaster: will next attempt to relocate up from %+v", *failedInstanceKey)) - relocatedReplicas, masterInstance, err, errs := inst.RelocateReplicas(failedInstanceKey, &analysisEntry.AnalyzedInstanceMasterKey, "") + relocatedReplicas, masterInstance, _, errs := inst.RelocateReplicas(failedInstanceKey, &analysisEntry.AnalyzedInstanceMasterKey, "") topologyRecovery.AddErrors(errs) topologyRecovery.ParticipatingInstanceKeys.AddKey(analysisEntry.AnalyzedInstanceMasterKey) @@ -1379,7 +1379,7 @@ func checkAndRecoverDeadCoMaster(analysisEntry inst.ReplicationAnalysis, candida recoverDeadCoMasterSuccessCounter.Inc(1) if config.Config.ApplyMySQLPromotionAfterMasterFailover { - AuditTopologyRecovery(topologyRecovery, fmt.Sprintf("- RecoverDeadMaster: will apply MySQL changes to promoted master")) + AuditTopologyRecovery(topologyRecovery, "- RecoverDeadMaster: will apply MySQL changes to promoted master") inst.SetReadOnly(&promotedReplica.Key, false) } if !skipProcesses { @@ -1668,7 +1668,7 @@ func executeCheckAndRecoverFunction(analysisEntry inst.ReplicationAnalysis, cand if b, err := json.Marshal(topologyRecovery); err == nil { log.Infof("Topology recovery: %+v", string(b)) } else { - log.Infof("Topology recovery: %+v", *topologyRecovery) + log.Infof("Topology recovery: %+v", topologyRecovery) } if !skipProcesses { if topologyRecovery.SuccessorKey == nil { diff --git a/go/vt/orchestrator/logic/topology_recovery_dao.go b/go/vt/orchestrator/logic/topology_recovery_dao.go index c586ef03bb3..f80a955de18 100644 --- a/go/vt/orchestrator/logic/topology_recovery_dao.go +++ b/go/vt/orchestrator/logic/topology_recovery_dao.go @@ -269,7 +269,7 @@ func ClearActiveRecoveries() error { // RegisterBlockedRecoveries writes down currently blocked recoveries, and indicates what recovery they are blocked on. // Recoveries are blocked thru the in_active_period flag, which comes to avoid flapping. func RegisterBlockedRecoveries(analysisEntry *inst.ReplicationAnalysis, blockingRecoveries []TopologyRecovery) error { - for _, recovery := range blockingRecoveries { + for _, recovery := range blockingRecoveries { //nolint:govet _, err := db.ExecOrchestrator(` insert into blocked_topology_recovery ( @@ -424,7 +424,7 @@ func AcknowledgeClusterRecoveries(clusterName string, owner string, comment stri countAcknowledgedEntries = countAcknowledgedEntries + count } { - clusterInfo, err := inst.ReadClusterInfo(clusterName) + clusterInfo, _ := inst.ReadClusterInfo(clusterName) whereClause := `cluster_alias = ? and cluster_alias != ''` args := sqlutils.Args(clusterInfo.ClusterAlias) clearAcknowledgedFailureDetections(whereClause, args) @@ -578,7 +578,7 @@ func readRecoveries(whereCondition string, limit string, args []interface{}) ([] topologyRecovery.LastDetectionId = m.GetInt64("last_detection_id") - res = append(res, topologyRecovery) + res = append(res, topologyRecovery) //nolint:govet return nil }) @@ -737,7 +737,7 @@ func readFailureDetections(whereCondition string, limit string, args []interface failureDetection.AnalysisEntry.ClusterDetails.ReadRecoveryInfo() - res = append(res, failureDetection) + res = append(res, failureDetection) //nolint:govet return nil }) diff --git a/go/vt/orchestrator/process/election_dao.go b/go/vt/orchestrator/process/election_dao.go index e121e99ef94..23b4101b641 100644 --- a/go/vt/orchestrator/process/election_dao.go +++ b/go/vt/orchestrator/process/election_dao.go @@ -151,5 +151,5 @@ func ElectedNode() (node NodeHealth, isElected bool, err error) { }) isElected = (node.Hostname == ThisHostname && node.Token == util.ProcessToken.Hash) - return node, isElected, log.Errore(err) + return node, isElected, log.Errore(err) //nolint copylocks: return copies lock value } diff --git a/go/vt/orchestrator/process/health.go b/go/vt/orchestrator/process/health.go index cc1dd9f8e9d..81ae3d477da 100644 --- a/go/vt/orchestrator/process/health.go +++ b/go/vt/orchestrator/process/health.go @@ -89,7 +89,7 @@ type OrchestratorExecutionMode string const ( OrchestratorExecutionCliMode OrchestratorExecutionMode = "CLIMode" - OrchestratorExecutionHttpMode = "HttpMode" + OrchestratorExecutionHttpMode OrchestratorExecutionMode = "HttpMode" ) var continuousRegistrationOnce sync.Once @@ -135,7 +135,7 @@ func HealthTest() (health *HealthStatus, err error) { return health, log.Errore(err) } } - health.AvailableNodes, err = ReadAvailableNodes(true) + health.AvailableNodes, _ = ReadAvailableNodes(true) return health, nil } diff --git a/go/vt/orchestrator/raft/file_snapshot.go b/go/vt/orchestrator/raft/file_snapshot.go index c12cdbdf0c9..537ecebd57d 100644 --- a/go/vt/orchestrator/raft/file_snapshot.go +++ b/go/vt/orchestrator/raft/file_snapshot.go @@ -103,9 +103,6 @@ func NewFileSnapshotStoreWithLogger(base string, retain int) (*FileSnapshotStore // on a base directory. The `retain` parameter controls how many // snapshots are retained. Must be at least 1. func NewFileSnapshotStore(base string, retain int, logOutput io.Writer) (*FileSnapshotStore, error) { - if logOutput == nil { - logOutput = os.Stderr - } return NewFileSnapshotStoreWithLogger(base, retain) } @@ -300,7 +297,7 @@ func (f *FileSnapshotStore) Open(id string) (*raft.SnapshotMeta, io.ReadCloser, // Verify the hash computed := stateHash.Sum(nil) - if bytes.Compare(meta.CRC, computed) != 0 { + if !bytes.Equal(meta.CRC, computed) { _ = log.Errorf("snapshot: CRC checksum failed (stored: %v computed: %v)", meta.CRC, computed) fh.Close() diff --git a/go/vt/orchestrator/raft/raft.go b/go/vt/orchestrator/raft/raft.go index d68f1b550c5..e745aa10b6e 100644 --- a/go/vt/orchestrator/raft/raft.go +++ b/go/vt/orchestrator/raft/raft.go @@ -378,6 +378,7 @@ func HealthyMembers() (advertised []string) { // Monitor is a utility function to routinely observe leadership state. // It doesn't actually do much; merely takes notes. +//nolint SA1015: using time.Tick leaks the underlying ticker func Monitor() { t := time.Tick(5 * time.Second) heartbeat := time.Tick(1 * time.Minute) diff --git a/go/vt/orchestrator/ssl/ssl.go b/go/vt/orchestrator/ssl/ssl.go index 96a0a06c08d..3f20a5ae610 100644 --- a/go/vt/orchestrator/ssl/ssl.go +++ b/go/vt/orchestrator/ssl/ssl.go @@ -59,7 +59,7 @@ func NewTLSConfig(caFile string, verifyCert bool) (*tls.Config, error) { return &c, err } c.ClientCAs = caPool - c.BuildNameToCertificate() + c.BuildNameToCertificate() //nolint SA1019: c.BuildNameToCertificate is deprecated return &c, nil } From 430a3df70cd41da1d85378fca37cb6b69ccc6889 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Fri, 14 Aug 2020 12:56:29 -0700 Subject: [PATCH 4/5] orc: copy web files Signed-off-by: Sugu Sougoumarane --- .../public/bootstrap/css/bootstrap-theme.css | 347 + .../bootstrap/css/bootstrap-theme.css.map | 1 + .../bootstrap/css/bootstrap-theme.min.css | 7 + .../public/bootstrap/css/bootstrap.css | 5785 +++++++++++++++++ .../public/bootstrap/css/bootstrap.css.map | 1 + .../public/bootstrap/css/bootstrap.min.css | 7 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20335 bytes .../fonts/glyphicons-halflings-regular.svg | 229 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41280 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23320 bytes .../public/bootstrap/js/bootstrap.min.js | 6 + web/orchestrator/public/css/custom.css | 0 web/orchestrator/public/css/orchestrator.css | 1012 +++ .../public/images/ajax-loader.gif | Bin 0 -> 1849 bytes .../public/images/booking-logo-32.png | Bin 0 -> 629 bytes .../public/images/booking-logo-s.png | Bin 0 -> 1893 bytes ...nd-let-orchestrator-handle-it-transp-m.png | Bin 0 -> 26849 bytes .../public/images/octocat-logo-32.png | Bin 0 -> 1571 bytes .../public/images/orchestrator-logo-32.png | Bin 0 -> 1744 bytes .../public/images/outbrain-logo-32.png | Bin 0 -> 1334 bytes .../public/images/outbrain-logo-s.png | Bin 0 -> 2727 bytes web/orchestrator/public/images/tile.png | Bin 0 -> 140 bytes web/orchestrator/public/js/agent.js | 297 + web/orchestrator/public/js/agents.js | 32 + .../public/js/audit-failure-detection.js | 112 + .../public/js/audit-recovery-shared.js | 22 + web/orchestrator/public/js/audit-recovery.js | 226 + web/orchestrator/public/js/audit.js | 47 + web/orchestrator/public/js/bootbox.min.js | 6 + .../public/js/cluster-analysis-shared.js | 54 + web/orchestrator/public/js/cluster-pools.js | 126 + web/orchestrator/public/js/cluster-tree.js | 268 + web/orchestrator/public/js/cluster.js | 1935 ++++++ .../public/js/clusters-analysis.js | 141 + web/orchestrator/public/js/clusters.js | 156 + web/orchestrator/public/js/common.js | 6 + web/orchestrator/public/js/corex-jquery.js | 148 + web/orchestrator/public/js/corex.js | 2112 ++++++ web/orchestrator/public/js/custom.js | 0 web/orchestrator/public/js/d3.v3.min.js | 5 + web/orchestrator/public/js/discover.js | 33 + .../public/js/instance-problems.js | 69 + web/orchestrator/public/js/jquery-ui.min.js | 7 + .../public/js/jquery.cookie-1.4.1.min.js | 2 + web/orchestrator/public/js/jquery.min.js | 6 + web/orchestrator/public/js/md5.js | 177 + web/orchestrator/public/js/orchestrator.js | 1162 ++++ web/orchestrator/public/js/search.js | 28 + web/orchestrator/public/js/seed-shared.js | 56 + web/orchestrator/public/js/seed.js | 21 + web/orchestrator/public/js/seeds.js | 18 + web/orchestrator/public/js/status.js | 110 + web/orchestrator/templates/about.tmpl | 66 + web/orchestrator/templates/agent.tmpl | 161 + .../templates/agent_seed_details.tmpl | 56 + web/orchestrator/templates/agents.tmpl | 23 + web/orchestrator/templates/audit.tmpl | 42 + .../templates/audit_failure_detection.tmpl | 44 + .../templates/audit_recovery.tmpl | 73 + web/orchestrator/templates/cluster.tmpl | 88 + web/orchestrator/templates/cluster_pools.tmpl | 30 + web/orchestrator/templates/clusters.tmpl | 26 + .../templates/clusters_analysis.tmpl | 11 + web/orchestrator/templates/discover.tmpl | 25 + web/orchestrator/templates/faq.tmpl | 102 + web/orchestrator/templates/home.tmpl | 54 + web/orchestrator/templates/keep-calm.tmpl | 5 + web/orchestrator/templates/layout.tmpl | 270 + web/orchestrator/templates/search.tmpl | 10 + web/orchestrator/templates/seeds.tmpl | 34 + web/orchestrator/templates/status.tmpl | 17 + 71 files changed, 15914 insertions(+) create mode 100644 web/orchestrator/public/bootstrap/css/bootstrap-theme.css create mode 100644 web/orchestrator/public/bootstrap/css/bootstrap-theme.css.map create mode 100644 web/orchestrator/public/bootstrap/css/bootstrap-theme.min.css create mode 100644 web/orchestrator/public/bootstrap/css/bootstrap.css create mode 100644 web/orchestrator/public/bootstrap/css/bootstrap.css.map create mode 100644 web/orchestrator/public/bootstrap/css/bootstrap.min.css create mode 100644 web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 web/orchestrator/public/bootstrap/js/bootstrap.min.js create mode 100644 web/orchestrator/public/css/custom.css create mode 100644 web/orchestrator/public/css/orchestrator.css create mode 100644 web/orchestrator/public/images/ajax-loader.gif create mode 100644 web/orchestrator/public/images/booking-logo-32.png create mode 100644 web/orchestrator/public/images/booking-logo-s.png create mode 100644 web/orchestrator/public/images/keep-calm-and-let-orchestrator-handle-it-transp-m.png create mode 100644 web/orchestrator/public/images/octocat-logo-32.png create mode 100644 web/orchestrator/public/images/orchestrator-logo-32.png create mode 100644 web/orchestrator/public/images/outbrain-logo-32.png create mode 100644 web/orchestrator/public/images/outbrain-logo-s.png create mode 100644 web/orchestrator/public/images/tile.png create mode 100644 web/orchestrator/public/js/agent.js create mode 100644 web/orchestrator/public/js/agents.js create mode 100644 web/orchestrator/public/js/audit-failure-detection.js create mode 100644 web/orchestrator/public/js/audit-recovery-shared.js create mode 100644 web/orchestrator/public/js/audit-recovery.js create mode 100644 web/orchestrator/public/js/audit.js create mode 100644 web/orchestrator/public/js/bootbox.min.js create mode 100644 web/orchestrator/public/js/cluster-analysis-shared.js create mode 100644 web/orchestrator/public/js/cluster-pools.js create mode 100644 web/orchestrator/public/js/cluster-tree.js create mode 100644 web/orchestrator/public/js/cluster.js create mode 100644 web/orchestrator/public/js/clusters-analysis.js create mode 100644 web/orchestrator/public/js/clusters.js create mode 100644 web/orchestrator/public/js/common.js create mode 100644 web/orchestrator/public/js/corex-jquery.js create mode 100644 web/orchestrator/public/js/corex.js create mode 100644 web/orchestrator/public/js/custom.js create mode 100644 web/orchestrator/public/js/d3.v3.min.js create mode 100644 web/orchestrator/public/js/discover.js create mode 100644 web/orchestrator/public/js/instance-problems.js create mode 100644 web/orchestrator/public/js/jquery-ui.min.js create mode 100644 web/orchestrator/public/js/jquery.cookie-1.4.1.min.js create mode 100644 web/orchestrator/public/js/jquery.min.js create mode 100644 web/orchestrator/public/js/md5.js create mode 100644 web/orchestrator/public/js/orchestrator.js create mode 100644 web/orchestrator/public/js/search.js create mode 100644 web/orchestrator/public/js/seed-shared.js create mode 100644 web/orchestrator/public/js/seed.js create mode 100644 web/orchestrator/public/js/seeds.js create mode 100644 web/orchestrator/public/js/status.js create mode 100644 web/orchestrator/templates/about.tmpl create mode 100644 web/orchestrator/templates/agent.tmpl create mode 100644 web/orchestrator/templates/agent_seed_details.tmpl create mode 100644 web/orchestrator/templates/agents.tmpl create mode 100644 web/orchestrator/templates/audit.tmpl create mode 100644 web/orchestrator/templates/audit_failure_detection.tmpl create mode 100644 web/orchestrator/templates/audit_recovery.tmpl create mode 100644 web/orchestrator/templates/cluster.tmpl create mode 100644 web/orchestrator/templates/cluster_pools.tmpl create mode 100644 web/orchestrator/templates/clusters.tmpl create mode 100644 web/orchestrator/templates/clusters_analysis.tmpl create mode 100644 web/orchestrator/templates/discover.tmpl create mode 100644 web/orchestrator/templates/faq.tmpl create mode 100644 web/orchestrator/templates/home.tmpl create mode 100644 web/orchestrator/templates/keep-calm.tmpl create mode 100644 web/orchestrator/templates/layout.tmpl create mode 100644 web/orchestrator/templates/search.tmpl create mode 100644 web/orchestrator/templates/seeds.tmpl create mode 100644 web/orchestrator/templates/status.tmpl diff --git a/web/orchestrator/public/bootstrap/css/bootstrap-theme.css b/web/orchestrator/public/bootstrap/css/bootstrap-theme.css new file mode 100644 index 00000000000..a4069929bce --- /dev/null +++ b/web/orchestrator/public/bootstrap/css/bootstrap-theme.css @@ -0,0 +1,347 @@ +/*! + * Bootstrap v3.1.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #2b669a; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #2d6ca2; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #2d6ca2; + border-color: #2b669a; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #357ebd; + background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; +} +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%); + background-image: linear-gradient(to bottom, #222 0%, #282828 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #3071a9; + background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); + background-repeat: repeat-x; + border-color: #3278b3; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/web/orchestrator/public/bootstrap/css/bootstrap-theme.css.map b/web/orchestrator/public/bootstrap/css/bootstrap-theme.css.map new file mode 100644 index 00000000000..b36fc9a4970 --- /dev/null +++ b/web/orchestrator/public/bootstrap/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["less/theme.less","less/mixins.less"],"names":[],"mappings":"AAeA;AACA;AACA;AACA;AACA;AACA;EACE,wCAAA;ECoGA,2FAAA;EACQ,mFAAA;;ADhGR,YAAC;AAAD,YAAC;AAAD,YAAC;AAAD,SAAC;AAAD,YAAC;AAAD,WAAC;AACD,YAAC;AAAD,YAAC;AAAD,YAAC;AAAD,SAAC;AAAD,YAAC;AAAD,WAAC;EC8FD,wDAAA;EACQ,gDAAA;;ADnER,IAAC;AACD,IAAC;EACC,sBAAA;;AAKJ;EC4PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED7TA,2BAAA;EACA,qBAAA;EAyB2C,yBAAA;EAA2B,kBAAA;;AAvBtE,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAeJ;EC2PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED7TA,2BAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAgBJ;EC0PI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED7TA,2BAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAiBJ;ECyPI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED7TA,2BAAA;EACA,qBAAA;;AAEA,SAAC;AACD,SAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,SAAC;AACD,SAAC;EACC,yBAAA;EACA,qBAAA;;AAkBJ;ECwPI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED7TA,2BAAA;EACA,qBAAA;;AAEA,YAAC;AACD,YAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,YAAC;AACD,YAAC;EACC,yBAAA;EACA,qBAAA;;AAmBJ;ECuPI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EAEA,sHAAA;EAoCF,mEAAA;ED7TA,2BAAA;EACA,qBAAA;;AAEA,WAAC;AACD,WAAC;EACC,yBAAA;EACA,4BAAA;;AAGF,WAAC;AACD,WAAC;EACC,yBAAA;EACA,qBAAA;;AA2BJ;AACA;EC6CE,kDAAA;EACQ,0CAAA;;ADpCV,cAAe,KAAK,IAAG;AACvB,cAAe,KAAK,IAAG;ECmOnB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EDpOF,yBAAA;;AAEF,cAAe,UAAU;AACzB,cAAe,UAAU,IAAG;AAC5B,cAAe,UAAU,IAAG;EC6NxB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED9NF,yBAAA;;AAUF;ECiNI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EAoCF,mEAAA;EDrPA,kBAAA;ECaA,2FAAA;EACQ,mFAAA;;ADjBV,eAOE,YAAY,UAAU;EC0MpB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EApMF,wDAAA;EACQ,gDAAA;;ADLV;AACA,WAAY,KAAK;EACf,8CAAA;;AAIF;EC+LI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EAoCF,mEAAA;;ADtOF,eAIE,YAAY,UAAU;EC2LpB,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;EApMF,uDAAA;EACQ,+CAAA;;ADCV,eASE;AATF,eAUE,YAAY,KAAK;EACf,yCAAA;;AAKJ;AACA;AACA;EACE,gBAAA;;AAUF;EACE,6CAAA;EChCA,0FAAA;EACQ,kFAAA;;AD2CV;ECqJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED5JF,qBAAA;;AAKF;ECoJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED5JF,qBAAA;;AAMF;ECmJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED5JF,qBAAA;;AAOF;ECkJI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED5JF,qBAAA;;AAgBF;ECyII,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADlIJ;EC+HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADjIJ;EC8HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADhIJ;EC6HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;AD/HJ;EC4HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;AD9HJ;EC2HI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADtHJ;EACE,kBAAA;EC/EA,kDAAA;EACQ,0CAAA;;ADiFV,gBAAgB;AAChB,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;EACrB,6BAAA;EC4GE,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED7GF,qBAAA;;AAUF;ECjGE,iDAAA;EACQ,yCAAA;;AD0GV,cAAe;ECsFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADxFJ,cAAe;ECqFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADvFJ,cAAe;ECoFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADtFJ,WAAY;ECmFR,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADrFJ,cAAe;ECkFX,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;ADpFJ,aAAc;ECiFV,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;;AD5EJ;ECyEI,kBAAkB,sDAAlB;EACA,kBAAkB,oDAAlB;EACA,2BAAA;EACA,sHAAA;ED1EF,qBAAA;EC1HA,yFAAA;EACQ,iFAAA","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-bg, 5%); @end-color: darken(@navbar-default-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-bg; @end-color: lighten(@navbar-inverse-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n}\n\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","//\n// Mixins\n// --------------------------------------------------\n\n\n// Utilities\n// -------------------------\n\n// Clearfix\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n\n// WebKit-style focus\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n\n// Center-align a block level element\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n\n// Sizing shortcuts\n.size(@width; @height) {\n width: @width;\n height: @height;\n}\n.square(@size) {\n .size(@size; @size);\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n &::-moz-placeholder { color: @color; // Firefox\n opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Text overflow\n// Requires inline-block or block for proper styling\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note\n// that we cannot chain the mixins together in Less, so they are repeated.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n\n\n\n// CSS3 PROPERTIES\n// --------------------------------------------------\n\n// Single side border-radius\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support the\n// standard `box-shadow` property.\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Transitions\n.transition(@transition) {\n -webkit-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n// Transformations\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n transform: rotate(@degrees);\n}\n.scale(@ratio; @ratio-y...) {\n -webkit-transform: scale(@ratio, @ratio-y);\n -ms-transform: scale(@ratio, @ratio-y); // IE9 only\n transform: scale(@ratio, @ratio-y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n transform: translate(@x, @y);\n}\n.skew(@x; @y) {\n -webkit-transform: skew(@x, @y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n transform: skew(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// User select\n// For selecting text on the page\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n\n// Resize anything\n.resizable(@direction) {\n resize: @direction; // Options: horizontal, vertical, both\n overflow: auto; // Safari fix\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Opacity\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\n\n// GRADIENTS\n// --------------------------------------------------\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n\n// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n\n\n\n// Retina images\n//\n// Short retina mixin for setting background-image and -size\n\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// COMPONENT MIXINS\n// --------------------------------------------------\n\n// Horizontal dividers\n// -------------------------\n// Dividers (basically an hr) within dropdowns and nav lists\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n\n// Panels\n// -------------------------\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse .panel-body {\n border-top-color: @border;\n }\n }\n & > .panel-footer {\n + .panel-collapse .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n\n// Alerts\n// -------------------------\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n\n// Tables\n// -------------------------\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n\n// List Groups\n// -------------------------\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a& {\n color: @color;\n\n .list-group-item-heading { color: inherit; }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n\n// Button variants\n// -------------------------\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:hover,\n &:focus,\n &:active,\n &.active,\n .open .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 8%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &:active,\n &.active {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n// -------------------------\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n\n// Pagination\n// -------------------------\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n\n// Labels\n// -------------------------\n.label-variant(@color) {\n background-color: @color;\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n\n// Contextual backgrounds\n// -------------------------\n.bg-variant(@color) {\n background-color: @color;\n a&:hover {\n background-color: darken(@color, 10%);\n }\n}\n\n// Typography\n// -------------------------\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover {\n color: darken(@color, 10%);\n }\n}\n\n// Navbar vertical align\n// -------------------------\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n\n// Progress bars\n// -------------------------\n.progress-bar-variant(@color) {\n background-color: @color;\n .progress-striped & {\n #gradient > .striped();\n }\n}\n\n// Responsive utilities\n// -------------------------\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n\n\n// Grid System\n// -----------\n\n// Centered container element\n.container-fixed() {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: (@gutter / -2);\n margin-right: (@gutter / -2);\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n @media (min-width: @screen-xs-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-xs-column-push(@columns) {\n @media (min-width: @screen-xs-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-xs-column-pull(@columns) {\n @media (min-width: @screen-xs-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) when (@index = 1) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) when (@index = 1) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n\n// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-focus-border` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. ``\n// element gets special love because it's special, and that's a fact!\n\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Variables\n// --------------------------------------------------\n\n\n//== Colors\n//\n//## Gray and brand colors for use across Bootstrap.\n\n@gray-darker: lighten(#000, 13.5%); // #222\n@gray-dark: lighten(#000, 20%); // #333\n@gray: lighten(#000, 33.5%); // #555\n@gray-light: lighten(#000, 60%); // #999\n@gray-lighter: lighten(#000, 93.5%); // #eee\n\n@brand-primary: #428bca;\n@brand-success: #5cb85c;\n@brand-info: #5bc0de;\n@brand-warning: #f0ad4e;\n@brand-danger: #d9534f;\n\n\n//== Scaffolding\n//\n// ## Settings for some of the most global styles.\n\n//** Background color for ``.\n@body-bg: #fff;\n//** Global text color on ``.\n@text-color: @gray-dark;\n\n//** Global textual link color.\n@link-color: @brand-primary;\n//** Link hover color set via `darken()` function.\n@link-hover-color: darken(@link-color, 15%);\n\n\n//== Typography\n//\n//## Font, line-height, and color for body text, headings, and more.\n\n@font-family-sans-serif: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n@font-family-serif: Georgia, \"Times New Roman\", Times, serif;\n//** Default monospace fonts for ``, ``, and `
`.\n@font-family-monospace:   Menlo, Monaco, Consolas, \"Courier New\", monospace;\n@font-family-base:        @font-family-sans-serif;\n\n@font-size-base:          14px;\n@font-size-large:         ceil((@font-size-base * 1.25)); // ~18px\n@font-size-small:         ceil((@font-size-base * 0.85)); // ~12px\n\n@font-size-h1:            floor((@font-size-base * 2.6)); // ~36px\n@font-size-h2:            floor((@font-size-base * 2.15)); // ~30px\n@font-size-h3:            ceil((@font-size-base * 1.7)); // ~24px\n@font-size-h4:            ceil((@font-size-base * 1.25)); // ~18px\n@font-size-h5:            @font-size-base;\n@font-size-h6:            ceil((@font-size-base * 0.85)); // ~12px\n\n//** Unit-less `line-height` for use in components like buttons.\n@line-height-base:        1.428571429; // 20/14\n//** Computed \"line-height\" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.\n@line-height-computed:    floor((@font-size-base * @line-height-base)); // ~20px\n\n//** By default, this inherits from the ``.\n@headings-font-family:    inherit;\n@headings-font-weight:    500;\n@headings-line-height:    1.1;\n@headings-color:          inherit;\n\n\n//-- Iconography\n//\n//## Specify custom locations of the include Glyphicons icon font. Useful for those including Bootstrap via Bower.\n\n@icon-font-path:          \"../fonts/\";\n@icon-font-name:          \"glyphicons-halflings-regular\";\n@icon-font-svg-id:        \"glyphicons_halflingsregular\";\n\n//== Components\n//\n//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).\n\n@padding-base-vertical:     6px;\n@padding-base-horizontal:   12px;\n\n@padding-large-vertical:    10px;\n@padding-large-horizontal:  16px;\n\n@padding-small-vertical:    5px;\n@padding-small-horizontal:  10px;\n\n@padding-xs-vertical:       1px;\n@padding-xs-horizontal:     5px;\n\n@line-height-large:         1.33;\n@line-height-small:         1.5;\n\n@border-radius-base:        4px;\n@border-radius-large:       6px;\n@border-radius-small:       3px;\n\n//** Global color for active items (e.g., navs or dropdowns).\n@component-active-color:    #fff;\n//** Global background color for active items (e.g., navs or dropdowns).\n@component-active-bg:       @brand-primary;\n\n//** Width of the `border` for generating carets that indicator dropdowns.\n@caret-width-base:          4px;\n//** Carets increase slightly in size for larger components.\n@caret-width-large:         5px;\n\n\n//== Tables\n//\n//## Customizes the `.table` component with basic values, each used across all table variations.\n\n//** Padding for ``s and ``s.\n@table-cell-padding:            8px;\n//** Padding for cells in `.table-condensed`.\n@table-condensed-cell-padding:  5px;\n\n//** Default background color used for all tables.\n@table-bg:                      transparent;\n//** Background color used for `.table-striped`.\n@table-bg-accent:               #f9f9f9;\n//** Background color used for `.table-hover`.\n@table-bg-hover:                #f5f5f5;\n@table-bg-active:               @table-bg-hover;\n\n//** Border color for table and cell borders.\n@table-border-color:            #ddd;\n\n\n//== Buttons\n//\n//## For each of Bootstrap's buttons, define text, background and border color.\n\n@btn-font-weight:                normal;\n\n@btn-default-color:              #333;\n@btn-default-bg:                 #fff;\n@btn-default-border:             #ccc;\n\n@btn-primary-color:              #fff;\n@btn-primary-bg:                 @brand-primary;\n@btn-primary-border:             darken(@btn-primary-bg, 5%);\n\n@btn-success-color:              #fff;\n@btn-success-bg:                 @brand-success;\n@btn-success-border:             darken(@btn-success-bg, 5%);\n\n@btn-info-color:                 #fff;\n@btn-info-bg:                    @brand-info;\n@btn-info-border:                darken(@btn-info-bg, 5%);\n\n@btn-warning-color:              #fff;\n@btn-warning-bg:                 @brand-warning;\n@btn-warning-border:             darken(@btn-warning-bg, 5%);\n\n@btn-danger-color:               #fff;\n@btn-danger-bg:                  @brand-danger;\n@btn-danger-border:              darken(@btn-danger-bg, 5%);\n\n@btn-link-disabled-color:        @gray-light;\n\n\n//== Forms\n//\n//##\n\n//** `` background color\n@input-bg:                       #fff;\n//** `` background color\n@input-bg-disabled:              @gray-lighter;\n\n//** Text color for ``s\n@input-color:                    @gray;\n//** `` border color\n@input-border:                   #ccc;\n//** `` border radius\n@input-border-radius:            @border-radius-base;\n//** Border color for inputs on focus\n@input-border-focus:             #66afe9;\n\n//** Placeholder text color\n@input-color-placeholder:        @gray-light;\n\n//** Default `.form-control` height\n@input-height-base:              (@line-height-computed + (@padding-base-vertical * 2) + 2);\n//** Large `.form-control` height\n@input-height-large:             (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);\n//** Small `.form-control` height\n@input-height-small:             (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);\n\n@legend-color:                   @gray-dark;\n@legend-border-color:            #e5e5e5;\n\n//** Background color for textual input addons\n@input-group-addon-bg:           @gray-lighter;\n//** Border color for textual input addons\n@input-group-addon-border-color: @input-border;\n\n\n//== Dropdowns\n//\n//## Dropdown menu container and contents.\n\n//** Background for the dropdown menu.\n@dropdown-bg:                    #fff;\n//** Dropdown menu `border-color`.\n@dropdown-border:                rgba(0,0,0,.15);\n//** Dropdown menu `border-color` **for IE8**.\n@dropdown-fallback-border:       #ccc;\n//** Divider color for between dropdown items.\n@dropdown-divider-bg:            #e5e5e5;\n\n//** Dropdown link text color.\n@dropdown-link-color:            @gray-dark;\n//** Hover color for dropdown links.\n@dropdown-link-hover-color:      darken(@gray-dark, 5%);\n//** Hover background for dropdown links.\n@dropdown-link-hover-bg:         #f5f5f5;\n\n//** Active dropdown menu item text color.\n@dropdown-link-active-color:     @component-active-color;\n//** Active dropdown menu item background color.\n@dropdown-link-active-bg:        @component-active-bg;\n\n//** Disabled dropdown menu item background color.\n@dropdown-link-disabled-color:   @gray-light;\n\n//** Text color for headers within dropdown menus.\n@dropdown-header-color:          @gray-light;\n\n// Note: Deprecated @dropdown-caret-color as of v3.1.0\n@dropdown-caret-color:           #000;\n\n\n//-- Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n//\n// Note: These variables are not generated into the Customizer.\n\n@zindex-navbar:            1000;\n@zindex-dropdown:          1000;\n@zindex-popover:           1010;\n@zindex-tooltip:           1030;\n@zindex-navbar-fixed:      1030;\n@zindex-modal-background:  1040;\n@zindex-modal:             1050;\n\n\n//== Media queries breakpoints\n//\n//## Define the breakpoints at which your layout will change, adapting to different screen sizes.\n\n// Extra small screen / phone\n// Note: Deprecated @screen-xs and @screen-phone as of v3.0.1\n@screen-xs:                  480px;\n@screen-xs-min:              @screen-xs;\n@screen-phone:               @screen-xs-min;\n\n// Small screen / tablet\n// Note: Deprecated @screen-sm and @screen-tablet as of v3.0.1\n@screen-sm:                  768px;\n@screen-sm-min:              @screen-sm;\n@screen-tablet:              @screen-sm-min;\n\n// Medium screen / desktop\n// Note: Deprecated @screen-md and @screen-desktop as of v3.0.1\n@screen-md:                  992px;\n@screen-md-min:              @screen-md;\n@screen-desktop:             @screen-md-min;\n\n// Large screen / wide desktop\n// Note: Deprecated @screen-lg and @screen-lg-desktop as of v3.0.1\n@screen-lg:                  1200px;\n@screen-lg-min:              @screen-lg;\n@screen-lg-desktop:          @screen-lg-min;\n\n// So media queries don't overlap when required, provide a maximum\n@screen-xs-max:              (@screen-sm-min - 1);\n@screen-sm-max:              (@screen-md-min - 1);\n@screen-md-max:              (@screen-lg-min - 1);\n\n\n//== Grid system\n//\n//## Define your custom responsive grid.\n\n//** Number of columns in the grid.\n@grid-columns:              12;\n//** Padding between columns. Gets divided in half for the left and right.\n@grid-gutter-width:         30px;\n// Navbar collapse\n//** Point at which the navbar becomes uncollapsed.\n@grid-float-breakpoint:     @screen-sm-min;\n//** Point at which the navbar begins collapsing.\n@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);\n\n\n//== Container sizes\n//\n//## Define the maximum width of `.container` for different screen sizes.\n\n// Small screen / tablet\n@container-tablet:             ((720px + @grid-gutter-width));\n//** For `@screen-sm-min` and up.\n@container-sm:                 @container-tablet;\n\n// Medium screen / desktop\n@container-desktop:            ((940px + @grid-gutter-width));\n//** For `@screen-md-min` and up.\n@container-md:                 @container-desktop;\n\n// Large screen / wide desktop\n@container-large-desktop:      ((1140px + @grid-gutter-width));\n//** For `@screen-lg-min` and up.\n@container-lg:                 @container-large-desktop;\n\n\n//== Navbar\n//\n//##\n\n// Basics of a navbar\n@navbar-height:                    50px;\n@navbar-margin-bottom:             @line-height-computed;\n@navbar-border-radius:             @border-radius-base;\n@navbar-padding-horizontal:        floor((@grid-gutter-width / 2));\n@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);\n@navbar-collapse-max-height:       340px;\n\n@navbar-default-color:             #777;\n@navbar-default-bg:                #f8f8f8;\n@navbar-default-border:            darken(@navbar-default-bg, 6.5%);\n\n// Navbar links\n@navbar-default-link-color:                #777;\n@navbar-default-link-hover-color:          #333;\n@navbar-default-link-hover-bg:             transparent;\n@navbar-default-link-active-color:         #555;\n@navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);\n@navbar-default-link-disabled-color:       #ccc;\n@navbar-default-link-disabled-bg:          transparent;\n\n// Navbar brand label\n@navbar-default-brand-color:               @navbar-default-link-color;\n@navbar-default-brand-hover-color:         darken(@navbar-default-brand-color, 10%);\n@navbar-default-brand-hover-bg:            transparent;\n\n// Navbar toggle\n@navbar-default-toggle-hover-bg:           #ddd;\n@navbar-default-toggle-icon-bar-bg:        #888;\n@navbar-default-toggle-border-color:       #ddd;\n\n\n// Inverted navbar\n// Reset inverted navbar basics\n@navbar-inverse-color:                      @gray-light;\n@navbar-inverse-bg:                         #222;\n@navbar-inverse-border:                     darken(@navbar-inverse-bg, 10%);\n\n// Inverted navbar links\n@navbar-inverse-link-color:                 @gray-light;\n@navbar-inverse-link-hover-color:           #fff;\n@navbar-inverse-link-hover-bg:              transparent;\n@navbar-inverse-link-active-color:          @navbar-inverse-link-hover-color;\n@navbar-inverse-link-active-bg:             darken(@navbar-inverse-bg, 10%);\n@navbar-inverse-link-disabled-color:        #444;\n@navbar-inverse-link-disabled-bg:           transparent;\n\n// Inverted navbar brand label\n@navbar-inverse-brand-color:                @navbar-inverse-link-color;\n@navbar-inverse-brand-hover-color:          #fff;\n@navbar-inverse-brand-hover-bg:             transparent;\n\n// Inverted navbar toggle\n@navbar-inverse-toggle-hover-bg:            #333;\n@navbar-inverse-toggle-icon-bar-bg:         #fff;\n@navbar-inverse-toggle-border-color:        #333;\n\n\n//== Navs\n//\n//##\n\n//=== Shared nav styles\n@nav-link-padding:                          10px 15px;\n@nav-link-hover-bg:                         @gray-lighter;\n\n@nav-disabled-link-color:                   @gray-light;\n@nav-disabled-link-hover-color:             @gray-light;\n\n@nav-open-link-hover-color:                 #fff;\n\n//== Tabs\n@nav-tabs-border-color:                     #ddd;\n\n@nav-tabs-link-hover-border-color:          @gray-lighter;\n\n@nav-tabs-active-link-hover-bg:             @body-bg;\n@nav-tabs-active-link-hover-color:          @gray;\n@nav-tabs-active-link-hover-border-color:   #ddd;\n\n@nav-tabs-justified-link-border-color:            #ddd;\n@nav-tabs-justified-active-link-border-color:     @body-bg;\n\n//== Pills\n@nav-pills-border-radius:                   @border-radius-base;\n@nav-pills-active-link-hover-bg:            @component-active-bg;\n@nav-pills-active-link-hover-color:         @component-active-color;\n\n\n//== Pagination\n//\n//##\n\n@pagination-color:                     @link-color;\n@pagination-bg:                        #fff;\n@pagination-border:                    #ddd;\n\n@pagination-hover-color:               @link-hover-color;\n@pagination-hover-bg:                  @gray-lighter;\n@pagination-hover-border:              #ddd;\n\n@pagination-active-color:              #fff;\n@pagination-active-bg:                 @brand-primary;\n@pagination-active-border:             @brand-primary;\n\n@pagination-disabled-color:            @gray-light;\n@pagination-disabled-bg:               #fff;\n@pagination-disabled-border:           #ddd;\n\n\n//== Pager\n//\n//##\n\n@pager-bg:                             @pagination-bg;\n@pager-border:                         @pagination-border;\n@pager-border-radius:                  15px;\n\n@pager-hover-bg:                       @pagination-hover-bg;\n\n@pager-active-bg:                      @pagination-active-bg;\n@pager-active-color:                   @pagination-active-color;\n\n@pager-disabled-color:                 @pagination-disabled-color;\n\n\n//== Jumbotron\n//\n//##\n\n@jumbotron-padding:              30px;\n@jumbotron-color:                inherit;\n@jumbotron-bg:                   @gray-lighter;\n@jumbotron-heading-color:        inherit;\n@jumbotron-font-size:            ceil((@font-size-base * 1.5));\n\n\n//== Form states and alerts\n//\n//## Define colors for form feedback states and, by default, alerts.\n\n@state-success-text:             #3c763d;\n@state-success-bg:               #dff0d8;\n@state-success-border:           darken(spin(@state-success-bg, -10), 5%);\n\n@state-info-text:                #31708f;\n@state-info-bg:                  #d9edf7;\n@state-info-border:              darken(spin(@state-info-bg, -10), 7%);\n\n@state-warning-text:             #8a6d3b;\n@state-warning-bg:               #fcf8e3;\n@state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);\n\n@state-danger-text:              #a94442;\n@state-danger-bg:                #f2dede;\n@state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);\n\n\n//== Tooltips\n//\n//##\n\n//** Tooltip max width\n@tooltip-max-width:           200px;\n//** Tooltip text color\n@tooltip-color:               #fff;\n//** Tooltip background color\n@tooltip-bg:                  #000;\n@tooltip-opacity:             .9;\n\n//** Tooltip arrow width\n@tooltip-arrow-width:         5px;\n//** Tooltip arrow color\n@tooltip-arrow-color:         @tooltip-bg;\n\n\n//== Popovers\n//\n//##\n\n//** Popover body background color\n@popover-bg:                          #fff;\n//** Popover maximum width\n@popover-max-width:                   276px;\n//** Popover border color\n@popover-border-color:                rgba(0,0,0,.2);\n//** Popover fallback border color\n@popover-fallback-border-color:       #ccc;\n\n//** Popover title background color\n@popover-title-bg:                    darken(@popover-bg, 3%);\n\n//** Popover arrow width\n@popover-arrow-width:                 10px;\n//** Popover arrow color\n@popover-arrow-color:                 #fff;\n\n//** Popover outer arrow width\n@popover-arrow-outer-width:           (@popover-arrow-width + 1);\n//** Popover outer arrow color\n@popover-arrow-outer-color:           fadein(@popover-border-color, 5%);\n//** Popover outer arrow fallback color\n@popover-arrow-outer-fallback-color:  darken(@popover-fallback-border-color, 20%);\n\n\n//== Labels\n//\n//##\n\n//** Default label background color\n@label-default-bg:            @gray-light;\n//** Primary label background color\n@label-primary-bg:            @brand-primary;\n//** Success label background color\n@label-success-bg:            @brand-success;\n//** Info label background color\n@label-info-bg:               @brand-info;\n//** Warning label background color\n@label-warning-bg:            @brand-warning;\n//** Danger label background color\n@label-danger-bg:             @brand-danger;\n\n//** Default label text color\n@label-color:                 #fff;\n//** Default text color of a linked label\n@label-link-hover-color:      #fff;\n\n\n//== Modals\n//\n//##\n\n//** Padding applied to the modal body\n@modal-inner-padding:         20px;\n\n//** Padding applied to the modal title\n@modal-title-padding:         15px;\n//** Modal title line-height\n@modal-title-line-height:     @line-height-base;\n\n//** Background color of modal content area\n@modal-content-bg:                             #fff;\n//** Modal content border color\n@modal-content-border-color:                   rgba(0,0,0,.2);\n//** Modal content border color **for IE8**\n@modal-content-fallback-border-color:          #999;\n\n//** Modal backdrop background color\n@modal-backdrop-bg:           #000;\n//** Modal backdrop opacity\n@modal-backdrop-opacity:      .5;\n//** Modal header border color\n@modal-header-border-color:   #e5e5e5;\n//** Modal footer border color\n@modal-footer-border-color:   @modal-header-border-color;\n\n@modal-lg:                    900px;\n@modal-md:                    600px;\n@modal-sm:                    300px;\n\n\n//== Alerts\n//\n//## Define alert colors, border radius, and padding.\n\n@alert-padding:               15px;\n@alert-border-radius:         @border-radius-base;\n@alert-link-font-weight:      bold;\n\n@alert-success-bg:            @state-success-bg;\n@alert-success-text:          @state-success-text;\n@alert-success-border:        @state-success-border;\n\n@alert-info-bg:               @state-info-bg;\n@alert-info-text:             @state-info-text;\n@alert-info-border:           @state-info-border;\n\n@alert-warning-bg:            @state-warning-bg;\n@alert-warning-text:          @state-warning-text;\n@alert-warning-border:        @state-warning-border;\n\n@alert-danger-bg:             @state-danger-bg;\n@alert-danger-text:           @state-danger-text;\n@alert-danger-border:         @state-danger-border;\n\n\n//== Progress bars\n//\n//##\n\n//** Background color of the whole progress component\n@progress-bg:                 #f5f5f5;\n//** Progress bar text color\n@progress-bar-color:          #fff;\n\n//** Default progress bar color\n@progress-bar-bg:             @brand-primary;\n//** Success progress bar color\n@progress-bar-success-bg:     @brand-success;\n//** Warning progress bar color\n@progress-bar-warning-bg:     @brand-warning;\n//** Danger progress bar color\n@progress-bar-danger-bg:      @brand-danger;\n//** Info progress bar color\n@progress-bar-info-bg:        @brand-info;\n\n\n//== List group\n//\n//##\n\n//** Background color on `.list-group-item`\n@list-group-bg:                 #fff;\n//** `.list-group-item` border color\n@list-group-border:             #ddd;\n//** List group border radius\n@list-group-border-radius:      @border-radius-base;\n\n//** Background color of single list elements on hover\n@list-group-hover-bg:           #f5f5f5;\n//** Text color of active list elements\n@list-group-active-color:       @component-active-color;\n//** Background color of active list elements\n@list-group-active-bg:          @component-active-bg;\n//** Border color of active list elements\n@list-group-active-border:      @list-group-active-bg;\n@list-group-active-text-color:  lighten(@list-group-active-bg, 40%);\n\n@list-group-link-color:         #555;\n@list-group-link-heading-color: #333;\n\n\n//== Panels\n//\n//##\n\n@panel-bg:                    #fff;\n@panel-body-padding:          15px;\n@panel-border-radius:         @border-radius-base;\n\n//** Border color for elements within panels\n@panel-inner-border:          #ddd;\n@panel-footer-bg:             #f5f5f5;\n\n@panel-default-text:          @gray-dark;\n@panel-default-border:        #ddd;\n@panel-default-heading-bg:    #f5f5f5;\n\n@panel-primary-text:          #fff;\n@panel-primary-border:        @brand-primary;\n@panel-primary-heading-bg:    @brand-primary;\n\n@panel-success-text:          @state-success-text;\n@panel-success-border:        @state-success-border;\n@panel-success-heading-bg:    @state-success-bg;\n\n@panel-info-text:             @state-info-text;\n@panel-info-border:           @state-info-border;\n@panel-info-heading-bg:       @state-info-bg;\n\n@panel-warning-text:          @state-warning-text;\n@panel-warning-border:        @state-warning-border;\n@panel-warning-heading-bg:    @state-warning-bg;\n\n@panel-danger-text:           @state-danger-text;\n@panel-danger-border:         @state-danger-border;\n@panel-danger-heading-bg:     @state-danger-bg;\n\n\n//== Thumbnails\n//\n//##\n\n//** Padding around the thumbnail image\n@thumbnail-padding:           4px;\n//** Thumbnail background color\n@thumbnail-bg:                @body-bg;\n//** Thumbnail border color\n@thumbnail-border:            #ddd;\n//** Thumbnail border radius\n@thumbnail-border-radius:     @border-radius-base;\n\n//** Custom text color for thumbnail captions\n@thumbnail-caption-color:     @text-color;\n//** Padding around the thumbnail caption\n@thumbnail-caption-padding:   9px;\n\n\n//== Wells\n//\n//##\n\n@well-bg:                     #f5f5f5;\n@well-border:                 darken(@well-bg, 7%);\n\n\n//== Badges\n//\n//##\n\n@badge-color:                 #fff;\n//** Linked badge text color on hover\n@badge-link-hover-color:      #fff;\n@badge-bg:                    @gray-light;\n\n//** Badge text color in active nav link\n@badge-active-color:          @link-color;\n//** Badge background color in active nav link\n@badge-active-bg:             #fff;\n\n@badge-font-weight:           bold;\n@badge-line-height:           1;\n@badge-border-radius:         10px;\n\n\n//== Breadcrumbs\n//\n//##\n\n@breadcrumb-padding-vertical:   8px;\n@breadcrumb-padding-horizontal: 15px;\n//** Breadcrumb background color\n@breadcrumb-bg:                 #f5f5f5;\n//** Breadcrumb text color\n@breadcrumb-color:              #ccc;\n//** Text color of current page in the breadcrumb\n@breadcrumb-active-color:       @gray-light;\n//** Textual separator for between breadcrumb elements\n@breadcrumb-separator:          \"/\";\n\n\n//== Carousel\n//\n//##\n\n@carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6);\n\n@carousel-control-color:                      #fff;\n@carousel-control-width:                      15%;\n@carousel-control-opacity:                    .5;\n@carousel-control-font-size:                  20px;\n\n@carousel-indicator-active-bg:                #fff;\n@carousel-indicator-border-color:             #fff;\n\n@carousel-caption-color:                      #fff;\n\n\n//== Close\n//\n//##\n\n@close-font-weight:           bold;\n@close-color:                 #000;\n@close-text-shadow:           0 1px 0 #fff;\n\n\n//== Code\n//\n//##\n\n@code-color:                  #c7254e;\n@code-bg:                     #f9f2f4;\n\n@kbd-color:                   #fff;\n@kbd-bg:                      #333;\n\n@pre-bg:                      #f5f5f5;\n@pre-color:                   @gray-dark;\n@pre-border-color:            #ccc;\n@pre-scrollable-max-height:   340px;\n\n\n//== Type\n//\n//##\n\n//** Text muted color\n@text-muted:                  @gray-light;\n//** Abbreviations and acronyms border color\n@abbr-border-color:           @gray-light;\n//** Headings small color\n@headings-small-color:        @gray-light;\n//** Blockquote small color\n@blockquote-small-color:      @gray-light;\n//** Blockquote font size\n@blockquote-font-size:        (@font-size-base * 1.25);\n//** Blockquote border color\n@blockquote-border-color:     @gray-lighter;\n//** Page header border color\n@page-header-border-color:    @gray-lighter;\n\n\n//== Miscellaneous\n//\n//##\n\n//** Horizontal line color.\n@hr-border:                   @gray-lighter;\n\n//** Horizontal offset for forms and lists.\n@component-offset-horizontal: 180px;\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n  display: block;\n  padding: @thumbnail-padding;\n  margin-bottom: @line-height-computed;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  > img,\n  a > img {\n    &:extend(.img-responsive);\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  // Add a hover state for linked versions only\n  a&:hover,\n  a&:focus,\n  a&.active {\n    border-color: @link-color;\n  }\n\n  // Image captions\n  .caption {\n    padding: @thumbnail-caption-padding;\n    color: @thumbnail-caption-color;\n  }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n\n  > .item {\n    display: none;\n    position: relative;\n    .transition(.6s ease-in-out left);\n\n    // Account for jankitude on images\n    > img,\n    > a > img {\n      &:extend(.img-responsive);\n      line-height: 1;\n    }\n  }\n\n  > .active,\n  > .next,\n  > .prev { display: block; }\n\n  > .active {\n    left: 0;\n  }\n\n  > .next,\n  > .prev {\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  > .next {\n    left: 100%;\n  }\n  > .prev {\n    left: -100%;\n  }\n  > .next.left,\n  > .prev.right {\n    left: 0;\n  }\n\n  > .active.left {\n    left: -100%;\n  }\n  > .active.right {\n    left: 100%;\n  }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: @carousel-control-width;\n  .opacity(@carousel-control-opacity);\n  font-size: @carousel-control-font-size;\n  color: @carousel-control-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  // We can't have this transition here because WebKit cancels the carousel\n  // animation if you trip this while in the middle of another animation.\n\n  // Set gradients for backgrounds\n  &.left {\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n  }\n  &.right {\n    left: auto;\n    right: 0;\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n  }\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    outline: none;\n    color: @carousel-control-color;\n    text-decoration: none;\n    .opacity(.9);\n  }\n\n  // Toggles\n  .icon-prev,\n  .icon-next,\n  .glyphicon-chevron-left,\n  .glyphicon-chevron-right {\n    position: absolute;\n    top: 50%;\n    z-index: 5;\n    display: inline-block;\n  }\n  .icon-prev,\n  .glyphicon-chevron-left {\n    left: 50%;\n  }\n  .icon-next,\n  .glyphicon-chevron-right {\n    right: 50%;\n  }\n  .icon-prev,\n  .icon-next {\n    width:  20px;\n    height: 20px;\n    margin-top: -10px;\n    margin-left: -10px;\n    font-family: serif;\n  }\n\n  .icon-prev {\n    &:before {\n      content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n    }\n  }\n  .icon-next {\n    &:before {\n      content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n    }\n  }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n\n  li {\n    display: inline-block;\n    width:  10px;\n    height: 10px;\n    margin: 1px;\n    text-indent: -999px;\n    border: 1px solid @carousel-indicator-border-color;\n    border-radius: 10px;\n    cursor: pointer;\n\n    // IE8-9 hack for event handling\n    //\n    // Internet Explorer 8-9 does not support clicks on elements without a set\n    // `background-color`. We cannot use `filter` since that's not viewed as a\n    // background color by the browser. Thus, a hack is needed.\n    //\n    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n    // set alpha transparency for the best results possible.\n    background-color: #000 \\9; // IE8\n    background-color: rgba(0,0,0,0); // IE9\n  }\n  .active {\n    margin: 0;\n    width:  12px;\n    height: 12px;\n    background-color: @carousel-indicator-active-bg;\n  }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: @carousel-caption-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  & .btn {\n    text-shadow: none; // No shadow for button elements in carousel-caption\n  }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n  // Scale up the controls a smidge\n  .carousel-control {\n    .glyphicon-chevron-left,\n    .glyphicon-chevron-right,\n    .icon-prev,\n    .icon-next {\n      width: 30px;\n      height: 30px;\n      margin-top: -15px;\n      margin-left: -15px;\n      font-size: 30px;\n    }\n  }\n\n  // Show and left align the captions\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n\n  // Move up the indicators\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  font-family: @headings-font-family;\n  font-weight: @headings-font-weight;\n  line-height: @headings-line-height;\n  color: @headings-color;\n\n  small,\n  .small {\n    font-weight: normal;\n    line-height: 1;\n    color: @headings-small-color;\n  }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n  margin-top: @line-height-computed;\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 65%;\n  }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n  margin-top: (@line-height-computed / 2);\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 75%;\n  }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n  margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n  margin-bottom: @line-height-computed;\n  font-size: floor((@font-size-base * 1.15));\n  font-weight: 200;\n  line-height: 1.4;\n\n  @media (min-width: @screen-sm-min) {\n    font-size: (@font-size-base * 1.5);\n  }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: 14px base font * 85% = about 12px\nsmall,\n.small  { font-size: 85%; }\n\n// Undo browser default styling\ncite    { font-style: normal; }\n\n// Alignment\n.text-left           { text-align: left; }\n.text-right          { text-align: right; }\n.text-center         { text-align: center; }\n.text-justify        { text-align: justify; }\n\n// Contextual colors\n.text-muted {\n  color: @text-muted;\n}\n.text-primary {\n  .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n  .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n  .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n  .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n  .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n  // Given the contrast here, this is the only class to have its color inverted\n  // automatically.\n  color: #fff;\n  .bg-variant(@brand-primary);\n}\n.bg-success {\n  .bg-variant(@state-success-bg);\n}\n.bg-info {\n  .bg-variant(@state-info-bg);\n}\n.bg-warning {\n  .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n  .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n  padding-bottom: ((@line-height-computed / 2) - 1);\n  margin: (@line-height-computed * 2) 0 @line-height-computed;\n  border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// --------------------------------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n  margin-top: 0;\n  margin-bottom: (@line-height-computed / 2);\n  ul,\n  ol {\n    margin-bottom: 0;\n  }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  .list-unstyled();\n  margin-left: -5px;\n\n  > li {\n    display: inline-block;\n    padding-left: 5px;\n    padding-right: 5px;\n  }\n}\n\n// Description Lists\ndl {\n  margin-top: 0; // Remove browser default\n  margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n  line-height: @line-height-base;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n@media (min-width: @grid-float-breakpoint) {\n  .dl-horizontal {\n    dt {\n      float: left;\n      width: (@component-offset-horizontal - 20);\n      clear: left;\n      text-align: right;\n      .text-overflow();\n    }\n    dd {\n      margin-left: @component-offset-horizontal;\n      &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n    }\n  }\n}\n\n// MISC\n// ----\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n  padding: (@line-height-computed / 2) @line-height-computed;\n  margin: 0 0 @line-height-computed;\n  font-size: @blockquote-font-size;\n  border-left: 5px solid @blockquote-border-color;\n\n  p,\n  ul,\n  ol {\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  // Note: Deprecated small and .small as of v3.1.0\n  // Context: https://github.com/twbs/bootstrap/issues/11660\n  footer,\n  small,\n  .small {\n    display: block;\n    font-size: 80%; // back to default font-size\n    line-height: @line-height-base;\n    color: @blockquote-small-color;\n\n    &:before {\n      content: '\\2014 \\00A0'; // em dash, nbsp\n    }\n  }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid @blockquote-border-color;\n  border-left: 0;\n  text-align: right;\n\n  // Account for citation\n  footer,\n  small,\n  .small {\n    &:before { content: ''; }\n    &:after {\n      content: '\\00A0 \\2014'; // nbsp, em dash\n    }\n  }\n}\n\n// Quotes\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\n// Addresses\naddress {\n  margin-bottom: @line-height-computed;\n  font-style: normal;\n  line-height: @line-height-base;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n  font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @code-color;\n  background-color: @code-bg;\n  white-space: nowrap;\n  border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @kbd-color;\n  background-color: @kbd-bg;\n  border-radius: @border-radius-small;\n  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n}\n\n// Blocks of code\npre {\n  display: block;\n  padding: ((@line-height-computed - 1) / 2);\n  margin: 0 0 (@line-height-computed / 2);\n  font-size: (@font-size-base - 1); // 14px to 13px\n  line-height: @line-height-base;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: @pre-color;\n  background-color: @pre-bg;\n  border: 1px solid @pre-border-color;\n  border-radius: @border-radius-base;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    padding: 0;\n    font-size: inherit;\n    color: inherit;\n    white-space: pre-wrap;\n    background-color: transparent;\n    border-radius: 0;\n  }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n  max-height: @pre-scrollable-max-height;\n  overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n  .container-fixed();\n\n  @media (min-width: @screen-sm-min) {\n    width: @container-sm;\n  }\n  @media (min-width: @screen-md-min) {\n    width: @container-md;\n  }\n  @media (min-width: @screen-lg-min) {\n    width: @container-lg;\n  }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n  .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n  .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n  .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n  .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n  .make-grid(lg);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  max-width: 100%;\n  background-color: @table-bg;\n}\nth {\n  text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n  width: 100%;\n  margin-bottom: @line-height-computed;\n  // Cells\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-cell-padding;\n        line-height: @line-height-base;\n        vertical-align: top;\n        border-top: 1px solid @table-border-color;\n      }\n    }\n  }\n  // Bottom align for column headings\n  > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid @table-border-color;\n  }\n  // Remove top border from thead by default\n  > caption + thead,\n  > colgroup + thead,\n  > thead:first-child {\n    > tr:first-child {\n      > th,\n      > td {\n        border-top: 0;\n      }\n    }\n  }\n  // Account for multiple tbody instances\n  > tbody + tbody {\n    border-top: 2px solid @table-border-color;\n  }\n\n  // Nesting\n  .table {\n    background-color: @body-bg;\n  }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-condensed-cell-padding;\n      }\n    }\n  }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n  border: 1px solid @table-border-color;\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        border: 1px solid @table-border-color;\n      }\n    }\n  }\n  > thead > tr {\n    > th,\n    > td {\n      border-bottom-width: 2px;\n    }\n  }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-child(odd) {\n    > td,\n    > th {\n      background-color: @table-bg-accent;\n    }\n  }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover {\n    > td,\n    > th {\n      background-color: @table-bg-hover;\n    }\n  }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n  position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n  float: none;\n  display: table-column;\n}\ntable {\n  td,\n  th {\n    &[class*=\"col-\"] {\n      position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n      float: none;\n      display: table-cell;\n    }\n  }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n@media (max-width: @screen-xs-max) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: (@line-height-computed * 0.75);\n    overflow-y: hidden;\n    overflow-x: scroll;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid @table-border-color;\n    -webkit-overflow-scrolling: touch;\n\n    // Tighten up spacing\n    > .table {\n      margin-bottom: 0;\n\n      // Ensure the content doesn't wrap\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th,\n          > td {\n            white-space: nowrap;\n          }\n        }\n      }\n    }\n\n    // Special overrides for the bordered tables\n    > .table-bordered {\n      border: 0;\n\n      // Nuke the appropriate borders so that the parent can handle them\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th:first-child,\n          > td:first-child {\n            border-left: 0;\n          }\n          > th:last-child,\n          > td:last-child {\n            border-right: 0;\n          }\n        }\n      }\n\n      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n      // chances are there will be only one `tr` in a `thead` and that would\n      // remove the border altogether.\n      > tbody,\n      > tfoot {\n        > tr:last-child {\n          > th,\n          > td {\n            border-bottom: 0;\n          }\n        }\n      }\n\n    }\n  }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  // Chrome and Firefox set a `min-width: -webkit-min-content;` on fieldsets,\n  // so we reset that to ensure it behaves more like a standard block element.\n  // See https://github.com/twbs/bootstrap/issues/12359.\n  min-width: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: @line-height-computed;\n  font-size: (@font-size-base * 1.5);\n  line-height: inherit;\n  color: @legend-color;\n  border: 0;\n  border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n  display: inline-block;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n  .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9; /* IE8-9 */\n  line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n  display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  .tab-focus();\n}\n\n// Adjust output element\noutput {\n  display: block;\n  padding-top: (@padding-base-vertical + 1);\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  background-color: @input-bg;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid @input-border;\n  border-radius: @input-border-radius;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n  .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  .form-control-focus();\n\n  // Placeholder\n  .placeholder();\n\n  // Disabled and read-only inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &[disabled],\n  &[readonly],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    background-color: @input-bg-disabled;\n    opacity: 1; // iOS fix for unreadable disabled content\n  }\n\n  // Reset height for `textarea`s\n  textarea& {\n    height: auto;\n  }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n\n\n// Special styles for iOS date input\n//\n// In Mobile Safari, date inputs require a pixel line-height that matches the\n// given height of the input.\n\ninput[type=\"date\"] {\n  line-height: @input-height-base;\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n  margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n  display: block;\n  min-height: @line-height-computed; // clear the floating input if there is no label text\n  margin-top: 10px;\n  margin-bottom: 10px;\n  padding-left: 20px;\n  label {\n    display: inline;\n    font-weight: normal;\n    cursor: pointer;\n  }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"],\n.radio,\n.radio-inline,\n.checkbox,\n.checkbox-inline {\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n  }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n\n.input-sm {\n  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n.input-lg {\n  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n  // Enable absolute positioning\n  position: relative;\n\n  // Ensure icons don't overlap text\n  .form-control {\n    padding-right: (@input-height-base * 1.25);\n  }\n\n  // Feedback icon (requires .glyphicon classes)\n  .form-control-feedback {\n    position: absolute;\n    top: (@line-height-computed + 5); // Height of the `label` and its margin\n    right: 0;\n    display: block;\n    width: @input-height-base;\n    height: @input-height-base;\n    line-height: @input-height-base;\n    text-align: center;\n  }\n}\n\n// Feedback states\n.has-success {\n  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n  margin-bottom: 0; // Remove default margin from `p`\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n  display: block; // account for any element using help-block\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n  // Kick in the inline\n  @media (min-width: @screen-sm-min) {\n    // Inline-block all the things for \"inline\"\n    .form-group {\n      display: inline-block;\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // In navbar-form, allow folks to *not* use `.form-group`\n    .form-control {\n      display: inline-block;\n      width: auto; // Prevent labels from stacking above inputs in `.form-group`\n      vertical-align: middle;\n    }\n    // Input groups need that 100% width though\n    .input-group > .form-control {\n      width: 100%;\n    }\n\n    .control-label {\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // Remove default margin on radios/checkboxes that were used for stacking, and\n    // then undo the floating of radios and checkboxes to match (which also avoids\n    // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n    .radio,\n    .checkbox {\n      display: inline-block;\n      margin-top: 0;\n      margin-bottom: 0;\n      padding-left: 0;\n      vertical-align: middle;\n    }\n    .radio input[type=\"radio\"],\n    .checkbox input[type=\"checkbox\"] {\n      float: none;\n      margin-left: 0;\n    }\n\n    // Validation states\n    //\n    // Reposition the icon because it's now within a grid column and columns have\n    // `position: relative;` on them. Also accounts for the grid gutter padding.\n    .has-feedback .form-control-feedback {\n      top: 0;\n    }\n  }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n  // Consistent vertical alignment of labels, radios, and checkboxes\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n  }\n  // Account for padding we're adding to ensure the alignment and of help text\n  // and other content below items\n  .radio,\n  .checkbox {\n    min-height: (@line-height-computed + (@padding-base-vertical + 1));\n  }\n\n  // Make form groups behave like rows\n  .form-group {\n    .make-row();\n  }\n\n  .form-control-static {\n    padding-top: (@padding-base-vertical + 1);\n  }\n\n  // Only right align form labels here when the columns stop stacking\n  @media (min-width: @screen-sm-min) {\n    .control-label {\n      text-align: right;\n    }\n  }\n\n  // Validation states\n  //\n  // Reposition the icon because it's now within a grid column and columns have\n  // `position: relative;` on them. Also accounts for the grid gutter padding.\n  .has-feedback .form-control-feedback {\n    top: 0;\n    right: (@grid-gutter-width / 2);\n  }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n  display: inline-block;\n  margin-bottom: 0; // For input.btn\n  font-weight: @btn-font-weight;\n  text-align: center;\n  vertical-align: middle;\n  cursor: pointer;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  white-space: nowrap;\n  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n  .user-select(none);\n\n  &,\n  &:active,\n  &.active {\n    &:focus {\n      .tab-focus();\n    }\n  }\n\n  &:hover,\n  &:focus {\n    color: @btn-default-color;\n    text-decoration: none;\n  }\n\n  &:active,\n  &.active {\n    outline: 0;\n    background-image: none;\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    pointer-events: none; // Future-proof disabling of clicks\n    .opacity(.65);\n    .box-shadow(none);\n  }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n  color: @link-color;\n  font-weight: normal;\n  cursor: pointer;\n  border-radius: 0;\n\n  &,\n  &:active,\n  &[disabled],\n  fieldset[disabled] & {\n    background-color: transparent;\n    .box-shadow(none);\n  }\n  &,\n  &:hover,\n  &:focus,\n  &:active {\n    border-color: transparent;\n  }\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: underline;\n    background-color: transparent;\n  }\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus {\n      color: @btn-link-disabled-color;\n      text-decoration: none;\n    }\n  }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n  // line-height: ensure even-numbered height of button next to large input\n  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n  // line-height: ensure proper height of button next to small input\n  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  &.btn-block {\n    width: 100%;\n  }\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n  > .btn {\n    position: relative;\n    float: left;\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      z-index: 2;\n    }\n    &:focus {\n      // Remove focus outline when dropdown JS adds it after closing the menu\n      outline: none;\n    }\n  }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n  .btn + .btn,\n  .btn + .btn-group,\n  .btn-group + .btn,\n  .btn-group + .btn-group {\n    margin-left: -1px;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  margin-left: -5px; // Offset the first child's margin\n  &:extend(.clearfix all);\n\n  .btn-group,\n  .input-group {\n    float: left;\n  }\n  > .btn,\n  > .btn-group,\n  > .input-group {\n    margin-left: 5px;\n  }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  &:not(:last-child):not(.dropdown-toggle) {\n    .border-right-radius(0);\n  }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-right-radius(0);\n  }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n  .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    .box-shadow(none);\n  }\n}\n\n\n// Reposition the caret\n.btn .caret {\n  margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n  border-width: @caret-width-large @caret-width-large 0;\n  border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n  border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n  > .btn,\n  > .btn-group,\n  > .btn-group > .btn {\n    display: block;\n    float: none;\n    width: 100%;\n    max-width: 100%;\n  }\n\n  // Clear floats so dropdown menus can be properly placed\n  > .btn-group {\n    &:extend(.clearfix all);\n    > .btn {\n      float: none;\n    }\n  }\n\n  > .btn + .btn,\n  > .btn + .btn-group,\n  > .btn-group + .btn,\n  > .btn-group + .btn-group {\n    margin-top: -1px;\n    margin-left: 0;\n  }\n}\n\n.btn-group-vertical > .btn {\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n  &:first-child:not(:last-child) {\n    border-top-right-radius: @border-radius-base;\n    .border-bottom-radius(0);\n  }\n  &:last-child:not(:first-child) {\n    border-bottom-left-radius: @border-radius-base;\n    .border-top-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-bottom-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-top-radius(0);\n}\n\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n  > .btn,\n  > .btn-group {\n    float: none;\n    display: table-cell;\n    width: 1%;\n  }\n  > .btn-group .btn {\n    width: 100%;\n  }\n}\n\n\n// Checkbox and radio options\n[data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552.\n\n.fade {\n  opacity: 0;\n  .transition(opacity .15s linear);\n  &.in {\n    opacity: 1;\n  }\n}\n\n.collapse {\n  display: none;\n  &.in {\n    display: block;\n  }\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition(height .35s ease);\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n//  Star\n\n// Import the fonts\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot')\";\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.woff') format('woff')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg')\";\n}\n\n// Catchall baseclass\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk               { &:before { content: \"\\2a\"; } }\n.glyphicon-plus                   { &:before { content: \"\\2b\"; } }\n.glyphicon-euro                   { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus                  { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud                  { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope               { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil                 { &:before { content: \"\\270f\"; } }\n.glyphicon-glass                  { &:before { content: \"\\e001\"; } }\n.glyphicon-music                  { &:before { content: \"\\e002\"; } }\n.glyphicon-search                 { &:before { content: \"\\e003\"; } }\n.glyphicon-heart                  { &:before { content: \"\\e005\"; } }\n.glyphicon-star                   { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty             { &:before { content: \"\\e007\"; } }\n.glyphicon-user                   { &:before { content: \"\\e008\"; } }\n.glyphicon-film                   { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large               { &:before { content: \"\\e010\"; } }\n.glyphicon-th                     { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list                { &:before { content: \"\\e012\"; } }\n.glyphicon-ok                     { &:before { content: \"\\e013\"; } }\n.glyphicon-remove                 { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in                { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out               { &:before { content: \"\\e016\"; } }\n.glyphicon-off                    { &:before { content: \"\\e017\"; } }\n.glyphicon-signal                 { &:before { content: \"\\e018\"; } }\n.glyphicon-cog                    { &:before { content: \"\\e019\"; } }\n.glyphicon-trash                  { &:before { content: \"\\e020\"; } }\n.glyphicon-home                   { &:before { content: \"\\e021\"; } }\n.glyphicon-file                   { &:before { content: \"\\e022\"; } }\n.glyphicon-time                   { &:before { content: \"\\e023\"; } }\n.glyphicon-road                   { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt           { &:before { content: \"\\e025\"; } }\n.glyphicon-download               { &:before { content: \"\\e026\"; } }\n.glyphicon-upload                 { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox                  { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle            { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat                 { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh                { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt               { &:before { content: \"\\e032\"; } }\n.glyphicon-lock                   { &:before { content: \"\\e033\"; } }\n.glyphicon-flag                   { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones             { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off             { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down            { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up              { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode                 { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode                { &:before { content: \"\\e040\"; } }\n.glyphicon-tag                    { &:before { content: \"\\e041\"; } }\n.glyphicon-tags                   { &:before { content: \"\\e042\"; } }\n.glyphicon-book                   { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark               { &:before { content: \"\\e044\"; } }\n.glyphicon-print                  { &:before { content: \"\\e045\"; } }\n.glyphicon-camera                 { &:before { content: \"\\e046\"; } }\n.glyphicon-font                   { &:before { content: \"\\e047\"; } }\n.glyphicon-bold                   { &:before { content: \"\\e048\"; } }\n.glyphicon-italic                 { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height            { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width             { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left             { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center           { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right            { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify          { &:before { content: \"\\e055\"; } }\n.glyphicon-list                   { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left            { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right           { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video         { &:before { content: \"\\e059\"; } }\n.glyphicon-picture                { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker             { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust                 { &:before { content: \"\\e063\"; } }\n.glyphicon-tint                   { &:before { content: \"\\e064\"; } }\n.glyphicon-edit                   { &:before { content: \"\\e065\"; } }\n.glyphicon-share                  { &:before { content: \"\\e066\"; } }\n.glyphicon-check                  { &:before { content: \"\\e067\"; } }\n.glyphicon-move                   { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward          { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward          { &:before { content: \"\\e070\"; } }\n.glyphicon-backward               { &:before { content: \"\\e071\"; } }\n.glyphicon-play                   { &:before { content: \"\\e072\"; } }\n.glyphicon-pause                  { &:before { content: \"\\e073\"; } }\n.glyphicon-stop                   { &:before { content: \"\\e074\"; } }\n.glyphicon-forward                { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward           { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward           { &:before { content: \"\\e077\"; } }\n.glyphicon-eject                  { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left           { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right          { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign              { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign             { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign            { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign                { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign          { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign              { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot             { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle          { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle              { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle             { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left             { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right            { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up               { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down             { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt              { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full            { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small           { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign       { &:before { content: \"\\e101\"; } }\n.glyphicon-gift                   { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf                   { &:before { content: \"\\e103\"; } }\n.glyphicon-fire                   { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open               { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close              { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign           { &:before { content: \"\\e107\"; } }\n.glyphicon-plane                  { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar               { &:before { content: \"\\e109\"; } }\n.glyphicon-random                 { &:before { content: \"\\e110\"; } }\n.glyphicon-comment                { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet                 { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up             { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down           { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet                { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart          { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close           { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open            { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical        { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal      { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd                    { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn               { &:before { content: \"\\e122\"; } }\n.glyphicon-bell                   { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate            { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up              { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down            { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right             { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left              { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up                { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down              { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right     { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left      { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up        { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down      { &:before { content: \"\\e134\"; } }\n.glyphicon-globe                  { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench                 { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks                  { &:before { content: \"\\e137\"; } }\n.glyphicon-filter                 { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase              { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen             { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard              { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip              { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty            { &:before { content: \"\\e143\"; } }\n.glyphicon-link                   { &:before { content: \"\\e144\"; } }\n.glyphicon-phone                  { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin                { &:before { content: \"\\e146\"; } }\n.glyphicon-usd                    { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp                    { &:before { content: \"\\e149\"; } }\n.glyphicon-sort                   { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet       { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt   { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order          { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt      { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes     { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked              { &:before { content: \"\\e157\"; } }\n.glyphicon-expand                 { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down          { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up            { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in                 { &:before { content: \"\\e161\"; } }\n.glyphicon-flash                  { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out                { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window             { &:before { content: \"\\e164\"; } }\n.glyphicon-record                 { &:before { content: \"\\e165\"; } }\n.glyphicon-save                   { &:before { content: \"\\e166\"; } }\n.glyphicon-open                   { &:before { content: \"\\e167\"; } }\n.glyphicon-saved                  { &:before { content: \"\\e168\"; } }\n.glyphicon-import                 { &:before { content: \"\\e169\"; } }\n.glyphicon-export                 { &:before { content: \"\\e170\"; } }\n.glyphicon-send                   { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk            { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved           { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove          { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save            { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open            { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card            { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer               { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery                { &:before { content: \"\\e179\"; } }\n.glyphicon-header                 { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed             { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone               { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt              { &:before { content: \"\\e183\"; } }\n.glyphicon-tower                  { &:before { content: \"\\e184\"; } }\n.glyphicon-stats                  { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video               { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video               { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles              { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo           { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby            { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1              { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1              { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1              { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark         { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark      { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download         { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload           { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer           { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous         { &:before { content: \"\\e200\"; } }\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top:   @caret-width-base solid;\n  border-right: @caret-width-base solid transparent;\n  border-left:  @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n  position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: @zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0; // override default ul\n  list-style: none;\n  font-size: @font-size-base;\n  background-color: @dropdown-bg;\n  border: 1px solid @dropdown-fallback-border; // IE8 fallback\n  border: 1px solid @dropdown-border;\n  border-radius: @border-radius-base;\n  .box-shadow(0 6px 12px rgba(0,0,0,.175));\n  background-clip: padding-box;\n\n  // Aligns the dropdown menu to right\n  //\n  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n  &.pull-right {\n    right: 0;\n    left: auto;\n  }\n\n  // Dividers (basically an hr) within the dropdown\n  .divider {\n    .nav-divider(@dropdown-divider-bg);\n  }\n\n  // Links within the dropdown menu\n  > li > a {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: @line-height-base;\n    color: @dropdown-link-color;\n    white-space: nowrap; // prevent links from randomly breaking onto new lines\n  }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @dropdown-link-hover-color;\n    background-color: @dropdown-link-hover-bg;\n  }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-active-color;\n    text-decoration: none;\n    outline: 0;\n    background-color: @dropdown-link-active-bg;\n  }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-disabled-color;\n  }\n}\n// Nuke hover/focus effects\n.dropdown-menu > .disabled > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: transparent;\n    background-image: none; // Remove CSS gradient\n    .reset-filter();\n    cursor: not-allowed;\n  }\n}\n\n// Open state for the dropdown\n.open {\n  // Show the menu\n  > .dropdown-menu {\n    display: block;\n  }\n\n  // Remove the outline when :focus is triggered\n  > a {\n    outline: 0;\n  }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n  left: auto; // Reset the default from `.dropdown-menu`\n  right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: @font-size-small;\n  line-height: @line-height-base;\n  color: @dropdown-header-color;\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n  // Reverse the caret\n  .caret {\n    border-top: 0;\n    border-bottom: @caret-width-base solid;\n    content: \"\";\n  }\n  // Different positioning for bottom up menu\n  .dropdown-menu {\n    top: auto;\n    bottom: 100%;\n    margin-bottom: 1px;\n  }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-right {\n    .dropdown-menu {\n      .dropdown-menu-right();\n    }\n    // Necessary for overrides of the default right aligned menu.\n    // Will remove come v4 in all likelihood.\n    .dropdown-menu-left {\n      .dropdown-menu-left();\n    }\n  }\n}\n\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n  position: relative; // For dropdowns\n  display: table;\n  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n  // Undo padding and float of grid classes\n  &[class*=\"col-\"] {\n    float: none;\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  .form-control {\n    // Ensure that the input is always above the *appended* addon button for\n    // proper border colors.\n    position: relative;\n    z-index: 2;\n\n    // IE9 fubars the placeholder attribute in text inputs and the arrows on\n    // select elements in input groups. To fix it, we float the input. Details:\n    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n    float: left;\n\n    width: 100%;\n    margin-bottom: 0;\n  }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn { .input-lg(); }\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn { .input-sm(); }\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 1;\n  color: @input-color;\n  text-align: center;\n  background-color: @input-group-addon-bg;\n  border: 1px solid @input-group-addon-border-color;\n  border-radius: @border-radius-base;\n\n  // Sizing\n  &.input-sm {\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    border-radius: @border-radius-small;\n  }\n  &.input-lg {\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    border-radius: @border-radius-large;\n  }\n\n  // Nuke default margins from checkboxes and radios to vertically center within.\n  input[type=\"radio\"],\n  input[type=\"checkbox\"] {\n    margin-top: 0;\n  }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  .border-right-radius(0);\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  .border-left-radius(0);\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n  position: relative;\n  // Jankily prevent input button groups from wrapping with `white-space` and\n  // `font-size` in combination with `inline-block` on buttons.\n  font-size: 0;\n  white-space: nowrap;\n\n  // Negative margin for spacing, position for bringing hovered/focused/actived\n  // element above the siblings.\n  > .btn {\n    position: relative;\n    + .btn {\n      margin-left: -1px;\n    }\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active {\n      z-index: 2;\n    }\n  }\n\n  // Negative margin to only have a 1px border between the two\n  &:first-child {\n    > .btn,\n    > .btn-group {\n      margin-right: -1px;\n    }\n  }\n  &:last-child {\n    > .btn,\n    > .btn-group {\n      margin-left: -1px;\n    }\n  }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n  margin-bottom: 0;\n  padding-left: 0; // Override default ul/ol\n  list-style: none;\n  &:extend(.clearfix all);\n\n  > li {\n    position: relative;\n    display: block;\n\n    > a {\n      position: relative;\n      display: block;\n      padding: @nav-link-padding;\n      &:hover,\n      &:focus {\n        text-decoration: none;\n        background-color: @nav-link-hover-bg;\n      }\n    }\n\n    // Disabled state sets text to gray and nukes hover/tab effects\n    &.disabled > a {\n      color: @nav-disabled-link-color;\n\n      &:hover,\n      &:focus {\n        color: @nav-disabled-link-hover-color;\n        text-decoration: none;\n        background-color: transparent;\n        cursor: not-allowed;\n      }\n    }\n  }\n\n  // Open dropdowns\n  .open > a {\n    &,\n    &:hover,\n    &:focus {\n      background-color: @nav-link-hover-bg;\n      border-color: @link-color;\n    }\n  }\n\n  // Nav dividers (deprecated with v3.0.1)\n  //\n  // This should have been removed in v3 with the dropping of `.nav-list`, but\n  // we missed it. We don't currently support this anywhere, but in the interest\n  // of maintaining backward compatibility in case you use it, it's deprecated.\n  .nav-divider {\n    .nav-divider();\n  }\n\n  // Prevent IE8 from misplacing imgs\n  //\n  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n  > li > a > img {\n    max-width: none;\n  }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n  border-bottom: 1px solid @nav-tabs-border-color;\n  > li {\n    float: left;\n    // Make the list-items overlay the bottom border\n    margin-bottom: -1px;\n\n    // Actual tabs (as links)\n    > a {\n      margin-right: 2px;\n      line-height: @line-height-base;\n      border: 1px solid transparent;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n      &:hover {\n        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n      }\n    }\n\n    // Active state, and its :hover to override normal :hover\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-tabs-active-link-hover-color;\n        background-color: @nav-tabs-active-link-hover-bg;\n        border: 1px solid @nav-tabs-active-link-hover-border-color;\n        border-bottom-color: transparent;\n        cursor: default;\n      }\n    }\n  }\n  // pulling this in mainly for less shorthand\n  &.nav-justified {\n    .nav-justified();\n    .nav-tabs-justified();\n  }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n  > li {\n    float: left;\n\n    // Links rendered as pills\n    > a {\n      border-radius: @nav-pills-border-radius;\n    }\n    + li {\n      margin-left: 2px;\n    }\n\n    // Active state\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-pills-active-link-hover-color;\n        background-color: @nav-pills-active-link-hover-bg;\n      }\n    }\n  }\n}\n\n\n// Stacked pills\n.nav-stacked {\n  > li {\n    float: none;\n    + li {\n      margin-top: 2px;\n      margin-left: 0; // no need for this gap between nav items\n    }\n  }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n  width: 100%;\n\n  > li {\n    float: none;\n     > a {\n      text-align: center;\n      margin-bottom: 5px;\n    }\n  }\n\n  > .dropdown .dropdown-menu {\n    top: auto;\n    left: auto;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li {\n      display: table-cell;\n      width: 1%;\n      > a {\n        margin-bottom: 0;\n      }\n    }\n  }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n  border-bottom: 0;\n\n  > li > a {\n    // Override margin from .nav-tabs\n    margin-right: 0;\n    border-radius: @border-radius-base;\n  }\n\n  > .active > a,\n  > .active > a:hover,\n  > .active > a:focus {\n    border: 1px solid @nav-tabs-justified-link-border-color;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li > a {\n      border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n    }\n    > .active > a,\n    > .active > a:hover,\n    > .active > a:focus {\n      border-bottom-color: @nav-tabs-justified-active-link-border-color;\n    }\n  }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n  // make dropdown border overlap tab border\n  margin-top: -1px;\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n  margin-bottom: @navbar-margin-bottom;\n  border: 1px solid transparent;\n\n  // Prevent floats from breaking the navbar\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: @navbar-border-radius;\n  }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n  }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n  max-height: @navbar-collapse-max-height;\n  overflow-x: visible;\n  padding-right: @navbar-padding-horizontal;\n  padding-left:  @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n  &:extend(.clearfix all);\n  -webkit-overflow-scrolling: touch;\n\n  &.in {\n    overflow-y: auto;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.collapse {\n      display: block !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    &.in {\n      overflow-y: visible;\n    }\n\n    // Undo the collapse side padding for navbars with containers to ensure\n    // alignment of right-aligned contents.\n    .navbar-fixed-top &,\n    .navbar-static-top &,\n    .navbar-fixed-bottom & {\n      padding-left: 0;\n      padding-right: 0;\n    }\n  }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n  > .navbar-header,\n  > .navbar-collapse {\n    margin-right: -@navbar-padding-horizontal;\n    margin-left:  -@navbar-padding-horizontal;\n\n    @media (min-width: @grid-float-breakpoint) {\n      margin-right: 0;\n      margin-left:  0;\n    }\n  }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n  z-index: @zindex-navbar;\n  border-width: 0 0 1px;\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: @zindex-navbar-fixed;\n\n  // Undo the rounded corners\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0; // override .navbar defaults\n  border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n  float: left;\n  padding: @navbar-padding-vertical @navbar-padding-horizontal;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n  height: @navbar-height;\n\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    .navbar > .container &,\n    .navbar > .container-fluid & {\n      margin-left: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: @navbar-padding-horizontal;\n  padding: 9px 10px;\n  .navbar-vertical-align(34px);\n  background-color: transparent;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  border-radius: @border-radius-base;\n\n  // We remove the `outline` here, but later compensate by attaching `:hover`\n  // styles to `:focus`.\n  &:focus {\n    outline: none;\n  }\n\n  // Bars\n  .icon-bar {\n    display: block;\n    width: 22px;\n    height: 2px;\n    border-radius: 1px;\n  }\n  .icon-bar + .icon-bar {\n    margin-top: 4px;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    display: none;\n  }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n  margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n  > li > a {\n    padding-top:    10px;\n    padding-bottom: 10px;\n    line-height: @line-height-computed;\n  }\n\n  @media (max-width: @grid-float-breakpoint-max) {\n    // Dropdowns get custom display when collapsed\n    .open .dropdown-menu {\n      position: static;\n      float: none;\n      width: auto;\n      margin-top: 0;\n      background-color: transparent;\n      border: 0;\n      box-shadow: none;\n      > li > a,\n      .dropdown-header {\n        padding: 5px 15px 5px 25px;\n      }\n      > li > a {\n        line-height: @line-height-computed;\n        &:hover,\n        &:focus {\n          background-image: none;\n        }\n      }\n    }\n  }\n\n  // Uncollapse the nav\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin: 0;\n\n    > li {\n      float: left;\n      > a {\n        padding-top:    @navbar-padding-vertical;\n        padding-bottom: @navbar-padding-vertical;\n      }\n    }\n\n    &.navbar-right:last-child {\n      margin-right: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-left  { .pull-left(); }\n  .navbar-right { .pull-right(); }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n  margin-left: -@navbar-padding-horizontal;\n  margin-right: -@navbar-padding-horizontal;\n  padding: 10px @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n\n  // Mixin behavior for optimum display\n  .form-inline();\n\n  .form-group {\n    @media (max-width: @grid-float-breakpoint-max) {\n      margin-bottom: 5px;\n    }\n  }\n\n  // Vertically center in expanded, horizontal navbar\n  .navbar-vertical-align(@input-height-base);\n\n  // Undo 100% width for pull classes\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    .box-shadow(none);\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n  .navbar-vertical-align(@input-height-base);\n\n  &.btn-sm {\n    .navbar-vertical-align(@input-height-small);\n  }\n  &.btn-xs {\n    .navbar-vertical-align(22);\n  }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n  .navbar-vertical-align(@line-height-computed);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin-left: @navbar-padding-horizontal;\n    margin-right: @navbar-padding-horizontal;\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: 0;\n    }\n  }\n}\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  background-color: @navbar-default-bg;\n  border-color: @navbar-default-border;\n\n  .navbar-brand {\n    color: @navbar-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-brand-hover-color;\n      background-color: @navbar-default-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-default-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-default-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-hover-color;\n        background-color: @navbar-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-active-color;\n        background-color: @navbar-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n        background-color: @navbar-default-link-disabled-bg;\n      }\n    }\n  }\n\n  .navbar-toggle {\n    border-color: @navbar-default-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-default-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-default-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: @navbar-default-border;\n  }\n\n  // Dropdown menu items\n  .navbar-nav {\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-default-link-active-bg;\n        color: @navbar-default-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display when collapsed\n      .open .dropdown-menu {\n        > li > a {\n          color: @navbar-default-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-hover-color;\n            background-color: @navbar-default-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-active-color;\n            background-color: @navbar-default-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-disabled-color;\n            background-color: @navbar-default-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n\n  // Links in navbars\n  //\n  // Add a class to ensure links outside the navbar nav are colored correctly.\n\n  .navbar-link {\n    color: @navbar-default-link-color;\n    &:hover {\n      color: @navbar-default-link-hover-color;\n    }\n  }\n\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n  background-color: @navbar-inverse-bg;\n  border-color: @navbar-inverse-border;\n\n  .navbar-brand {\n    color: @navbar-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-brand-hover-color;\n      background-color: @navbar-inverse-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-inverse-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-inverse-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-hover-color;\n        background-color: @navbar-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-active-color;\n        background-color: @navbar-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n        background-color: @navbar-inverse-link-disabled-bg;\n      }\n    }\n  }\n\n  // Darken the responsive nav toggle\n  .navbar-toggle {\n    border-color: @navbar-inverse-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-inverse-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-inverse-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: darken(@navbar-inverse-bg, 7%);\n  }\n\n  // Dropdowns\n  .navbar-nav {\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-inverse-link-active-bg;\n        color: @navbar-inverse-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display\n      .open .dropdown-menu {\n        > .dropdown-header {\n          border-color: @navbar-inverse-border;\n        }\n        .divider {\n          background-color: @navbar-inverse-border;\n        }\n        > li > a {\n          color: @navbar-inverse-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-hover-color;\n            background-color: @navbar-inverse-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-active-color;\n            background-color: @navbar-inverse-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-disabled-color;\n            background-color: @navbar-inverse-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n  .navbar-link {\n    color: @navbar-inverse-link-color;\n    &:hover {\n      color: @navbar-inverse-link-hover-color;\n    }\n  }\n\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n  .clearfix();\n}\n.center-block {\n  .center-block();\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n  position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n  margin-bottom: @line-height-computed;\n  list-style: none;\n  background-color: @breadcrumb-bg;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline-block;\n\n    + li:before {\n      content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n      padding: 0 5px;\n      color: @breadcrumb-color;\n    }\n  }\n\n  > .active {\n    color: @breadcrumb-active-color;\n  }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline; // Remove list-style and block-level defaults\n    > a,\n    > span {\n      position: relative;\n      float: left; // Collapse white-space\n      padding: @padding-base-vertical @padding-base-horizontal;\n      line-height: @line-height-base;\n      text-decoration: none;\n      color: @pagination-color;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      margin-left: -1px;\n    }\n    &:first-child {\n      > a,\n      > span {\n        margin-left: 0;\n        .border-left-radius(@border-radius-base);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius-base);\n      }\n    }\n  }\n\n  > li > a,\n  > li > span {\n    &:hover,\n    &:focus {\n      color: @pagination-hover-color;\n      background-color: @pagination-hover-bg;\n      border-color: @pagination-hover-border;\n    }\n  }\n\n  > .active > a,\n  > .active > span {\n    &,\n    &:hover,\n    &:focus {\n      z-index: 2;\n      color: @pagination-active-color;\n      background-color: @pagination-active-bg;\n      border-color: @pagination-active-border;\n      cursor: default;\n    }\n  }\n\n  > .disabled {\n    > span,\n    > span:hover,\n    > span:focus,\n    > a,\n    > a:hover,\n    > a:focus {\n      color: @pagination-disabled-color;\n      background-color: @pagination-disabled-bg;\n      border-color: @pagination-disabled-border;\n      cursor: not-allowed;\n    }\n  }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  list-style: none;\n  text-align: center;\n  &:extend(.clearfix all);\n  li {\n    display: inline;\n    > a,\n    > span {\n      display: inline-block;\n      padding: 5px 14px;\n      background-color: @pager-bg;\n      border: 1px solid @pager-border;\n      border-radius: @pager-border-radius;\n    }\n\n    > a:hover,\n    > a:focus {\n      text-decoration: none;\n      background-color: @pager-hover-bg;\n    }\n  }\n\n  .next {\n    > a,\n    > span {\n      float: right;\n    }\n  }\n\n  .previous {\n    > a,\n    > span {\n      float: left;\n    }\n  }\n\n  .disabled {\n    > a,\n    > a:hover,\n    > a:focus,\n    > span {\n      color: @pager-disabled-color;\n      background-color: @pager-bg;\n      cursor: not-allowed;\n    }\n  }\n\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: @label-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n\n  // Add hover effects, but only for links\n  &[href] {\n    &:hover,\n    &:focus {\n      color: @label-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Empty labels collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for labels in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n  .label-variant(@label-default-bg);\n}\n\n.label-primary {\n  .label-variant(@label-primary-bg);\n}\n\n.label-success {\n  .label-variant(@label-success-bg);\n}\n\n.label-info {\n  .label-variant(@label-info-bg);\n}\n\n.label-warning {\n  .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n  .label-variant(@label-danger-bg);\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base classes\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: @font-size-small;\n  font-weight: @badge-font-weight;\n  color: @badge-color;\n  line-height: @badge-line-height;\n  vertical-align: baseline;\n  white-space: nowrap;\n  text-align: center;\n  background-color: @badge-bg;\n  border-radius: @badge-border-radius;\n\n  // Empty badges collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for badges in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n  .btn-xs & {\n    top: 0;\n    padding: 1px 5px;\n  }\n}\n\n// Hover state, but only for links\na.badge {\n  &:hover,\n  &:focus {\n    color: @badge-link-hover-color;\n    text-decoration: none;\n    cursor: pointer;\n  }\n}\n\n// Account for counters in navs\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: @badge-active-color;\n  background-color: @badge-active-bg;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding: @jumbotron-padding;\n  margin-bottom: @jumbotron-padding;\n  color: @jumbotron-color;\n  background-color: @jumbotron-bg;\n\n  h1,\n  .h1 {\n    color: @jumbotron-heading-color;\n  }\n  p {\n    margin-bottom: (@jumbotron-padding / 2);\n    font-size: @jumbotron-font-size;\n    font-weight: 200;\n  }\n\n  .container & {\n    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n  }\n\n  .container {\n    max-width: 100%;\n  }\n\n  @media screen and (min-width: @screen-sm-min) {\n    padding-top:    (@jumbotron-padding * 1.6);\n    padding-bottom: (@jumbotron-padding * 1.6);\n\n    .container & {\n      padding-left:  (@jumbotron-padding * 2);\n      padding-right: (@jumbotron-padding * 2);\n    }\n\n    h1,\n    .h1 {\n      font-size: (@font-size-base * 4.5);\n    }\n  }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n  padding: @alert-padding;\n  margin-bottom: @line-height-computed;\n  border: 1px solid transparent;\n  border-radius: @alert-border-radius;\n\n  // Headings for larger alerts\n  h4 {\n    margin-top: 0;\n    // Specified for the h4 to prevent conflicts of changing @headings-color\n    color: inherit;\n  }\n  // Provide class for links that match alerts\n  .alert-link {\n    font-weight: @alert-link-font-weight;\n  }\n\n  // Improve alignment and spacing of inner content\n  > p,\n  > ul {\n    margin-bottom: 0;\n  }\n  > p + p {\n    margin-top: 5px;\n  }\n}\n\n// Dismissable alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable {\n padding-right: (@alert-padding + 20);\n\n  // Adjust close link position\n  .close {\n    position: relative;\n    top: -2px;\n    right: -21px;\n    color: inherit;\n  }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n  overflow: hidden;\n  height: @line-height-computed;\n  margin-bottom: @line-height-computed;\n  background-color: @progress-bg;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: @font-size-small;\n  line-height: @line-height-computed;\n  color: @progress-bar-color;\n  text-align: center;\n  background-color: @progress-bar-bg;\n  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n  .transition(width .6s ease);\n}\n\n// Striped bars\n.progress-striped .progress-bar {\n  #gradient > .striped();\n  background-size: 40px 40px;\n}\n\n// Call animation for the active one\n.progress.active .progress-bar {\n  .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n  .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n  .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n  .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n  .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Media objects\n// Source: http://stubbornella.org/content/?p=497\n// --------------------------------------------------\n\n\n// Common styles\n// -------------------------\n\n// Clear the floats\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n\n// Proper spacing between instances of .media\n.media,\n.media .media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n\n// For images and videos, set to block\n.media-object {\n  display: block;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n  margin: 0 0 5px;\n}\n\n\n// Media image alignment\n// -------------------------\n\n.media {\n  > .pull-left {\n    margin-right: 10px;\n  }\n  > .pull-right {\n    margin-left: 10px;\n  }\n}\n\n\n// Media list variation\n// -------------------------\n\n// Undo default ul/ol styles\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on 
    ,
      , or
      .\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n\n // Align badges within list items\n > .badge {\n float: right;\n }\n > .badge + .badge {\n margin-right: 5px;\n }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @list-group-hover-bg;\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: 10px 15px;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table {\n margin-bottom: 0;\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n overflow: hidden; // crop contents when collapsed\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n + .panel-collapse .panel-body {\n border-top: 1px solid @panel-inner-border;\n }\n }\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: auto;\n overflow-y: scroll;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0)}\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: none;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n margin-top: 15px;\n padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n visibility: visible;\n font-size: @font-size-small;\n line-height: 1.4;\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n text-decoration: none;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n text-align: left; // Reset given new insertion method\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Overrides for proper insertion\n white-space: normal;\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 18px;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: 5px 5px 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#browsers\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n"]} \ No newline at end of file diff --git a/web/orchestrator/public/bootstrap/css/bootstrap.min.css b/web/orchestrator/public/bootstrap/css/bootstrap.min.css new file mode 100644 index 00000000000..679272d2585 --- /dev/null +++ b/web/orchestrator/public/bootstrap/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.1.1 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! normalize.css v3.0.0 | MIT License | git.io/normalize */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,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:0 0}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{-moz-box-sizing:content-box;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;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;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}@media print{*{text-shadow:none!important;color:#000!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;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:20px;margin-bottom:20px;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}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.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-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-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:0}.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:0}.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:0}.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:0}.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:0}.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:0}.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:0}.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:0}.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}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:400;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{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:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);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:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{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:12px;line-height:1.42857143;color:#999}.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 solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;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:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);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:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.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}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;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;text-decoration:none;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{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000}.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;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!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}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.eot b/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..4a4ca865d67e86f961bc6e2ef00bffa4e34bb9ed GIT binary patch literal 20335 zcma%iRa9Lu*X_aGIXLtH2X}XOcXxM};>BGK?k>gMi@Uo+afec%&=$Y_zI(@iAMVRd zMzYtMnVHGh`(bBgBrYld0G2WU0R1n+0{)ZW{#ye8Pyh%N;2)-_`hS4`dHjR_o8s?3 z%Kr!aAA=Sk15gC$0aO9906BmJKn0)-&;Wq`d1e4dfc3v(2XF@106hNnKnJJ;tp3?v z|4=i4`#;17p#2YV|JP~t*4IuDO^FK=e+xx$$?LVd`z~aAr@Bit+ z4B+|46aYB=Q+D{L`5%t;Kdt|aZw_GpXL0?v@B%pgd3^uI=KcSkIq3hHHvk~6A@l#d zDHwovCxFWvz!d;sGQ^&}h@CLq(3!MVaFhSyL!rg*&d8F%X_&hML`QYBTiRZ}i=N8C zfX|m2SCm$2B^?XKJ=3POS}r1sVM9Nj*l5q`5#S% zQ}FD^zy1Pj*xUGOm4;*C;l80oktO?~%SdX8H^8@@idBFWyOINSr_!xo{REWRlXgw| z3-(h5XcHaEdPKzyy2-P+Rljn4lR?IelEOtWLiC?_9FW&x@kpuRtfsn*-QLS4EoN{{q0u8pt_^hD_!V);D{hen z-XpV~5QeQTYTIl1+B^5r72`!7FRQQ$Jh74=Gm*OkaIoNUC7!wk7rRZVuVK6urnp@}QDpB~9*S zkVWg8LyXz8-%53>GXb$%*H0(bqkUIN`Oz8g=bse?bAumC8`5XqA+(_y{fV^j(1$BZ za*@mJ(&?Dl2k;8tW}O6OaavJE|17u#1t>M^0!@SDJc2)cLZL`m7!-)74CQUXoksM* z9m|Sjh}@dm-Tnc8<77&TfjT6H{3)kXMM774`D!eA0|(RuQz@iQO(4-7lX|aK*M`Y=f%R{_&<*A? zB(AZUl6JXgz^9c9q7ZW~Lpncpv1I^6O4mGX@3P^Q)?jBgx(f#RD_4y0q5aC_beGG> zn%RbEy_vdx`sL?|Jvlgyxal-}XM^FDQYp|Euiu=%8o(=wic+XSimJ4(Adn3`QH6^D zQ}H@oBN{|Zg^2u|@8c~h7Kv&HCx??xy^J$3{B0{XnlrThDaoQqjXjXHi#b!KIjA7( z$hT;Ah_VP&j)(Z6&(xn;KF3rHsF^A#il?$)q4Pp#sly?|%OmoRG|MiNW3+)?3Wd9= zgbUjzTLX+!G&oYj9P;jnHmT91qKPzxkj@>rsqi|=M5$PfrRCY%E7${xLDZFtYcC%k zorpLj$T65dN+HV@=yRlKSS8W~SMxFkK1~U-XW2@DXcG`4-V)z|605uD4Q{MP10fD5 zc!T#)n57))zXXfg=dwnZuD_`DCJc3cHE6HuA(>36o_neqgoF0pRK0eEc~{rD8%Pfh z@dtE6ovkazKj3fd{)*&tB0YA^1d^^?2oeNyB7u(P+O4$@lCNc~%mb5iP)dLGM|z;x zEkRYM_^U`g%s5jiH=8Q2h zlS%BdC6DaYEWi0UNhnc*zFT$fV`4_VMNU~nH;q(Ld?!#lIvm)K;W_4C(l3+4TZ=QI zD%siB%cY+Y7vMFM_KAg?sxm(^nJsMIV?v|vAS8l;zotv$#Ml-Y!n7|X5Y5C)=TiGZ zQ+=(9%lk0&L&hDtwRD=Ua6wQeS{g2mvwc>^|4$ot-2Hi`z)|V$N{mNAEZC3gw_8%z zq(L3Bcwr2gin62dXM8cG-D-auD7HayLz zJI2|m=8$F?Ko>v@P4{(W5g=}-b$%tJgfywp`6&A96|Zx{9N;1@_>hto7TQf3EIMm+ zJ`;@@4ycXnHM>|iJ?FXkWGc8YuGviO&L*^ajd+vyLIxAAT{isADQQM5S;YP+jAYp7 z3E1Nm1HDd%SXi``NR*so7XidvRPj#BM7A`S{cU%VISQOhrMLr08;N36AYg9}40Ml# zU)GUxQy(D1%P`@`HDaXn&%m8`hOu~_2a`%P{v7w2;KUNhll)N(y4wD#p#{+($uLOB z!X;K=sci1erRm1=Qcx#ja(r=E8*89RNH8`C7T4|#uVRc=Kaf}0Xw)>8g0(4H!ZrK^ zh-Kf(V#NQcMU79on9bk?`U7eI{Nu-CdboLYH-7lJI|7VCob2872$p->3n)-J>N|b% zIn3vzKet~nvHB=bP6rDRV|&&4LL}S7`iu2ok&r8ecw~yUROul?44VSV3;z7qSQWl+y^cX=$j~OQ;o~0+_)5WDRF0^JbuD_umr4Mn$EPEyB-_eog^1*P#Ui}dCDH6-GndXgi$XV2SNHe#HHQoU z`2f{kT*~Y-Gtyd}I#v=*PbShJzp4hgaK>cr++;2GSGr7^2gA_3H1F;=06B{L4@fTs zD?F!vb_51Hnzb3BJlYiI4qZ5fDt|CaKX-N&2aP_DVX`bH*FN93cV*3fPvociz|dFF zDI@_;;4`*j9yW7pmnXjEwqe@BEQw*5Kcl$=zJxCo$}$5>0aU8*UXir zlo6vuHSn81M=rz-M|tYukSa7I2M$#Q-7`8&2-+UvW25@8gOf1VSR}3RdVFr|-&}4T zky0u`XuQc%0#b=LJWu5hm&cbB$Zk2FeYD~v-Cc92u|%sIUh-65dJR zZ3)g?oGWe-H6(Dl5E)k2)Hal?$9R73FM9`l`qB^<^f4kuce&|T)yCo{^=_a`TY*c$ zRRh_284jJjLoW$Wjv_@n$8LbXuW0pZw;g`-3$XUHD0Me!pbdD8z$3+L^KKYOabFdl zZW8&J8yRWfjLh?e7QJEkgl<&QwDnZ2^WwgBH0{AjxI^@Q)51nlGRVgj8j^jL0%{L5 zg~N&QybX0(ldaaot?}x4%vuVeTbZ96fpg*k(_p?a+IFGn!YUuS;~_Z0CLyGFeQ=ow zhS}^5R4dLfu9Q@MFw7c5_Tg`%mq$XF81YXSFD~rt=E6o|lVBQmHpMG(*<)M(E(4f* zifS(;Yjenr?~y*l>F20zQ%mciliU45f-wznJZdw(tS7t6>004*2#X3Ej3pco3fi`a z?|gM_ckVQxZ*D!nTeU+|gbdPEj(!rKUXu)| zkLqUGanZqn25Ek?PHa9%4W|%Ad_2AJ^C4ZsK(9AW?d?fe_y54j#ceCX7%ZMmS`{x=_0fcCjb0L>U_D>5f4kNy zHQQg5@4aYV)6gpTnv`z06M5a}w7=9Zxp`bcn&i(EOAPWj!?Z(2O?^DESnGfRDGcs1 z?IvJ*{LKonl7#robcFc@OJ<~_Nrt1&v@ePe#wEFKMxfTA!AwJm2~n9HG8Q3?YR-Yz z9Qm3kx|c48;)6Kyoo?<`!|@@xwp~u#ofuQm>ip4bLvO_8W)9{2phqI7{WR9NLgJ5S zHO8hXtJ(CY)mUG&o(gGo!3Qk!=#XUS13O&o{vweBJ4o1y<~#&5^$s69ECV9xM}=+2 z3!NJW8%Q`f_Ja)nexErX5!VB@V=TLVghSEjRt5vdJ8zuRg0R+Y>(Wb*7ED)es#R7< zyyj>az=m}1XQ+E7Z@KG=Cs|{!+EejQ_B-7_Z_Y;kETxVVJOayFzr&scDu#RzsdT7?ZD( zjt$GiPqMQDN##jNA(UuHMgjopqE;pkUTep+3YhG2G!BnK?~X#v(Hh{G+w3pu5aBF+5$)Hq);#9CbG zsE7UhKwvg;w*V(0K7kvgnm5CXt2oMK#y!&dqW6^CO`o-9h;rpe8sX@M7vdNHrSI)y z9KlvS+@+-`CzlS3h}P)VbJn)MN&1rZJDgsR=F2FHZMpd&S1VRKi;7W;=|X`v`iwr; z6={w%x(Bj(^(a<%?7PB*S%}>sft}U!!qdscsQgT@3X5WihmLBxuS7?1$@SvvJ3<<| zt}Y%yqH_W&6!_(na-jr#Zv7W*Cu#c6Hqr$o{eMTHmIWfcuI+rsXc1x$ibc)|lxs`| z^lhQp&^b^BTL(xEI!6k8bxom-D8C}+6_a%`?CYjSuFcEh5J1&Y`Z-6Dj-I`%()n$9 zg*b<&Zs^xdC{p2ab~}fxiuobr7XT7pIefDq+B0S-e*#Ncv}xLJi{{yPWu)?Esyu0; z1qsK_FAEg-C+$p0cp*xgs1s4btkM&3lqqeQRpD2eomd(OP0Q@*e&Xas38amh5^boC zOw$(pnvN$4MdoQ_u*a%EGU#34!L8h;hCq2qu>vma`dr@6OJ$uR*Uy0|v+9(q#{vUE z-6#WJn9K=D1b|=3z9t2tlyis<332BeH7r+zY@~b=^WA5yuvSMiyU=H97SQ7PJ=xDq8^5h@!5s)7NwIC(^9c}UqFKh>XnFPu|+L@P;S z3sSA!`G>+GcF}A^nfl|n_2P=oi#0>A$BphJo^niV$39q>jBn7=yG3jodFC|0-)C$R z@AvsPawzRcdI+N@#+XCUhE-bV6R(fb0#L8<{kZo-bBF0d_eb2=Oq%CRy|M%BGBmTi z*(vF=mDqfB)Ffbr1WObL5rtaXXn7h$vMIMyd!!E!)5Fe{yHa{ZKHpGwQ9J-@cQ$OX z8Bux&6WJ%|zF+jJZ&(g-&u~QV-Y_~q?DJ>#3~9WiBeIU_uh)eb{b{VUn_K9kFfYXL z#W?5L8z;XrA?Kc&ua35Hi_uhWghl9)h*)J}%wG+Xnnp2ZOl*YtK3VQxUMfBM+z>E2 zeI`!tBDijjXYxlLEZu7t_T<~!mR0{o>6W*Ejr z6v8z^G$W!dDq*^y$WbyhI)x}-s>tdk0{-;A z91U?k6Rg*%T*U)Uv_PP_}4jhJ6|~ z)$B}m4(d`YtCBcrVbz?cQGo|NhMK(@OnGsU7OAKgUBJLh?E@OO@sfUG8M``oQbcDgDKEy^t6!AhE@HqgSG<3Q{ND7tH!G1 zQFCZgl=Ykxr~0pdq)`n2y3~Y0cvkO5i!CLTAc68-9cOMi2c29BTcg!W5=XzHR68tT zH%o4w$B?>YF0Aq0w*Q@DIf|UyjajcxO2`!Av{p;s2#z_Xfp*{$2fM>65~br|rCyhX zcrN@r4!w~3imlj-eew7qq8d&vtYnSAT9&|&Y&=~}zF5=-5at@Gr1s6~`eBk{nJh+@ z#(=xEI>c6xXU(ucS*a_!ww@WYvo?~@3dBjqAUH~h9mW5q!R#);8l%8+oJnb+-ydqv)LHQJSgY=p%{@~Fk(V6=o{<5fV>)fPWOyXSo|G?G=*~> z?z><)(Ss@lE|vU-2vhORxCM>@LEx4O{!kmzI5 zFUOuOX^BHASj%#FATqS(FnqPTp^|Sq;eg3wKvIzUJ%FNpoCY`^OPv(^>&j{V#RFzE z@3Y)bA(4m_iaS`J&gG(v^)Jth;W$iESCeCBA1#B(N63V{dggoJ%RQn}c>a@^%gazJ zI$Shg5yVpcpnJOOWY^dBUI=3iC>#a1p2NQs|b zgZHukR9HwV8Sgp{#+jN7ZB3DI6~hIHv@&% z=$?K2gzM;xC?K<9N0|-BMSk4bLI)uB*!ugfY0qP3R%y5O?&{Xfzojfbw?zj^P+_;e zRVm>&GsN)=HBH+0BHxJo&ckuL8w0=_w~q6R{ghxeMmsDh;9@n%VFE`Zx%pQglC=A4 zmJFxIgNwqP)8^b#RwBGP+eI;wi}{^pYMTtQ4h21k5DL#G?TZ4VCjrqHlXx z5GWyy1)M+9Im*H1Nb!*p1miCdMHEs>^!0KnPX60;FztLJwN}7vh;E>|7i^aSKwZPp zbmc@;Z{n(|)caxrl1Z94YDTS$mif`TC>B#m4S#$l?uReS>1@v!TRjv$vg^osFiop z3Ec1yBx|_DM8|$B+gdt2+Wo8>VSiOZMk{KxbsETEqXrMe43bz3J;k2|bk1|VfW}}N ziBRxsE0VSSOf}i%^gY0FFMldwBHt78EjW?Hs`TiH)s0WX#E(VMU>!x(pRNEl0?(%d z(09!|c3J9g+xi&)MKNr%Lz~VacC(%gKWoY@ID6_>a>(E=mVmuqrKtH5d$d}xX&NeD z5RiuBXo9`O{xL>+V-49mRc(3kT+>qNP814Xc&F=6k?M%@t6NOb@@_X`d3htI>|zGN z&z3d$7^TV;cV+eyHCzB+pyNz1atbYX3gZfiSjHB<0Ehv&M)7xxzlJu32@Iosx5?qd z-7Ka#WS9+1pr}6b%d2z-ZT+Fzpf`63fy)jTb-|y39hX-WFKTi7kn^+4(;QJI%l!pK ze2L!7r+ad0PfD2bsar6XgD>XWJxwwoHCORf9r0VEIM_qM zCzw=0@8aB8TV{tjzE5zvR&0MR>so`xq~rHSLBuI)mS!Dh1{CI~)~Nb^?^R@Gb*0A1 z=&MnM%PG*qmrKBjp8ZIYS@DFDNwe5Ww=2e65vs{7e0?Ou*xB{?A9P$i{y zM|4xJ3)%!G%8d{u-AC5&>)0?3EeMgln4Yut1`I~s-Cl*~G*Ri1k>5}JY295;&pq@- z#Lm^4Hp$Vz)X?2y^sW@;*ClyG-%gBU|LBB2+bG$zX%YcrI$cSa$$Sdz2EBDDiX$!I z{_-)%I3e)hC3KOBqNUpTOsPtReVV3GD|?sDzlEY;lsV>UYEWf_58h)t*RN0JkrGu0p9p8L{s_RPwvTR zXR9)eJN*RNMO^RZbZOXGNdieWgVSs&xvqTIv}1x>vCDtEk6_WWAVXu?Nu7sREv!;U zh%KMgdA}u72`Xz6{1nx8ud@3we5$9_>x#f2Ci}@h{1$Fh&}3CiF{d z+}gjEHbU-5+06vi&lbqcVU4dKyM_2lgko*2LU$@58M9ER0>@8%8{Q`H zM^pmfKp*!)YkLi|P(GT%H`-^=EmrEUhQ4I?ux{(gb8Cfs3Y;=$r!4-O%2yn10(6sR zU6xmo^&_$SnfCEbTemLPST3#%z3J!5Y}po{ihZicg?6_ADfUcz?o1} zmJxCzhnNT~o!=vhmRTEXGQ4OT$Zvhr5{5Midj2y-p}oGVqRFwQiNxp#2-*sjF6fsF zV6XhhsSL>wR!QmL`QcBPeEpof>)1LNkZE`AL+G5)@6qC>qR! z8+){akxki?kaFfX6i}pXp_`Xlck94~S-?9*q=QqL2z=I4B@Zvi@4?yJho3QIdNI8l z#4QKGd<)2;6Vy;X#e*x_gP*hHWyFFgqukOJH7ndQUKry!7s+}S>|FP?VT3DlK1qQQ zk=oA%rP%@u3Q)BH2;)Li&oL3#M*r$!{Ih zASM=(#VCobo1BhR#*@dO*~PX)#gN9<0l;rNRKG4|p!^Nocw@Iy>-~ZJ?0T#CqSxD+ zevj?m@H}89TT2L<6HsC#BB(?}DykVK9k*1%F~}N9y4KadeB)RvJq;@3pmQntjRuyp zd+bH2w#~~?gnNl>cBMwx5@vUCsl~4k*^~r4aR!EORAjW02r1eGW<}-vIl3BCwVUEw zh(xbpj>h?!;M4gDxV}8^il-Ur;r34S_`LeD#vXa-JKk@`B;%!=m}ILfo6GCRP-vnwGMvS1TCwL(fwPc-To}O1cyV3K?4x z{_{-2*jZ}zOd{hm(Z%1afi9LPcXUtDSf?C9Eh3I80lt-6uc=&~q`FuW) zKHDvFXfegSj8LcxD#zUuFPYuggI{ZvI5 zj|TJPpX&$cTSpufZ23uYl>m#4Uva-%N<10wTI1Mav~)-=p+fo(j6RRxz{*!Z9U-)C z9>Fg)gf&-?LrVVy@(_wx>%nb~#fWvMjZ~3snIE4PjYc%6*#^HD>*h`@M=No(8gEO?tGG;DGL! zIknN6VVIpLepd7%^9kPQ=@m~$#G`d&22uBd7N`xiP7nd~8%zL8zY7$6HJXuC?e(YU zo|ZhfFlXWkh}8`aNOTEuicNS}80_)bI`FU)e}Gw)H(>SGZcAB2IjJ%f(xjS0D3g$f zpKWvE6C}I95gE5ucsGJw!I(^u@Qq2m!}b62JC2|pO%)yPHM(i^a4hL6s!^uhSYDQ( zs6-SU+3-3w$KoVN{lR=H^hVSP#EnRfCNooS9%oP_bri+sHqLwpN!J;gB#HbCT*wP$kPMWfp>3s$!F>BG0nI}(tOBcS z`;|a~gZLF43#h#S#h9K-xNW62tdPsD6m#K0iM?V&GbYaL+Tv1R7X)gj~#SmUb78qLnlqoP^ zSe`gkIP@zojM0&GO=h@|U1Brj_A5+?CK^Vl?qgjE)=Mo|Man|gckYv`pkbSNoKK!l zI{10#kbR9{p%uRJ4wx<2MtMI>or0N#cP<&(WR_(NRzrNObQ6E4VtUzc?fH?Q`SmTe ze9vOyJ~XZ1o3+9UPw0YlgJEIwL%gBxaQO=tjEqDxu@8q>P<_RrX#GyAh7*w=e!%zM zvmm+X4>-{%3kZ>L>`>A9e(Oe^W8*8imEKjvrX~B9Z?mF4pdgAW0GcqQ8K?PWbOtli z6v1wXRcjUM?UkNSiRv~-lG&n=6 z$-Xti>!AZ`H4B7vrP6?>0{7UrywB2v>KcE_pW4LIO&E1X8z-=JL#R3C|YNnMkc!*60bMHvnH<`ilEG%{J&Fe*%+ zjTZG$y6;1$L>`qR_sp}wV!83lNr^{s08V1fY$}RtDBk_ zY{PKqIRP(E+njlJ>;-Ne9DTE9Yc-7W#!7e7F3YVtOg2yK#&M<)w#4K*c(bn^FnHGi zOO53p1ce|18`isRiPy2)Cp&cXWCMewS7U(<3?fr$6<2fP(VAkoOk?Mn;n6cy6eoEN zcTNR*-IloNR3v5#qTkK~&Q92!hff@mt5?U>fQ)(sn9?kZ zoELH=@&o-m=!`QtVP*4!Zq3MI*C)c*169O@A6{Sw1BrU77bX<7)o+B=OKOT3M_qUu z)G%1v*Dw$3!{WTWe}2o~d*W7}{itvohqK!zI4HNk!NALAmrWckmSUmNsWC3}z589I z?(Ph?T0sx*T5P5eOv%MYbRzUJ)6Kn!@@StdaavA^up>Bu#v(VH%nlM5iNgY!YUrMi ze_F{-tA~K?Z+>D_Z`ea`+x(I5S4rc!$&2G#xZi5!P+od8TU36$-U+2lUz(G)^M=`)XHCub}p+?s<^N%UM4vVLX!W z3!0^;2XT5crok6h1={vUZ6hmQ4N20z`>5mfN}W4i2ah$KgcnPPpEs_(#;Q{)27f<( z*y2iflq`qB-OJXu(8w@R=)->-a6|4bNxNMnft?20HkuCy$6$L09kd)G)W4O=9BM|{ z0njynOnyNaTVrFARb&?Wz)KO0c=aeIrmJGdj2T21U*d{=r&%WGB_fB}!Crdq%$!h6 zTYHZU91PZ_u6~E*gTy3XA#JV7W1QF6sjN;@hLE{nCX07QHTpvH15PaG$-!bfNO#d# zLz-yQ&tSY!D@K{1sPCqy(XopWKKD^Su(X0yAdtrAPbwvb;0KzwfBiTWK|Q z=@~d0^<3M_hSR&Ce?AW}16N8iRRYrnJD8B8G!k~7@GQoI<#32mT-zRtY2CpF2f(XA zMU6CkH@0EN1UN@jBxhBao0Y7;t{jc1e4a+0fB6N7b2yPo(8A@@2haBnasAf%nJCjH zql`!qJ9zbokA$A+Li$D^=r%*k928%W0a#oK{oyi-%i#({q!i0)WJ1(aFJgY*$gn{8I=(Ww04qI1{H zye0i*Mr`~uq|h*1yj(Kb6ltw^K@0am&(EmI`#hR*0ct8#{B~3BSz88+3Bzg4k81*^8%KE#*02QR*UK z2M-^JFu#z+ux)Gj9-Ypn7I{$oQ)oL1`l&|nToNk4Tamb^hRS)nuoZIEjHOtFqfhay zZUTan1jXVWhNrTYA$UlLl2*5w4DdkB`Zffs@;~cY=26uyjz?2T9bVi&2sRpcJQEc} zswq*+P- zDN^CmeDw%s_1+%}Im49+!#OjZ;j(Q*hfk#Bm}vcixtLUk-l>q@`BV7ppOrG2W#Z%& zW()~2c*wbgWlG&}uVkUND;LEy@?#C{}77N~WYzz)?Az@B@SyxF&QfwgRVOOn%0aye75&&}>S zzXc$D2{D5sKzp?kZ^aDn`*nF+3|f|e(o$M#yR)s_4THwu&3vi*JPwOBR)%9|cQ^)g z4XHCFEsKY{w1K@z=AIAvPKl3~tb_^UIhBwmBDl`00~fq=Sz&xh<>PA2hJCH!hGwUW zSgtprf2*L$jmE;I<{4F(Ggnc%YAXfr=SqhudnSKgbgU~un2Z{YIR{ZU&6?3OUcSLAaY@eW`eEgpt7 zlUlHem*R=;T?P@87+ei=K*i)c(`M7rgYp~;1v3UAroT0zo2b1J>$(E72e7wJRJ^j+ zfwa{lP}teWV2Cat(t`GRp|FvPh+q_fqDrDbm_Mgv ze11tcDh~Zxw+#nx2(x{He?+>B8}7!V`sarmVDe6{$$s5`AD)NF!*)Lkxhe86X@8YJ zUKj5XynC5Tkh`933miE2XeIrq#2DMX^k7QLZ zL|1DDSCs` zP~b8wgEc_AKuOkS68=kJJcC!LEhv(jc*PJc+JDJEZntc9XnDeon^R1KS8VypEKVS=!F?4_G(KTNE3yww1& z<<4Fsm#(W&-EE|$ep#8R2{KX@^9n+)nbR_CuKu2`y-?j&_Et#qL+_J4;tN=2WAJ?_ z>GAwa1Ld2`rz_J{-N+hUE`7D?$vACB{U+#Df4rK7HY2#|H7ad3`gquCdhAM5`64&^ zml&N+{;t8*A@sURFNd(28=x_y`ZPiZmZ*JTwE@14fXfD|h6GL5)jmGBn&D0L=Vf@m zCfsvhVa?!2*QXbkyXRHMlvIPVI=myUYfFf`Kvx;HNNg+~nfLnniq{U32A~2`%1Vz|wmTEs2e$)WSRz z)ul1TY;;WAQl)z-Kdg2cN`8In{^lIY0O)kQ^I2SoQWf~F>*MJp!pVm!TB9y-tC8z^ zo;bCQ?{j%6p6`I;Hk8t!SYr(BA&>}DrGxg2UYggV|Zk#`Og7%@FQAPviijGoxn3uBn010T08 zQ!nFZtP~|hjSMd!(1+p*Ez!^!t-}`5!O{-R&*GB$6p41JkhO#U#f{uNj#66xGL$#dz~=tSkpT%4i1 zgjkQKiEant8(H)O7-+8ZSoA)7^JvjbKP-NF5#si838FETR9 z{>F}aEty|AxCF?_9K2a!PCD&{mLIaLn~rY9PkVlT{$&jW-^9L(DZPjb!3!(?6gP

      !oRptb@n+ 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 literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.svg b/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000000..e3e2dc739dd --- /dev/null +++ b/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.ttf b/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..67fa00bf83801d2fa568546b982c80d27f6ef74e GIT binary patch literal 41280 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

      PBK;&Wcg|NX{>QR@W3{K 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 literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.woff b/web/orchestrator/public/bootstrap/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..8c54182aa5d4d1ab3c9171976b615c1dcb1dc187 GIT binary patch literal 23320 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 mX4Rtsthis.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('

      '}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery); \ No newline at end of file diff --git a/web/orchestrator/public/css/custom.css b/web/orchestrator/public/css/custom.css new file mode 100644 index 00000000000..e69de29bb2d diff --git a/web/orchestrator/public/css/orchestrator.css b/web/orchestrator/public/css/orchestrator.css new file mode 100644 index 00000000000..15d7c1e387d --- /dev/null +++ b/web/orchestrator/public/css/orchestrator.css @@ -0,0 +1,1012 @@ +.hiddenMessage { + display: none; +} + +.hiddenMessage p { + font-size: inherit; +} + +body { + background-color: #f7f7f7; + background-repeat: repeat; + padding-top: 50px; +} + +.orchestrator-brand { + height: 32px; + margin-top: 9px; + padding: 0px 15px; +} + +.orchestrator-brand img { + padding: 0px; + padding-right: 8px; +} + +.table { + font-size: 13px; +} + +#dropdown-clusters.dropdown-menu { + height: auto; + max-height: 600px; + overflow-x: hidden; + overflow-y: auto; +} + +.navbar { + margin-bottom: 0px; +} + +.navbar-nav > li > .dropdown { + padding-bottom: 15px; + padding-top: 15px; +} + +.navbar-nav #searchInput { + height: 30px; +} + +.navbar-nav > li > a { + padding-left: 10px; + padding-right: 10px; +} + +#dashboard-sort, #move-instance-method { + padding-bottom: 0px; +} + +#move-instance-method button { + text-transform: capitalize; +} + +#alerts_container .alert { + margin-bottom: 4px; + padding: 8px; + padding-right: 30px; + border-radius: 0px; +} + +.node circle { + fill: #fff; + stroke: steelblue; + stroke-width: 1.5px; + cursor: pointer; +} + +.link { + fill: none; + stroke: #ccc; + stroke-width: 1.5px; +} + +.node .svgInstanceWrapper { + font: 10px sans-serif; + width: 276px; +} + +/*.instance { + transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; +}*/ + +.instance.selected { + border-width: 3px; + border-color: #808080; +} + +.instance h3 .small { + font-size: 80%; + font-weight: inherit; + line-height: inherit; + color: inherit; +} + +.instance h3 { + overflow: auto; + margin: 0; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; + padding: 2px 8px; + font-size: inherit; + line-height: 18px; +} + +.instance h3 .pull-left { + max-width: 190px; + width: auto; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.instance h3 .pull-right { + width: auto; +} + +.instance h3 .pull-right > .glyphicon { + color: #606060; +} + +.instance h3 .pull-right > .glyphicon.text-muted { + color: #999999; +} + +.instance h3 .pull-right > .glyphicon.text-danger { + color: #a94442; +} + + +.instance h3 .glyphicon { + position: inherit; + cursor: default; +} + +.instance h3 .instance-glyphs { + cursor: pointer; +} + +.instance h3 .glyphicon { + cursor: pointer; +} + +.instance h3.label-info { + background-color: #5bc0de; + color: #ffffff; +} + +.instance h3.label-info .glyphicon { + color: #ffffff; +} + +.instance h3.label-warning { + background-color: #f0ad4e; + color: #ffffff; +} + +.instance h3.label-warning .glyphicon { + color: #ffffff; +} + +.glyphicon.text-warning { + color: #f0ad4e; +} + +.instance h3.label-danger { + background-color: #d9534f; + color: #ffffff; +} + +.instance h3.label-danger .glyphicon { + color: #ffffff; +} + +.instance h3.label-stale { + background-color: #808080; + color: #ffffff; +} + +.instance h3.label-stale .glyphicon { + color: #ffffff; +} + +.instance h3.label-errant { + background-color: #b0b0b0; + color: #ffffff; +} + +.instance h3.label-errant .glyphicon { + color: #ffffff; +} + +.instance h3.label-fatal { + background-color: #000000; + color: #ffffff; +} + +.instance h3.label-fatal .glyphicon { + color: #ffffff; +} + +.instance h3.label-primary { + background-color: #428BCA; + color: #ffffff; +} + +.instance h3.label-primary .glyphicon { + color: #ffffff; +} + +.instance .badge { + color: #ffffff; + font-size: 10px; +} + +.instance .badge.label-info { + background-color: #5bc0de; +} + +.instance .badge.label-warning { + background-color: #f0ad4e; +} + +.instance .badge.label-danger { + background-color: #d9534f; +} + +.instance .badge.label-stale { + background-color: #808080; +} + +.instance .badge.label-fatal { + background-color: #000000; +} + +.instance .badge.label-errant { + background-color: #b0b0b0; +} + +.instance .badge.label-primary { + background-color: #428BCA; +} + +.instance.dc-color { + border-width: 2px; +} + +.instance.draggable-hovers { + background-color: #f7f7f7; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.66); +} + +.instance.draggable-hovers h3 { + background-color: #e0e0e0; + color: inherit; +} + +.cluster-graph .instance.original-dragged { + background-color: #808080; +} + +.cluster-graph .instance-trailer.original-dragged { + background-color: #808080; +} + +.cluster-graph > .instance.original-dragged h3 { + background-color: #808080; +} + +.cluster-graph > * { + position: absolute; +} +.cluster-graph > svg{ + position:relative; +} + +.cluster-graph > .instance.draggable-msg { +} + +#clusters .instance h3, +#clusters_analysis .instance h3, +.instance.instance-search h3 { + padding: 8px 14px; +} + + +#clusters .instance h3 .pull-right > .glyphicon { + margin-right: 2px; + font-size: 12px; + color: #31708f; +} + +#clusters .instance h3 .pull-left > .glyphicon { + margin-right: 2px; +} + +#instance_problems { + z-index: 10; + position: fixed; + right: 0px; + padding-right: 15px; +} + +#instance_problems button.btn-stale { + background-color: #808080; + color: #ffffff; +} + +#instance_problems button.btn-fatal { + background-color: #000000; + color: #ffffff; +} + +#instance_problems ul.dropdown-menu { + height: auto; + max-height: 600px; + overflow: auto; +} + +.instance.instance-problem { + font: 10px sans-serif; + display: block; + position: inherit; + width: 276px; + min-height: 50px; + margin: 10px; + cursor: pointer; +} + +.instance.instance-problem h3 { + font-size: 10px; + padding: 2px 8px; +} + +.instance.instance-problem .instance-content p, +.instance.instance-search .instance-content p { + margin: 4px 0px; +} + +.instance.instance-problem .instance-content { + padding: 4px 8px; +} +.instance.instance-search .instance-content { + padding: 4px 14px; +} + +.instance-content .tooltip-inner { + text-align: left; + min-width: 420px; + white-space: nowrap; +} + +#pools .popover { + vertical-align: top; +} + +#pools .popover div.pool-instances-listing { + font: 12px sans-serif; +} + +#pools .popover div.pool-instances-listing div { + margin-top: 8px; +} + +#node_modal .modal-dialog { + width: 800px; +} + +#node_modal .modal-body { + padding-bottom: 0px; +} + +#node_modal .modal-title code { + background-color: inherit; + font-weight: bold; +} + +#node_modal .modal-title .downtime-message { + padding-top: 8px; + font-weight: bold; +} + +#node_modal .modal-content { + font-size: 12px; +} + +#node_modal .hidden-zone { + display: none; +} + +.modal-content .btn { + font-size: 11px; + line-height: 16px; + padding: 5px 9px; +} + +#node_modal .begin-downtime .panel-body { + background-color: #d9edf7; +} + +#modalDataAttributesTable tbody tr td:first-child { + white-space: nowrap; + background-color: #f7f7f7; +} + +#modalDataAttributesTable tbody tr td { + padding: 3px; +} + +#modalDataAttributesTable td code { + white-space: normal; + background-color: inherit; + padding: 0px; +} + +#modalDataAttributesTable div.attributes-buttons > button { + margin-left: 4px; +} +#modalDataAttributesTable div.attributes-buttons > .btn-group { + margin-left: 4px; +} + +.popover-footer div.dropdown code { + color: inherit; + background-color: inherit; +} + + +.bootbox .modal-body { + padding: 12px; +} + +.bootbox .modal-footer { + padding: 12px; +} + +#audit table tr td:first-child { + white-space: nowrap; +} + +#audit table .more-recovery-info { + cursor: pointer; +} + +#audit table .more-detection-info { + cursor: pointer; +} + +#audit table .more-info ul { + list-style: none; +} + +#audit table .more-info code { + padding-left: 0; + font-weight: bold; + white-space: normal; + color: inherit; + background-color: inherit; +} + +#audit span.acknowledge-indicator { + padding-right: 8px; +} + +#audit span.acknowledge-indicator.unacknowledged { + cursor: pointer; +} + +#audit_recovery_steps thead tr th { + border-bottom: 0px; +} + +#audit_recovery_steps tbody tr td:first-child { + background-color: #f7f7f7; +} + +#audit_recovery_details thead tr th { + border-bottom: 0px; +} + +#audit_recovery_details tbody tr td:first-child { + background-color: #f7f7f7; +} +#audit_recovery_details tbody tr td:nth-child(2) { + white-space: nowrap; +} +#audit_recovery_details tbody tr td:nth-child(3) { + width: 100%; + border: 1px dotted #cccccc; +} +#audit_recovery_details tbody tr ul { + padding-left: 16px; +} +#audit_recovery_details tbody tr code { + background-color: inherit; +} +#audit_recovery_details tbody tr:first-child td:nth-child(3) { + background-color: #f7f7f7; +} + +.table-unbordered > tbody > tr > td { + border: 0px; +} + +#long_queries tbody td div { + overflow: auto; +} + +#long_queries tbody td div.query { + max-width: 1080px; + max-height: 240px; +} + +#long_queries div.process-query { + overflow: auto; + max-height: 240px; +} + +#long_queries div.row > div { + overflow: auto; +} + +#long_queries table tbody tr td:first-child { + width: 200px; +} + +#long_queries table { + margin-bottom: 0px; +} + +#long_queries pre { + border-top: 0px; + border-radius: 0px; + border-color: #dddddd; +} + +.popover-footer { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 0 0 5px 5px; +} + +#cluster_sidebar { + float: left; + position: fixed; + left: 0px; + padding: 8px 15px 8px 15px; + z-index:100; + border-right: dotted 1px #bbbbbb; + background-color: #f7f7f7; + height: 100%; +} + +#cluster_sidebar li { + font-size: 1.2em; +} + +#cluster_sidebar li > div > span { + cursor: pointer; +} + +#cluster_sidebar li[data-bullet] span.glyphicon { + font-size: 20px; + margin-bottom: 15px; +} + +#cluster_sidebar li a .glyphicon { + cursor: pointer; +} + +#cluster_sidebar .nav li > a { + padding: 0; +} + +#cluster_sidebar .nav li a:hover { + background-color: inherit; +} + +#cluster_sidebar li .popover { + max-width: 640px; + width: 640px; + font: 12px sans-serif; +} + +#cluster_sidebar li .popover hr { + margin-top: 8px; + margin-bottom: 8px; +} + +#cluster_sidebar li div.glyphicon { + font-size: 24px; + padding-right: 8px; +} + +#cluster_sidebar li .popover pre { + margin-top: 8px; + margin-bottom: 8px; +} + +#cluster_sidebar .text-indicate { + color: #e68545; +} + +#cluster_info { + position: fixed; + height: 100%; + overflow: auto; + z-index: 50; + + padding-left: 64px; + margin-left: -64px; + padding-right: 24px; + + border-right: dotted 1px #bbbbbb; + background-color: #f7f7f7; + font: 12px sans-serif; + + display: none; +} + +#cluster_info > div { + margin-top: 8px; + margin-bottom: 8px; +} + +#cluster_info [data-tag=glyphs] span.glyphicon { + font-size: 20px; +} + +#cluster_info hr { + margin-top: 8px; + margin-bottom: 8px; +} + + +#cluster_info div[data-tag=analysis] { + background-color: white; + border: 1px dotted #bbbbbb; + padding: 8px; +} + +#cluster_info div[data-tag=analysis] div { + padding: 4px; +} + +#cluster_info div[data-tag=analysis] div .pull-left.glyphicon { + font-size: 32px; +} + +#cluster_name_info { + position: fixed; + z-index: 50; + padding-left: 64px; + background-color: #f7f7f7; +} + +#cluster_wrapper { + padding-left: 64px; + padding-top: 36px; +} + +#cluster_name { + font-size: 24px; +} + +#cluster_subtitle { + font-size: 12px; +} + +.arrow_box { + position: relative; + background: #ffffff; + border: 1px solid #9c9c9c; +} + +.arrow_box:after, .arrow_box:before { + right: 100%; + top: 50%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; +} + +.arrow_box:after { + border-color: rgba(255, 255, 255, 0); + border-right-color: #ffffff; + border-width: 10px; + margin-top: -10px; +} + +.arrow_box:before { + border-color: rgba(156, 156, 156, 0); + border-right-color: #9c9c9c; + border-width: 11px; + margin-top: -11px; +} + + +/* Cluster - container, instance, instance trailer */ + +.cluster-graph { + overflow-x: visible; + overflow-y: visible; + position: relative; + /*height: 600px;*/ +} + +.instance { + display: block; + cursor: move; + padding: 1px; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,.2); + border-radius: 6px; +} + + +.instance.instance-diagram, +.instance.instance-problem, +.instance.instance-search { + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); + box-shadow: 0 5px 10px rgba(0,0,0,.2); +} + +.instance.instance-diagram:hover { + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.6); + box-shadow: 0 5px 10px rgba(0,0,0,.6); +} + +.instance.instance-diagram, +.instance.instance-problem { + font: 10px sans-serif; + width: 276px; + min-height: 50px; +} + +.instance.instance-diagram { + position: absolute; +} + +.instance.instance-search { + margin: 10px 0; +} + + +.instance.instance-search p { + line-height: 26px; +} + + +.instance h4 { + font-size: 10px; + padding: 2px 8px; +} + + +.instance .instance-content { + padding: 4px 8px; +} + +.instance .instance-content p { + margin-bottom: 0px; +} + +.instance .instance-content p.high { + margin-top: 4px; + margin-bottom: 8px; +} + +.instance .instance-master-section { + position: absolute; + bottom: 0px; + left: 0px; + z-index: 20; + height: 0%; + width: 48%; +} + +.instance.accept_drop_check .instance-master-section { + height: 100%; +} + +.instance .instance-normal-section { + position: absolute; + bottom: 0px; + right: 0px; + z-index: 20; + height: 0%; + width: 51%; +} + +.instance.accept_drop_check .instance-normal-section { + height: 100%; +} + +.instance h4.popover-footer { + z-index: 25; +} + +/*.cluster-graph > .instance[data-duplicate-node] { + position: absolute; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.66); +}*/ + +.instance.accept_drop h3 { + background-color: #5CB85C; + color: #ffffff; +} + +.instance.accept_drop h3 .glyphicon { + color: #ffffff; +} + +.instance.accept_drop_warning h3 { + background-color: #ff6600; + color: #ffffff; +} + +.instance.accept_drop_warning h3 .glyphicon { + color: #ffffff; +} + +.instance > .instance-trailer { + font: 10px sans-serif; + position: absolute; + display: block; + width: 13px; + cursor: move; + left: 100%; + height: 100%; + top: -1px; + text-align: left; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0,0,0,.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); + box-shadow: 0 5px 10px rgba(0,0,0,.2); + overflow: hidden; + box-sizing: content-box; + padding: 0; +} + +.instance > .instance-trailer.colorized { + top: -2px; +} + +.instance > .instance-trailer > div:first-child { + float: left; + padding-left: 1px; + position: relative; + top: 50%; + transform: translateY(-50%); + margin-left: -1px; +} + + +.instance > .instance-trailer .instance-trailer-title { + padding-top: 3px; + line-height: 18px; +} + +.instance > .instance-trailer .instance-trailer-title, +.instance > .instance-trailer .instance-trailer-content { + display: none; + padding-left: 16px; +} + +.instance > .instance-trailer:hover, +.instance > .instance-trailer.ui-draggable-dragging { + width: 200px; +} + +.instance > .instance-trailer:hover .instance-trailer-title, +.instance > .instance-trailer.ui-draggable-dragging .instance-trailer-title, +.instance > .instance-trailer:hover .instance-trailer-content, +.instance > .instance-trailer.ui-draggable-dragging .instance-trailer-content { + display: block; +} + +.instance > .instance-trailer:hover { + z-index: 50; +} + +.instance:hover { + z-index: 50; +} + +#cluster_legend { + margin-top: 20px; +} + +#cluster_legend span { + padding: 3px 5px; + white-space: nowrap; + font-size: 12px; +} + +#cluster_legend span.dc { + margin-right: 10px; + border: 2px solid; + border-radius: 5px; +} + +#clusters_analysis .popover { + width: 430px; + max-width: 430px; + vertical-align: top; +} + +#clusters_analysis .popover-content span.glyphicon { + font-family: "Glyphicons Halflings"; +} + +#main_container { + margin-top: 15px; +} + +#main_container.container, #main_container .container { + width: inherit; +} + +.container.clusters .popover.instance { + display: inline-block; + position: inherit; + width: 276px; +} + +.container.clusters .popover.instance { + margin: 8px; +} + +.container.clusters .popover.instance p { + margin: 8px 0px; +} + + +.container.clusters .popover.instance code { + white-space: normal; + color: inherit; + background-color: inherit; +} + + +.container.clusters .popover.instance .popover-content span { + font: 12px sans-serif; +} + +.container.clusters .popover.instance .popover-content div.downtimed { + background-color: #e7e7e7; +} + +.container.clusters .popover.instance .popover-content div.blocked { + background-color: #ebccd1; +} + +.container.clusters .popover.instance .popover-content span.badge { + color: #ffffff; + font-size: 10px; + font-weight: bold; +} + + +.status-table { + font: 12px sans-serif; +} + +.status-table code { + font-size: 100%; + background-color: inherit; +} +.status-table .long-text { + overflow: auto; +} + +.instance.instance-search { + display: block; + position: inherit; + max-width: inherit; +} + +.instance.instance-search h3 { + cursor: pointer; +} + +.instance.instance-search { + margin: 8px; +} + +.instance.instance-search p { + margin: 8px 0px; +} diff --git a/web/orchestrator/public/images/ajax-loader.gif b/web/orchestrator/public/images/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..c528e381382f466c0bb095a45f2864fd00eb529e GIT binary patch literal 1849 zcma*oeNfY7902h7`#rz?e*3*_4-;uj;>H-djm?d>F~#h+0fImTs8GDb296v-4g#S< zWG@IqUX?IRQ;P^i4e;gc1;ojnRAW!wJfuXWe=kLQo)p6@-M z`+lGAJ!zXZ>eref2XcPn_~PNihkQQ2uC6XTJp96i3oe(-yE8mIeB;KAyu3V?Wfv9} z%F4>4e)%$pbSw>Y`hVy?4nlQdZCwoA;F z=EkZW=51@N&sXf=MBE2F(tAqfyTOO#U=0!pg76}~8$nWx#1%vDXnL6Y=B($W@XRIi z7&@Hd@WAg`$usAJ4R@Zp*PAoME?tmrbvn-EM)E$nWwaM39l1(fjyWNuMc9r{*Tu@j zJ5d&pvL;m=5Ktro9Ho&6!R0X9KuZGP#vPDSFCQ$bO(Vfq*RJxq>YR-It%Oo0;;{FDT~V#>-N3e^wL57;l!fEfRsibOC^ z8w*4~&99xz${9+Hi$+K&cOXV7!=);^UT#+!3raQa-3Y^$%G{3T%vyV*p*AqaUzacA zy%<*nk-jATSSjpTNnOkB(Xh_(b~PUg?eQ%TV3&{EU_8GwFZz!U)I$8o?Q^zM#O&Lq zxg7a`j&R;OdRV-;Rr9BWM^H)?a47&PkJgk(tDbDt>`@w?>)XA*gUamh>?kob>vTtT z0qaubZ;{AX7b$UNDcnnGTS?KAQyf(Nxn7$NgpTo+$Fh@-(bql-+Tu#Rdks#8oL=!$ z%?c>KJ@n(a<#l>t>yFIW(t^TYzUj<&pN*+}wg6bzy83jDror@htGl8(a-VxZ*S|k9 zAfVX?cvs~GIHZJgNj#$@_axD_yfaaVYb;XB9Xe<_CYctmzFa;i9|}SHGgvk({Nf{* z&IyCXnwU#gG#<8lOq2Pi#BP8Zzn#hl0;YbKOInWOm^s_3q45%&Rw%mEIKj!XRPE;B zRJC;%2jEP#r6@We=|vxD6ZDciQsRkUbu&uOh%_VV76rpe`5tFGH>D%rx;x83*O z3zE>TpQG4Q0AdX%3l$RRvQ?pSvZu{{{ZuzW)cjtrTpohsd8^8~kcXRafkGjtaTI@H zcWFj1Xx~s;%*R*r)2b7RPFY}$f1v#uM5)>WZoXZ zO*?SH(kOaq;%m{FPB0njd+6wc$|a@qO>yywRn4-CJ0m9GodZo+u>*89Ojc+wQ%o>-gD|O{@kO-rbYdr`?AxP9v=*` zd>)KqtSF8O1f;DfPuj#oIuU~37fB8xJb@0g7B-YODF3@pevK-#UwQxh46=7bdxSC{ zO!{K)wXtPS>+NNx_&d)Jg;SmpV;RR$_I_j76s8)#bUi3^s_*Fd$01W!m(S11c|v@4 za_mtFpa^ahxdFu)0;6a$Rtazc(t&UVRwc#LVAwi17%fB5oq;v=zE|VdR27|&-6AJ4 zU`^4Ro*FuC(3D$rkDsvIes5hUzvGofu<5A??R2dnMK7Y0caHXc7>s?Lo>O5BnwqzA za{ED#(~!g3R>EX16P3bYa<~u(a^rP0=EX49aw`If>`H9|<5C13seik)hOU_!AysJz zbvgrbYUS^QW%TN4qAhuGUK!NUw#Rr@H7M?GU05YrPqx}S&wdpu+&)ehG^^nUeWp1T zk8T_IeMqFby8%TYH;H8QdD-h#6xs^c$7~V65-vi%S`PXStY&JSlaZ`XljQq|{P7RJ CTNO+I literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/images/booking-logo-32.png b/web/orchestrator/public/images/booking-logo-32.png new file mode 100644 index 0000000000000000000000000000000000000000..d1ce30a870351428f44286843d8b09e050549042 GIT binary patch literal 629 zcmV-*0*d{KP)WFU8GbZ8()Nlj2>E@cM*00G%aL_t(o!|j$oixW{4 z#eesW!QEt81#N6xu+YLr!9s+Qh<`wAtu6cj`UMpH4t@Y8oGw0rUu)qTUJ8ZuPe#x&zveRRmB%`0I^z&#GeV(Za$7+8~6Kpi?SS;;C z%U2S$04^r_w=x7=PqO8r`9zXSk^Kzx%%K>wCT3cSsrqoC1hr)C25~h#pBq1pjH0G#i)=tdEFChv1nAdxag?UFRQWWGVt&vcBgEC#D-PRhVTEoYJXwiOR3sUoRyBp^v@D&v*3-0Sa=)KaD_Nn<2kCh5Jy?Dcv{&BN?JPEyNA z4XL2Grcx!3RN=>uH<#{_jHim)9TA5t>=xjo9&Z4M2qcXMt^>{nnk01qn}C}l;&760 z8YEo~d-_gk=fE3*3DmQFz!kvrzzx88K!tktE8wb-)CG(NHUL|I*8*P# zCIcC8YD9EOngRS27+-?@E?`zf9I!S11SqrWPT+G9u};!*U7f=mjo}h&+zh6EN1(+L=V zbAP@2CjqM^RgpNxIaYj-4L{UuV_p}TeP7cNZeLtxR-<){!e&FZDN)h-rwQ6?~>Hw4ivM))n z+knU1onAP|_(GNPhQz~OP6T;fq1c_9oxGW-!qYT~YNGs;a&r_&O7y(rV`Mk}Cj}!kr{93C~Rq(*^t{;aenW zlq;EWz!yCJ54+(XaxaiHH6rrL>uP&ZKd>_a=b4C@mBith1&=JFz9CB2uovbAbgiVb ze8FAi{pr)7A}^z!t)ZT^TJ|HB>w0?!gB4RfTko9MIcTW$Y{DQP%+1#~UvpxpWiJd_ zLGI(q-m4{DVPGbut`!lxBy9yQ1ZDt_NO}S|CkYYjBcfN*DksE~fE|*4;ruhhe2)Q7 z02k#l`1xj$tFtC2x-(7`vr5Y6N<_TiJukLWwkL`ns0{km$Cj)u2~8(ctInsM?evBC zJnGqA;C`32=hz6o3VaP%?#uH|>e-K+H!e*g&7;n{!-`+lt|Xo@7I=FBjAaqA(d{dN zN8FwQ)RJ&@b3`n4d#eS;W$DEU7<++>BBCe1-+2E9;Fn3&Hbc@<=L8C2hmz0}1p}Mw zYBBxpKpsvT27pYTYjRmGNRsX(;BteJ7aJL{I>`yA+4C<=s;+s|svU_em4foiqEqg( zqZ)npXf90d12#v*L-}PdBKAuXU+4V&v(dWJ(hco3z_E< z`ERs*qeuLV`>(wE4#%6v{o?$I)-TTI{j%?TIsLUm;~!lHe;laVh^9rvQ>D)xxzY#v zO~6rVRSm(@U~lcCR_!U}DZT^@x96+)1$%{trkh@=7wrGj(11*rbi1S%{dn3V=>bU> f4EHGd-$4Ha7R`DIZTO0O00000NkvXXu0mjf8g7cg literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/images/keep-calm-and-let-orchestrator-handle-it-transp-m.png b/web/orchestrator/public/images/keep-calm-and-let-orchestrator-handle-it-transp-m.png new file mode 100644 index 0000000000000000000000000000000000000000..b0895207e8b318051cba11d2e5f6dd7bcbee7de7 GIT binary patch literal 26849 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 literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/images/octocat-logo-32.png b/web/orchestrator/public/images/octocat-logo-32.png new file mode 100644 index 0000000000000000000000000000000000000000..628da97c70890c73e59204f5b140c4e67671e92d GIT binary patch literal 1571 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 literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/images/outbrain-logo-s.png b/web/orchestrator/public/images/outbrain-logo-s.png new file mode 100644 index 0000000000000000000000000000000000000000..aee1e71e6b3c3f368d677c2cd9a258c7940712c7 GIT binary patch literal 2727 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 literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/images/tile.png b/web/orchestrator/public/images/tile.png new file mode 100644 index 0000000000000000000000000000000000000000..faf8c2f911f7a367800e2ec42a9facc677ddf691 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_|R1SIp{XE)7O>#9xJzyh~&Do>#RT_IZqeI5RU7~fByfsXVywcOi1|g@iF@* g0byn~g=h|j2rJglDTfN0fGQb0UHx3vIVCg!0LyM7I{*Lx literal 0 HcmV?d00001 diff --git a/web/orchestrator/public/js/agent.js b/web/orchestrator/public/js/agent.js new file mode 100644 index 00000000000..c30a1940920 --- /dev/null +++ b/web/orchestrator/public/js/agent.js @@ -0,0 +1,297 @@ +$(document).ready(function() { + showLoader(); + + var hasActiveSeeds = false; + + $.get(appUrl("/api/agent/" + currentAgentHost()), function(agent) { + showLoader(); + agent.AvailableLocalSnapshots || (agent.AvailableLocalSnapshots = []) + agent.AvailableSnapshots || (agent.AvailableSnapshots = []) + displayAgent(agent); + }, "json"); + + $.get(appUrl("/api/agent-active-seeds/" + currentAgentHost()), function(activeSeeds) { + showLoader(); + activeSeeds.forEach(function(activeSeed) { + appendSeedDetails(activeSeed, "[data-agent=active_seeds]"); + }); + if (activeSeeds.length == 0) { + $("div.active_seeds").parent().hide(); + $("div.seed_states").parent().hide(); + } + if (activeSeeds.length > 0) { + hasActiveSeeds = true; + activateRefreshTimer(); + + $.get(appUrl("/api/agent-seed-states/" + activeSeeds[0].SeedId), function(seedStates) { + showLoader(); + seedStates.forEach(function(seedState) { + appendSeedState(seedState); + }); + }, "json"); + } + }, "json"); + $.get(appUrl("/api/agent-recent-seeds/" + currentAgentHost()), function(recentSeeds) { + showLoader(); + recentSeeds.forEach(function(recentSeed) { + appendSeedDetails(recentSeed, "[data-agent=recent_seeds]"); + }); + if (recentSeeds.length == 0) { + $("div.recent_seeds").parent().hide(); + } + }, "json"); + + function displayAgent(agent) { + if (!agent.Hostname) { + $("[data-agent=hostname]").html('Not found'); + return; + } + $("[data-agent=hostname]").html(agent.Hostname) + $("[data-agent=hostname_search]").html( + '' + agent.Hostname + '' + '
      ' + ); + $("[data-agent=port]").html(agent.Port) + $("[data-agent=last_submitted]").html(agent.LastSubmitted) + + var mySQLStatus = "" + agent.MySQLRunning + '
      ' + + (agent.MySQLRunning ? '' : + '') + + '
      '; + $("[data-agent=mysql_running]").html(mySQLStatus) + $("[data-agent=mysql_port]").html(agent.MySQLPort) + $("[data-agent=mysql_disk_usage]").html(toHumanFormat(agent.MySQLDiskUsage)) + + if (agent.MySQLErrorLogTail != null && agent.MySQLErrorLogTail.length > 0) { + rows = agent.MySQLErrorLogTail; + rows = rows.map(function(row) { + if (row.trim() == "") { + row = "[empty line]" + } + return row; + }); + $("[data-agent=mysql_error_log_tail]").html(rows[rows.length - 1]) + $("body").on("click", "a[data-agent=mysql_error_log_tail]", function(event) { + rows = rows.map(function(row) { + return '' + row + ''; + }); + rows = rows.map(function(row) { + if (row.indexOf("[ERROR]") >= 0) { + return '' + row + ''; + } else if (row.indexOf("[Warning]") >= 0) { + return '' + row + ''; + } else if (row.indexOf("[Note]") >= 0) { + return '' + row + ''; + } else { + return '' + row + ''; + } + }); + bootbox.alert('
      ' + rows.join("
      ") + '
      '); + return false; + }); + } + + function beautifyAvailableSnapshots(hostnames) { + var result = hostnames.filter(function(hostname) { + return hostname.trim() != ""; + }); + result = result.map(function(hostname) { + if (hostname == agent.Hostname) { + return '' + hostname + ''; + } + var isLocal = $.inArray(hostname, agent.AvailableLocalSnapshots) >= 0; + var btnType = (isLocal ? "btn-success" : "btn-warning"); + return '' + hostname + '
      '; + }); + result = result.map(function(entry) { + return '' + entry + ''; + }); + return result; + } + beautifyAvailableSnapshots(agent.AvailableLocalSnapshots).forEach(function(entry) { + $("[data-agent=available_local_snapshots]").append(entry) + }); + availableRemoteSnapshots = agent.AvailableSnapshots.filter(function(snapshot) { + return agent.AvailableLocalSnapshots.indexOf(snapshot) < 0; + }); + beautifyAvailableSnapshots(availableRemoteSnapshots).forEach(function(entry) { + $("[data-agent=available_remote_snapshots]").append(entry) + }); + + var mountedVolume = "" + if (agent.MountPoint) { + if (agent.MountPoint.IsMounted) { + mountedVolume = agent.MountPoint.LVPath; + var mountMessage = ''; + mountMessage += '' + mountedVolume + ' mounted on ' + + '' + agent.MountPoint.Path + ', size ' + toHumanFormat(agent.MountPoint.DiskUsage); + mountMessage += '
      MySQL data path: ' + agent.MountPoint.MySQLDataPath + ''; + mountMessage += '
      '; + $("[data-agent=mount_point]").append(mountMessage); + } + } + + if (agent.LogicalVolumes) { + var lvSnapshots = agent.LogicalVolumes.filter(function(logicalVolume) { + return logicalVolume.IsSnapshot; + }).map(function(logicalVolume) { + return logicalVolume.Path; + }); + var result = lvSnapshots.map(function(volume) { + var volumeText = ''; + var volumeTextType = 'text-info'; + if (volume == mountedVolume) { + volumeText = ''; + volumeTextType = 'text-success'; + } else if (!(agent.MountPoint && agent.MountPoint.IsMounted)) { + volumeText += '' + volumeText += ' ' + } else { + // Do nothing + } + volumeText = '' + volume + '
      ' + volumeText + '
      '; + return volumeText; + }); + result = result.map(function(entry) { + return '' + entry + ''; + }); + + result.forEach(function(entry) { + $("[data-agent=lv_snapshots]").append(entry) + }); + } + + hideLoader(); + } + + + $("body").on("click", "button[data-command=unmount]", function(event) { + if (hasActiveSeeds) { + addAlert("This agent participates in an active seed; please await or abort active seed before unmounting"); + return; + } + showLoader(); + $.get(appUrl("/api/agent-umount/" + currentAgentHost()), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }, "json"); + }); + $("body").on("click", "button[data-command=mountlv]", function(event) { + var lv = $(event.target).attr("data-lv") + showLoader(); + $.get(appUrl("/api/agent-mount/" + currentAgentHost() + "?lv=" + encodeURIComponent(lv)), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }, "json"); + }); + $("body").on("click", "button[data-command=removelv]", function(event) { + var lv = $(event.target).attr("data-lv") + var message = "Are you sure you wish to remove logical volume " + lv + "?"; + bootbox.confirm(message, function(confirm) { + if (confirm) { + showLoader(); + $.get(appUrl("/api/agent-removelv/" + currentAgentHost() + "?lv=" + encodeURIComponent(lv)), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }, "json"); + } + }); + }); + $("body").on("click", "button[data-command=create-snapshot]", function(event) { + var message = "Are you sure you wish to create a new snapshot on " + + currentAgentHost() + "?"; + bootbox.confirm(message, function(confirm) { + if (confirm) { + showLoader(); + $.get(appUrl("/api/agent-create-snapshot/" + currentAgentHost()), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }, "json"); + } + }); + }); + $("body").on("click", "button[data-command=mysql-stop]", function(event) { + var message = "Are you sure you wish to shut down MySQL service on " + + currentAgentHost() + "?"; + bootbox.confirm(message, function(confirm) { + if (confirm) { + showLoader(); + $.get(appUrl("/api/agent-mysql-stop/" + currentAgentHost()), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }, "json"); + } + }); + }); + $("body").on("click", "button[data-command=mysql-start]", function(event) { + showLoader(); + $.get(appUrl("/api/agent-mysql-start/" + currentAgentHost()), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }, "json"); + }); + $("body").on("click", "button[data-command=seed]", function(event) { + if (hasActiveSeeds) { + addAlert("This agent already participates in an active seed; please await or abort active seed"); + return; + } + if ($(event.target).attr("data-mysql-running") == "true") { + addAlert("MySQL is running on this host. Please first stop the MySQL service"); + return; + } + var sourceHost = $(event.target).attr("data-seed-source-host"); + var isLocalSeed = ($(event.target).attr("data-seed-local") == "true"); + + var message = "Are you sure you wish to destroy data on " + + currentAgentHost() + " and seed from " + + sourceHost + "?"; + if (isLocalSeed) { + message += '

      This seed is dc-local'; + } else { + message += '

      This seed is non-local and will require cross-DC data transfer!'; + } + + bootbox.confirm(message, function(confirm) { + if (confirm) { + showLoader(); + $.get(appUrl("/api/agent-seed/" + currentAgentHost() + "/" + sourceHost), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }, "json"); + } + }); + }); + $("body").on("click", "button[data-command=discover]", function(event) { + var hostname = $(event.target).attr("data-hostname") + var mySQLPort = $(event.target).attr("data-mysql-port") + discover(hostname, mySQLPort) + }); + +}); diff --git a/web/orchestrator/public/js/agents.js b/web/orchestrator/public/js/agents.js new file mode 100644 index 00000000000..0ed433e3297 --- /dev/null +++ b/web/orchestrator/public/js/agents.js @@ -0,0 +1,32 @@ + +$(document).ready(function () { + showLoader(); + activateRefreshTimer(); + + $.get(appUrl("/api/agents"), function (agents) { + displayAgents(agents); + }, "json"); + function displayAgents(agents) { + hideLoader(); + + agents.forEach(function (agent) { + $("#agents").append('

      '); + var popoverElement = $("#agents [data-agent-name='" + agent.Hostname + "'].popover"); + //var title = agent.Hostname; + //popoverElement.find("h3 a").html(title); + var contentHtml = '' + + '' + + agent.Hostname + + '' + ; + popoverElement.find(".popover-content").html(contentHtml); + }); + + $("div.popover").popover(); + $("div.popover").show(); + + if (agents.length == 0) { + addAlert("No agents found"); + } + } +}); diff --git a/web/orchestrator/public/js/audit-failure-detection.js b/web/orchestrator/public/js/audit-failure-detection.js new file mode 100644 index 00000000000..f8533be392b --- /dev/null +++ b/web/orchestrator/public/js/audit-failure-detection.js @@ -0,0 +1,112 @@ +$(document).ready(function() { + showLoader(); + var apiUri = "/api/audit-failure-detection/" + currentPage(); + if (clusterAlias() != "") { + apiUri = "/api/audit-failure-detection/alias/" + clusterAlias() + "/" + currentPage(); + } else if (detectionId() > 0) { + apiUri = "/api/audit-failure-detection/id/" + detectionId(); + } + $.get(appUrl(apiUri), function(auditEntries) { + auditEntries = auditEntries || []; + $.get(appUrl("/api/replication-analysis-changelog"), function(analysisChangelog) { + analysisChangelog = analysisChangelog || []; + displayAudit(auditEntries, analysisChangelog); + }, "json"); + }, "json"); + + function displayAudit(auditEntries, analysisChangelog) { + var baseWebUri = appUrl("/web/audit-failure-detection/"); + if (clusterAlias()) { + baseWebUri += "alias/" + clusterAlias() + "/"; + } + var changelogMap = {} + analysisChangelog.forEach(function(changelogEntry) { + changelogMap[getInstanceId(changelogEntry.AnalyzedInstanceKey.Hostname, changelogEntry.AnalyzedInstanceKey.Port)] = changelogEntry.Changelog; + }); + + hideLoader(); + auditEntries.forEach(function(audit) { + var analyzedInstanceDisplay = audit.AnalysisEntry.AnalyzedInstanceKey.Hostname + ":" + audit.AnalysisEntry.AnalyzedInstanceKey.Port; + var row = $(''); + var analysisElement = $('').attr("data-detection-id", audit.Id).text(audit.AnalysisEntry.Analysis); + + $('').prepend(analysisElement).appendTo(row); + $('', { + text: analyzedInstanceDisplay, + href: appUrl("/web/search/" + analyzedInstanceDisplay) + }).wrap($("")).parent().appendTo(row); + $('', { + text: audit.AnalysisEntry.CountReplicas + }).appendTo(row); + $('', { + text: audit.AnalysisEntry.ClusterDetails.ClusterName, + href: appUrl("/web/cluster/" + audit.AnalysisEntry.ClusterDetails.ClusterName) + }).wrap($("")).parent().appendTo(row); + $('', { + text: audit.AnalysisEntry.ClusterDetails.ClusterAlias, + href: appUrl("/web/cluster/alias/" + audit.AnalysisEntry.ClusterDetails.ClusterAlias) + }).wrap($("")).parent().appendTo(row); + $('', { + text: audit.RecoveryStartTimestamp + }).appendTo(row); + + var moreInfo = ""; + moreInfo += '
      Detected: ' + audit.RecoveryStartTimestamp + '
      '; + if (audit.AnalysisEntry.Replicas.length > 0) { + moreInfo += '
      ' + audit.AnalysisEntry.CountReplicas + ' replicating hosts :
        '; + audit.AnalysisEntry.Replicas.forEach(function(instanceKey) { + moreInfo += "
      • " + getInstanceTitle(instanceKey.Hostname, instanceKey.Port) + "
      • "; + }); + moreInfo += "
      "; + } + var changelog = changelogMap[getInstanceId(audit.AnalysisEntry.AnalyzedInstanceKey.Hostname, audit.AnalysisEntry.AnalyzedInstanceKey.Port)]; + if (changelog) { + moreInfo += '
      Changelog :
        '; + changelog.reverse().forEach(function(changelogEntry) { + var changelogEntryTokens = changelogEntry.split(';'); + var changelogEntryTimestamp = changelogEntryTokens[0]; + var changelogEntryAnalysis = changelogEntryTokens[1]; + + if (changelogEntryTimestamp > audit.RecoveryStartTimestamp) { + // This entry is newer than the detection time; irrelevant + return; + } + moreInfo += "
      • " + changelogEntryTimestamp + " " + changelogEntryAnalysis + "
      • "; + }); + moreInfo += "
      "; + } + moreInfo += '
      '; + + moreInfo += "
      Processed by " + audit.ProcessingNodeHostname + "
      "; + row.appendTo('#audit tbody'); + + var row = $(''); + row.attr("data-detection-id-more-info", audit.Id); + row.addClass("more-info"); + $('').append(moreInfo).appendTo(row); + row.hide().appendTo('#audit tbody'); + }); + if (auditEntries.length == 1) { + $("[data-detection-id-more-info]").show(); + } + if (currentPage() <= 0) { + $("#audit .pager .previous").addClass("disabled"); + } + if (auditEntries.length == 0) { + $("#audit .pager .next").addClass("disabled"); + } + $("#audit .pager .previous").not(".disabled").find("a").click(function() { + window.location.href = appUrl(baseWebUri + (currentPage() - 1)); + }); + $("#audit .pager .next").not(".disabled").find("a").click(function() { + window.location.href = appUrl(baseWebUri + (currentPage() + 1)); + }); + $("#audit .pager .disabled a").click(function() { + return false; + }); + $("body").on("click", ".more-detection-info", function(event) { + var detectionId = $(event.target).attr("data-detection-id"); + $('[data-detection-id-more-info=' + detectionId + ']').slideToggle(); + }); + } +}); diff --git a/web/orchestrator/public/js/audit-recovery-shared.js b/web/orchestrator/public/js/audit-recovery-shared.js new file mode 100644 index 00000000000..3a7f59083db --- /dev/null +++ b/web/orchestrator/public/js/audit-recovery-shared.js @@ -0,0 +1,22 @@ +function auditRecoverySteps(uid, target) { + var uri = "/api/audit-recovery-steps/" + uid; + $.get(appUrl(uri), function(steps) { + steps = steps || []; + displayAuditSteps(steps, target); + }, "json"); + + function displayAuditSteps(steps, target) { + hideLoader(); + steps.forEach(function(step) { + var row = $(''); + $('', { + text: step.AuditAt + }).appendTo(row); + $('', { + text: step.Message + }).appendTo(row); + + row.appendTo(target); + }); + } +} diff --git a/web/orchestrator/public/js/audit-recovery.js b/web/orchestrator/public/js/audit-recovery.js new file mode 100644 index 00000000000..2461a350cd9 --- /dev/null +++ b/web/orchestrator/public/js/audit-recovery.js @@ -0,0 +1,226 @@ +$(document).ready(function() { + $("#audit_recovery_steps").hide(); + showLoader(); + var apiUri = "/api/audit-recovery/" + currentPage(); + if (clusterName()) { + apiUri = "/api/audit-recovery/cluster/" + clusterName() + "/" + currentPage(); + } else if (clusterAlias()) { + apiUri = "/api/audit-recovery/alias/" + clusterAlias() + "/" + currentPage();; + } else if (recoveryId() > 0) { + apiUri = "/api/audit-recovery/id/" + recoveryId(); + } else if (recoveryUid()) { + apiUri = "/api/audit-recovery/uid/" + recoveryUid(); + } + $.get(appUrl(apiUri), function(auditEntries) { + auditEntries = auditEntries || []; + displayAudit(auditEntries); + }, "json"); + + function ackInfo(audit) { + var info = ""; + if (audit.Acknowledged) { + info += '
      Acknowledged by ' + audit.AcknowledgedBy + ', ' + audit.AcknowledgedAt + '
        '; + info += "
      • " + audit.AcknowledgedComment + "
      • "; + info += '
      '; + } else { + info += '
      '; + info += ' This recovery is unacknowledged.'; + info += '
      '; + } + return info; + } + + function auditInfo(audit) { + var moreInfo = ""; + if (audit.LostReplicas.length > 0) { + moreInfo += "
      Lost replicas:
        "; + audit.LostReplicas.forEach(function(instanceKey) { + moreInfo += "
      • " + getInstanceTitle(instanceKey.Hostname, instanceKey.Port) + "
      • "; + }); + moreInfo += "
      "; + } + if (audit.ParticipatingInstanceKeys.length > 0) { + moreInfo += "
      Participating instances:
        "; + audit.ParticipatingInstanceKeys.forEach(function(instanceKey) { + moreInfo += "
      • " + getInstanceTitle(instanceKey.Hostname, instanceKey.Port) + "
      • "; + }); + moreInfo += "
      "; + } + if (audit.AnalysisEntry.Replicas.length > 0) { + moreInfo += '
      ' + audit.AnalysisEntry.CountReplicas + ' replicating hosts :
        '; + audit.AnalysisEntry.Replicas.forEach(function(instanceKey) { + moreInfo += "
      • " + getInstanceTitle(instanceKey.Hostname, instanceKey.Port) + "
      • "; + }); + moreInfo += "
      "; + } + if (audit.AllErrors.length > 0 && audit.AllErrors[0]) { + moreInfo += "All errors:
        "; + audit.AllErrors.forEach(function(err) { + moreInfo += "
      • " + err; + }); + moreInfo += "
      "; + } + moreInfo += ''; + moreInfo += '
      Processed by ' + audit.ProcessingNodeHostname + '
      '; + return moreInfo; + } + function displaySingleAudit(audit) { + $("#audit .pager").hide(); + $("#audit_recovery_table").hide(); + + var clusterAlias = audit.AnalysisEntry.ClusterDetails.ClusterAlias; + var clusterName = audit.AnalysisEntry.ClusterDetails.ClusterName; + var failedInstanceTitle = getInstanceTitle(audit.AnalysisEntry.AnalyzedInstanceKey.Hostname, audit.AnalysisEntry.AnalyzedInstanceKey.Port); + $("#audit_recovery_details thead h3").text(audit.AnalysisEntry.Analysis + ' on ' + clusterAlias + '/' + failedInstanceTitle) + + var appendRow = function(td1, td2) { + var row = $(''); + $('', { + text: td1 + }).appendTo(row); + $('', { + html: td2 + }).appendTo(row); + + row.appendTo($("#audit_recovery_details tbody")); + } + appendRow("Failed instance", failedInstanceTitle) + var successor = getInstanceTitle(audit.SuccessorKey.Hostname, audit.SuccessorKey.Port); + if (audit.IsSuccessful === false) { + successor = ' FAIL '+successor+''; + } else { + successor = ' '+successor+''; + } + appendRow("Successor", successor) + if (clusterAlias != clusterName) { + appendRow("Cluster alias", '' + clusterAlias + '') + } + appendRow("Cluster name", '' + clusterName + '') + appendRow("Affected replicas", audit.AnalysisEntry.CountReplicas) + appendRow("Start time", audit.RecoveryStartTimestamp) + appendRow("End time", audit.RecoveryEndTimestamp) + + var numRows = $("#audit_recovery_details tbody tr").length; + $('', { + html: ackInfo(audit) + }).attr("rowspan", 1).addClass("ack").appendTo($("#audit_recovery_details tbody tr:first-child")); + $('', { + html: auditInfo(audit) + }).attr("rowspan", numRows-1).appendTo($("#audit_recovery_details tbody tr:nth-child(2)")); + + auditRecoverySteps(audit.UID, $('#audit_recovery_steps')) + $("#audit_recovery_steps").show(); + } + + function displayAudit(auditEntries) { + var baseWebUri = appUrl("/web/audit-recovery/"); + if (clusterName()) { + baseWebUri += "cluster/" + clusterName() + "/"; + } else if (clusterAlias()) { + baseWebUri += "alias/" + clusterAlias() + "/"; + } + var singleRecoveryAudit = (auditEntries.length == 1); + + hideLoader(); + auditEntries.forEach(function(audit) { + if (singleRecoveryAudit) { + displaySingleAudit(audit) + return; + } + + var analyzedInstanceDisplay = getInstanceTitle(audit.AnalysisEntry.AnalyzedInstanceKey.Hostname, audit.AnalysisEntry.AnalyzedInstanceKey.Port); + var sucessorInstanceDisplay = getInstanceTitle(audit.SuccessorKey.Hostname, audit.SuccessorKey.Port); + var row = $(''); + var ack = $(''); + if (audit.Acknowledged) { + ack.addClass("glyphicon-ok-sign").addClass("text-primary"); + var ackTitle = "Acknowledged by " + audit.AcknowledgedBy + " at " + audit.AcknowledgedAt + ": " + audit.AcknowledgedComment; + ack.attr("title", ackTitle); + } else { + ack.addClass("glyphicon-question-sign").addClass("text-danger").addClass("ack-recovery"); + ack.attr("data-recovery-id", audit.Id); + ack.attr("title", "Unacknowledged. Click to acknowledge"); + } + + $('', { + html: ''+audit.AnalysisEntry.Analysis+'' + }).prepend(ack).appendTo(row); + $('', { + text: analyzedInstanceDisplay, + href: appUrl("/web/search/" + analyzedInstanceDisplay) + }).wrap($("")).parent().appendTo(row); + $('', { + text: audit.AnalysisEntry.CountReplicas + }).appendTo(row); + $('', { + text: audit.AnalysisEntry.ClusterDetails.ClusterName, + href: appUrl("/web/cluster/" + audit.AnalysisEntry.ClusterDetails.ClusterName) + }).wrap($("")).parent().appendTo(row); + $('', { + text: audit.AnalysisEntry.ClusterDetails.ClusterAlias, + href: appUrl("/web/cluster/alias/" + audit.AnalysisEntry.ClusterDetails.ClusterAlias) + }).wrap($("")).parent().appendTo(row); + $('', { + text: audit.RecoveryStartTimestamp + }).appendTo(row); + $('', { + text: audit.RecoveryEndTimestamp + }).appendTo(row); + if (audit.RecoveryEndTimestamp && !audit.IsSuccessful && !audit.SuccessorKey.Hostname) { + $('', { + text: "FAIL" + }).appendTo(row); + } else if (audit.SuccessorKey.Hostname) { + $('', { + text: sucessorInstanceDisplay, + href: appUrl("/web/search/" + sucessorInstanceDisplay) + }).wrap($("")).parent().appendTo(row); + } else { + $('', { + text: "pending" + }).appendTo(row); + } + var moreInfo = auditInfo(audit); + row.appendTo('#audit_recovery_table tbody'); + + var row = $(''); + row.addClass("more-info"); + row.attr("data-recovery-id-more-info", audit.Id); + $('').append(moreInfo).appendTo(row); + if (audit.Acknowledged) { + row.hide() + } + row.appendTo('#audit_recovery_table tbody'); + }); + if (singleRecoveryAudit) { + $("[data-recovery-id-more-info]").show(); + } + if (currentPage() <= 0) { + $("#audit .pager .previous").addClass("disabled"); + } + if (auditEntries.length == 0) { + $("#audit .pager .next").addClass("disabled"); + } + $("#audit .pager .previous").not(".disabled").find("a").click(function() { + window.location.href = baseWebUri + (currentPage() - 1); + }); + $("#audit .pager .next").not(".disabled").find("a").click(function() { + window.location.href = baseWebUri + (currentPage() + 1); + }); + $("#audit .pager .disabled a").click(function() { + return false; + }); + $("body").on("click", ".ack-recovery", function(event) { + var recoveryId = $(event.target).attr("data-recovery-id"); + bootbox.prompt({ + title: "Acknowledge recovery", + placeholder: "comment", + callback: function(result) { + if (result !== null) { + apiCommand("/api/ack-recovery/" + recoveryId + "?comment=" + encodeURIComponent(result)); + } + } + }); + }); + } +}); diff --git a/web/orchestrator/public/js/audit.js b/web/orchestrator/public/js/audit.js new file mode 100644 index 00000000000..cb2fca79851 --- /dev/null +++ b/web/orchestrator/public/js/audit.js @@ -0,0 +1,47 @@ + +$(document).ready(function () { + showLoader(); + var apiUri = "/api/audit/"+currentPage(); + if (auditHostname()) { + apiUri = "/api/audit/instance/"+auditHostname()+"/"+auditPort()+"/"+currentPage(); + } + $.get(appUrl(apiUri), function (auditEntries) { + auditEntries = auditEntries || []; + displayAudit(auditEntries); + }, "json"); + function displayAudit(auditEntries) { + var baseWebUri = appUrl("/web/audit/"); + if (auditHostname()) { + baseWebUri += "instance/"+auditHostname()+"/"+auditPort()+"/"; + } + hideLoader(); + auditEntries.forEach(function (audit) { + var row = jQuery(''); + jQuery('', { text: audit.AuditTimestamp }).appendTo(row); + jQuery('', { text: audit.AuditType }).appendTo(row); + if (audit.AuditInstanceKey.Hostname) { + var uri = appUrl("/web/audit/instance/"+audit.AuditInstanceKey.Hostname+"/"+audit.AuditInstanceKey.Port); + $('', { text: audit.AuditInstanceKey.Hostname+":"+audit.AuditInstanceKey.Port , href: uri}).wrap($("")).parent().appendTo(row); + } else { + jQuery('', { text: audit.AuditInstanceKey.Hostname+":"+audit.AuditInstanceKey.Port }).appendTo(row); + } + jQuery('', { text: audit.Message }).appendTo(row); + row.appendTo('#audit tbody'); + }); + if (currentPage() <= 0) { + $("#audit .pager .previous").addClass("disabled"); + } + if (auditEntries.length == 0) { + $("#audit .pager .next").addClass("disabled"); + } + $("#audit .pager .previous").not(".disabled").find("a").click(function() { + window.location.href = baseWebUri+(currentPage() - 1); + }); + $("#audit .pager .next").not(".disabled").find("a").click(function() { + window.location.href = baseWebUri+(currentPage() + 1); + }); + $("#audit .pager .disabled a").click(function() { + return false; + }); + } +}); diff --git a/web/orchestrator/public/js/bootbox.min.js b/web/orchestrator/public/js/bootbox.min.js new file mode 100644 index 00000000000..737d9e9f754 --- /dev/null +++ b/web/orchestrator/public/js/bootbox.min.js @@ -0,0 +1,6 @@ +/** + * bootbox.js v4.2.0 + * + * http://bootboxjs.com/license.txt + */ +!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["jquery"],b):"object"==typeof exports?module.exports=b(require("jquery")):a.bootbox=b(a.jQuery)}(this,function a(b,c){"use strict";function d(a){var b=q[o.locale];return b?b[a]:q.en[a]}function e(a,c,d){a.stopPropagation(),a.preventDefault();var e=b.isFunction(d)&&d(a)===!1;e||c.modal("hide")}function f(a){var b,c=0;for(b in a)c++;return c}function g(a,c){var d=0;b.each(a,function(a,b){c(a,b,d++)})}function h(a){var c,d;if("object"!=typeof a)throw new Error("Please supply an object of options");if(!a.message)throw new Error("Please specify a message");return a=b.extend({},o,a),a.buttons||(a.buttons={}),a.backdrop=a.backdrop?"static":!1,c=a.buttons,d=f(c),g(c,function(a,e,f){if(b.isFunction(e)&&(e=c[a]={callback:e}),"object"!==b.type(e))throw new Error("button with key "+a+" must be an object");e.label||(e.label=a),e.className||(e.className=2>=d&&f===d-1?"btn-primary":"btn-default")}),a}function i(a,b){var c=a.length,d={};if(1>c||c>2)throw new Error("Invalid argument length");return 2===c||"string"==typeof a[0]?(d[b[0]]=a[0],d[b[1]]=a[1]):d=a[0],d}function j(a,c,d){return b.extend(!0,{},a,i(c,d))}function k(a,b,c,d){var e={className:"bootbox-"+a,buttons:l.apply(null,b)};return m(j(e,d,c),b)}function l(){for(var a={},b=0,c=arguments.length;c>b;b++){var e=arguments[b],f=e.toLowerCase(),g=e.toUpperCase();a[f]={label:d(g)}}return a}function m(a,b){var d={};return g(b,function(a,b){d[b]=!0}),g(a.buttons,function(a){if(d[a]===c)throw new Error("button key "+a+" is not allowed (options are "+b.join("\n")+")")}),a}var n={dialog:"",header:"",footer:"",closeButton:"",form:"
      ",inputs:{text:"",textarea:"",email:"",select:"",checkbox:"
      ",date:"",time:"",number:"",password:""}},o={locale:"en",backdrop:!0,animate:!0,className:null,closeButton:!0,show:!0,container:"body"},p={};p.alert=function(){var a;if(a=k("alert",["ok"],["message","callback"],arguments),a.callback&&!b.isFunction(a.callback))throw new Error("alert requires callback property to be a function when provided");return a.buttons.ok.callback=a.onEscape=function(){return b.isFunction(a.callback)?a.callback():!0},p.dialog(a)},p.confirm=function(){var a;if(a=k("confirm",["cancel","confirm"],["message","callback"],arguments),a.buttons.cancel.callback=a.onEscape=function(){return a.callback(!1)},a.buttons.confirm.callback=function(){return a.callback(!0)},!b.isFunction(a.callback))throw new Error("confirm requires a callback");return p.dialog(a)},p.prompt=function(){var a,d,e,f,h,i,k;f=b(n.form),d={className:"bootbox-prompt",buttons:l("cancel","confirm"),value:"",inputType:"text"},a=m(j(d,arguments,["title","callback"]),["cancel","confirm"]),i=a.show===c?!0:a.show;var o=["date","time","number"],q=document.createElement("input");if(q.setAttribute("type",a.inputType),o[a.inputType]&&(a.inputType=q.type),a.message=f,a.buttons.cancel.callback=a.onEscape=function(){return a.callback(null)},a.buttons.confirm.callback=function(){var c;switch(a.inputType){case"text":case"textarea":case"email":case"select":case"date":case"time":case"number":case"password":c=h.val();break;case"checkbox":var d=h.find("input:checked");c=[],g(d,function(a,d){c.push(b(d).val())})}return a.callback(c)},a.show=!1,!a.title)throw new Error("prompt requires a title");if(!b.isFunction(a.callback))throw new Error("prompt requires a callback");if(!n.inputs[a.inputType])throw new Error("invalid prompt type");switch(h=b(n.inputs[a.inputType]),a.inputType){case"text":case"textarea":case"email":case"date":case"time":case"number":case"password":h.val(a.value);break;case"select":var r={};if(k=a.inputOptions||[],!k.length)throw new Error("prompt with select requires options");g(k,function(a,d){var e=h;if(d.value===c||d.text===c)throw new Error("given options in wrong format");d.group&&(r[d.group]||(r[d.group]=b("").attr("label",d.group)),e=r[d.group]),e.append("")}),g(r,function(a,b){h.append(b)}),h.val(a.value);break;case"checkbox":var s=b.isArray(a.value)?a.value:[a.value];if(k=a.inputOptions||[],!k.length)throw new Error("prompt with checkbox requires options");if(!k[0].value||!k[0].text)throw new Error("given options in wrong format");h=b("
      "),g(k,function(c,d){var e=b(n.inputs[a.inputType]);e.find("input").attr("value",d.value),e.find("label").append(d.text),g(s,function(a,b){b===d.value&&e.find("input").prop("checked",!0)}),h.append(e)})}return a.placeholder&&h.attr("placeholder",a.placeholder),a.pattern&&h.attr("pattern",a.pattern),f.append(h),f.on("submit",function(a){a.preventDefault(),e.find(".btn-primary").click()}),e=p.dialog(a),e.off("shown.bs.modal"),e.on("shown.bs.modal",function(){h.focus()}),i===!0&&e.modal("show"),e},p.dialog=function(a){a=h(a);var c=b(n.dialog),d=c.find(".modal-body"),f=a.buttons,i="",j={onEscape:a.onEscape};if(g(f,function(a,b){i+="",j[a]=b.callback}),d.find(".bootbox-body").html(a.message),a.animate===!0&&c.addClass("fade"),a.className&&c.addClass(a.className),a.title&&d.before(n.header),a.closeButton){var k=b(n.closeButton);a.title?c.find(".modal-header").prepend(k):k.css("margin-top","-10px").prependTo(d)}return a.title&&c.find(".modal-title").html(a.title),i.length&&(d.after(n.footer),c.find(".modal-footer").html(i)),c.on("hidden.bs.modal",function(a){a.target===this&&c.remove()}),c.on("shown.bs.modal",function(){c.find(".btn-primary:first").focus()}),c.on("escape.close.bb",function(a){j.onEscape&&e(a,c,j.onEscape)}),c.on("click",".modal-footer button",function(a){var d=b(this).data("bb-handler");e(a,c,j[d])}),c.on("click",".bootbox-close-button",function(a){e(a,c,j.onEscape)}),c.on("keyup",function(a){27===a.which&&c.trigger("escape.close.bb")}),b(a.container).append(c),c.modal({backdrop:a.backdrop,keyboard:!1,show:!1}),a.show&&c.modal("show"),c},p.setDefaults=function(){var a={};2===arguments.length?a[arguments[0]]=arguments[1]:a=arguments[0],b.extend(o,a)},p.hideAll=function(){b(".bootbox").modal("hide")};var q={br:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Sim"},da:{OK:"OK",CANCEL:"Annuller",CONFIRM:"Accepter"},de:{OK:"OK",CANCEL:"Abbrechen",CONFIRM:"Akzeptieren"},en:{OK:"OK",CANCEL:"Cancel",CONFIRM:"OK"},es:{OK:"OK",CANCEL:"Cancelar",CONFIRM:"Aceptar"},fi:{OK:"OK",CANCEL:"Peruuta",CONFIRM:"OK"},fr:{OK:"OK",CANCEL:"Annuler",CONFIRM:"D'accord"},he:{OK:"אישור",CANCEL:"ביטול",CONFIRM:"אישור"},it:{OK:"OK",CANCEL:"Annulla",CONFIRM:"Conferma"},lt:{OK:"Gerai",CANCEL:"Atšaukti",CONFIRM:"Patvirtinti"},lv:{OK:"Labi",CANCEL:"Atcelt",CONFIRM:"Apstiprināt"},nl:{OK:"OK",CANCEL:"Annuleren",CONFIRM:"Accepteren"},no:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},pl:{OK:"OK",CANCEL:"Anuluj",CONFIRM:"Potwierdź"},ru:{OK:"OK",CANCEL:"Отмена",CONFIRM:"Применить"},sv:{OK:"OK",CANCEL:"Avbryt",CONFIRM:"OK"},tr:{OK:"Tamam",CANCEL:"İptal",CONFIRM:"Onayla"},zh_CN:{OK:"OK",CANCEL:"取消",CONFIRM:"确认"},zh_TW:{OK:"OK",CANCEL:"取消",CONFIRM:"確認"}};return p.init=function(c){return a(c||b)},p}); \ No newline at end of file diff --git a/web/orchestrator/public/js/cluster-analysis-shared.js b/web/orchestrator/public/js/cluster-analysis-shared.js new file mode 100644 index 00000000000..42857127817 --- /dev/null +++ b/web/orchestrator/public/js/cluster-analysis-shared.js @@ -0,0 +1,54 @@ +var interestingAnalysis = { + "DeadMaster" : true, + "DeadMasterAndReplicas" : true, + "DeadMasterAndSomeReplicas" : true, + "DeadMasterWithoutReplicas" : true, + "UnreachableMasterWithLaggingReplicas": true, + "UnreachableMaster" : true, + "LockedSemiSyncMaster" : true, + "AllMasterReplicasNotReplicating" : true, + "AllMasterReplicasNotReplicatingOrDead" : true, + "DeadCoMaster" : true, + "DeadCoMasterAndSomeReplicas" : true, + "DeadIntermediateMaster" : true, + "DeadIntermediateMasterWithSingleReplicaFailingToConnect" : true, + "DeadIntermediateMasterWithSingleReplica" : true, + "DeadIntermediateMasterAndSomeReplicas" : true, + "DeadIntermediateMasterAndReplicas" : true, + "AllIntermediateMasterReplicasFailingToConnectOrDead" : true, + "AllIntermediateMasterReplicasNotReplicating" : true, + "UnreachableIntermediateMasterWithLaggingReplicas": true, + "UnreachableIntermediateMaster" : true, + "BinlogServerFailingToConnectToMaster" : true, +}; + +var errorMapping = { + "in_maintenance": { + "badge": "label-info", + "description": "In maintenance" + }, + "last_check_invalid": { + "badge": "label-fatal", + "description": "Last check invalid" + }, + "not_recently_checked": { + "badge": "label-stale", + "description": "Not recently checked (stale)" + }, + "not_replicating": { + "badge": "label-danger", + "description": "Not replicating" + }, + "replication_lag": { + "badge": "label-warning", + "description": "Replication lag" + }, + "errant_gtid": { + "badge": "label-errant", + "description": "Errant GTID" + }, + "group_replication_member_not_online": { + "badge": "label-danger", + "description": "Replication group member is not ONLINE" + } +}; diff --git a/web/orchestrator/public/js/cluster-pools.js b/web/orchestrator/public/js/cluster-pools.js new file mode 100644 index 00000000000..3974cbdff4c --- /dev/null +++ b/web/orchestrator/public/js/cluster-pools.js @@ -0,0 +1,126 @@ +$(document).ready(function() { + var isExpanded = true; + + showLoader(); + + $.get(appUrl("/api/cluster-pool-instances/" + currentClusterName()), function(clusterPoolInstances) { + $.get(appUrl("/api/problems"), function(problemInstances) { + problemInstances = problemInstances || []; + var problemInstancesMap = normalizeInstances(problemInstances, []); + displayClusterPoolInstances(clusterPoolInstances, problemInstances, problemInstancesMap); + }, "json"); + }, "json"); + + function sortByCountInstances(pool1, pool2) { + var diff = pool2.instances.length - pool1.instances.length; + if (diff != 0) { + return diff; + } + return pool1.name.localeCompare(pool2.name); + } + + function displayClusterPoolInstances(clusterPoolInstances, problemInstances, problemInstancesMap) { + hideLoader(); + + var poolsProblems = {}; + var pools = new Array(); + for (var pool in clusterPoolInstances.Details) { + if (clusterPoolInstances.Details.hasOwnProperty(pool)) { + poolsProblems[pool] = {}; + pools.push({ + name: pool, + instances: clusterPoolInstances.Details[pool] + }); + } + } + pools.sort(sortByCountInstances); + + function addInstancesBadge(poolName, count, badgeClass, title) { + $("#pools [data-pool-name='" + poolName + "'].popover").find(".popover-content .pull-right").append('' + count + ' '); + } + + function incrementPoolProblems(poolName, problemType) { + if (poolsProblems[poolName][problemType] > 0) { + poolsProblems[poolName][problemType] = poolsProblems[poolName][problemType] + 1; + } else { + poolsProblems[poolName][problemType] = 1; + } + } + + function incrementPoolsProblems(instance, problemType) { + if (!problemType) { + return + } + if (typeof instance.problemHint === 'undefined') { + instance.problemHint = problemType + } + pools.forEach(function(pool) { + pool.instances.forEach(function(poolInstance) { + if ((poolInstance.Hostname == instance.Key.Hostname) && (poolInstance.Port = instance.Key.Port)) { + incrementPoolProblems(pool.name, problemType) + } + }); + }); + } + problemInstances.forEach(function(instance) { + incrementPoolsProblems(instance, instance.problem) + }); + + pools.forEach(function(pool) { + $("#pools").append('

      ' + pool.name + '
       
       

      '); + var popoverElement = $("#pools [data-pool-name='" + pool.name + "'].popover"); + + var contentHtml = '' + '
      Instances:
      '; + popoverElement.find(".popover-content").html(contentHtml); + addInstancesBadge(pool.name, pool.instances.length, "label-primary", "Total instances in pool"); + for (var problemType in poolsProblems[pool.name]) { + addInstancesBadge(pool.name, poolsProblems[pool.name][problemType], errorMapping[problemType]["badge"], errorMapping[problemType]["description"]); + } + pool.instances.forEach(function(instance) { + var instanceId = getInstanceId(instance.Hostname, instance.Port); + var problemInstance = problemInstancesMap[instanceId]; + var instanceDisplay = instance.Hostname + ":" + instance.Port; + if (typeof removeTextFromHostnameDisplay != "undefined" && removeTextFromHostnameDisplay()) { + instanceDisplay = instanceDisplay.replace(removeTextFromHostnameDisplay(), ''); + } + var instanceContent = "
      "; + if (problemInstance && problemInstance.problemHint) { + instanceContent += '  ' + } + instanceContent += instanceDisplay; + instanceContent += "
      "; + popoverElement.find("div.pool-instances-listing").append(instanceContent); + }); + }); + + $("div.popover").popover(); + $("div.popover").show(); + + if (pools.length == 0) { + addAlert("No pools found"); + } + } + + if (isAuthorizedForAction()) { + // Read-only users don't get auto-refresh. Sorry! + activateRefreshTimer(); + } + $("#dropdown-context").append('
    1. Expand
    2. '); + $("#dropdown-context").append('
    3. Topology
    4. '); + $("body").on("click", "a[data-command=expand-instances]", function(event) { + isExpanded = !isExpanded; + updateExpandedStatus(); + }); + + function updateExpandedStatus() { + if (isExpanded) { + $("div.pool-instances-listing").removeClass('hidden'); + $("#dropdown-context a[data-command=expand-instances]").prepend(' '); + } else { + $("div.pool-instances-listing").addClass('hidden'); + $("#dropdown-context a[data-command=expand-instances] span").remove(); + } + } + + updateExpandedStatus(); +}); diff --git a/web/orchestrator/public/js/cluster-tree.js b/web/orchestrator/public/js/cluster-tree.js new file mode 100644 index 00000000000..7ca61c45aec --- /dev/null +++ b/web/orchestrator/public/js/cluster-tree.js @@ -0,0 +1,268 @@ +function visualizeInstances(nodesMap, onSvgInstanceWrapper, clusterControl) { + nodesList = [] + for (var nodeId in nodesMap) { + nodesList.push(nodesMap[nodeId]); + } + var anchorVisualizationExperimentalMode = false; + if (anchorVisualizationExperimentalMode) { + nodesList.forEach(function(node) { + if (node.children.length == 0) { + return; + } + var realChildren = node.children; + var pseudoChild = jQuery.extend({}, node) + pseudoChild.children = realChildren; + pseudoChild.children.forEach(function(child) { + child.parent = pseudoChild; + }); + pseudoChild.hasMaster = true; + pseudoChild.parent = node; + pseudoChild.isAnchor = true; + pseudoChild.id += "__virtualnode"; + + nodesMap[pseudoChild.id] = pseudoChild; + nodesList.push(pseudoChild); + node.children = [pseudoChild]; + }); + } + // Calculate tree dimensions + var maxNodeDepth = 20; + // virtualDepth is the depth in tree excluding virtual nodes. + // Virtual nodes are introduced as a means to present co-masters on same depth while retaining tree structure. This is + // merely for visualization purposes. In such case, a virtual node is introduced which is the parent (though not master) of + // said co-masters. But the virtual node is not displayed, and does not affect the visualized depth positioning of the nodes + // underneath it. + function getNodeDepth(node, recursiveLevel) { + if (recursiveLevel > maxNodeDepth) + return 0; + if (node.virtualDepth == null) { + if (node.parent == null) { + node.virtualDepth = 0; + } else { + var parentDepth = getNodeDepth(node.parent, recursiveLevel + 1); + node.virtualDepth = (node.parent.isVirtual || node.parent.isAnchor ? parentDepth : parentDepth + 1); + } + } + return node.virtualDepth; + } + nodesList.forEach(function(node) { + getNodeDepth(node, 0); + }); + var numNodesPerDepth = {} + nodesList.forEach(function(node) { + if (node.virtualDepth in numNodesPerDepth) { + numNodesPerDepth[node.virtualDepth] = numNodesPerDepth[node.virtualDepth] + 1; + } else { + numNodesPerDepth[node.virtualDepth] = 1; + } + }); + var maxDepth = 0; + var maxNodesAtDepth = 0; + $.each(numNodesPerDepth, function(key, value) { + maxDepth = Math.max(maxDepth, key); + maxNodesAtDepth = Math.max(maxNodesAtDepth, value); + }); + + var margin = { + top: 0, + right: 60, + bottom: 0, + left: 15, + }; + var horizontalSpacing = 320; + var verticalSpacing = 100; + var svgWidth = $("#cluster_container").width() - margin.right - margin.left; + svgWidth = Math.min(svgWidth, (maxDepth + 1) * horizontalSpacing); + var svgHeight = $("#cluster_container").height() - margin.top - margin.bottom; + svgHeight = Math.max(svgHeight, maxNodesAtDepth * verticalSpacing); + + var i = 0; + var duration = 0; + + var tree = d3.layout.tree(); + tree = tree.size([svgHeight, svgWidth]); + + var diagonal = d3.svg.diagonal().projection(function(d) { + return [d.y, d.x]; + }); + + var svg = d3.select("#cluster_container").append("svg") + .attr("width", svgWidth + margin.right + margin.left) + .attr("height", svgHeight + margin.top + margin.bottom) + .attr("xmlns", "http://www.w3.org/2000/svg").attr("version", "1.1").append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + var root = null; + nodesList.forEach(function(node) { + if (!node.hasMaster) { + root = node; + } + }); + if (root == null) { + nodesList.forEach(function(node) { + if (node.isCoMaster) { + root = node; + } + }); + } + root.x0 = svgHeight / 2; + root.y0 = 0; + update(root); + + function update(source) { + nodesList.where(function(t) { + return t.x != 0; + }).forEach(function(t) { + t.prevX = t.x; + t.prevY = t.y; + }); + // Compute the new tree layout. + var nodes = tree.nodes(root).reverse(); + var links = tree.links(nodes); + nodesList.where(function(t) { + return t.prevX != null; + }).forEach(function(t) { + t.x = t.prevX; + t.y = t.prevY; + }); + + // Normalize for fixed-depth. + nodes.forEach(function(d) { + // Position on screen according to virtual-depth, not mathematical tree depth + // (ignores virtual nodes, which are hidden) + if (d.isAnchor) { + d.y = (d.virtualDepth * horizontalSpacing) - horizontalSpacing / 2; + } else { + d.y = d.virtualDepth * horizontalSpacing; + } + }); + + // Update the nodes… + var node = svg.selectAll("g.node").data(nodes, + function(d) { + return d.id || (d.id = ++i); + }); + + // Enter any new nodes at the parent's previous position. + var nodeEnter = node.enter().append("g").attr("class", "node").attr("transform", function(d) { + return "translate(" + source.y0 + "," + source.x0 + ")"; + }).each( + function() { + this.parentNode.insertBefore(this, this.parentNode.firstChild); + } + ); + + nodeEnter.append("circle").attr("data-nodeid", function(d) { + if (d.isVirtual) { + return null; + } + if (d.isAnchor) { + return null; + } + return d.id; + }).attr("r", 1e-6).style("fill", function(d) { + return d._children ? "lightsteelblue" : "#fff"; + }).on("click", click); + + var fo = nodeEnter.append("g").attr("class", "svgInstanceWrapper").attr("data-fo-id", function(d) { + return d.id + }).attr("data-fo-is-virtual", function(d) { + return d.isVirtual + }).attr("data-fo-is-anchor", function(d) { + return d.isAnchor + }).attr("width", "100%").attr("dy", ".35em").attr("text-anchor", function(d) { + return d.children || d._children ? "end" : "start"; + }).attr("x", function(d) { + return 4; + }).attr("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility"); + + $("#cluster_container .instance").remove(); + $("g.svgInstanceWrapper").each(function() { + onSvgInstanceWrapper(this, nodesMap); + }) + + // Transition nodes to their new position. + var nodeUpdate = node + //.transition() + //.duration(duration) + .attr("transform", function(d) { + return "translate(" + d.y + "," + d.x + ")"; + }); + + nodeUpdate.select("circle").attr("r", function(d) { + if (d.isVirtual) { + return 0; + } + if (d.isAnchor) { + return 0; + } + return 4.5; + }).style("fill", function(d) { + return d._children ? "lightsteelblue" : "#fff"; + }); + + // Transition exiting nodes to the parent's new position. + var nodeExit = node.exit().transition().duration(duration).attr("transform", function(d) { + return "translate(" + source.y + "," + source.x + ")"; + }).remove(); + nodeExit.select("circle").attr("r", 1e-6); + + // Update the links… + var link = svg.selectAll("path.link").data(links, function(d) { + return d.target.id; + }); + + // Enter any new links at the parent's previous position. + link.enter().insert("path", "g").attr("class", "link").attr("d", function(d) { + var o = { + x: source.x0, + y: source.y0 + }; + return diagonal({ + source: o, + target: o + }); + }).style("stroke-dasharray", function(o) { + return o.source.DataCenter == o.target.DataCenter ? ("1, 0") : ("3, 3"); + }); + + // Transition links to their new position. + link.transition().duration(duration).attr("d", diagonal); + + // Transition exiting nodes to the parent's new position. + link.exit().transition().duration(duration).attr("d", function(d) { + var o = { + x: source.x, + y: source.y + }; + return diagonal({ + source: o, + target: o + }); + }).remove(); + + // Stash the old positions for transition. + nodes.forEach(function(d) { + d.x0 = d.x; + d.y0 = d.y; + }); + + nodeUpdate.each(function(d) { + //window.setTimeout(function(){clusterControl.repositionIntanceDiv(d.id);}, 100); + clusterControl.repositionIntanceDiv(d.id); + }); + + } + + // Toggle children on click. + function click(d) { + if (d.children) { + d._children = d.children; + d.children = null; + } else { + d.children = d._children; + d._children = null; + } + update(d); + } +} diff --git a/web/orchestrator/public/js/cluster.js b/web/orchestrator/public/js/cluster.js new file mode 100644 index 00000000000..b67b3e08787 --- /dev/null +++ b/web/orchestrator/public/js/cluster.js @@ -0,0 +1,1935 @@ +function Cluster() { + if (this == window) + return new Cluster(); + var _this = this; + Function.addTo(_this, [repositionIntanceDiv]); + + + var moveInstanceMethod = $.cookie("move-instance-method") || "smart"; + var droppableIsActive = false; + + var renderColors = ["#ff8c00", "#4682b4", "#9acd32", "#dc143c", "#9932cc", "#ffd700", "#191970", "#7fffd4", "#808080", "#dda0dd"]; + var dcColorsMap = {}; + + var _instances, _replicationAnalysis, _maintenanceList, _instancesMap, _isDraggingTrailer = false; + var _countDragOver = 0; + + var _instanceCommands = { + "recover-auto": function(e) { + apiCommand("/api/recover/" + _instancesMap[e.draggedNodeId].Key.Hostname + "/" + _instancesMap[e.draggedNodeId].Key.Port); + return true; + }, + "recover-auto-lite": function(e) { + apiCommand("/api/recover-lite/" + _instancesMap[e.draggedNodeId].Key.Hostname + "/" + _instancesMap[e.draggedNodeId].Key.Port); + return true; + }, + "force-master-failover": function(e) { + apiCommand("/api/force-master-failover/" + _instancesMap[e.draggedNodeId].Key.Hostname + "/" + _instancesMap[e.draggedNodeId].Key.Port); + return true; + }, + "recover-suggested-successor": function(e) { + var suggestedSuccessorHost = $(e.target).attr("data-successor-host"); + var suggestedSuccessorPort = $(e.target).attr("data-successor-port"); + apiCommand("/api/recover/" + _instancesMap[e.draggedNodeId].Key.Hostname + "/" + _instancesMap[e.draggedNodeId].Key.Port + "/" + suggestedSuccessorHost + "/" + suggestedSuccessorPort); + return true; + }, + "relocate-replicas": function(e) { + var belowHost = $(e.target).attr("data-successor-host"); + var belowPort = $(e.target).attr("data-successor-port"); + apiCommand("/api/relocate-replicas/" + _instancesMap[e.draggedNodeId].Key.Hostname + "/" + _instancesMap[e.draggedNodeId].Key.Port + "/" + belowHost + "/" + belowPort); + return true; + }, + "make-master": function(e) { + makeMaster(_instancesMap[e.draggedNodeId]); + return false; + }, + "make-local-master": function(e) { + makeLocalMaster(_instancesMap[e.draggedNodeId]); + return false; + }, + }; + + Object.defineProperties(_this, { + moveInstanceMethod: { + get: function() { + return moveInstanceMethod; + } + }, + droppableIsActive: { + get: function() { + return droppableIsActive; + } + }, + renderColors: { + get: function() { + return renderColors; + } + }, + dcColorsMap: { + get: function() { + return dcColorsMap; + } + }, + _instances: { + get: function() { + return _instances; + } + }, + _replicationAnalysis: { + get: function() { + return _replicationAnalysis; + } + }, + _maintenanceList: { + get: function() { + return _maintenanceList; + } + }, + _instancesMap: { + get: function() { + return _instancesMap; + } + }, + }); + + main(); + + function isColorizeDC() { + if ($.cookie("colorize-dc") == "false") { + return false + } + return true + } + + function getInstanceDiv(instanceId) { + var popoverDiv = $("#cluster_container > .instance[data-nodeid='" + instanceId + "']"); + return popoverDiv + } + + function repositionIntanceDiv(id) { + if (!id) + return false; + + var popoverDiv = getInstanceDiv(id); + var wrapper = $(popoverDiv).data("svg-instance-wrapper"); + if (!wrapper) { + // Can happen for virtual node + return false; + } + var circle = wrapper.previousElementSibling; + var pos = getSvgPos(circle); + pos.left += 25; + pos.top -= popoverDiv.height() / 2 - 2; + popoverDiv.css({ + left: pos.left + "px", + top: pos.top + "px" + }); + + popoverDiv.show(); + } + + function clearDroppable() { + $(".original-dragged").removeClass("original-dragged"); + resetRefreshTimer(); + $("#cluster_container .accept_drop_check").removeClass("accept_drop_check"); + $("#cluster_container .accept_drop").removeClass("accept_drop"); + $("#cluster_container .accept_drop_warning").removeClass("accept_drop_warning"); + $(".being-dragged").removeClass("being-dragged"); + $(".instance-trailer").show(); + droppableIsActive = false; + } + + + // All instance dragging/dropping code goes here + function activateInstanceDraggable(instanceEl) { + if (!isAuthorizedForAction()) + return; + + var nodesMap = _instancesMap; + var draggedNodeId = instanceEl.attr("data-nodeid"); + var trailerEl = instanceEl_getTrailerEl(instanceEl); + var opts = { + addClasses: true, + opacity: 1, + cancel: "button,a,span, .instance-trailer", + snap: "#cluster_container .instance", + snapMode: "inner", + snapTolerance: 10, + helper: "clone", + zIndex: 100, + containment: "#cluster_container", + start: instance_dragStart, + drag: instance_drag, + stop: instance_dragStop, + }; + + if (nodesMap[draggedNodeId].lastCheckInvalidProblem() || nodesMap[draggedNodeId].notRecentlyCheckedProblem()) { + instanceEl.find("h3").click(function() { + openNodeModal(nodesMap[draggedNodeId]); + return false; + }); + } else { + $(instanceEl).draggable(opts); + } + + var opts2 = Q.copy(opts); + opts.cancel = "button,a"; + $(trailerEl).draggable(opts); + } + + function instance_dragStart(e, ui) { + var instanceEl = $(e.target).closest(".instance"); + var trailerEl = instanceEl_getTrailerEl(instanceEl); + + clearDroppable(); + droppableIsActive = true; + + // dragging begins + _isDraggingTrailer = $(e.originalEvent.target).closest(".instance-trailer").length == 1; + if (_isDraggingTrailer) { + if (!isAuthorizedForAction()) + return false; + + var draggedNode = instanceEl_getNode(instanceEl); + draggedNode.children.forEach(function f(instance) { + var instanceEl2 = getInstanceDiv(instance.id); + instanceEl2.addClass("original-dragged"); + }); + + trailerEl.addClass("original-dragged"); + } else { + instanceEl.addClass("original-dragged"); + } + } + + function instance_drag(e, ui) { + resetRefreshTimer(); + } + + function instance_dragStop(e, ui) { + clearDroppable(); + + } + + function instanceEl_getNode(instanceEl) { + return _instancesMap[instanceEl.attr("data-nodeid")]; + } + + function generateInstanceDiv(svgInstanceWrapper, nodesMap) { + var isVirtual = $(svgInstanceWrapper).attr("data-fo-is-virtual") == "true"; + var isAnchor = $(svgInstanceWrapper).attr("data-fo-is-anchor") == "true"; + if (isVirtual || isAnchor) + return; + var id = $(svgInstanceWrapper).attr("data-fo-id"); + var node = nodesMap[id]; + + var instanceEl = Instance.createElement(node).addClass("instance-diagram arrow_box").appendTo("#cluster_container"); + $(instanceEl).hide(); + $(svgInstanceWrapper).data("instance-popover", instanceEl); + $(instanceEl).data("svg-instance-wrapper", svgInstanceWrapper); + + renderInstanceElement(instanceEl, node, "cluster"); + + var masterSectionEl = $('
      ').appendTo(instanceEl); + var normalSectionEl = $('
      ').appendTo(instanceEl); + if (node.children) { + var trailerEl = $('
      ').appendTo(instanceEl); + instanceEl.data("instance-trailer", trailerEl); + var numReplicas = 0; + node.children.forEach(function(replica) { + if (replica.isAggregate) { + numReplicas += replica.aggregatedInstances.length; + } else { + numReplicas += 1; + } + }); + var numReplicasMessage = ((numReplicas == 1) ? "1 replica" : "" + numReplicas + " replicas"); + trailerEl.getAppend(".instance-trailer-title").text(numReplicasMessage); + trailerEl.getAppend(".instance-trailer-content").text("Drag to move replicas"); + } + if (isColorizeDC()) { + var dcColor = dcColorsMap[node.DataCenter]; + $(instanceEl).css("border-color", dcColor); + $(instanceEl).css("border-width", 2); + + var trailerEl = $(instanceEl).data("instance-trailer"); + if (trailerEl) { + $(trailerEl).css("border-color", dcColor); + $(trailerEl).css("border-width", 2); + $(trailerEl).addClass("colorized"); + } + } + + activateInstanceDraggable(instanceEl); + prepareInstanceDroppable(normalSectionEl); + prepareInstanceMasterSectionDroppable(masterSectionEl); + } + + function instanceEl_getTrailerEl(instanceEl) { + return instanceEl.find(".instance-trailer").not(".ui-draggable-dragging"); + } + + + + function wireInstanceCommands() { + $("body").on("click", ".instance h3 .instance-glyphs", function(e) { + var target = $(e.target); + e.draggedNodeId = target.attr("data-nodeid"); + if (e.draggedNodeId == $(".instance").attr("data-nodeid")) + return; + openNodeModal(_instancesMap[draggedNodeId]); + return false; + }); + + $("body").on("click", ".instance a[data-command], .instance button[data-command]", function(e) { + var target = $(e.target).closest("a"); + var instanceEl = target.closest(".instance"); + e.draggedNodeId = instanceEl.attr("data-nodeid"); + + var cmd = target.attr("data-command"); + + var action = _instanceCommands[cmd]; + if (action == null) + return; + var res = action(e); + return res; + }); + } + + + + function prepareInstanceDroppable(instanceEl) { + var nodesMap = _instancesMap; + instanceEl.droppable({ + accept: function(draggable) { + // Find the objects that accept a draggable (i.e. valid droppables) + if (!droppableIsActive) { + return false + } + if (instanceEl[0] == draggable[0]) + return false; + var draggedNodeId = draggable.attr("data-nodeid"); + var draggedNode = nodesMap[draggedNodeId]; + var targetNode = nodesMap[instanceEl.attr("data-nodeid")]; + var action = _isDraggingTrailer ? moveChildren : moveInstance; + var acceptDrop = action(draggedNode, targetNode, false); + var instanceDiv = $(this).closest(".instance"); + instanceDiv.addClass("accept_drop_check"); + if (acceptDrop.accept == "ok") { + instanceDiv.addClass("accept_drop"); + } + if (acceptDrop.accept == "warning") { + instanceDiv.addClass("accept_drop_warning"); + } + $(this).attr("data-drop-comment", acceptDrop.accept ? acceptDrop.type : ""); + var accepted = acceptDrop.accept != null; + return accepted; + }, + hoverClass: "draggable-hovers", + over: function(event, ui) { + _countDragOver++; + var duplicate = ui.helper; + // Called once when dragged object is over another object + if ($(this).attr("data-drop-comment")) { + $(duplicate).addClass("draggable-msg"); + $(duplicate).find(".instance-content,.instance-trailer-content").html($(this).attr("data-drop-comment")) + } else { + $(duplicate).find(".instance-content,.instance-trailer-content").html(' Cannot drop here') + } + }, + out: function(event, ui) { + _countDragOver--; + if (_countDragOver > 0) { + return; + } + var duplicate = ui.helper; + // Called once when dragged object leaves other object + $(duplicate).removeClass("draggable-msg"); + $(duplicate).find(".instance-content,.instance-trailer-content").html("") + }, + drop: function(e, ui) { + var draggedNodeId = ui.draggable.attr("data-nodeid"); + var action = _isDraggingTrailer ? moveChildren : moveInstance; + var duplicate = ui.helper; + action(nodesMap[draggedNodeId], nodesMap[$(this).attr("data-nodeid")], true); + clearDroppable(); + } + }); + + } + + function prepareInstanceMasterSectionDroppable(instanceMasterSectionEl) { + var nodesMap = _instancesMap; + instanceMasterSectionEl.droppable({ + accept: function(draggable) { + // Find the objects that accept a draggable (i.e. valid droppables) + if (!droppableIsActive) { + return false + } + if (instanceMasterSectionEl[0] == draggable[0]) + return false; + var draggedNodeId = draggable.attr("data-nodeid"); + var draggedNode = nodesMap[draggedNodeId]; + var targetNode = nodesMap[instanceMasterSectionEl.attr("data-nodeid")]; + var action = _isDraggingTrailer ? moveChildren : moveInstanceOnMaster; + var acceptDrop = action(draggedNode, targetNode, false); + var instanceDiv = $(this).closest(".instance"); + instanceDiv.addClass("accept_drop_check"); + if (acceptDrop.accept == "ok") { + instanceDiv.addClass("accept_drop"); + } + if (acceptDrop.accept == "warning") { + instanceDiv.addClass("accept_drop_warning"); + } + $(this).attr("data-drop-comment", acceptDrop.accept ? acceptDrop.type : ""); + var accepted = acceptDrop.accept != null; + return accepted; + }, + hoverClass: "draggable-hovers", + over: function(event, ui) { + _countDragOver += 1; + var duplicate = ui.helper; + // Called once when dragged object is over another object + if ($(this).attr("data-drop-comment")) { + $(duplicate).addClass("draggable-msg"); + $(duplicate).find(".instance-content,.instance-trailer-content").html($(this).attr("data-drop-comment")) + } else { + $(duplicate).find(".instance-content,.instance-trailer-content").html(' Cannot drop here') + } + }, + out: function(event, ui) { + _countDragOver--; + if (_countDragOver > 0) { + return; + } + var duplicate = ui.helper; + // Called once when dragged object leaves other object + $(duplicate).removeClass("draggable-msg"); + $(duplicate).find(".instance-content,.instance-trailer-content").html("") + }, + drop: function(e, ui) { + var draggedNodeId = ui.draggable.attr("data-nodeid"); + var duplicate = ui.helper; + var action = _isDraggingTrailer ? moveChildren : moveInstanceOnMaster; + action(nodesMap[draggedNodeId], nodesMap[$(this).attr("data-nodeid")], true); + clearDroppable(); + } + }); + + } + + // moveInstance checks whether an instance (node) can be dropped on another (droppableNode). + // The function consults with the current moveInstanceMethod; the type of action taken is based on that. + // For example, actions can be repoint, match-below, relocate, move-up, take-master etc. + // When shouldApply is false nothing gets executed, and the function merely serves as a predictive + // to the possibility of the drop. + function moveInstance(node, droppableNode, shouldApply) { + if (!isAuthorizedForAction()) { + // Obviously this is also checked on server side, no need to try stupid hacks + return { + accept: false + }; + } + var droppableTitle = getInstanceDiv(droppableNode.id).find("h3 .pull-left").html(); + if (moveInstanceMethod == "smart") { + // Moving via GTID or Pseudo GTID + if (node.hasConnectivityProblem || droppableNode.hasConnectivityProblem || droppableNode.isAggregate) { + // Obviously can't handle. + return { + accept: false + }; + } + if (droppableNode.MasterKey.Hostname && droppableNode.MasterKey.Hostname != "_") { + // droppableNode has master + if (!droppableNode.LogReplicationUpdatesEnabled) { + // Obviously can't handle. + return { + accept: false + }; + } + // It's OK for the master itself to not have log_slave_updates + } + + if (node.id == droppableNode.id) { + return { + accept: false + }; + } + if (instanceIsChild(droppableNode, node) && node.isMaster && !node.isCoMaster) { + if (node.hasProblem) { + return { + accept: false + }; + } + if (shouldApply) { + makeCoMaster(node, droppableNode); + } + return { + accept: "ok", + type: ' MAKE CO MASTER with ' + droppableTitle, + }; + } + if (instanceIsDescendant(droppableNode, node)) { + // Wrong direction! + return { + accept: false + }; + } + if (node.isAggregate) { + if (shouldApply) { + relocateReplicas(node.masterNode, droppableNode, node.aggregatedInstancesPattern); + } + return { + accept: "warning", + type: "relocate [" + node.aggregatedInstances.length + "] < " + droppableTitle + }; + } + // the general case + if (shouldApply) { + relocate(node, droppableNode); + } + return { + accept: "warning", + type: "relocate < " + droppableTitle + }; + } + var gtidBelowFunc = null; + var gtidOperationName = ""; + if (moveInstanceMethod == "pseudo-gtid") { + gtidBelowFunc = matchBelow; + gtidOperationName = "match"; + } + if (moveInstanceMethod == "gtid") { + gtidBelowFunc = moveBelowGTID; + gtidOperationName = "move:gtid"; + } + if (gtidBelowFunc != null) { + // Moving via GTID or Pseudo GTID + if (node.hasConnectivityProblem || droppableNode.hasConnectivityProblem || droppableNode.isAggregate) { + // Obviously can't handle. + return { + accept: false + }; + } + if (node.isAggregate) { + return { + accept: false + }; + } + if (droppableNode.MasterKey.Hostname && droppableNode.MasterKey.Hostname != "_") { + // droppableNode has master + if (!droppableNode.LogReplicationUpdatesEnabled) { + // Obviously can't handle. + return { + accept: false + }; + } + // It's OK for the master itself to not have log_slave_updates + } + + if (node.id == droppableNode.id) { + return { + accept: false + }; + } + if (instanceIsChild(droppableNode, node) && node.isMaster && !node.isCoMaster) { + if (node.hasProblem) { + return { + accept: false + }; + } + if (shouldApply) { + makeCoMaster(node, droppableNode); + } + return { + accept: "ok", + type: ' MAKE CO MASTER with ' + droppableTitle, + }; + } + if (instanceIsDescendant(droppableNode, node)) { + // Wrong direction! + return { + accept: false + }; + } + if (instanceIsDescendant(node, droppableNode)) { + // clearly node cannot be more up to date than droppableNode + if (shouldApply) { + gtidBelowFunc(node, droppableNode); + } + return { + accept: "ok", + type: gtidOperationName + " " + droppableTitle + }; + } + if (isReplicationBehindSibling(node, droppableNode)) { + // verified that node isn't more up to date than droppableNode + if (shouldApply) { + gtidBelowFunc(node, droppableNode); + } + return { + accept: "ok", + type: gtidOperationName + " " + droppableTitle + }; + } + // the general case, where there's no clear family connection, meaning we cannot infer + // which instance is more up to date. It's under the user's responsibility! + if (shouldApply) { + gtidBelowFunc(node, droppableNode); + } + return { + accept: "warning", + type: gtidOperationName + " " + droppableTitle + }; + } + if (moveInstanceMethod == "classic") { + // Not pseudo-GTID mode, non GTID mode + if (node.id == droppableNode.id) { + return { + accept: false + }; + } + if (node.isAggregate) { + return { + accept: false + }; + } + if (instanceIsChild(droppableNode, node) && node.isCoMaster) { + // We may allow a co-master to change its other co-master under some conditions, + // see MakeCoMaster() in instance_topology.go + if (!droppableNode.ReadOnly) { + return { + accept: false + }; + } + var coMaster = node.masterNode; + if (coMaster.id == droppableNode.id) { + return { + accept: false + }; + } + if (coMaster.lastCheckInvalidProblem() || coMaster.notRecentlyCheckedProblem() || coMaster.ReadOnly) { + if (shouldApply) { + makeCoMaster(node, droppableNode); + } + return { + accept: "ok", + type: ' MAKE CO MASTER with ' + droppableTitle, + }; + } + } + if (node.isCoMaster) { + return { + accept: false + }; + } + if (instancesAreSiblings(node, droppableNode)) { + if (node.hasProblem || droppableNode.hasProblem || droppableNode.isAggregate || !droppableNode.LogReplicationUpdatesEnabled) { + return { + accept: false + }; + } + if (shouldApply) { + moveBelow(node, droppableNode); + } + return { + accept: "ok", + type: "moveBelow " + droppableTitle + }; + } + if (instanceIsGrandchild(node, droppableNode)) { + if (node.hasProblem) { + // Typically, when a node has a problem we do not allow moving it up. + // But there's a special situation when allowing is desired: when the parent has personal issues, + // (say disk issue or otherwise something heavyweight running which slows down replication) + // and you want to move up the replica which is only delayed by its master. + // So to help out, if the instance is identically at its master's trail, it is allowed to move up. + if (!node.isSQLThreadCaughtUpWithIOThread) { + return { + accept: false + }; + } + } + if (shouldApply) { + moveUp(node, droppableNode); + } + return { + accept: "ok", + type: "moveUp under " + droppableTitle + }; + } + if (instanceIsChild(node, droppableNode) && !droppableNode.isMaster) { + if (node.hasProblem) { + // Typically, when a node has a problem we do not allow moving it up. + // But there's a special situation when allowing is desired: when + // this replica is completely caught up; + if (!node.isSQLThreadCaughtUpWithIOThread) { + return { + accept: false + }; + } + } + if (shouldApply) { + takeMaster(node, droppableNode); + } + return { + accept: "ok", + type: "takeMaster " + droppableTitle + }; + } + if (instanceIsChild(droppableNode, node) && node.isMaster && !node.isCoMaster) { + if (node.hasProblem) { + return { + accept: false + }; + } + if (shouldApply) { + makeCoMaster(node, droppableNode); + } + return { + accept: "ok", + type: ' MAKE CO MASTER with ' + droppableTitle, + }; + } + return { + accept: false + }; + } + if (shouldApply) { + addAlert( + "Cannot move " + + node.Key.Hostname + ":" + node.Key.Port + + " under " + + droppableNode.Key.Hostname + ":" + droppableNode.Key.Port + + ". " + + "You may only move a node down below its sibling or up below its grandparent." + ); + } + return { + accept: false + }; + } + + + function moveInstanceOnMaster(node, droppableNode, shouldApply) { + var unaccepted = { + accept: false + }; + if (!isAuthorizedForAction()) { + // Obviously this is also checked on server side, no need to try stupid hacks + return unaccepted; + } + var droppableTitle = getInstanceDiv(droppableNode.id).find("h3 .pull-left").html(); + + if (node.hasConnectivityProblem || droppableNode.hasConnectivityProblem || droppableNode.isAggregate) { + // Obviously can't handle. + return unaccepted; + } + if (instanceIsChild(node, droppableNode) && !droppableNode.isMaster && !droppableNode.isCoMaster) { + if (node.hasProblem) { + // Typically, when a node has a problem we do not allow moving it up. + // But there's a special situation when allowing is desired: when + // this replica is completely caught up; + if (!node.isSQLThreadCaughtUpWithIOThread) { + return { + accept: false + }; + } + } + if (shouldApply) { + takeMaster(node, droppableNode); + } + return { + accept: "ok", + type: ' take master ' + droppableTitle + }; + } + if (instanceIsChild(node, droppableNode) && + droppableNode.isMaster && + !node.isCoMaster + ) { + if (node.hasProblem) { + return { + accept: false + }; + } + if (shouldApply) { + gracefulMasterTakeover(node, droppableNode); + } + return { + accept: "ok", + type: ' PROMOTE AS MASTER ' + }; + } + return moveInstance(node, droppableNode, shouldApply); + } + + // moveChildren checks whether an children of an instance (node) can be dropped on another (droppableNode). + // The function consults with the current moveInstanceMethod; the type of action taken is based on that. + // For example, actions can be repoint-replicas, match-replicas, relocate-replicas, move-up-replicas etc. + // When shouldApply is false nothing gets executed, and the function merely serves as a predictive + // to the possibility of the drop. + function moveChildren(node, droppableNode, shouldApply) { + if (!isAuthorizedForAction()) { + // Obviously this is also checked on server side, no need to try stupid hacks + return { + accept: false + }; + } + var droppableTitle = getInstanceDiv(droppableNode.id).find("h3 .pull-left").html(); + if (moveInstanceMethod == "smart") { + // Moving via GTID or Pseudo GTID + if (droppableNode.hasConnectivityProblem || droppableNode.isAggregate) { + // Obviously can't handle. + return { + accept: false + }; + } + if (droppableNode.MasterKey.Hostname && droppableNode.MasterKey.Hostname != "_") { + // droppableNode has master + if (!droppableNode.LogReplicationUpdatesEnabled) { + // Obviously can't handle. + return { + accept: false + }; + } + // It's OK for the master itself to not have log_slave_updates + } + + if (node.id == droppableNode.id) { + if (shouldApply) { + relocateReplicas(node, droppableNode); + } + return { + accept: "ok", + type: "relocate < " + droppableTitle + }; + } + if (instanceIsDescendant(droppableNode, node) && node.children.length <= 1) { + // Can generally move replicas onto one of them, but there needs to be at least two replicas... + // Otherwise we;re trying to mvoe a replica under itself which is clearly an error. + return { + accept: false + }; + } + // the general case + if (shouldApply) { + relocateReplicas(node, droppableNode); + } + return { + accept: "warning", + type: "relocate < " + droppableTitle + }; + } + + var gtidBelowFunc = null; + var gtidOperationName = ""; + if (moveInstanceMethod == "pseudo-gtid") { + gtidBelowFunc = matchReplicas; + gtidOperationName = "match"; + } + if (moveInstanceMethod == "gtid") { + gtidBelowFunc = moveReplicasGTID; + gtidOperationName = "move:gtid"; + } + if (gtidBelowFunc != null) { + // Moving via GTID or Pseudo GTID + if (droppableNode.hasConnectivityProblem || droppableNode.isAggregate) { + // Obviously can't handle. + return { + accept: false + }; + } + if (droppableNode.MasterKey.Hostname && droppableNode.MasterKey.Hostname != "_") { + // droppableNode has master + if (!droppableNode.LogReplicationUpdatesEnabled) { + // Obviously can't handle. + return { + accept: false + }; + } + // It's OK for the master itself to not have log_slave_updates + } + if (node.id == droppableNode.id) { + if (shouldApply) { + gtidBelowFunc(node, droppableNode); + } + return { + accept: "ok", + type: gtidOperationName + " < " + droppableTitle + }; + } + if (instanceIsDescendant(droppableNode, node) && node.children.length <= 1) { + // Can generally move replicas onto one of them, but there needs to be at least two replicas... + // Otherwise we;re trying to mvoe a replica under itself which is clearly an error. + // Wrong direction! + return { + accept: false + }; + } + if (instanceIsDescendant(node, droppableNode)) { + // clearly node cannot be more up to date than droppableNode + if (shouldApply) { + gtidBelowFunc(node, droppableNode); + } + return { + accept: "ok", + type: gtidOperationName + " < " + droppableTitle + }; + } + // the general case, where there's no clear family connection, meaning we cannot infer + // which instance is more up to date. It's under the user's responsibility! + if (shouldApply) { + gtidBelowFunc(node, droppableNode); + } + return { + accept: "warning", + type: gtidOperationName + " < " + droppableTitle + }; + } + if (moveInstanceMethod == "classic") { + // Not pseudo-GTID mode, non GTID mode + if (node.id == droppableNode.id) { + if (shouldApply) { + repointReplicas(node); + } + return { + accept: "ok", + type: "repointReplicas < " + droppableTitle + }; + } + if (instanceIsChild(node, droppableNode)) { + if (shouldApply) { + moveUpReplicas(node, droppableNode); + } + return { + accept: "ok", + type: "moveUpReplicas < " + droppableTitle + }; + } + return { + accept: false + }; + } + if (shouldApply) { + addAlert( + "Cannot move replicas of " + + node.Key.Hostname + ":" + node.Key.Port + + " under " + + droppableNode.Key.Hostname + ":" + droppableNode.Key.Port + + ". " + + "You may only repoint or move up the replicas of an instance. Otherwise try Smart Mode." + ); + } + return { + accept: false + }; + } + + + function executeMoveOperation(message, apiUrl) { + if (isSilentUI()) { + apiCommand(apiUrl); + } else { + bootbox.confirm(anonymizeIfNeedBe(message), function(confirm) { + if (confirm) { + apiCommand(apiUrl); + } + }); + } + $("#cluster_container .accept_drop_check").removeClass("accept_drop_check"); + $("#cluster_container .accept_drop").removeClass("accept_drop"); + $("#cluster_container .accept_drop").removeClass("accept_drop_warning"); + return false; + } + + function relocate(node, siblingNode) { + var message = "

      relocate

      Are you sure you wish to turn " + + node.Key.Hostname + ":" + node.Key.Port + + " into a replica of " + + siblingNode.Key.Hostname + ":" + siblingNode.Key.Port + + "?" + + "

      Note

      Orchestrator will try and figure out the best relocation path. This may involve multiple steps. " + + "

      In case multiple steps are involved, failure of one would leave your instance hanging in a different location than you expected, " + + "but it would still be in a valid state."; + var apiUrl = "/api/relocate/" + node.Key.Hostname + "/" + node.Key.Port + "/" + siblingNode.Key.Hostname + "/" + siblingNode.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function relocateReplicas(node, siblingNode, pattern) { + pattern = pattern || ""; + var message = "

      relocate-replicas

      Are you sure you wish to relocate replicas of " + + node.Key.Hostname + ":" + node.Key.Port + + " below " + + siblingNode.Key.Hostname + ":" + siblingNode.Key.Port + + "?" + + "

      Note

      Orchestrator will try and figure out the best relocation path. This may involve multiple steps. " + + "

      In case multiple steps are involved, failure of one may leave some instances hanging in a different location than you expected, " + + "but they would still be in a valid state."; + var apiUrl = "/api/relocate-replicas/" + node.Key.Hostname + "/" + node.Key.Port + "/" + siblingNode.Key.Hostname + "/" + siblingNode.Key.Port + "?pattern=" + encodeURIComponent(pattern); + return executeMoveOperation(message, apiUrl); + } + + function repointReplicas(node, siblingNode) { + var message = "

      repoint-replicas

      Are you sure you wish to repoint replicas of " + + node.Key.Hostname + ":" + node.Key.Port + + "?"; + var apiUrl = "/api/repoint-replicas/" + node.Key.Hostname + "/" + node.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function moveUpReplicas(node, masterNode) { + var message = "

      move-up-replicas

      Are you sure you wish to move up replicas of " + + node.Key.Hostname + ":" + node.Key.Port + + " below " + + masterNode.Key.Hostname + ":" + masterNode.Key.Port + + "?"; + var apiUrl = "/api/move-up-replicas/" + node.Key.Hostname + "/" + node.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function matchReplicas(node, otherNode) { + var message = "

      match-replicas

      Are you sure you wish to match replicas of " + + node.Key.Hostname + ":" + node.Key.Port + + " below " + + otherNode.Key.Hostname + ":" + otherNode.Key.Port + + "?"; + var apiUrl = "/api/match-replicas/" + node.Key.Hostname + "/" + node.Key.Port + "/" + otherNode.Key.Hostname + "/" + otherNode.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function moveBelow(node, siblingNode) { + var message = "

      move-below

      Are you sure you wish to turn " + + node.Key.Hostname + ":" + node.Key.Port + + " into a replica of " + + siblingNode.Key.Hostname + ":" + siblingNode.Key.Port + + "?"; + var apiUrl = "/api/move-below/" + node.Key.Hostname + "/" + node.Key.Port + "/" + siblingNode.Key.Hostname + "/" + siblingNode.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function moveUp(node, grandparentNode) { + var message = "

      move-up

      Are you sure you wish to turn " + + node.Key.Hostname + ":" + node.Key.Port + + " into a replica of " + + grandparentNode.Key.Hostname + ":" + grandparentNode.Key.Port + + "?"; + var apiUrl = "/api/move-up/" + node.Key.Hostname + "/" + node.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function takeMaster(node, masterNode) { + var message = "

      take-master

      Are you sure you wish to make " + + node.Key.Hostname + ":" + node.Key.Port + + " master of " + + masterNode.Key.Hostname + ":" + masterNode.Key.Port + + "?"; + var apiUrl = "/api/take-master/" + node.Key.Hostname + "/" + node.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function matchBelow(node, otherNode) { + var message = "

      PSEUDO-GTID MODE, match-below

      Are you sure you wish to turn " + + node.Key.Hostname + ":" + node.Key.Port + + " into a replica of " + + otherNode.Key.Hostname + ":" + otherNode.Key.Port + + "?"; + var apiUrl = "/api/match-below/" + node.Key.Hostname + "/" + node.Key.Port + "/" + otherNode.Key.Hostname + "/" + otherNode.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function moveBelowGTID(node, otherNode) { + var message = "

      GTID MODE, move-below

      Are you sure you wish to turn " + + node.Key.Hostname + ":" + node.Key.Port + + " into a replica of " + + otherNode.Key.Hostname + ":" + otherNode.Key.Port + + "?"; + var apiUrl = "/api/move-below-gtid/" + node.Key.Hostname + "/" + node.Key.Port + "/" + otherNode.Key.Hostname + "/" + otherNode.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function moveReplicasGTID(node, otherNode) { + var message = "

      GTID MODE, move-replicas

      Are you sure you wish to move replicas of " + + node.Key.Hostname + ":" + node.Key.Port + + " below " + + otherNode.Key.Hostname + ":" + otherNode.Key.Port + + "?"; + var apiUrl = "/api/move-replicas-gtid/" + node.Key.Hostname + "/" + node.Key.Port + "/" + otherNode.Key.Hostname + "/" + otherNode.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + function makeCoMaster(node, childNode) { + var message = "

      make-co-master

      Are you sure you wish to make " + + node.Key.Hostname + ":" + node.Key.Port + + " and " + + childNode.Key.Hostname + ":" + childNode.Key.Port + + " co-masters?"; + bootbox.confirm(anonymizeIfNeedBe(message), function(confirm) { + if (confirm) { + apiCommand("/api/make-co-master/" + childNode.Key.Hostname + "/" + childNode.Key.Port); + return true; + } + }); + return false; + } + + + function gracefulMasterTakeover(newMasterNode, existingMasterNode) { + var message = '

      DANGER ZONE

      Graceful-master-takeover

      Are you sure you wish to promote ' + + newMasterNode.Key.Hostname + ':' + newMasterNode.Key.Port + + ' as master?'; + bootbox.confirm(anonymizeIfNeedBe(message), function(confirm) { + if (confirm) { + apiCommand("/api/graceful-master-takeover/" + existingMasterNode.Key.Hostname + "/" + existingMasterNode.Key.Port + "/" + newMasterNode.Key.Hostname + "/" + newMasterNode.Key.Port); + return true; + } + }); + return false; + } + + function instancesAreSiblings(node1, node2) { + if (node1.id == node2.id) return false; + if (node1.masterNode == null) return false; + if (node2.masterNode == null) return false; + if (node1.masterNode.id != node2.masterNode.id) return false; + return true; + } + + + function instanceIsChild(node, parentNode) { + if (!node.hasMaster) { + return false; + } + if (node.masterNode.id != parentNode.id) { + return false; + } + if (node.id == parentNode.id) { + return false; + } + return true; + } + + + function instanceIsGrandchild(node, grandparentNode) { + if (!node.hasMaster) { + return false; + } + var masterNode = node.masterNode; + if (!masterNode.hasMaster) { + return false; + } + if (masterNode.masterNode.id != grandparentNode.id) { + return false; + } + if (node.id == grandparentNode.id) { + return false; + } + return true; + } + + function instanceIsDescendant(node, nodeAtQuestion, depth) { + depth = depth || 0; + if (depth > node.ReplicationDepth + 1) { + // Safety check for master-master topologies: avoid infinite loop + return false; + } + if (nodeAtQuestion == null) { + return false; + } + if (node.id == nodeAtQuestion.id) { + return false; + } + if (!node.hasMaster) { + return false; + } + if (node.masterNode.id == nodeAtQuestion.id) { + return true; + } + return instanceIsDescendant(node.masterNode, nodeAtQuestion, depth + 1) + } + + // Returns true when the two instances are siblings, and 'node' is behind or at same position + // (in reltation to shared master) as its 'sibling'. + // i.e. 'sibling' is same as, or more up to date by master than 'node'. + function isReplicationBehindSibling(node, sibling) { + if (!instancesAreSiblings(node, sibling)) { + return false; + } + return compareInstancesExecBinlogCoordinates(node, sibling) <= 0; + } + + function isReplicationStrictlyBehindSibling(node, sibling) { + if (!instancesAreSiblings(node, sibling)) { + return false; + } + return compareInstancesExecBinlogCoordinates(node, sibling) < 0; + } + + function compareInstancesExecBinlogCoordinates(i0, i1) { + if (i0.ExecBinlogCoordinates.LogFile == i1.ExecBinlogCoordinates.LogFile) { + // executing from same master log file + return i0.ExecBinlogCoordinates.LogPos - i1.ExecBinlogCoordinates.LogPos; + } + return (getLogFileNumber(i0.ExecBinlogCoordinates.LogFile) - getLogFileNumber(i1.ExecBinlogCoordinates.LogFile)); + + } + + function getLogFileNumber(logFileName) { + logFileTokens = logFileName.split(".") + return parseInt(logFileTokens[logFileTokens.length - 1]) + } + + // compactInstances aggregates sibling instances of same DC such that they are visualized as a single box. + function compactInstances(instances, instancesMap) { + function aggregateInstances(parentInstance, dataCenter, instances) { + if (!instances) { + return false; + } + if (instances.length < 2) { + return false; + } + + var aggregatedProblems = {} + + function incrementProblems(problemType, title) { + if (aggregatedProblems[problemType]) { + aggregatedProblems[problemType].push(title); + } else { + aggregatedProblems[problemType] = [title]; + } + } + var instanceFullNames = []; + instances.forEach(function(instance) { + var instanceDescription = instance.title + " " + instance.Version; + if (isAnonymized()) { + instanceDescription = anonymizeInstanceId(instance.id); + } + instanceDescription += ", " + instance.ReplicationLagSeconds.Int64 + "s lag"; + incrementProblems("", instanceDescription) + instanceFullNames.push(getInstanceTitle(instance.Key.Hostname, instance.Key.Port)); + instance.Problems.forEach(function(problem) { + incrementProblems(problem, instanceDescription) + }); + }); + var aggergateInstance = instances[0]; + aggergateInstance.isAggregate = true; + aggergateInstance.title = "[aggregation]"; + if (dataCenter) { + aggergateInstance.title = "[aggregation in " + dataCenter + "]"; + aggergateInstance.InstanceAlias = aggergateInstance.title; + } + aggergateInstance.canonicalTitle = aggergateInstance.title; + aggergateInstance.aggregatedInstances = instances; // includes itself + aggergateInstance.aggregatedProblems = aggregatedProblems; + aggergateInstance.aggregatedInstancesPattern = "(" + instanceFullNames.join("|") + ")"; + + instances.forEach(function(instance) { + if (!instance.isAggregate) { + parentInstance.children.remove(instance); + delete instancesMap[instance.id]; + } + }); + return true; + } + instances.forEach(function(instance) { + if (!instance.children) { + return false; + } + // Aggregating children who are childless + childlessChildren = instance.children.filter(function(child) { + return (!child.children || child.children.length == 0) + }); + + var dcInstances = {}; + childlessChildren.forEach(function(instance) { + if (!dcInstances[instance.DataCenter]) { + dcInstances[instance.DataCenter] = []; + } + dcInstances[instance.DataCenter].push(instance); + }); + for (var dc in dcInstances) { + if (dcInstances.hasOwnProperty(dc)) { + aggregateInstances(instance, dc, dcInstances[dc]) + } + } + return true; + }); + return instancesMap; + } + + function analyzeClusterInstances() { + var nodesMap = _instancesMap; + instances = [] + for (var nodeId in nodesMap) { + instances.push(nodesMap[nodeId]); + } + + instances.forEach(function(instance) { + if (!instance.hasConnectivityProblem) + return; + // The instance has a connectivity problem! Do a client-side recommendation of most advanced replica: + // a direct child of the master, with largest exec binlog coordinates. + var sortedChildren = instance.children.slice(); + sortedChildren.sort(compareInstancesExecBinlogCoordinates) + + instance.children.forEach(function(child) { + if (!child.hasConnectivityProblem) { + if (compareInstancesExecBinlogCoordinates(child, sortedChildren[sortedChildren.length - 1]) == 0) { + child.isMostAdvancedOfSiblings = true; + if (instance.isMaster && !instance.isCoMaster) { + // Moreover, the instance is the (only) master! + // Therefore its most advanced replicas are candidate masters + child.isCandidateMaster = true; + } + } + } + }); + }); + instances.forEach(function(instance) { + if (instance.children && instance.children.length > 0) { + instance.children[0].isFirstChildInDisplay = true + } + }); + } + + function preVisualizeInstances() { + var nodesMap = _instancesMap; + // DC colors + var knownDCs = []; + instances.forEach(function(instance) { + knownDCs.push(instance.DataCenter) + }); + + function uniq(a) { + return a.sort().filter(function(item, pos) { + return !pos || item != a[pos - 1]; + }) + } + knownDCs = uniq(knownDCs); + if (isColorizeDC() && !isAnonymized()) { + $('Data centers:').appendTo('#cluster_legend'); + } + for (i = 0; i < knownDCs.length; ++i) { + var color = renderColors[i % renderColors.length] + dcColorsMap[knownDCs[i]] = color; + if (isColorizeDC() && !isAnonymized() && knownDCs[i]) { + $('' + knownDCs[i] + '').addClass("dc").css('border-color', color).appendTo('#cluster_legend'); + } + } + } + + + function refreshClusterOperationModeButton() { + if (moveInstanceMethod == "smart") { + $("#move-instance-method-button").removeClass("btn-success").removeClass("btn-primary").removeClass("btn-warning").addClass("btn-info"); + } else if (moveInstanceMethod == "classic") { + $("#move-instance-method-button").removeClass("btn-info").removeClass("btn-primary").removeClass("btn-warning").addClass("btn-success"); + } else if (moveInstanceMethod == "gtid") { + $("#move-instance-method-button").removeClass("btn-success").removeClass("btn-info").removeClass("btn-warning").addClass("btn-primary"); + } else if (moveInstanceMethod == "pseudo-gtid") { + $("#move-instance-method-button").removeClass("btn-success").removeClass("btn-primary").removeClass("btn-info").addClass("btn-warning"); + } + $("#move-instance-method-button").html(moveInstanceMethod + ' mode ') + } + + // This is legacy and will be removed + function makeMaster(instance) { + var message = "Are you sure you wish to make " + instance.Key.Hostname + ":" + instance.Key.Port + " the new master?" + "

      Siblings of " + instance.Key.Hostname + ":" + instance.Key.Port + " will turn to be its children, " + "via Pseudo-GTID." + "

      The instance will be set to be writeable (read_only = 0)." + "

      Replication on this instance will be stopped, but not reset. You should run RESET SLAVE yourself " + "if this instance will indeed become the master." + "

      Pointing your application servers to the new master is on you."; + var apiUrl = "/api/make-master/" + instance.Key.Hostname + "/" + instance.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + //This is legacy and will be removed + function makeLocalMaster(instance) { + var message = "Are you sure you wish to make " + instance.Key.Hostname + ":" + instance.Key.Port + " a local master?" + "

      Siblings of " + instance.Key.Hostname + ":" + instance.Key.Port + " will turn to be its children, " + "via Pseudo-GTID." + "

      The instance will replicate from its grandparent."; + var apiUrl = "/api/make-local-master/" + instance.Key.Hostname + "/" + instance.Key.Port; + return executeMoveOperation(message, apiUrl); + } + + + function promptForAlias(oldAlias) { + bootbox.prompt({ + title: "Enter alias for this cluster", + value: oldAlias, + callback: function(result) { + if (result !== null) { + showLoader(); + getData("/api/set-cluster-alias/" + currentClusterName() + "?alias=" + encodeURIComponent(result), function(operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR") { + addAlert(operationResult.Message) + } else { + location.reload(); + } + }); + } + } + }); + } + + function showOSCReplicas() { + getData("/api/cluster-osc-replicas/" + currentClusterName(), function(instances) { + var instancesMap = normalizeInstances(instances, Array()); + var instancesTitles = Array(); + instances.forEach(function(instance) { + instancesTitles.push(instance.title); + }); + var instancesTitlesConcatenates = instancesTitles.join(" "); + bootbox.alert("Heuristic list of OSC controller replicas:

      " + instancesTitlesConcatenates + "
      "); + }); + } + + function anonymizeIfNeedBe(message) { + if (isAnonymized()) { + message = message.replace(/.*?<\/strong>/g, "############"); + } + return message; + } + + function addSidebarInfoPopoverContent(content, tag, hr) { + if (hr === true) { + content = '
      ' + content + } + wrappedContent = '
      ' + content + '
      '; + $("#cluster_info").append(wrappedContent) + } + + function populateSidebar(clusterInfo) { + var content = ''; + + { + var content = ''; + addSidebarInfoPopoverContent(content, "close", false); + $("#cluster_info button.close").click(function() { + $("#cluster_info").hide(); + }); + } + { + var content = currentClusterName(); + addSidebarInfoPopoverContent(content, "cluster-name", true); + } + { + var content = 'Alias: ' + clusterInfo.ClusterAlias + ''; + addSidebarInfoPopoverContent(content, "cluster-alias", true); + } { + var content = 'Domain: ' + clusterInfo.ClusterDomain + ''; + addSidebarInfoPopoverContent(content, "cluster-domain", true); + } + + var maxItems = 5 + getData("/api/audit-recovery/alias/" + clusterInfo.ClusterAlias, function(recoveries) { + recoveries = recoveries || [] + recoveries = recoveries.slice(0, maxItems) + if (recoveries.length > 0) { + var content = 'Recovery history'; + addSidebarInfoPopoverContent(content, "audit-recovery-title", true); + } + recoveries.forEach(function(recovery) { + var glyph = ''; + if (recovery.IsSuccessful === false) { + glyph = ''; + } + var content = '' + recovery.RecoveryStartTimestamp + ': ' + glyph + ' ' + recovery.AnalysisEntry.Analysis + addSidebarInfoPopoverContent(content, "audit-recovery", true); + }); + }); + getData("/api/audit-failure-detection/alias/" + clusterInfo.ClusterAlias, function(failureDetections) { + failureDetections = failureDetections || [] + failureDetections = failureDetections.slice(0, maxItems) + if (failureDetections.length > 0) { + var content = 'Failure detection'; + addSidebarInfoPopoverContent(content, "audit-detection-title", true); + } + failureDetections.forEach(function(failureDetection) { + var content = failureDetection.RecoveryStartTimestamp + ': ' + failureDetection.AnalysisEntry.Analysis + addSidebarInfoPopoverContent(content, "audit-detection", true); + }); + }); + // Colorize-dc + { + var glyph = $("#cluster_sidebar [data-bullet=colorize-dc] .glyphicon"); + if (isColorizeDC()) { + glyph.addClass("text-info"); + glyph.attr("title", "Disable colors"); + } else { + glyph.addClass("text-muted"); + glyph.attr("title", "Color by data center"); + } + } + // Compact display + { + var anchor = $("#cluster_sidebar [data-bullet=compact-display] a"); + var glyph = $(anchor).find(".glyphicon") + if (isCompactDisplay()) { + glyph.addClass("text-info"); + glyph.attr("title", "Disable compact display"); + } else { + glyph.addClass("text-muted"); + glyph.attr("title", "Enable compact display"); + } + } + // Pool indicator + { + var glyph = $("#cluster_sidebar [data-bullet=pool-indicator] .glyphicon"); + if ($.cookie("pool-indicator") == "true") { + glyph.addClass("text-info"); + glyph.attr("title", "Disable pool indication"); + } else { + glyph.addClass("text-muted"); + glyph.attr("title", "Enable pool indication"); + } + } + // Anonymize + { + var glyph = $("#cluster_sidebar [data-bullet=anonymize] .glyphicon"); + if (isAnonymized()) { + glyph.addClass("text-info"); + glyph.attr("title", "Cancel anonymize"); + } else { + glyph.addClass("text-muted"); + glyph.attr("title", "Anonymize display"); + } + } + // Alias + { + var glyph = $("#cluster_sidebar [data-bullet=alias] .glyphicon"); + var is = isAliased(); + glyph.addClass(is ? "text-info" : "text-muted"); + glyph.attr("title", is ? "Cancel alias" : "Instance alias display"); + } + // Silent UI + { + var glyph = $("#cluster_sidebar [data-bullet=silent-ui] .glyphicon"); + if (isSilentUI()) { + glyph.addClass("text-info"); + glyph.attr("title", "Cancel UI silence"); + } else { + glyph.addClass("text-muted"); + glyph.attr("title", "Silence UI questions"); + } + } + } + + function onAnalysisEntry(analysisEntry, instance) { + var glyph = ''; + var hasDowntime = analysisEntry.IsDowntimed || analysisEntry.IsReplicasDowntimed + if (analysisEntry.IsStructureAnalysis) { + glyph = ''; + } else { + glyph = ''; + } + var analysisContent = '
      ' + analysisEntry.Analysis + "
      "; + var extraText = ''; + if (analysisEntry.IsDowntimed) { + extraText = 'downtime till ' + analysisEntry.DowntimeEndTimestamp + ''; + } else if (analysisEntry.IsReplicasDowntimed) { + extraText = 'replicas downtimed'; + } + if (extraText != '') { + analysisContent += '
      ' + extraText + '
      '; + } + analysisContent += "
      " + analysisEntry.AnalyzedInstanceKey.Hostname + ":" + analysisEntry.AnalyzedInstanceKey.Port + "
      "; + var content = '
      '+glyph+'
      '+analysisContent+'
      '; + addSidebarInfoPopoverContent(content, "analysis", false); + if (analysisEntry.IsStructureAnalysis) { + return; + } + var popoverElement = getInstanceDiv(instance.id); + + popoverElement.append(''); + popoverElement.find(".popover-footer .dropdown").append(''); + popoverElement.find(".popover-footer .dropdown").append(''); + var recoveryListing = popoverElement.find(".dropdown ul"); + + if (instance.isMaster) { + recoveryListing.append('
    5. Force fail over now (even if normal handling would not fail over)
    6. '); + recoveryListing.append(''); + + // Suggest successor + instance.children.forEach(function(replica) { + if (!replica.LogBinEnabled) { + return + } + if (replica.SQLDelay > 0) { + return + } + if (!replica.LogReplicationUpdatesEnabled) { + return + } + if (replica.lastCheckInvalidProblem()) { + return + } + if (replica.notRecentlyCheckedProblem()) { + return + } + recoveryListing.append( + '
    7. Recover, try to promote ' + replica.title + '
    8. '); + }); + } + if (!instance.isMaster) { + recoveryListing.append('
    9. Auto (implies running external hooks/processes)
    10. '); + recoveryListing.append(''); + recoveryListing.append('
    11. Relocate replicas to ' + instance.masterTitle + '
    12. '); + } + if (instance.masterNode) { + // Intermediate master; suggest successor + instance.masterNode.children.forEach(function(sibling) { + if (sibling.id == instance.id) { + return + } + if (!sibling.LogBinEnabled) { + return + } + if (!sibling.LogReplicationUpdatesEnabled) { + return + } + if (sibling.lastCheckInvalidProblem()) { + return + } + if (sibling.notRecentlyCheckedProblem()) { + return + } + recoveryListing.append( + '
    13. Relocate replicas to ' + sibling.title + '
    14. '); + }); + } + } + + function reviewReplicationAnalysis(replicationAnalysis) { + var instancesMap = _instancesMap; + var clusterHasReplicationAnalysisIssue = false; + var allIssuesAreDowntimed = true; + var clusterHasStructureAnalysisIssue = false; + replicationAnalysis.Details.forEach(function(analysisEntry) { + if (analysisEntry.ClusterDetails.ClusterName != currentClusterName()) { + return; + } + var hasDowntime = analysisEntry.IsDowntimed || analysisEntry.IsReplicasDowntimed + if (!hasDowntime) { + allIssuesAreDowntimed = false; + } + var instanceId = getInstanceId(analysisEntry.AnalyzedInstanceKey.Hostname, analysisEntry.AnalyzedInstanceKey.Port); + var instance = instancesMap[instanceId] + if (analysisEntry.Analysis in interestingAnalysis) { + clusterHasReplicationAnalysisIssue = true; + onAnalysisEntry(analysisEntry, instance); + } + analysisEntry.StructureAnalysis = analysisEntry.StructureAnalysis || []; + analysisEntry.StructureAnalysis.forEach(function(structureAnalysis) { + clusterHasStructureAnalysisIssue = true; + analysisEntry.Analysis = structureAnalysis; + analysisEntry.IsStructureAnalysis = true; + onAnalysisEntry(analysisEntry, instance); + }); + }); + if (clusterHasReplicationAnalysisIssue) { + var iconClass = (allIssuesAreDowntimed ? "text-muted" : "text-danger"); + $("#cluster_sidebar [data-bullet=info] div span").addClass(iconClass).addClass("glyphicon-exclamation-sign");; + } else if (clusterHasStructureAnalysisIssue) { + var iconClass = (allIssuesAreDowntimed ? "text-muted" : "text-warning"); + $("#cluster_sidebar [data-bullet=info] div span").addClass(iconClass).addClass("glyphicon-exclamation-sign");; + } else { + $("#cluster_sidebar [data-bullet=info] div span").addClass("text-info").addClass("glyphicon-info-sign"); + } + } + + + function indicateClusterPoolInstances(clusterPoolInstances) { + var instancesMap = _instancesMap; + for (var pool in clusterPoolInstances.Details) { + if (clusterPoolInstances.Details.hasOwnProperty(pool)) { + clusterPoolInstances.Details[pool].forEach(function(instanceKey) { + var instanceId = getInstanceId(instanceKey.Hostname, instanceKey.Port) + var instance = instancesMap[instanceId]; + if (!instance.IsInPool) { + instance.IsInPool = true; + getInstanceDiv(instance.id).find("h3 div.pull-right").prepend(' '); + } + var indicatorElement = getInstanceDiv(instance.id).find("h3 div.pull-right span.glyphicon-tint"); + indicatorElement.attr("title", indicatorElement.attr("title") + " " + pool); + }); + } + } + } + + function main() { + $(domReady); + } + + function renderCluster() { + var instances = _instances; + var replicationAnalysis = _replicationAnalysis; + var maintenanceList = _maintenanceList; + _instancesMap = normalizeInstances(instances, maintenanceList); + if (isCompactDisplay()) { + _instancesMap = compactInstances(instances, _instancesMap); + } + analyzeClusterInstances(); + preVisualizeInstances(); + visualizeInstances(_instancesMap, generateInstanceDiv, _this); + wireInstanceCommands(); + + //prepareDraggable(); + + reviewReplicationAnalysis(replicationAnalysis); + + instances.forEach(function(instance) { + if (instance.isMaster) { + getData("/api/recently-active-instance-recovery/" + instance.Key.Hostname + "/" + instance.Key.Port, function(recoveries) { + if (!recoveries) { + return + } + // Result is an array: either empty (no active recovery) or with multiple entries + var recoveryEntry = recoveries[0]; + addInfo('' + instance.title + ' has just recently (' + recoveryEntry.RecoveryEndTimestamp + ') been promoted as result of ' + recoveryEntry.AnalysisEntry.Analysis + '. It may still take some time to rebuild topology graph.'); + }); + } + }); + if ($.cookie("pool-indicator") == "true") { + getData("/api/cluster-pool-instances/" + currentClusterName(), function(clusterPoolInstances) { + indicateClusterPoolInstances(clusterPoolInstances); + }); + } + if (reloadPageHint.hint == "refresh") { + var instanceId = getInstanceId(reloadPageHint.hostname, reloadPageHint.port); + var instance = _instancesMap[instanceId] + if (instance) { + openNodeModal(instance); + } + } + } + + function domReady() { + getData("/api/cluster/" + currentClusterName(), function(instances) { + _instances = instances; + getData("/api/replication-analysis/" + currentClusterName(), function(replicationAnalysis) { + _replicationAnalysis = replicationAnalysis; + getData("/api/maintenance", function(maintenanceList) { + _maintenanceList = maintenanceList; + $(document).trigger('orchestrator:preRenderCluster'); + renderCluster(); + $(document).trigger('orchestrator:postRenderCluster'); + }); + }); + }); + getData("/api/cluster-info/" + currentClusterName(), function(clusterInfo) { + var alias = clusterInfo.ClusterAlias + var visualAlias = (alias ? alias : currentClusterName()) + document.title = document.title.split(" - ")[0] + " - " + visualAlias; + + if (!isAnonymized()) { + $("#cluster_name").text(visualAlias); + var clusterSubtitle = ''; + if (clusterInfo.HasAutomatedMasterRecovery === true) { + clusterSubtitle += ''; + } else { + clusterSubtitle += ''; + } + if (clusterInfo.HasAutomatedIntermediateMasterRecovery === true) { + clusterSubtitle += ''; + } else { + clusterSubtitle += ''; + } + $("#cluster_subtitle").append(clusterSubtitle) + + + $("#dropdown-context").append('
    15. Alias: ' + alias + '
    16. '); + } + $("#dropdown-context").append('
    17. Pools
    18. '); + if (isCompactDisplay()) { + $("#dropdown-context").append('
    19. Compact display
    20. '); + } else { + $("#dropdown-context").append('
    21. Compact display
    22. '); + } + $("#dropdown-context").append('
    23. Pool indicator
    24. '); + $("#dropdown-context").append('
    25. Colorize DC
    26. '); + $("#dropdown-context").append('
    27. Anonymize
    28. '); + $("#dropdown-context").append('
    29. Alias
    30. '); + if ($.cookie("pool-indicator") == "true") { + $("#dropdown-context a[data-command=pool-indicator]").prepend(' '); + } + if (isAnonymized()) { + $("#dropdown-context a[data-command=anonymize]").prepend(' '); + } + if (isAliased()) { + $("#dropdown-context a[data-command=alias]").prepend(' '); + } + if (isColorizeDC()) { + $("#dropdown-context a[data-command=colorize-dc]").prepend(' '); + } + populateSidebar(clusterInfo); + }); + + getData("/api/active-cluster-recovery/" + currentClusterName(), function(recoveries) { + // Result is an array: either empty (no active recovery) or with multiple entries + recoveries.forEach(function(recoveryEntry) { + addInfo('' + recoveryEntry.AnalysisEntry.Analysis + ' active recovery in progress. Topology is subject to change in the next moments.'); + }); + }); + getData("/api/recently-active-cluster-recovery/" + currentClusterName(), function(recoveries) { + if (!recoveries) { + return + } + // Result is an array: either empty (no active recovery) or with multiple entries + var recoveryEntry = recoveries[0] + addInfo('This cluster just recently (' + recoveryEntry.RecoveryEndTimestamp + ') recovered from ' + recoveryEntry.AnalysisEntry.Analysis + '. It may still take some time to rebuild topology graph.'); + }); + getData("/api/blocked-recoveries/cluster/" + currentClusterName(), function(blockedRecoveries) { + // Result is an array: either empty (no active recovery) or with multiple entries + blockedRecoveries.forEach(function(blockedRecovery) { + addAlert('A ' + blockedRecovery.Analysis + ' on ' + getInstanceTitle(blockedRecovery.FailedInstanceKey.Hostname, blockedRecovery.FailedInstanceKey.Port) + ' is blocked due to a previous recovery'); + }); + }); + + $("#li-move-instance-method").appendTo("ul.navbar-nav").show(); + $("#move-instance-method a").click(function() { + moveInstanceMethod = $(this).attr("data-method"); + refreshClusterOperationModeButton(); + $.cookie("move-instance-method", moveInstanceMethod, { + path: '/', + expires: 1 + }); + }); + $("#instance_problems_button").attr("title", "Cluster Problems"); + + $("body").on("click", "a[data-command=change-cluster-alias]", function(event) { + promptForAlias($(event.target).attr("data-alias")); + }); + $("body").on("click", "a[data-command=cluster-osc-replicas]", function(event) { + showOSCReplicas(); + }); + $("body").on("click", "a[data-command=pool-indicator]", function(event) { + if ($.cookie("pool-indicator") == "true") { + $.cookie("pool-indicator", "false", { + path: '/', + expires: 1 + }); + location.reload(); + return + } + $.cookie("pool-indicator", "true", { + path: '/', + expires: 1 + }); + location.reload(); + }); + $("body").on("click", "a[data-command=anonymize]", function(event) { + if (isAnonymized()) { + $.cookie("anonymize", "false", { + path: '/', + expires: 1 + }); + location.reload(); + return + } + $.cookie("anonymize", "true", { + path: '/', + expires: 1 + }); + location.reload(); + }); + $("body").on("click", "a[data-command=alias]", function(event) { + $.cookie("alias", isAliased() ? "false" : "true", { + path: '/', + expires: 1 + }); + location.reload(); + }); + $("body").on("click", "a[data-command=info]", function(event) { + $("#cluster_info").toggle(); + return false + }); + $("body").on("click", "a[data-command=colorize-dc]", function(event) { + if (isColorizeDC()) { + $.cookie("colorize-dc", "false", { + path: '/', + expires: 1 + }); + } else { + $.cookie("colorize-dc", "true", { + path: '/', + expires: 1 + }); + } + location.reload(); + return + }); + $("body").on("click", "a[data-command=compact-display]", function(event) { + if ($.cookie("compact-display") == "true") { + $.cookie("compact-display", "false", { + path: '/', + expires: 1 + }); + } else { + $.cookie("compact-display", "true", { + path: '/', + expires: 1 + }); + } + location.reload(); + return + }); + $("body").on("click", "a[data-command=silent-ui]", function(event) { + if ($.cookie("silent-ui") == "true") { + $.cookie("silent-ui", "false", { + path: '/', + expires: 1 + }); + } else { + $.cookie("silent-ui", "true", { + path: '/', + expires: 1 + }); + } + location.reload(); + return + }); + + $("[data-toggle=popover]").popover(); + $("[data-toggle=popover]").show(); + + if (isAuthorizedForAction()) { + // Read-only users don't get auto-refresh. Sorry! + activateRefreshTimer(); + } + refreshClusterOperationModeButton(); + } + + $(document).keyup(function(e) { + if (e.keyCode == 27) { + $("#cluster_info").hide(); + } + }); + + function getData(url, cb) { + $.get(appUrl(url), cb, "json"); + } + + +} + +function getHtmlPos(el) { + return { + left: el.offsetLeft, + top: el.offsetTop + }; +} + +function getSvgPos(el) { + var svg = $(el).closest("svg")[0]; + if (!svg) { + return false; + } + var pt = svg.createSVGPoint(); + var matrix = el.getCTM(); + var box = el.getBBox(); + pt.x = box.x; + pt.y = box.y; + var pt2 = pt.matrixTransform(matrix); + return { + left: pt2.x, + top: pt2.y + }; +} + +var _page = new Cluster(); diff --git a/web/orchestrator/public/js/clusters-analysis.js b/web/orchestrator/public/js/clusters-analysis.js new file mode 100644 index 00000000000..74b7e9d335e --- /dev/null +++ b/web/orchestrator/public/js/clusters-analysis.js @@ -0,0 +1,141 @@ +$(document).ready(function() { + showLoader(); + + $.get(appUrl("/api/clusters-info"), function(clusters) { + clusters = clusters || []; + $.get(appUrl("/api/replication-analysis"), function(replicationAnalysis) { + $.get(appUrl("/api/blocked-recoveries"), function(blockedRecoveries) { + blockedRecoveries = blockedRecoveries || []; + displayClustersAnalysis(clusters, replicationAnalysis, blockedRecoveries); + }, "json"); + }, "json"); + }, "json"); + $.get(appUrl("/api/blocked-recoveries"), function(blockedRecoveries) { + blockedRecoveries = blockedRecoveries || []; + // Result is an array: either empty (no active recovery) or with multiple entries + blockedRecoveries.forEach(function(blockedRecovery) { + addAlert('A ' + blockedRecovery.Analysis + ' on ' + getInstanceTitle(blockedRecovery.FailedInstanceKey.Hostname, blockedRecovery.FailedInstanceKey.Port) + ' is blocked due to a previous recovery'); + }); + }); + + function sortByCountInstances(cluster1, cluster2) { + if (cluster2.allAnalysisDowntimed && !cluster1.allAnalysisDowntimed) { + return 1 + } + if (cluster1.allAnalysisDowntimed && !cluster2.allAnalysisDowntimed) { + return 1 + } + var diff = cluster2.CountInstances - cluster1.CountInstances; + if (diff != 0) { + return diff; + } + return cluster1.ClusterName.localeCompare(cluster2.ClusterName); + } + + function getBlockedRecoveryKey(hostname, port, analysis) { + return hostname + ":" + port + ":" + analysis; + } + + function displayClustersAnalysis(clusters, replicationAnalysis, blockedRecoveries) { + hideLoader(); + + var clustersMap = {}; + clusters.forEach(function(cluster) { + cluster.analysisEntries = Array(); + cluster.allAnalysisDowntimed = true; + clustersMap[cluster.ClusterName] = cluster; + }); + + // Apply/associate analysis to clusters + replicationAnalysis.Details.forEach(function(analysisEntry) { + if (analysisEntry.Analysis in interestingAnalysis) { + clustersMap[analysisEntry.ClusterDetails.ClusterName].analysisEntries.push(analysisEntry); + if (!analysisEntry.IsDowntimed) { + clustersMap[analysisEntry.ClusterDetails.ClusterName].allAnalysisDowntimed = false; + } + } + analysisEntry.StructureAnalysis = analysisEntry.StructureAnalysis || []; + analysisEntry.StructureAnalysis.forEach(function(structureAnalysis) { + analysisEntry.Analysis = structureAnalysis; + analysisEntry.IsStructureAnalysis = true; + clustersMap[analysisEntry.ClusterDetails.ClusterName].analysisEntries.push(analysisEntry); + }); + }); + // Only keep clusters with some analysis (the rest are fine, no need to include them) + clusters = clusters.filter(function(cluster) { + return (cluster.analysisEntries.length > 0); + }); + + + var blockedrecoveriesMap = {} + blockedRecoveries.forEach(function(blockedRecovery) { + var blockedKey = getBlockedRecoveryKey(blockedRecovery.FailedInstanceKey.Hostname, blockedRecovery.FailedInstanceKey.Port, blockedRecovery.Analysis); + blockedrecoveriesMap[blockedKey] = true; + }); + + function displayInstancesBadge(popoverElement, text, count, badgeClass, title) { + popoverElement.find(".popover-content>div").append('
      ' + text + ':
      ' + count + '
      '); + } + + function displayAnalysisEntry(analysisEntry, popoverElement) { + var blockedKey = getBlockedRecoveryKey(analysisEntry.AnalyzedInstanceKey.Hostname, analysisEntry.AnalyzedInstanceKey.Port, analysisEntry.Analysis); + var displayText = '
      ' + analysisEntry.Analysis + (analysisEntry.IsDowntimed ? '
      [downtime till ' + analysisEntry.DowntimeEndTimestamp + ']' : '') + (blockedrecoveriesMap[blockedKey] ? '
      Blocked' : '') + "
      " + "
      " + "" + analysisEntry.AnalyzedInstanceKey.Hostname + ":" + analysisEntry.AnalyzedInstanceKey.Port + ""; + if (analysisEntry.IsDowntimed) { + displayText = '
      ' + displayText + '
      '; + } else if (blockedrecoveriesMap[blockedKey]) { + displayText = '
      ' + displayText + '
      '; + } + popoverElement.find(".popover-content>div").append('
      ' + displayText + '
      '); + if (analysisEntry.IsStructureAnalysis) { + displayInstancesBadge(popoverElement, "Participating replicas", analysisEntry.CountReplicas, "label-warning", "Replicas having structural issue"); + } else { + displayInstancesBadge(popoverElement, "Affected replicas", analysisEntry.CountReplicas, "label-danger", "Direct replicas of failing instance"); + } + } + + function displayCluster(cluster) { + $("#clusters_analysis").append(''); + var popoverElement = $("#clusters_analysis [data-cluster-name='" + cluster.ClusterName + "'].popover"); + + if (typeof removeTextFromHostnameDisplay != "undefined" && removeTextFromHostnameDisplay()) { + var title = cluster.ClusterName.replace(removeTextFromHostnameDisplay(), ''); + popoverElement.find("h3 .pull-left a span").html(title); + } + if (cluster.ClusterAlias != "") { + popoverElement.find("h3 .pull-left a span").addClass("small"); + popoverElement.find("h3 .pull-left").prepend('' + cluster.ClusterAlias + '
      '); + popoverElement.find("h3 .pull-right").append(''); + } + displayInstancesBadge(popoverElement, "Instances", cluster.CountInstances, "label-primary", "Total instances in cluster"); + + cluster.analysisEntries.forEach(function(analysisEntry) { + displayAnalysisEntry(analysisEntry, popoverElement); + }); + } + + clusters.sort(sortByCountInstances); + clusters.forEach(function(cluster) { + displayCluster(cluster); + }); + + if (clusters.length == 0) { + // No problems + var info = "No incidents which require a failover to report. Orchestrator reports the following incidents:
        "; + for (var analysis in interestingAnalysis) { + if (interestingAnalysis[analysis]) { + info += "
      • " + analysis + "
      • "; + } + } + info += "
      "; + addInfo(info); + } + + $("div.popover").popover(); + $("div.popover").show(); + } + + if (isAuthorizedForAction()) { + // Read-only users don't get auto-refresh. Sorry! + activateRefreshTimer(); + } +}); diff --git a/web/orchestrator/public/js/clusters.js b/web/orchestrator/public/js/clusters.js new file mode 100644 index 00000000000..d32fa03f1f6 --- /dev/null +++ b/web/orchestrator/public/js/clusters.js @@ -0,0 +1,156 @@ +$(document).ready(function() { + showLoader(); + + $.get(appUrl("/api/clusters-info"), function(clusters) { + $.get(appUrl("/api/replication-analysis"), function(replicationAnalysis) { + $.get(appUrl("/api/problems"), function(problemInstances) { + if (problemInstances == null) { + problemInstances = []; + } + normalizeInstances(problemInstances, []); + displayClusters(clusters, replicationAnalysis, problemInstances); + }, "json"); + }, "json"); + }, "json"); + + function sortByCountInstances(cluster1, cluster2) { + var diff = cluster2.CountInstances - cluster1.CountInstances; + if (diff != 0) { + return diff; + } + return cluster1.ClusterName.localeCompare(cluster2.ClusterName); + } + + function sortByClusterName(cluster1, cluster2) { + return cluster1.ClusterName.localeCompare(cluster2.ClusterName); + } + + function sortByClusterAlias(cluster1, cluster2) { + return cluster1.ClusterAlias.localeCompare(cluster2.ClusterAlias); + } + + function displayClusters(clusters, replicationAnalysis, problemInstances) { + hideLoader(); + + clusters = clusters || []; + + var dashboardSort = $.cookie("dashboard-sort") || "count" + + refreshDashboardSortButton(); + $("#li-dashboard-sort").appendTo("ul.navbar-nav").show(); + $("#dashboard-sort a").click(function() { + $.cookie("dashboard-sort", $(this).attr("dashboard-sort"), { + path: '/', + expires: 3650 + }); + location.reload(); + }); + + var clustersProblems = {}; + clusters.forEach(function(cluster) { + clustersProblems[cluster.ClusterName] = {}; + }); + + var clustersAnalysisProblems = {}; + replicationAnalysis.Details.forEach(function(analysisEntry) { + if (!clustersAnalysisProblems[analysisEntry.ClusterDetails.ClusterName]) { + clustersAnalysisProblems[analysisEntry.ClusterDetails.ClusterName] = []; + } + if (analysisEntry.Analysis in interestingAnalysis) { + clustersAnalysisProblems[analysisEntry.ClusterDetails.ClusterName].push(analysisEntry); + } + analysisEntry.StructureAnalysis = analysisEntry.StructureAnalysis || []; + analysisEntry.StructureAnalysis.forEach(function(structureAnalysis) { + analysisEntry.Analysis = structureAnalysis; + analysisEntry.IsStructureAnalysis = true; + clustersAnalysisProblems[analysisEntry.ClusterDetails.ClusterName].push(analysisEntry); + }); + }); + + function refreshDashboardSortButton() { + if (dashboardSort == "name") { + clusters.sort(sortByClusterName); + } else if (dashboardSort == "alias") { + clusters.sort(sortByClusterAlias); + } else { + clusters.sort(sortByCountInstances); + } + + $("#dashboard-sort-button").html("Sort by " + dashboardSort + ' ') + } + + function addInstancesBadge(clusterName, count, badgeClass, title) { + $("#clusters [data-cluster-name='" + clusterName + "'].popover").find(".popover-content .pull-right").append('' + count + ' '); + } + + function incrementClusterProblems(clusterName, problemType) { + if (!problemType) { + return + } + if (clustersProblems[clusterName][problemType] > 0) { + clustersProblems[clusterName][problemType] = clustersProblems[clusterName][problemType] + 1; + } else { + clustersProblems[clusterName][problemType] = 1; + } + } + problemInstances.forEach(function(instance) { + incrementClusterProblems(instance.ClusterName, instance.problem) + }); + + clusters.forEach(function(cluster) { + $("#clusters").append(''); + var popoverElement = $("#clusters [data-cluster-name='" + cluster.ClusterName + "'].popover"); + + if (typeof removeTextFromHostnameDisplay != "undefined" && removeTextFromHostnameDisplay()) { + var title = cluster.ClusterName.replace(removeTextFromHostnameDisplay(), ''); + popoverElement.find("h3 .pull-left a span").html(title); + } + var compactClusterUri = appUrl('/web/cluster/' + cluster.ClusterName + '?compact=true'); + if (cluster.ClusterAlias) { + popoverElement.find("h3 .pull-left a span").addClass("small"); + popoverElement.find("h3 .pull-left").prepend('' + cluster.ClusterAlias + '
      '); + compactClusterUri = appUrl('/web/cluster/alias/' + encodeURIComponent(cluster.ClusterAlias) + '?compact=true'); + } + if (clustersAnalysisProblems[cluster.ClusterName]) { + clustersAnalysisProblems[cluster.ClusterName].forEach(function(analysisEntry) { + var analysisLabel = "text-danger"; + if (analysisEntry.IsStructureAnalysis) { + analysisLabel = "text-warning"; + } + var hasDowntime = analysisEntry.IsDowntimed || analysisEntry.IsReplicasDowntimed + if (hasDowntime) { + analysisLabel = "text-muted"; + } + popoverElement.find("h3 .pull-left").prepend(''); + }); + + } + popoverElement.find("h3 .pull-right").append(''); + if (cluster.HasAutomatedIntermediateMasterRecovery === true) { + popoverElement.find("h3 .pull-right").prepend(''); + } + if (cluster.HasAutomatedMasterRecovery === true) { + popoverElement.find("h3 .pull-right").prepend(''); + } + + var contentHtml = '' + '
      Instances:
      '; + popoverElement.find(".popover-content").html(contentHtml); + addInstancesBadge(cluster.ClusterName, cluster.CountInstances, "label-primary", "Total instances in cluster"); + for (var problemType in clustersProblems[cluster.ClusterName]) { + addInstancesBadge(cluster.ClusterName, clustersProblems[cluster.ClusterName][problemType], errorMapping[problemType]["badge"], errorMapping[problemType]["description"]); + } + }); + + $("div.popover").popover(); + $("div.popover").show(); + + if (clusters.length == 0) { + addAlert("No clusters found"); + } + } + + if (isAuthorizedForAction()) { + // Read-only users don't get auto-refresh. Sorry! + activateRefreshTimer(); + } +}); diff --git a/web/orchestrator/public/js/common.js b/web/orchestrator/public/js/common.js new file mode 100644 index 00000000000..546294a5bc9 --- /dev/null +++ b/web/orchestrator/public/js/common.js @@ -0,0 +1,6 @@ +function Instance(){ + +} +Instance.createElement = function (instance){ + return $('

      '); +} \ No newline at end of file diff --git a/web/orchestrator/public/js/corex-jquery.js b/web/orchestrator/public/js/corex-jquery.js new file mode 100644 index 00000000000..92f759266c8 --- /dev/null +++ b/web/orchestrator/public/js/corex-jquery.js @@ -0,0 +1,148 @@ +function jQueryHelper() { + Function.addTo(jQueryHelper, [parseSelector, createElementFromSelectorNode, getOrAppendChildBySelector, createElementFromSelector]); + + function parseSelector(s) { + var sizzle = jQuery.find; + var groups = sizzle.tokenize(s); + return groups; + } + + function createElementFromSelector(selector) { + var nodes = parseSelector(selector); + return createElementFromSelectorNode(nodes[0]); + } + function createElementFromSelectorNode(node) { + var tagName = "div"; + var tagToken = node.first(function (t) { return t.type == "TAG"; }); + if (tagToken != null) + tagName = tagToken.value; + + var idToken = node.first(function (t) { return t.type == "ID"; }); + var el = $("<" + tagName + "/>"); + if (idToken != null) + el.attr("id", idToken.value.substr(1)); + + var atts = node.whereEq("type", "ATTR").select(function (t) { return t.value.substr(1, t.value.length - 2).split('='); }); + if (atts.length > 0) { + atts.forEach(function (att) { + el.attr(att[0], att[1]); + }); + } + + var classes = node.whereEq("type", "CLASS").select(function (t) { return t.value.substr(1); }); + if (classes.length > 0) + el.addClass(classes.join(" ")); + + return el; + } + + function getOrAppendChildBySelector(parentEl, selector, options) { + var childEls = parentEl.children(selector).toArray(); + var total = null; + var list = null; + var action = null; + var storeDataItem = false; + var removeRemaining = false; + if (options != null) { + if (options.total != null) + total = options.total; + if (options.list != null) { + list = options.list; + if (total == null) + total = list.length; + } + action = options.action; + storeDataItem = options.storeDataItem; + removeRemaining = options.removeRemaining; + } + if (total == null) + total = 1; + + var index = childEls.length; + + if (action != null || storeDataItem) { + var min = Math.min(index, total); + if (list == null) + list = []; + for (var i = 0; i < min; i++) { + var child = $(childEls[i]); + var dataItem = list[i]; + if (storeDataItem) + child.data("DataItem", dataItem); + if (action != null) + action(child, dataItem, index); + } + } + if (index < total) { + var selectorNodes = parseSelector(selector); + if (selectorNodes.length != 1) + throw new Error(); + var selectorNode = selectorNodes[0]; + while (index < total) { + var dataItem = list != null ? list[index] : null; + var child = createElementFromSelectorNode(selectorNode); + var childEl = child[0]; + parentEl.append(childEl); + childEls.push(childEl); + if (storeDataItem) + child.data("DataItem", dataItem); + if (action != null) + action(child, dataItem, index); + index++; + } + } + if (removeRemaining) { + while (childEls.length > total) { + var parentEl = childEls.pop(); + $(parentEl).remove(); + } + } + return $(childEls); + } +} +jQueryHelper(); + +jQuery.fn.getAppend = function (selector, options) { + return jQueryHelper.getOrAppendChildBySelector(this, selector, options); +} +jQuery.fn.getAppendRemove = function (selector, total) { + if (typeof (total) == "boolean") + total = total ? 1 : 0; + return jQueryHelper.getOrAppendChildBySelector(this, selector, { total: total, removeRemaining: true }); +} +jQuery.fn.getAppendRemoveForEach = function (selector, list, action, options) { + if (options == null) + options = {}; + options.list = list; + options.action = action; + options.removeRemaining = true; + return jQueryHelper.getOrAppendChildBySelector(this, selector, options); +} +jQuery.create = function (selector) { + return jQueryHelper.createElementFromSelector(selector); +} + +//binds a container's children selector to a list, matching the number of elements to the list.length (creating/deleting elements where needed), optionally performing action(el, dataItem, index) on each element +//returns a new jQuery object containing all children relevant to the selector +jQuery.fn.bindChildrenToList = function (selector, list, action, options) { + if (options == null) + options = {}; + options.list = list; + options.action = action; + options.storeDataItem = true; + options.removeRemaining = true; + return jQueryHelper.getOrAppendChildBySelector(this, selector, options); +} + +//Turns a jquery object to an array of single jquery objects +jQuery.fn.toArray$ = function (action) { + var list = []; + for (var i = 0; i < this.length; i++) + list.push($(this[i])); + return list; +} + +//Turns an array of jquery objects to a single jquery object +jQuery.fromArray$ = function (list) { + return $(list.selectMany(function (j) { return j.toArray(); })); +} diff --git a/web/orchestrator/public/js/corex.js b/web/orchestrator/public/js/corex.js new file mode 100644 index 00000000000..2538c9cdcdb --- /dev/null +++ b/web/orchestrator/public/js/corex.js @@ -0,0 +1,2112 @@ + +//******** Object +(function () { + Object.toArray = function (obj) { + var list = []; + for (var p in obj) { + list.push(p, obj[p]); + } + return list; + } + Object.allKeys = function (obj) { + var list = []; + for (var p in obj) { + list.push(p); + } + return list; + } + Object.keysValues = function (obj) { + var list = []; + for (var p in obj) { + list.push({ key: p, value: obj[p] }); + } + return list; + } + Object.pairs = function (obj) { + var list = []; + list.isArrayOfPairs = true; + for (var p in obj) { + list.push([p, obj[p]]); + } + return list; + } + Object.fromPairs = function (keysValues) { + var obj = {}; + keysValues.forEach(function (pair) { + obj[pair[0]] = pair[1]; + }); + return obj; + } + Object.fromKeysValues = function (keysValues) { + var obj = {}; + keysValues.forEach(function (keyValue) { + obj[keyValue.key] = keyValue.value; + }); + return obj; + } + Object.reversePairs = function (obj) { + var list = []; + for (var i = 0; i < obj.length; i++) { + list.push([obj[i][1], obj[i][0]]); + } + return list; + } + Object.forEach = function (obj, keyValueAction) { + Object.keys(obj).forEach(function (p) { + keyValueAction(p, obj[p]); + }); + } + Object.toSortedByKey = function (obj) { + var sortedKeys = Object.keys(obj).sort(); + return sortedKeys.toObject(function (key) { return [key, obj[key]]; }) + } + Object.getCreateArray = function (obj, p) { + var value = obj[p]; + if (value == null) { + value = []; + obj[p] = value; + } + return value; + } + Object.jsonStringifyEquals = function (x, y) { + return JSON.stringify(x) == JSON.stringify(y); + } + Object.tryGet = function (obj, indexers) { + if (typeof (indexers) == "string") + indexers = indexers.split("."); + var value = obj; + for (var i = 0; i < indexers.length; i++) { + if (value == null) + return null; + value = value[indexers[i]]; + } + return value; + } + Object.trySet = function (obj, indexers, value) { + if (typeof (indexers) == "string") + indexers = indexers.split("."); + var obj2 = obj; + if (indexers.length > 1) { + obj2 = Object.tryGet(obj, indexers.take(indexers.length - 1)); + } + if (obj2 == null) + return; + obj2[indexers[indexers.length - 1]] = value; + } + Object.select = function (obj, selector) { + return Q.createSelectorFunction(selector)(obj); + } + ///Deletes all keys in obj that have the same value: Object.delete({a:"b", c:"d"}, {a:"b", c:"g"}) => {c:"d"}; + Object.deleteKeysWithValues = function (obj, keysValues) { + Object.keys(keysValues).forEach(function (key) { + var value = keysValues[key]; + if (obj[key] == value) + delete obj[key]; + }); + } + + var __hashKeyIndex = 0; + Object.getHashKey = function (obj) { + if (obj == null) + return null; + var x = obj.valueOf(); + var type = typeof (x); + if (type == "number") + return x.toString(); + if (type == "string") + return x; + if (x.__hashKey == null) { + x.__hashKey = "\0" + "_" + x.constructor.name + "_" + __hashKeyIndex++; + } + return x.__hashKey + } + Object.values = function (obj) { + var list = []; + for (var p in obj) { + list.push(obj[p]); + } + return list; + } + + Object.removeAll = function (obj, predicate) { + var toRemove = []; + Object.forEach(obj, function (key, value) { + if (predicate(key, value)) + toRemove.push(key); + }); + toRemove.forEach(function (t) { delete obj[t]; }); + } + + Object.clear = function (obj) { + Object.keys(obj).forEach(function (p) { delete obj[p]; }); + } + +})(); + + +//******** Function +(function () { + + //Acts like Function.prototype.bind, but preserves the 'this' context that is being sent to the newly generated function. + //function Hello(a,b,c){return [a,b,c].join();} + //Hello.bindArgs("a")("b","c") -> a,b,c + Function.prototype.bindArgs = function () { + var args = Array.from(arguments); + var func = this; + return function () { + var args2 = args.concat(Array.from(arguments)); + return func.apply(this, args2); + }; + } + //String.hello(a,b,c) -> String.prototype.hello(b,c) (a=this) + Function.prototype.toPrototypeFunction = function () { + var func = this; + return function () { + var args2 = Array.from(arguments); + args2.insert(0, this); + return func.apply(null, args2); + }; + } + //String.prototype.hello(b,c) -> String.hello(a,b,c) (a=this) + Function.prototype.toStaticFunction = function () { + return Function.prototype.call.bind(this); + } + //converts a constructor to a function that doesn't require the new operator + Function.prototype.toNew = function () { + var func = this; + return function () { + var x = func.applyNew(Array.from(arguments)); + return x; + }; + } + // Similar to func.apply(thisContext, args), but creates a new object instead of just calling the function - new func(args[0], args[1], args[2]...) + Function.prototype.applyNew = function (args) { + var count = args == null ? 0 : args.length; + var ctor = this; + switch (count) { + case 0: return new ctor(); + case 1: return new ctor(args[0]); + case 2: return new ctor(args[0], args[1]); + case 3: return new ctor(args[0], args[1], args[2]); + case 4: return new ctor(args[0], args[1], args[2], args[3]); + case 5: return new ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + throw new Error("Function.prototype.applyNew doesn't support more than 8 parameters"); + } + // Similar to func.call(thisContext, args), but creates a new object instead of just calling the function - new func(arguments[0], arguments[1], arguments[2]...) + Function.prototype.callNew = function (varargs) { + var args = Array.from(arguments); + return this.applyNew(args); + } + Function.prototype.getName = function () { + var func = this; + if (func.name != null) + return func.name; + var name = func.toString().substringBetween("function ", "(").trim(); + func.name = name; + return name; + } + Function.prototype.addTo = function (target) { + return Function.addTo(target, [this]); + } + // Creates a combination of two functions, where the new function will invoke the two functions, if the left side is already a combination function, it will be cloned and add the new function to it + Function.combine = function (f1, f2) { + if (f1 == null) + return f2; + if (f2 == null) + return f1; + var funcs; + if (f1._isCombined) { + var funcs = f1._funcs.toArray(); + funcs.add(f2); + } + else { + funcs = [f1, f2]; + } + return Function._combined(funcs); + } + Function._combined = function (funcs) { + var func = function () { + for (var i = 0; i < func._funcs.length; i++) + func._funcs[i].apply(this, arguments); + } + func._isCombined = true; + func._funcs = funcs; + return func; + } + + + Function._lambda_cache = {}; + Function.lambda = function (exp) { + var cache = Function._lambda_cache; + var func = cache[exp]; + if (func == null) { + func = Function._lambda(exp); + cache[exp] = func; + } + return func; + } + Function._lambda = function (exp) { + var arrow = exp.indexOf("=>"); + var prms; + var body; + if (arrow > 0) { + var tPrms = exp.substring(0, arrow).replace("(", "").replace(")", ""); + prms = tPrms.split(",").map(function (t) { return t.trim(); }); + body = exp.substring(arrow + 2); + } + else { + prms = []; + body = exp; + } + if (!body.contains("return")) + body = "return " + body + ";"; + prms.push(body); + return Function.applyNew(prms); + } + Function.addTo = function (target, funcs) { + funcs = Array.wrapIfNeeded(funcs); + funcs.forEach(function (func) { + target[func.getName()] = func; + }); + } + +})(); + + +//******** Array +(function () { + + + //Array Extensions + Array.prototype.forEachJoin = function (action, actionBetweenItems) { + var first = true; + for (var i = 0; i < this.length; i++) { + if (first) + first = false; + else + actionBetweenItems(); + action(this[i]); + } + } + Array.prototype.first = function (predicate) { + if (predicate == null) + return this[0]; + for (var i = 0; i < this.length; i++) { + if (predicate(this[i])) + return this[i]; + } + return null; + } + Array.prototype.toArray = function () { + return this.slice(0); + } + Array.prototype.insert = function (index, item) { + this.splice(index, 0, item); + } + Array.prototype.insertRange = function (index, items) { + var args = items.toArray(); + args.insert(0, 0); + args.insert(0, index); + this.splice.apply(this, args); + } + Array.prototype.last = function (predicate) { + var len = this.length; + if (len == 0) + return null; + if (predicate == null) + return this[len - 1]; + for (var i = len - 1; i >= 0; i--) { + if (predicate(this[i])) + return this[i]; + } + return null; + } + Array.prototype.toObject = function (selector) { + if (selector == null) { + return this.copyPairsToObject(); + } + var obj = {}; + for (var i = 0; i < this.length; i++) { + var obj2 = selector(this[i]); + if (obj2 instanceof Array) + obj2.copyPairsToObject(obj); + else { + for (var p in obj2) + obj[p] = obj2[p]; + } + } + return obj; + }; + Array.prototype.toObjectKeys = function (defaultValue) { + var obj = {}; + for (var i = 0; i < this.length; i++) { + var p = this[i]; + obj[p] = defaultValue; + } + return obj; + }; + Array.prototype.keysToObject = Array.prototype.toObjectKeys; + Array.prototype.pairsToObject = Array.prototype.toObject; + Array.prototype.copyPairsToObject = function (obj) { + if (obj == null) + obj = {}; + for (var i = 0; i < this.length; i += 2) { + obj[this[i]] = this[i + 1]; + } + return obj; + }; + Array.prototype.removeFirst = function () { + return this.splice(0, 1)[0]; + } + Array.prototype.remove = function (item) { + for (var i = 0; i < this.length; i++) { + if (this[i] === item) { + this.removeAt(i); + return true; + } + } + return false; + } + Array.prototype.removeRange = function (items) { + items.forEach(function (t) { this.remove(t); }); + } + Array.prototype.contains = function (s) { + return this.indexOf(s) >= 0; + } + Array.prototype.containsAny = function (items) { + return items.any(function (t) { return this.contains(t); }.bind(this)); + } + Array.prototype.any = function (predicate) { + return this.some(Q.createSelectorFunction(predicate)); + } + Array.prototype.distinct = function (keyGen) { + if (keyGen == null) + keyGen = Object.getHashKey; + var list = []; + var set = {}; + this.forEach(function (t) { + var key = keyGen(t); + if (set[key]) + return; + set[key] = true; + list.push(t); + }); + return list; + } + Array.prototype.removeAll = function (predicate) { + var toRemove = []; + for (var i = 0; i < this.length; i++) { + if (predicate(this[i])) { + toRemove.push(i); + } + } + while (toRemove.length > 0) { + var index = toRemove.pop(); + this.removeAt(index); + } + } + Array.prototype.removeAt = function (index) { + this.splice(index, 1); + } + ///Iterates over the array, performing an async function for each item, going to the next one only when the previous one has finished (called his callback) + Array.prototype.forEachAsyncProgressive = function (actionWithCallback, finalCallback) { + this._forEachAsyncProgressive(actionWithCallback, finalCallback, 0); + } + Array.prototype.where = function (predicate) { + return this.filter(Q.createSelectorFunction(predicate)); + } + Array.prototype.whereEq = function (selector, value) { + selector = Q.createSelectorFunction(selector); + return this.filter(function (t, i) { return selector(t, i) == value; }); + } + Array.prototype.whereNotEq = function (selector, value) { + selector = Q.createSelectorFunction(selector); + return this.filter(function (t, i) { return selector(t, i) != value; }); + } + Array.prototype.firstEq = function (selector, value) { + selector = Q.createSelectorFunction(selector); + return this.first(function (t, i) { return selector(t, i) == value; }); + } + Array.prototype.firstNotEq = function (selector, value) { + selector = Q.createSelectorFunction(selector); + return this.first(function (t, i) { return selector(t, i) != value; }); + } + Array.prototype.addRange = function (items) { + this.push.apply(this, items); + } + Array.prototype.diff = function (target) { + var source = this; + var res = { + added: source.where(function (t) { return !target.contains(t); }), + removed: target.where(function (t) { return !source.contains(t); }), + }; + return res; + } + Array.prototype.hasDiff = function (target) { + var diff = this.diff(target); + return diff.added.length > 0 || diff.removed.length > 0; + } + Array.prototype._forEachAsyncProgressive = function (actionWithCallback, finalCallback, index) { + if (index == null) + index = 0; + if (index >= this.length) { + if (finalCallback != null) + finalCallback(); + return; + } + var item = this[index]; + actionWithCallback(item, function () { this._forEachAsyncProgressive(actionWithCallback, finalCallback, index + 1); }.bind(this)); + } + /// Iterates over the array, performing an async function for each item, going to the next one only when the previous one has finished (called his callback) + Array.prototype.mapAsyncProgressive = function (actionWithCallback, finalCallback) { + this._mapAsyncProgressive(actionWithCallback, finalCallback, 0, []); + } + Array.prototype._mapAsyncProgressive = function (actionWithCallbackWithResult, finalCallback, index, results) { + if (index == null) + index = 0; + if (index >= this.length) { + if (finalCallback != null) + finalCallback(results); + return; + } + var item = this[index]; + actionWithCallbackWithResult(item, function (res) { + results.push(res); + this._mapAsyncProgressive(actionWithCallbackWithResult, finalCallback, index + 1, results); + }.bind(this)); + } + Array.prototype.mapWith = function (anotherList, funcForTwoItems) { + if (funcForTwoItems == null) + funcForTwoItems = function (x, y) { return [x, y]; }; + var list = []; + var maxLength = Math.max(this.length, anotherList.length); + for (var i = 0; i < maxLength; i++) + list.push(funcForTwoItems(this[i], anotherList[i])); + return list; + } + Array.prototype.min = function () { + var min = null; + for (var i = 0; i < this.length; i++) { + var value = this[i]; + if (min == null || value < min) + min = value; + } + return min; + } + Array.prototype.max = function () { + var max = null; + for (var i = 0; i < this.length; i++) { + var value = this[i]; + if (max == null || value > max) + max = value; + } + return max; + } + Array.prototype.getEnumerator = function () { + return new ArrayEnumerator(this); + } + Array.prototype.orderBy = function (selector, desc) { + return this.toArray().sortBy(selector, desc); + } + Array.prototype.orderByDescending = function (selector, desc) { + return this.orderBy(selector, true); + } + Array.prototype.sortBy = function (selector, desc) { + var compareFunc; + if (selector instanceof Array) { + var pairs = selector; + var funcs = pairs.map(function (pair) { + if (pair instanceof Array) + return createSortFuncFromCompareFunc(pair[0], pair[1]); + return createCompareFuncFromSelector(pair); + }); + compareFunc = combineCompareFuncs(funcs); + } + else { + compareFunc = createCompareFuncFromSelector(selector, desc); + } + this.sort(compareFunc); + return this; + } + Array.prototype.sortByDescending = function (selector) { + return this.sortBy(selector, true); + } + //Performs an async function on each item in the array, invoking a finalCallback when all are completed + //asyncFunc -> function(item, callback -> function(result)) + //finalCallback -> function(results); + Array.prototype.mapAsyncParallel = function (asyncFunc, finalCallback) { + var results = []; + var list = this; + var length = list.length; + if (length == 0) { + finalCallback(results); + return; + } + var finished = 0; + var cb = function (res, index) { + results[index] = res; + finished++; + if (finished == length) + finalCallback(results); + }; + list.forEach(function (item, i) { + asyncFunc(item, function (res) { cb(res, i); }); + }); + } + //Performs an async function on each item in the array, invoking a finalCallback when all are completed + //asyncFunc -> function(item, callback -> function(result)) + //finalCallback -> function(results); + Array.prototype.forEachAsyncParallel = function (asyncFunc, finalCallback) { + var list = this; + var length = list.length; + if (length == 0) { + finalCallback(); + return; + } + var finished = 0; + var cb = function (res, index) { + finished++; + if (finished == length) + finalCallback(); + }; + list.forEach(function (item, i) { + asyncFunc(item, cb);//function () { cb(i); }); + }); + } + Array.prototype.clear = function () { + this.splice(0, this.length); + } + Array.prototype.itemsEqual = function (list) { + if (list == this) + return true; + if (list.length != this.length) + return false; + for (var i = 0; i < this.length; i++) + if (this[i] != list[i]) + return false; + return true; + } + Array.prototype.select = function (selector) { + var func = Q.createSelectorFunction(selector); + return this.map(func); + } + Array.prototype.selectInvoke = function (name) { + return this.map(function (t) { return t[name](); }); + } + Array.prototype.joinWith = function (list2, keySelector1, keySelector2, resultSelector) { + keySelector1 = Q.createSelectorFunction(keySelector1); + keySelector2 = Q.createSelectorFunction(keySelector2); + resultSelector = Q.createSelectorFunction(resultSelector); + + var list1 = this; + + var groups1 = list1.groupByToObject(keySelector1); + var groups2 = list2.groupByToObject(keySelector2); + + var list = []; + var group = {}; + for (var p in groups1) { + if (groups2[p] != null) + list.push(resultSelector(groups1[p], groups2[p])); + } + + return list; + } + Array.prototype.all = function (predicate) { + return this.every(Q.createSelectorFunction(predicate)); + } + Array.prototype.flatten = function () { + var list = []; + this.forEach(function (t) { + list.addRange(t); + }); + return list; + } + Array.prototype.selectToObject = function (keySelector, valueSelector) { + var obj = {}; + if (valueSelector == null) { + var list = this.select(keySelector); + for (var i = 0; i < list.length; i++) { + var obj2 = this[i]; + if (obj2 != null) { + if (obj2 instanceof Array) { + for (var i = 0; i < obj2.length; i++) { + obj[obj2[0]] = obj2[1]; + } + } + else { + Q.copy(obj2, obj, { overwrite: true }); + } + } + } + } + else { + keySelector = Q.createSelectorFunction(keySelector); + valueSelector = Q.createSelectorFunction(valueSelector); + + for (var i = 0; i < this.length; i++) { + var item = this[i]; + obj[keySelector(item)] = valueSelector(item); + } + } + return obj; + } + Array.prototype.groupByToObject = function (keySelector, itemSelector) { + keySelector = Q.createSelectorFunction(keySelector); + itemSelector = Q.createSelectorFunction(itemSelector); + var obj = {}; + for (var i = 0; i < this.length; i++) { + var item = this[i]; + var key = keySelector(item); + if (obj[key] == null) { + obj[key] = []; + obj[key].key = key; + } + var value = itemSelector(item); + obj[key].push(value); + } + return obj; + } + Array.prototype.groupBy = function (keySelector, itemSelector) { + var groupsMap = this.groupByToObject(keySelector, itemSelector); + return Object.values(groupsMap); + } + Array.prototype.splitIntoChunksOf = function (countInEachChunk) { + var chunks = Math.ceil(this.length / countInEachChunk); + var list = []; + for (var i = 0; i < this.length; i += countInEachChunk) { + list.push(this.slice(i, i + countInEachChunk)); + } + return list; + } + Array.prototype.avg = function () { + if (this.length == 0) + return null; + return this.sum() / this.length; + } + Array.prototype.selectMany = function (selector) { + var list = []; + this.select(selector).forEach(function (t) { t.forEach(function (x) { list.push(x); }); }); + return list; + } + Array.prototype.sum = function () { + if (this.length == 0) + return 0; + var sum = this[0]; + for (var i = 1; i < this.length; i++) + sum += this[i]; + return sum; + } + Array.prototype.skip = function (count) { + return this.slice(count); + } + Array.prototype.take = function (count) { + return this.slice(0, count); + } + Array.prototype.toSelector = function () { + return Q.createSelectorFunction(this); + } + Array.prototype.removeNulls = function () { + return this.removeAll(function (t) { return t == null; }); + } + Array.prototype.exceptNulls = function () { + return this.where(function (t) { return t != null; }); + } + Array.prototype.truncate = function (totalItems) { + if (this.length <= totalItems) + return; + this.splice(totalItems, this.length - totalItems); + } + Array.prototype.random = function () { + return this[Math.randomInt(0, this.length - 1)]; + } + Array.prototype.selectRecursive = function (selector, recursiveFunc) { + if (recursiveFunc == null) { + recursiveFunc = selector; + selector = null; + } + var list = this.select(selector); + var children = this.select(recursiveFunc); + var list2 = children.selectRecursive(selector, recursiveFunc); + list.addRange(list2); + return list; + } + Array.prototype.selectManyRecursive = function (selector, recursiveFunc) { + if (recursiveFunc == null) { + recursiveFunc = selector; + selector = null; + } + var list; + if (selector == null) + list = this.toArray(); + else + list = this.selectMany(selector); + var children = this.selectMany(recursiveFunc); + if (children.length > 0) { + var list2 = children.selectManyRecursive(selector, recursiveFunc); + list.addRange(list2); + } + return list; + } + + //Array Extension Aliases + Array.prototype.peek = Array.prototype.last; + Array.prototype.removeLast = Array.prototype.pop; + Array.prototype.add = Array.prototype.push; + Array.prototype.forEachWith = function (list, action) { + return Array.forEachTwice(this, list, action); + } + Array.prototype.selectWith = function (list, func) { + return Array.selectTwice(this, list, action); + } + + //Produces a cartesian product of two lists, if no selector(x1, y1) is defined, will return an array of pairs [[x1,y1],[x1,y2],[x1,y3]...] + Array.prototype.crossJoin = function (list2, selector) { + var list1 = this; + var list3 = []; + if (selector == null) + selector = function (x, y) { return [x, y]; }; + list1.forEach(function (t1) { + list2.forEach(function (t2) { + list3.push(selector(t1, t2)); + }); + }); + return list3; + } + + //Array Static Extensions + Array.joinAll = function (lists, keySelector, resultSelector) { + keySelector = Q.createSelectorFunction(keySelector); + resultSelector = Q.createSelectorFunction(resultSelector); + + var groupMaps = lists.map(function (list) { + return list.groupByToObject(keySelector); + }); + + var groupMap1 = groupMaps[0]; + + var list = []; + for (var p in groupMap1) { + if (groupMaps.all(p)) + list.push(resultSelector(groupMaps.select(p))); + } + + return list; + } + Array.outerJoin = function (list1, list2, keySelector1, keySelector2, resultSelector) { + keySelector1 = Q.createSelectorFunction(keySelector1); + keySelector2 = Q.createSelectorFunction(keySelector2); + resultSelector = Q.createSelectorFunction(resultSelector); + + + var groups1 = list1.groupByToObject(keySelector1); + var groups2 = list2.groupByToObject(keySelector2); + + + var allKeys = Object.keys(groups1); + allKeys.addRange(Object.keys(groups2)); + allKeys = allKeys.distinct(); + //allKeys.sort(); + + var list3 = []; + allKeys.forEach(function (key) { + var group1 = groups1[key] || []; + var group2 = groups2[key] || []; + var res = Array.selectTwice(group1, group2, function (item1, item2) { return resultSelector(key, item1, item2); }); + list3.addRange(res); + }); + return list3; + } + Array.outerJoinAll = function (lists, keySelector, resultSelector) { + keySelector = Q.createSelectorFunction(keySelector); + resultSelector = Q.createSelectorFunction(resultSelector); + + + var listsGroups = lists.select(function (list) { return list.groupByToObject(keySelector); }); + //[{key1:items, key2:items}, {key1:items, key2:items}] + + var allKeys = listsGroups.selectMany(function (t) { return Object.values(t).select("key"); }).distinct(); + + var list3 = []; + allKeys.forEach(function (key) { + var lists = listsGroups.select(function (obj) { return obj[key] || []; }); + var list2 = Array.selectAll(lists, function (items, index) { return resultSelector(key, items); }); + list3.addRange(list2); + }); + return list3; + } + Array.forEachAll = function (lists, action) { + var max = lists.select("length").max(); + for (var i = 0; i < max; i++) { + var values = lists.select(i); + action(values, i); + } + } + Array.selectAll = function (lists, func) { + var list2 = []; + Array.forEachAll(lists, function (items, i) { + list2.push(func(items, i)); + }); + return list2; + } + Array.forEachTwice = function (list1, list2, action) { + var l1 = list1.length; + var l2 = list2.length; + var max = Math.max(l1, l2); + for (var i = 0; i < max; i++) { + action(list1[i], list2[i], i); + } + } + Array.selectTwice = function (list1, list2, func) { + var list = []; + Array.forEachTwice(list1, list2, function (t1, t2, index) { + var item = func(t1, t2, index); + list.push(item); + }); + return list; + } + Array.generate = function (length, generator) { + var list = new Array(length); + for (var i = 0; i < length; i++) { + list[i] = generator(i); + } + return list; + } + Array.wrapIfNeeded = function (obj) { + if (obj instanceof Array) + return obj; + return [obj]; + } + Array.toArray = function (arrayLike) { + return Array.prototype.slice.call(arrayLike, 0); + } + Array.from = function (arrayLike) { + return Array.prototype.slice.call(arrayLike, 0); + } + Array.generateNumbers = function (from, until) { + if (arguments.length == 1) { + until = from; + from = 0; + } + var length = until - from; + var list = new Array(length); + for (var i = 0; i < length; i++) { + list[i] = i + from; + } + return list; + } + Array.slice = Array.prototype.slice.toStaticFunction(); + Array.concat = Array.prototype.concat.toStaticFunction(); + +})(); + + +//******** Date +(function () { + + /* Date extensions, taken from jsclr framework */ + Date.prototype.compareTo = function (value) { + return this.valueOf() - value.valueOf(); + }; + Date.prototype.year = function (value) { + if (value == null) { + if (this._Kind == 1) + return this.getUTCFullYear(); + return this.getFullYear(); + } + var d = this.clone(); + if (d._Kind == 1) + d.setUTCFullYear(value); + else + d.setFullYear(value); + return d; + }; + Date.prototype.totalDays = function () { + return this.valueOf() / (24 * 60 * 60 * 1000); + }; + Date.prototype.totalHours = function () { + return this.valueOf() / (60 * 60 * 1000); + }; + Date.prototype.totalMinutes = function () { + return this.valueOf() / (60 * 1000); + }; + Date.prototype.totalSeconds = function () { + return this.valueOf() / 1000; + }; + Date.prototype.month = function (value) { + if (value == null) { + if (this._Kind == 1) + return this.getUTCMonth() + 1; + return this.getMonth() + 1; + } + var d = this.clone(); + if (d._Kind == 1) + d.setUTCMonth(value - 1); + else + d.setMonth(value - 1); + return d; + }; + Date.prototype.day = function (value) { + if (value == null) { + if (this._Kind == 1) + return this.getUTCDate(); + return this.getDate(); + } + var d = this.clone(); + if (d._Kind == 1) + d.setUTCDate(value); + else + d.setDate(value); + return d; + }; + Date.prototype.hour = function (value) { + if (value == null) { + if (this._Kind == 1) + return this.getUTCHours(); + return this.getHours(); + } + var d = this.clone(); + if (d._Kind == 1) + d.setUTCHours(value); + else + d.setHours(value); + return d; + }; + Date.prototype.minute = function (value) { + if (value == null) { + if (this._Kind == 1) + return this.getUTCMinutes(); + return this.getMinutes(); + } + var d = this.clone(); + if (d._Kind == 1) + d.setUTCMinutes(value); + else + d.setMinutes(value); + return d; + }; + Date.prototype.second = function (value) { + if (value == null) { + if (this._Kind == 1) + return this.getUTCSeconds(); + return this.getSeconds(); + } + var d = this.clone(); + if (d._Kind == 1) + d.setUTCSeconds(value); + else + d.setSeconds(value); + return d; + }; + Date.prototype.ms = function (value) { + if (value == null) { + if (this._Kind == 1) + return this.getUTCMilliseconds(); + return this.getMilliseconds(); + } + var d = this.clone(); + if (d._Kind == 1) + d.setUTCMilliseconds(value); + else + d.setMilliseconds(value); + return d; + }; + Date.prototype.toUnix = function () { + if (this._Kind == 1) + throw new Error(); + return Math.round(this.getTime() / 1000); + }; + Date.prototype.dayOfWeek = function () { + return this.getDay() + 1; + }; + Date.prototype.toLocalTime = function () { + if (this._Kind != 1) + return this; + var x = this.clone(); + x._Kind = 2; + return x; + }; + Date.prototype.toUniversalTime = function () { + if (this._Kind == 1) + return this; + var x = this.clone(); + x._Kind = 1; + return x; + }; + Date.prototype.subtract = function (date) { + var diff = this.valueOf() - date.valueOf(); + return new Date(diff); + }; + Date.prototype.Subtract$$DateTime = function (value) { + var diff = this.valueOf() - value.valueOf(); + return new System.TimeSpan.ctor$$Int64(diff * 10000); + }; + Date.prototype.Subtract$$TimeSpan = function (value) { + var newDate = this.clone(); + newDate.setMilliseconds(this.getMilliseconds() + value.getTotalMilliseconds()); + return newDate; + }; + Date.prototype.format = function (format) { + if (typeof (format) == "object") { + var options = format; + if (options.noTime != null && !this.hasTime()) + return this.format(options.noTime); + else if (options.noDate != null && !this.hasDate()) + return this.format(options.noDate); + else if (options.fallback != null) + return this.format(options.fallback); + return this.toString(); + } + var s = format; + + var s2 = s.replaceMany("yyyy yy MMMM MMM MM M dddd ddd dd d HH H mm m ss s ff f".split(" "), function (t) { + switch (t) { + case "yyyy": return this.year().format("0000"); + case "yy": return this.year().format("00").truncateStart(2); + case "y": return this.year().toString(); + case "MMMM": return Date._monthNames[this.getMonth()]; + case "MMM": return Date._monthNamesAbbr[this.getMonth()]; + case "MM": return this.month().format("00"); + case "M": return this.month().toString(); + case "dd": return this.day().format("00"); + case "d": return this.day().toString(); + case "dddd": return Date._dowNames[this.getDay()]; + case "ddd": return Date._dowNamesAbbr[this.getDay()]; + case "HH": return this.hour().format("00"); + case "H": return this.hour().toString(); + case "mm": return this.minute().format("00"); + case "m": return this.minute().toString(); + case "ss": return this.second().format("00"); + case "s": return this.second().toString(); + case "ff": return this.ms().format("00"); + case "f": return this.ms().toString(); + } + + }.bind(this)); + return s2.toString(); + }; + Date.prototype.clone = function () { + var x = new Date(this.valueOf()); + x._Kind = this._Kind; + return x; + }; + Date.prototype.addMs = function (miliseconds) { + var date2 = this.clone(); + date2.setMilliseconds(date2.getMilliseconds() + miliseconds); + return date2; + }; + Date.prototype.addSeconds = function (seconds) { + var date2 = this.clone(); + date2.setSeconds(date2.getSeconds() + seconds); + return date2; + }; + Date.prototype.addMinutes = function (minutes) { + var date2 = this.clone(); + date2.setMinutes(date2.getMinutes() + minutes); + return date2; + }; + Date.prototype.addHours = function (hours) { + var date2 = this.clone(); + date2.setHours(date2.getHours() + hours); + return date2; + }; + Date.prototype.addDays = function (days) { + var date2 = this.clone(); + date2.setDate(date2.getDate() + days); + return date2; + }; + Date.prototype.addWeeks = function (weeks) { + return this.addDays(weeks * 7); + }; + Date.prototype.addMonths = function (months) { + var date2 = this.clone(); + date2.setMonth(date2.getMonth() + months); + return date2; + }; + Date.prototype.addYears = function (years) { + var date2 = this.clone(); + date2.setFullYear(date2.getFullYear() + years); + return date2; + }; + Date.prototype.removeTime = function () { + var date2 = this.clone(); + date2.setHours(0, 0, 0, 0); + return date2; + }; + Date.prototype.hasTime = function () { + return this.hour() != 0 && this.second() != 0 && this.ms() != 0; + }; + Date.prototype.hasDate = function () { + var date2 = new Date(0); + return this.year() != date2.year() && this.month() != date2.month() && this.day() != date2.day(); + }; + Date.prototype.removeDate = function () { + var time = this.clone(); + time.setHours(this.hour(), this.minute(), this.second(), this.ms()); + return time; + }; + Date.prototype.extractTime = function () { + return this.removeDate(); + }; + Date.prototype.extractDate = function () { + return this.removeTime(); + }; + Date.prototype.equals = function (obj) { + if (obj == null) + return false; + return obj.valueOf() == this.valueOf(); + }; + Date.prototype.GetHashCode = function () { + return this.valueOf(); + }; + Date.prototype.getKind = function () { + if (this._Kind == null) + return 2; + return this._Kind; + }; + Date.prototype.round = function (part, precision) { + return Date.roundUsing(Math.round, this, part, precision); + } + Date.prototype.floor = function (part, precision) { + return Date.roundUsing(Math.floor, this, part, precision); + } + Date.prototype.ceil = function (part, precision) { + return Date.roundUsing(Math.ceil, this, part, precision); + } + Date.prototype.add = function (value, part) { + var map = { + "day": "addDays", + "month": "addMonths", + "week": "addWeeks", + "hour": "addHours", + "minute": "addMinutes", + "second": "addSeconds", + "ms": "addMs", + }; + if (part == null) + part = "ms"; + var func = map[part]; + var date2 = this[func](value); + return date2; + }; + + + + Date._dowNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; + Date._dowNamesAbbr = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + Date._monthNamesAbbr = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + Date._monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + Date.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; + Date._parts = ["year", "month", "day", "hour", "minute", "second", "ms"]; + + + Date.fromUnix = function (value) { + return new Date(value * 1000); + }; + Date.today = function () { + return new Date().removeTime(); + }; + Date.current = function () { + return new Date(); + }; + Date.create = function (y, m, d, h, mm, s, ms) { + if (ms != null) + return new Date(y, m - 1, d, h, mm, s, ms); + if (s != null) + return new Date(y, m - 1, d, h, mm, s); + if (mm != null) + return new Date(y, m - 1, d, h, mm); + if (h != null) + return new Date(y, m - 1, d, h); + if (d != null) + return new Date(y, m - 1, d); + if (m != null) + return new Date(y, m - 1); + if (y != null) + return new Date(y); + var x = new Date(1970, 0, 1); + x.setHours(0, 0, 0, 0); + return x; + } + Date._parsePart = function (ctx, part, setter) { + if (ctx.failed) + return; + var index = ctx.format.indexOf(part); + if (index < 0) + return; + var token = ctx.s.substr(index, part.length); + if (token.length == 0) { + ctx.failed = true; + return; + } + var value = Q.parseInt(token); + if (value == null) { + ctx.failed = true; + return; + } + ctx.date = setter.call(ctx.date, value); + ctx.format = ctx.format.replaceAt(index, part.length, "".padRight(part.length)); + ctx.s = ctx.s.replaceAt(index, part.length, "".padRight(part.length)); + } + Date.tryParseExact = function (s, formats) { + if (typeof (formats) == "string") + formats = [formats]; + for (var i = 0; i < formats.length; i++) { + var x = Date._tryParseExact(s, formats[i]); + if (x != null) + return x; + } + return null; + }; + Date._tryParseExact = function (s, format) { + if (s.length != format.length) + return null; + var date = Date.create(); + var ctx = { date: date, s: s, format: format }; + Date._parsePart(ctx, "yyyy", date.year); + Date._parsePart(ctx, "yy", date.year); + Date._parsePart(ctx, "MM", date.month); + Date._parsePart(ctx, "dd", date.day); + Date._parsePart(ctx, "HH", date.hour); + Date._parsePart(ctx, "mm", date.minute); + Date._parsePart(ctx, "ss", date.second); + if (ctx.failed) + return null; + if (ctx.s != ctx.format) + return null; + return ctx.date; + }; + Date.tryParseJsonDate = function (s) { + if (s.length == 26 && s[0] == "\"" && s[value.length - 1] == "\"") { + s = s.substr(1, 24); + } + if (s.length == 24 && /[0-9]+-[0-9]+-[0-9]+T[0-9]+:[0-9]+:[0-9]+\.[0-9]+Z/.test(s)) { + var d = new Date(s); + if (!isNaN(d.valueOf())) + return d; + } + return null; + + } + Date.roundUsing = function (mathOp, date, part, precision) { + var parts = Date._parts; + if (part == null) + part = "second"; + if (!precision) + precision = 1; + var partIndex = parts.indexOf(part); + if (partIndex < 0) { + part = "second"; + partIndex = 5; + } + var date2 = date.clone(); + var value = date2[part](); + value = Number.roundUsing(mathOp, value, precision); + date2 = date2[part](value); + for (var i = partIndex + 1; i < parts.length; i++) { + var part2 = parts[i]; + date2 = date2[part2](0); + } + return date2; + } + + +})(); + + +//******** String +(function () { + String.prototype.forEach = Array.prototype.forEach; + + String.prototype.contains = function (s) { + return this.indexOf(s) >= 0; + } + String.prototype.endsWith = function (suffix) { + return this.indexOf(suffix, this.length - suffix.length) !== -1; + }; + String.prototype.startsWith = function (s) { + return this.indexOf(s) == 0; + } + /** + * ReplaceAll by Fagner Brack (MIT Licensed) + * Replaces all occurrences of a substring in a string + */ + String.prototype.replaceAll = function (token, newToken, ignoreCase) { + var _token; + var str = this + ""; + var i = -1; + + if (typeof token === "string") { + + if (ignoreCase) { + + _token = token.toLowerCase(); + + while (( + i = str.toLowerCase().indexOf( + token, i >= 0 ? i + newToken.length : 0 + )) !== -1 + ) { + str = str.substring(0, i) + + newToken + + str.substring(i + token.length); + } + + } else { + return this.split(token).join(newToken); + } + + } + return str; + }; + String.prototype.replaceMany = function (finds, replacer) { + var s = this; + var s2 = ""; + var i = 0; + while (i < s.length) { + var append = s[i]; + var inc = 1; + for (var j = 0; j < finds.length; j++) { + var find = finds[j]; + var token = s.substr(i, find.length); + if (find == token) { + var replace = replacer(find, i); + append = replace; + inc = find.length; + break; + } + } + s2 += append; + i += inc; + } + return s2; + } + String.prototype.truncateEnd = function (finalLength) { + if (this.length > finalLength) + return this.substr(0, finalLength); + return this; + } + String.prototype.truncateStart = function (finalLength) { + if (this.length > finalLength) + return this.substr(this.length - finalLength); + return this; + } + String.prototype.remove = function (index, length) { + var s = this.substr(0, index); + s += this.substr(index + length); + return s; + } + String.prototype.insert = function (index, text) { + var s = this.substr(0, index); + s += text; + s += this.substr(index); + return s; + } + String.prototype.replaceAt = function (index, length, text) { + return this.remove(index, length).insert(index, text); + } + String.prototype.padRight = function (totalWidth, paddingChar) { + if (paddingChar == null || paddingChar == "") + paddingChar = " "; + var s = this; + while (s.length < totalWidth) + s += paddingChar; + return s; + } + String.prototype.padLeft = function (totalWidth, paddingChar) { + if (paddingChar == null || paddingChar == "") + paddingChar = " "; + var s = this; + while (s.length < totalWidth) + s = paddingChar + s; + return s; + } + String.prototype.toLambda = function () { + return Function.lambda(this); + } + String.prototype.toSelector = function () { + return Q.createSelectorFunction(this); + } + String.prototype.substringBetween = function (start, end) { + var s = this; + var i1 = s.indexOf(start); + if (i1 < 0) + return null; + var i2 = s.indexOf(end, i1 + 1); + if (i2 < 0) + return null; + return s.substring(i1 + start.length, i2); + } + String.prototype.all = Array.prototype.all; + String.prototype.every = Array.prototype.every; + String.prototype.isInt = function () { + return String.isInt(this); + } + String.prototype.isFloat = function () { + var floatRegex = /^[+-]?[0-9]*[\.]?[0-9]*$/; + return String.isFloat(this); + } + String.isInt = function (s) { + var intRegex = /^[+-]?[0-9]+$/; + return intRegex.test(s); + } + String.isFloat = function (s) { + var floatRegex = /^[+-]?[0-9]*[\.]?[0-9]*$/; + return floatRegex.test(s); + } + String.prototype.last = function (predicate) { + if (this.length == 0) + return null; + if (predicate == null) + return this[this.length - 1]; + for (var i = this.length; i >= 0; i--) { + if (predicate(this[i])) + return this[i]; + } + return null; + } + + String.prototype.splitAt = function (index) { + return [this.substr(0, index), this.substr(index)]; + } + String.prototype.lines = function () { + return this.match(/[^\r\n]+/g); + } + +})(); + + +//******** Number +(function () { + + Number.prototype.format = function (format) { + var s = this.toString(); + for (var i = 0; i < format.length; i++) { + var ch = format.charAt(i); + if (ch == "0") { + if (s.length < i + 1) + s = "0" + s; + } + else + throw new Error("not implemented"); + } + return s; + } + Number.prototype.round = function (precision) { + return Number.roundUsing(Math.round, this, precision); + } + Number.prototype.ceil = function (precision) { + return Number.roundUsing(Math.ceil, this, precision); + } + Number.prototype.floor = function (precision) { + return Number.roundUsing(Math.floor, this, precision); + } + + Number.prototype.isInt = function () { + return (this | 0) === this; + } + Number.prototype.isFloat = function () { + return (this | 0) !== this; + } + Number.prototype.inRangeInclusive = function (min, max) { + return this >= min && this <= max; + } + + + Number.generate = function (min, max, step) { + var list = []; + if (step == null) + step = 1; + for (var i = min; i <= max; i += step) { + list.push(i); + } + return list; + } + Number.roundUsing = function (mathOp, x, precision) { + if (precision == null) + precision = 1; + else if (precision < 0) + precision *= -1; + var mul = 1; + while (((precision | 0) !== precision) && (mul < 10000000000)) { + precision *= 10; + x *= 10; + mul *= 10; + } + return (mathOp(x / precision) * precision) / mul; + } + + +})(); + + +//******** JSON +(function () { + JSON.iterateRecursively = function (obj, action) { + if (obj == null || typeof (obj) != "object" || obj instanceof Date) + return; + + if (obj instanceof Array) { + var list = obj; + list.forEach(function (item, index) { + action(obj, index, item); + JSON.iterateRecursively(item, action); + }); + } + else { + Object.keys(obj).forEach(function (key) { + var value = obj[key]; + action(obj, key, value); + JSON.iterateRecursively(value, action); + }); + } + } +})(); + + +//******** Math +(function () { + Math.randomInt = function (min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + } +})(); + + +//******** Error +(function () { + Error.prototype.wrap = function (e) { + e.innerError = this; + return e; + } + Error.prototype.causedBy = function (e) { + this.innerError = e; + } +})(); + + +//******** Q +(function () { + function Q() { + }; + Q.copy = function (src, target, options, depth) { + ///Copies an object into a target object, + ///recursively cloning any native json object or array on the way, overwrite=true will overwrite a primitive field value even if exists + ///Custom objects and functions are copied as/is by reference. + /// + /// + /// + ///{ overwrite:false } + ///The copied object + if (depth == null) + depth = 0; + if (depth == 100) { + console.warn("Q.copy is in depth of 100 - possible circular reference") + } + if (src === null && target === undefined) + return null; + if (src == target || src == null) + return target; + options = options || { overwrite: false }; + + if (typeof (src) != "object") { + if (options.overwrite || target == null) + return src; + return target; + } + if (typeof (src.clone) == "function") { + if (options.overwrite || target == null) + return src.clone(); + return target; + } + + if (src instanceof Array) { + if (target == null) + target = []; + + for (var i = 0; i < src.length; i++) { + var item = src[i]; + var item2 = target[i]; + item2 = Q.copy(item, item2, options, depth + 1); + target[i] = item2; + } + target.splice(src.length, target.length - src.length); + return target; + } + if (src.constructor != Object) { + if (options.overwrite || target == null) + return src; + return target; + } + + if (target == null) + target = {}; + for (var p in src) { + var value = src[p]; + var value2 = target[p]; + value2 = Q.copy(value, value2, options, depth + 1); + target[p] = value2; + } + return target; + } + Q.objectToNameValueArray = function () { + var list = []; + for (var p in this.obj) { + list.push({ name: p, value: this.obj[p] }); + } + return list; + } + Q.objectValuesToArray = function (obj) { + var list = []; + for (var p in obj) { + list.push(obj[p]); + } + return list; + } + Q.cloneJson = function (obj) { + if (obj == null) + return null; + return JSON.parse(JSON.stringify(obj)); + }; + Q.forEachValueInObject = function (obj, func, thisArg) { + for (var p in obj) { + func.call(thisArg, obj[p]); + } + }; + Q.mapKeyValueInArrayOrObject = function (objOrList, func, thisArg) { + var list = []; + if (objOrList instanceof Array) { + for (var i = 0; i < objOrList.length; i++) { + list.push(func.call(thisArg, i, objOrList[i])); + } + } + else { + for (var p in objOrList) { + list.push(func.call(thisArg, p, objOrList[p])); + } + } + return list; + }; + //Alternative to $.map of jquery - which has array reducers overhead, and sometimes causes stackOverflow + Q.jMap = function (objOrList, func, thisArg) { + var list = []; + if (objOrList instanceof Array) { + for (var i = 0; i < objOrList.length; i++) { + list.push(func.call(thisArg, objOrList[i], i)); + } + } + else { + for (var p in objOrList) { + list.push(func.call(thisArg, objOrList[p], p)); + } + } + return list; + }; + ///Returns if the parameter is null, or an empty json object + Q.isEmptyObject = function (obj) { + if (obj == null) + return true; + if (typeof (obj) != "object") + return false; + for (var p in obj) + return false; + return true; + }; + Q.min = function (list) { + return Math.min.apply(null, list); + }; + Q.max = function (list) { + return Math.max.apply(null, list); + }; + Q.stringifyFormatted = function (obj) { + var sb = []; + sb.indent = ""; + sb.indentSize = " "; + sb.startBlock = function (s, skipNewLine) { + this.indent += sb.indentSize; + this.push(s); + if (!skipNewLine) + this.newLine(); + }; + sb.endBlock = function (s, skipNewLine) { + this.indent = this.indent.substr(0, this.indent.length - this.indentSize.length); + if (!skipNewLine) + this.newLine(); + this.push(s); + }; + sb.newLine = function (s) { + this.push("\n"); + this.push(this.indent); + }; + Q.stringifyFormatted2(obj, sb); + return sb.join(""); + } + Q._canInlineObject = function (obj) { + return Object.values(obj).all(function (t) { return t == null || typeof (t) != "object" }); + } + Q._canInlineArray = function (list) { + if (list.length == 0) + return true; + if (["string", "number"].contains(typeof (list[0]))) + return true; + if (list.length == 1 && Q._canInlineObject(list[0])) + return true; + return false; + + } + Q.stringifyFormatted2 = function (obj, sb) { + if (obj === undefined) { + sb.push("undefined"); + return; + } + if (obj === null) { + sb.push("null"); + return; + } + var type = typeof (obj); + if (type == "object") { + if (obj instanceof Array) { + var list = obj; + if (Q._canInlineArray(list)) { + sb.push("["); + list.forEach(function (t, i) { + Q.stringifyFormatted2(t, sb); + if (i < list.length - 1) + sb.push(", "); + }); + sb.push("]"); + } + else { + sb.startBlock("["); + for (var i = 0; i < list.length; i++) { + Q.stringifyFormatted2(list[i], sb); + if (i < list.length - 1) { + sb.push(","); + sb.newLine(); + } + } + sb.endBlock("]"); + } + } + else if (obj instanceof Date) { + sb.push("new Date(" + obj.valueOf() + ")"); + } + else { + var canInline = Q._canInlineObject(obj); + sb.startBlock("{", canInline); + var first = true; + for (var p in obj) { + if (first) + first = false; + else { + sb.push(","); + if (!canInline) + sb.newLine(); + } + if (/^[$A-Z_][0-9A-Z_$]*$/i.test(p)) + sb.push(p + ": "); + else + sb.push(JSON.stringify(p) + ": "); + Q.stringifyFormatted2(obj[p], sb); + } + sb.endBlock("}", canInline); + } + } + else if (type == "function") { + sb.push(obj.toString()); + } + else { + sb.push(JSON.stringify(obj)); + } + } + /* Binds all function on an object to the object, so the 'this' context will be reserved even if referencing the function alone */ + Q.bindFunctions = function (obj) { + for (var p in obj) { + var func = obj[p]; + if (typeof (func) != "function") + continue; + if (func.boundTo == obj) + continue; + func = func.bind(obj); + func.boundTo = obj; + if (func.name == null) + func.name = p; + obj[p] = func; + } + } + + Q.parseInt = function (s) { + if (s == null) + return null; + if (typeof (s) == "number") + return s; + if (!String.isInt(s)) + return null; + var x = parseInt(s); + if (isNaN(x)) + return null; + return x; + } + Q.parseFloat = function (s) { + if (s == null) + return null; + if (typeof (s) == "number") + return s; + if (!String.isFloat(s)) + return null; + var x = parseFloat(s); + if (isNaN(x)) + return null; + return x; + } + Q.createSelectorFunction = function (selector) { + if (selector == null) + return function (t) { return t; }; + if (typeof (selector) == "function") + return selector; + if (selector instanceof Array) { + var list = selector; + if (typeof (list[0]) == "string") { + return function (t) { + var obj = {}; + for (var i = 0; i < list.length; i++) { + var prop = list[i]; + obj[prop] = t[prop]; + } + return obj; + }; + } + + var list2 = selector.map(Q.createSelectorFunction); + return function (t) { + var value = t; + for (var i = 0; i < list2.length; i++) { + if (value == null) + return undefined; + var func = list2[i]; + value = func(value); + }; + return value; + }; + } + return function (t) { return t[selector]; }; + } + Q.isNullOrEmpty = function (stringOrArray) { + return stringOrArray == null || stringOrArray.length == 0; + } + Q.isNotNullOrEmpty = function (stringOrArray) { + return stringOrArray != null && stringOrArray.length > 0; + } + Q.isNullEmptyOrZero = function (v) { + return v == null || v == 0 || v.length == 0; + } + Q.isAny = function (v, vals) { + return vals.any(function (t) { return v == t; }) + } + + Function.addTo(window, [Q]); +})(); + +//******** Utils +(function () { + + //function O(obj){ + // for(var p in obj){ + // this[p] = obj[p]; + // } + //} + + //O.prototype.getCreate + + function ArrayEnumerator(list) { + this.index = -1; + this.list = list; + } + ArrayEnumerator.prototype.moveNext = function () { + if (this.index == -2) + throw new Error("End of array"); + this.index++; + if (this.index >= this.list.length) { + this.index = -2; + return false; + } + return true; + } + ArrayEnumerator.prototype.getCurrent = function () { + if (this.index < 0) + throw new Error("Invalid array position"); + return this.list[this.index]; + } + + function Comparer() { + + } + Comparer.prototype.compare = function (x, y) { + if (x > y) + return 1; + if (x < y) + return -1; + return 0; + } + Comparer._default = new Comparer(); + + + function Timer(action, ms) { + this.action = action; + if (ms != null) + this.set(ms); + } + Timer.prototype.set = function (ms) { + if (ms == null) + ms = this._ms; + else + this._ms = ms; + this.clear(); + if (ms == null) + return; + this.timeout = window.setTimeout(this.onTick.bind(this), ms); + } + Timer.prototype.onTick = function () { + this.clear(); + this.action(); + } + Timer.prototype.clear = function (ms) { + if (this.timeout == null) + return; + window.clearTimeout(this.timeout); + this.timeout = null; + } + + function QueryString() { + + } + QueryString.parse = function (query, obj, defaults) { + if (query == null) + query = window.location.search.substr(1); + if (obj == null) + obj = {}; + if (defaults == null) + defaults = {}; + var index2 = query.indexOf("#"); + if (index2 >= 0) + query = query.substr(0, index2); + if (query.length == 0) + return obj; + var parts = query.split('&'); + var pairs = parts.select(function (part) { return part.split('='); }); + pairs.forEach(function (pair) { + var key = pair[0]; + var eValue = pair[1]; + var value; + var defaultValue = defaults[key]; + var currentValue = obj[key]; + if (currentValue == null || currentValue == defaultValue) { + value = decodeURIComponent(eValue); + obj[key] = value; + } + else if (currentValue instanceof Array || defaultValue instanceof Array) { + if (currentValue == null) { + currentValue = []; + obj[key] = currentValue; + } + if (defaultValue != null && currentValue.itemsEqual(defaultValue)) + currentValue.clear(); + if (eValue != "") { + var items = eValue.split(",").select(function (item) { return decodeURIComponent(item); }); + items.forEach(function (item) { + if (!currentValue.contains(item)) + currentValue.add(item); + }); + } + } + else if (currentValue != null) { + value = decodeURIComponent(eValue); + obj[key] = value; + //value = decodeURIComponent(eValue); + //obj[key] = [currentValue, value]; + } + if (typeof (defaultValue) == "boolean" && typeof (value) != "boolean") { + var boolValue = value == 1 || value == true || value == "1" || value == "true"; + obj[key] = boolValue; + } + + }); + return obj; + } + QueryString.stringify = function (obj) { + var sb = []; + QueryString.write(obj, sb); + return sb.join("&"); + } + QueryString.write = function (obj, sb) { + for (var p in obj) { + var value = obj[p]; + if (value instanceof Array) { + if (value.length > 0) + sb.push(p + "=" + value.select(function (item) { return encodeURIComponent(item); }).join(",")); + } + else { + sb.push(p + "=" + encodeURIComponent(value)); + } + } + } + + + function ValueOfEqualityComparer() { + + } + ValueOfEqualityComparer.prototype.equals = function (x, y) { + if (x == y) + return true; + if (x == null || y == null) + return false; + return x.valueOf() == y.valueOf(); + } + ValueOfEqualityComparer.prototype.getHashKey = function (x) { + return Object.getHashKey(x); + } + + Function.addTo(window, [ArrayEnumerator, Comparer, Timer, QueryString]); + + + + + + function combineCompareFuncs(compareFuncs) { + return function (a, b) { + var count = compareFuncs.length; + for (var i = 0; i < count; i++) { + var compare = compareFuncs[i]; + var x = compare(a, b); + if (x != 0) + return x; + } + return 0; + }; + } + + function createCompareFuncFromSelector(selector, desc) { + desc = desc ? -1 : 1; + var compare = Comparer._default.compare; + var type = typeof (selector); + if (type == "string" || type == "number") { + return function (x, y) { + return compare(x[selector], y[selector]) * desc; + }; + } + return function (x, y) { + return compare(selector(x), selector(y)) * desc; + }; + } + + function toStringOrEmpty(val) { + return val == null ? "" : val.toString(); + } + + Function.addTo(window, [toStringOrEmpty, createCompareFuncFromSelector, combineCompareFuncs]); + +})(); + + diff --git a/web/orchestrator/public/js/custom.js b/web/orchestrator/public/js/custom.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/web/orchestrator/public/js/d3.v3.min.js b/web/orchestrator/public/js/d3.v3.min.js new file mode 100644 index 00000000000..914b2ec5423 --- /dev/null +++ b/web/orchestrator/public/js/d3.v3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ha+n in this}function c(n){return n=ha+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===ga&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===ga)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=pa.length;r>e;++e){var u=pa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function U(n){return da(n,wa),n}function j(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.substring(0,a));var s=ka.get(n);return s&&(n=s,c=I),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Go.event;Go.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Go.event=r}}}function I(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function Y(){var n=".dragsuppress-"+ ++Aa,t="click"+n,e=Go.select(ea).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(Ea){var r=ta.style,u=r[Ea];r[Ea]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),Ea&&(r[Ea]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();return r.x=t.clientX,r.y=t.clientY,r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var u=n.getBoundingClientRect();return[t.clientX-u.left-n.clientLeft,t.clientY-u.top-n.clientTop]}function V(){return Go.event.changedTouches[0].identifier}function $(){return Go.event.target}function X(){return ea}function B(n){return n>0?1:0>n?-1:0}function J(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function W(n){return n>1?0:-1>n?Ca:Math.acos(n)}function G(n){return n>1?La:-1>n?-La:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return new ut(n,t,e)}function ut(n,t,e){this.h=n,this.s=t,this.l=e}function it(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,yt(u(n+120),u(n),u(n-120))}function ot(n,t,e){return new at(n,t,e)}function at(n,t,e){this.h=n,this.c=t,this.l=e}function ct(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),st(e,Math.cos(n*=za)*t,Math.sin(n)*t)}function st(n,t,e){return new lt(n,t,e)}function lt(n,t,e){this.l=n,this.a=t,this.b=e}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Za,r=gt(r)*Va,i=gt(i)*$a,yt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?ot(Math.atan2(e,t)*Ra,Math.sqrt(t*t+e*e),n):ot(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n){return yt(n>>16,255&n>>8,255&n)}function mt(n){return dt(n)+""}function yt(n,t,e){return new xt(n,t,e)}function xt(n,t,e){this.r=n,this.g=t,this.b=e}function Mt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _t(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ja.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function bt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),rt(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Za),u=pt((.2126729*n+.7151522*t+.072175*e)/Va),i=pt((.0193339*n+.119192*t+.9503041*e)/$a);return st(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return n}function Ct(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Go.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!ea.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Go.event;Go.event=n;try{o.progress.call(i,c)}finally{Go.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Qo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Go.rebind(i,o,"on"),null==r?i:i.get(Lt(r))}function Lt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Tt(){var n=qt(),t=zt()-n;t>24?(isFinite(t)&&(clearTimeout(Qa),Qa=setTimeout(Tt,t)),Ka=0):(Ka=1,tc(Tt))}function qt(){var n=Date.now();for(nc=Wa;nc;)n>=nc.t&&(nc.f=nc.c(n-nc.t)),nc=nc.n;return n}function zt(){for(var n,t=Wa,e=1/0;t;)t.f?t=n?n.n=t.n:Wa=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:At;return function(n){var e=rc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=uc.get(g)||Ut;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Go.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ht(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new oc(e-1)),1),e}function i(n,e){return t(n=new oc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{oc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{oc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ft(n);return c.floor=c,c.round=Ft(r),c.ceil=Ft(u),c.offset=Ft(i),c.range=a,n}function Ft(n){return function(t,e){try{oc=jt;var r=new jt;return r._=t,n(r,e)._}finally{oc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in cc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{oc=jt;var t=new oc;return t._=n,r(t)}finally{oc=Date}}var r=t(n);return e.parse=function(n){try{oc=jt;var t=r.parse(n);return t&&t._}finally{oc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var x=Go.map(),M=Yt(v),_=Zt(v),b=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ic.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ic.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ic.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:l,S:re,U:$t,w:Vt,W:Xt,x:c,X:s,y:Jt,Y:Bt,Z:Wt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(Go.requote).join("|")+")","i")}function Zt(n){for(var t=new o,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){sc.lastIndex=0;var r=sc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){sc.lastIndex=0;var r=sc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){sc.lastIndex=0;var r=sc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){sc.lastIndex=0;var r=sc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){sc.lastIndex=0;var r=sc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){sc.lastIndex=0;var r=sc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){sc.lastIndex=0;var r=sc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(fa(t)/60),u=fa(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){lc.lastIndex=0;var r=lc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);dc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;mc.point=function(o,a){mc.point=n,r=(t=o)*za,u=Math.cos(a=(e=a)*za/2+Ca/4),i=Math.sin(a)},mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function xe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function Me(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function _e(n,t){return fa(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Le(e,n,null,!0),s=new Le(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Le(r,n,null,!1),s=new Le(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Ne(i),Ne(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Ne(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(qe))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Go.merge(g);var n=De(m,p);g.length?(_||(i.polygonStart(),_=!0),Ce(g,Re,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=ze(),M=t(x),_=!1;return y}}function qe(n){return n.length>1}function ze(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Re(n,t){return((n=n.x)[0]<0?n[1]-La-Ta:La-n[1])-((t=t.x)[0]<0?t[1]-La-Ta:La-t[1])}function De(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;dc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Ca/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Ca/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Ca,k=p*x;if(dc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*Na:_,S^h>=e^m>=e){var E=de(pe(f),pe(n));xe(E);var A=de(u,E);xe(A);var C=(S^_>=0?-1:1)*G(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Ta>i||Ta>i&&0>dc)^1&o}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Ca:-Ca,c=fa(i-e);fa(c-Ca)0?La:-La),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Ca&&(fa(e-u)Ta?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*La,r.point(-Ca,u),r.point(0,u),r.point(Ca,u),r.point(Ca,0),r.point(Ca,-u),r.point(0,-u),r.point(-Ca,-u),r.point(-Ca,0),r.point(-Ca,u);else if(fa(n[0]-t[0])>Ta){var i=n[0]i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Ca:-Ca),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(_e(e,g)||_e(p,g))&&(p[0]+=Ta,p[1]+=Ta,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&_e(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),x=m*m-y*(ve(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ye(d,(-m-M)/y);if(me(_,p),_=Me(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=fa(A-Ca)A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(fa(_[0]-w)Ca^(w<=_[0]&&_[0]<=S)){var L=ye(d,(-m+M)/y);return me(L,p),[_,Me(L)]}}}function u(t,e){var r=o?n:Ca-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=fa(i)>Ta,c=gr(n,6*za);return Te(t,e,c,o?[0,-n]:[-Ca,n-Ca])}function Fe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Oe(n,t,e,r){function u(r,u){return fa(r[0]-n)0?0:3:fa(r[0]-e)0?2:1:fa(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&J(s,i,n)>0&&++t:i[1]<=r&&J(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=ze(),C=Fe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Go.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ie(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ye(n){var t=0,e=Ca/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Ca/180,e=n[1]*Ca/180):[180*(t/Ca),180*(e/Ca)]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){zc+=u*n-r*t,r=n,u=t}var t,e,r,u;jc.point=function(i,o){jc.point=n,t=r=i,e=u=o},jc.lineEnd=function(){n(t,e)}}function $e(n,t){Rc>n&&(Rc=n),n>Pc&&(Pc=n),Dc>t&&(Dc=t),t>Uc&&(Uc=t)}function Xe(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Je(n,t){Mc+=n,_c+=t,++bc}function We(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);wc+=o*(t+n)/2,Sc+=o*(e+r)/2,kc+=o,Je(t=n,e=r)}var t,e;Fc.point=function(r,u){Fc.point=n,Je(t=r,e=u)}}function Ge(){Fc.point=Je}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);wc+=o*(r+n)/2,Sc+=o*(u+t)/2,kc+=o,o=u*n-r*t,Ec+=o*(r+n),Ac+=o*(u+t),Cc+=3*o,Je(r=n,u=t)}var t,e,r,u;Fc.point=function(i,o){Fc.point=n,Je(t=r=i,e=u=o)},Fc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,Na)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:v};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=fa(fa(w)-1)i||fa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*za),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ra,e*Ra])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*za,n[1]*za),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*Ra,n[1]*Ra]}function r(){a=Ie(o=sr(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u() +}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Lc,_=At,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=or(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Lc):He((b=+n)*za),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Oe(n[0][0],n[0][1],n[1][0],n[1][1]):At,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*za,d=n[1]%360*za,r()):[v*Ra,d*Ra]},t.rotate=function(n){return arguments.length?(m=n[0]%360*za,y=n[1]%360*za,x=n.length>2?n[2]%360*za:0,r()):[m*Ra,y*Ra,x*Ra]},Go.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*za,e*za)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Ca?n-Na:-Ca>n?n+Na:n,t]}function sr(n,t,e){return n?t||e?Ie(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function lr(n){return function(t,e){return t+=n,[t>Ca?t-Na:-Ca>t?t+Na:t,e]}}function fr(n){var t=lr(n);return t.invert=lr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),G(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),G(l*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Na)):(u=n+o*Na,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=Me([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function pr(n,t){var e=pe(t);e[0]-=n,xe(e);var r=W(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ta)%(2*Math.PI)}function vr(n,t,e){var r=Go.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=Go.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function xr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(tt(r-t)+u*o*tt(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ra,Math.atan2(o,Math.sqrt(r*r+u*u))*Ra]}:function(){return[n*Ra,t*Ra]};return p.distance=h,p}function Mr(){function n(n,u){var i=Math.sin(u*=za),o=Math.cos(u),a=fa((n*=za)-t),c=Math.cos(a);Oc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Ic.point=function(u,i){t=u*za,e=Math.sin(i*=za),r=Math.cos(i),Ic.point=n},Ic.lineEnd=function(){Ic.point=Ic.lineEnd=v}}function _r(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function br(n,t){function e(n,t){o>0?-La+Ta>t&&(t=-La+Ta):t>La-Ta&&(t=La-Ta);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Ca/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-La]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return fa(u)u;u++){for(;r>1&&J(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Lr(n,t){return n[0]-t[0]||n[1]-t[1]}function Tr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function qr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function zr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=ns.pop()||new Rr;return t.site=n,t}function Pr(n){$r(n),Gc.remove(n),ns.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&fa(e-c.circle.x)l;++l)s=a[l],c=a[l-1],Kr(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Wr(c.site,s.site,null,u),Vr(c),Vr(s)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Gc._;a;)if(r=Hr(a,o)-i,r>Ta)a=a.L;else{if(u=i-Fr(a,o),!(u>Ta)){r>-Ta?(t=a.P,e=a):u>-Ta?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Gc.insert(t,c),t||e){if(t===e)return $r(t),e=Dr(t.site),Gc.insert(c,e),c.edge=e.edge=Wr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Wr(t.site,c.site),void 0;$r(t),$r(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};Kr(e.edge,s,p,M),c.edge=Wr(s,n,null,M),e.edge=Wr(n,p,null,M),Vr(t),Vr(e)}}function Hr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Fr(n,t){var e=n.N;if(e)return Hr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Wc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(fa(r-t)>Ta||fa(u-e)>Ta)&&(a.splice(o,0,new Qr(Gr(i.site,l,fa(r-f)Ta?{x:f,y:fa(t-f)Ta?{x:fa(e-p)Ta?{x:h,y:fa(t-h)Ta?{x:fa(e-g)=-qa)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=ts.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Qc._;x;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:pu(e,r)})),i=us.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function du(n,t){for(var e,r=Go.interpolators.length;--r>=0&&!(e=Go.interpolators[r](n,t)););return e}function mu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(du(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function yu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function Mu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function bu(n){return n*n*n}function wu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Su(n){return function(t){return Math.pow(t,n)}}function ku(n){return 1-Math.cos(n*La)}function Eu(n){return Math.pow(2,10*(n-1))}function Au(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Na*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Na/t)}}function Nu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Lu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Tu(n,t){n=Go.hcl(n),t=Go.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function qu(n,t){n=Go.hsl(n),t=Go.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return it(e+i*n,r+o*n,u+a*n)+""}}function zu(n,t){n=Go.lab(n),t=Go.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ft(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Du(n){var t=[n.a,n.b],e=[n.c,n.d],r=Uu(t),u=Pu(t,e),i=Uu(ju(e,t,-u))||0;t[0]*e[1]180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:pu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:pu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:pu(g[0],p[0])},{i:e-2,x:pu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++ie;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ai(n){return n.reduce(ci,0)}function ci(n,t){return n+t[1]}function si(n,t){return li(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function li(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function fi(n){return[Go.min(n),Go.max(n)]}function hi(n,t){return n.parent==t.parent?1:2}function gi(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function pi(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function vi(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i0&&(n=r);return n}function di(n,t){return n.x-t.x}function mi(n,t){return t.x-n.x}function yi(n,t){return n.depth-t.depth}function xi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function _i(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function bi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function wi(n,t){return n.value-t.value}function Si(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function ki(n,t){n._pack_next=t,t._pack_prev=n}function Ei(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Ai(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(Ci),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ti(r,u,i),t(i),Si(r,i),r._pack_prev=i,Si(i,u),u=r._pack_next,o=3;s>o;o++){Ti(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(Ei(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!Ei(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Ni)}}function Ci(n){n._pack_next=n._pack_prev=n}function Ni(n){delete n._pack_next,delete n._pack_prev}function Li(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++iu&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function ji(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Hi(n){return n.rangeExtent?n.rangeExtent():ji(n.range())}function Fi(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Oi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ii(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:vs}function Yi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Yi:Fi,c=r?Ou:Fu;return o=u(n,t,c,e),a=u(t,n,c,du),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Ru)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Bi(n,t)},i.tickFormat=function(t,e){return Ji(n,t,e)},i.nice=function(t){return $i(n,t),u()},i.copy=function(){return Zi(n,t,e,r)},u()}function Vi(n,t){return Go.rebind(n,t,"range","rangeRound","interpolate","clamp")}function $i(n,t){return Oi(n,Ii(Xi(n,t)[2]))}function Xi(n,t){null==t&&(t=10);var e=ji(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Bi(n,t){return Go.range.apply(Go,Xi(n,t))}function Ji(n,t,e){var r=Xi(n,t);if(e){var u=rc.exec(e);if(u.shift(),"s"===u[8]){var i=Go.formatPrefix(Math.max(fa(r[0]),fa(r[1])));return u[7]||(u[7]="."+Wi(i.scale(r[2]))),u[8]="f",e=Go.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Gi(u[8],r)),e=u.join("")}else e=",."+Wi(r[2])+"f";return Go.format(e)}function Wi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Gi(n,t){var e=Wi(t[2]);return n in ds?Math.abs(e-Wi(Math.max(fa(t[0]),fa(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ki(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Oi(r.map(u),e?Math:ys);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=ji(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++0;h--)o.push(i(s)*h);for(s=0;o[s]c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return ms;arguments.length<2?t=ms:"function"!=typeof t&&(t=Go.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ki(n.copy(),t,e,r)},Vi(o,n)}function Qi(n,t,e){function r(t){return n(u(t))}var u=no(t),i=no(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Bi(e,n)},r.tickFormat=function(n,t){return Ji(e,n,t)},r.nice=function(n){return r.domain($i(e,n))},r.exponent=function(o){return arguments.length?(u=no(t=o),i=no(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Qi(n.copy(),t,e)},Vi(r,n)}function no(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function to(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Go.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++an?[0/0,0/0]:[n>0?o[n-1]:e[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return ro(n,t,e)},u()}function uo(n,t){function e(e){return e>=e?t[Go.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return uo(n,t)},e}function io(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Bi(n,t)},t.tickFormat=function(t,e){return Ji(n,t,e)},t.copy=function(){return io(n)},t}function oo(n){return n.innerRadius}function ao(n){return n.outerRadius}function co(n){return n.startAngle}function so(n){return n.endAngle}function lo(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f1&&u.push("H",r[0]),u.join("")}function po(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?fo(n):n[0]+Mo(n,Lo(n))}function qo(n){for(var t,e,r,u=-1,i=n.length;++ue?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Go.timer(function(){return p.c=c(r||1)?Ae:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a);return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=nc,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Zo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Vo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function $o(n){return n.toISOString()}function Xo(n,t,e){function r(t){return n(t) +}function u(n,e){var r=n[1]-n[0],u=r/e,i=Go.bisect(Ys,u);return i==Ys.length?[t.year,Xi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Ys[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Bo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Bo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=ji(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Bo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Xo(n.copy(),t,e)},Vi(r,n)}function Bo(n){return new Date(n)}function Jo(n){return JSON.parse(n.responseText)}function Wo(n){var t=na.createRange();return t.selectNode(na.body),t.createContextualFragment(n.responseText)}var Go={version:"3.4.6"};Date.now||(Date.now=function(){return+new Date});var Ko=[].slice,Qo=function(n){return Ko.call(n)},na=document,ta=na.documentElement,ea=window;try{Qo(ta.childNodes)[0].nodeType}catch(ra){Qo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{na.createElement("div").style.setProperty("opacity",0,"")}catch(ua){var ia=ea.Element.prototype,oa=ia.setAttribute,aa=ia.setAttributeNS,ca=ea.CSSStyleDeclaration.prototype,sa=ca.setProperty;ia.setAttribute=function(n,t){oa.call(this,n,t+"")},ia.setAttributeNS=function(n,t,e){aa.call(this,n,t,e+"")},ca.setProperty=function(n,t,e){sa.call(this,n,t+"",e)}}Go.ascending=n,Go.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Go.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},Go.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},Go.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},Go.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i1&&(e=e.map(r)),e=e.filter(t),e.length?Go.quantile(e.sort(n),.5):void 0};var la=e(n);Go.bisectLeft=la.left,Go.bisect=Go.bisectRight=la.right,Go.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Go.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Go.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Go.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Go.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Go.min(arguments,r),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var fa=Math.abs;Go.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(fa(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Go.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Go.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ha+n]=!0,n},remove:function(n){return n=ha+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===ga&&n.call(this,t.substring(1))}}),Go.behavior={},Go.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Go.event=null,Go.requote=function(n){return n.replace(va,"\\$&")};var va=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,da={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ma=function(n,t){return t.querySelector(n)},ya=function(n,t){return t.querySelectorAll(n)},xa=ta[p(ta,"matchesSelector")],Ma=function(n,t){return xa.call(n,t)};"function"==typeof Sizzle&&(ma=function(n,t){return Sizzle(n,t)[0]||null},ya=Sizzle,Ma=Sizzle.matchesSelector),Go.selection=function(){return Sa};var _a=Go.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o=0&&(e=n.substring(0,t),n=n.substring(t+1)),ba.hasOwnProperty(e)?{space:ba[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Go.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(L(e,n[e],t));return this}if(2>r)return ea.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(L(n,t,e))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(T(t,n[t]));return this}return this.each(T(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=q(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=q(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},_a.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++rr;++r)p[r]=z(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},_a.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return this.each(function(){++n}),n};var wa=[];Go.selection.enter=U,Go.selection.enter.prototype=wa,wa.append=_a.append,wa.empty=_a.empty,wa.node=_a.node,wa.call=_a.call,wa.size=_a.size,wa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ka=Go.map({mouseenter:"mouseover",mouseleave:"mouseout"});ka.forEach(function(n){"on"+n in na&&ka.remove(n)});var Ea="onselectstart"in na?null:p(ta.style,"userSelect"),Aa=0;Go.mouse=function(n){return Z(n,x())},Go.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Qo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Go.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Go.event.target===f),g({type:"dragend"}))}var s,l=this,f=Go.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Go.select(u()).on(i+d,a).on(o+d,c),y=Y(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Go.mouse,X,"mousemove","mouseup"),i=t(V,Go.touch,$,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Go.rebind(n,e,"on")};var Ca=Math.PI,Na=2*Ca,La=Ca/2,Ta=1e-6,qa=Ta*Ta,za=Ca/180,Ra=180/Ca,Da=Math.SQRT2,Pa=2,Ua=4;Go.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(Pa*h)*(e*nt(Da*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Da*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Da*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+Ua*f)/(2*i*Pa*h),p=(c*c-i*i-Ua*f)/(2*c*Pa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Da;return e.duration=1e3*y,e},Go.behavior.zoom=function(){function n(n){n.on(A,s).on(Fa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Go.mouse(r),g),a(s)}function e(){f.on(C,ea===r?h:null).on(N,null),p(l&&Go.event.target===i),c(s)}var r=this,i=Go.event.target,s=T.of(r,arguments),l=0,f=Go.select(ea).on(C,n).on(N,e),g=t(Go.mouse(r)),p=Y();H.call(r),o(s)}function l(){function n(){var n=Go.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Go.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-m){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),y(),a(p)}m=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];d=h*h+g*g}}function i(){for(var n,t,e,i,o=Go.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Go.event.touches.length){for(var t=Go.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(x,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},d=0,x=".zoom-"+Go.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=Go.select(Go.event.target).on(M,i).on(_,f),w=Go.select(g).on(A,null).on(L,e),k=Y();H.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);d?clearTimeout(d):(H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y();var e=v||Go.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*ja())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Go.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Go.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Ha,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;Ls?Go.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Go.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Ha:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Go.rebind(n,T,"on")};var ja,Ha=[0,1/0],Fa="onwheel"in na?(ja=function(){return-Go.event.deltaY*(Go.event.deltaMode?120:1)},"wheel"):"onmousewheel"in na?(ja=function(){return Go.event.wheelDelta},"mousewheel"):(ja=function(){return-Go.event.detail},"MozMousePixelScroll");et.prototype.toString=function(){return this.rgb()+""},Go.hsl=function(n,t,e){return 1===arguments.length?n instanceof ut?rt(n.h,n.s,n.l):_t(""+n,bt,rt):rt(+n,+t,+e)};var Oa=ut.prototype=new et;Oa.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),rt(this.h,this.s,this.l/n)},Oa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),rt(this.h,this.s,n*this.l)},Oa.rgb=function(){return it(this.h,this.s,this.l)},Go.hcl=function(n,t,e){return 1===arguments.length?n instanceof at?ot(n.h,n.c,n.l):n instanceof lt?ht(n.l,n.a,n.b):ht((n=wt((n=Go.rgb(n)).r,n.g,n.b)).l,n.a,n.b):ot(+n,+t,+e)};var Ia=at.prototype=new et;Ia.brighter=function(n){return ot(this.h,this.c,Math.min(100,this.l+Ya*(arguments.length?n:1)))},Ia.darker=function(n){return ot(this.h,this.c,Math.max(0,this.l-Ya*(arguments.length?n:1)))},Ia.rgb=function(){return ct(this.h,this.c,this.l).rgb()},Go.lab=function(n,t,e){return 1===arguments.length?n instanceof lt?st(n.l,n.a,n.b):n instanceof at?ct(n.l,n.c,n.h):wt((n=Go.rgb(n)).r,n.g,n.b):st(+n,+t,+e)};var Ya=18,Za=.95047,Va=1,$a=1.08883,Xa=lt.prototype=new et;Xa.brighter=function(n){return st(Math.min(100,this.l+Ya*(arguments.length?n:1)),this.a,this.b)},Xa.darker=function(n){return st(Math.max(0,this.l-Ya*(arguments.length?n:1)),this.a,this.b)},Xa.rgb=function(){return ft(this.l,this.a,this.b)},Go.rgb=function(n,t,e){return 1===arguments.length?n instanceof xt?yt(n.r,n.g,n.b):_t(""+n,yt,it):yt(~~n,~~t,~~e)};var Ba=xt.prototype=new et;Ba.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),yt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):yt(u,u,u)},Ba.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),yt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Ba.hsl=function(){return bt(this.r,this.g,this.b)},Ba.toString=function(){return"#"+Mt(this.r)+Mt(this.g)+Mt(this.b)};var Ja=Go.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ja.forEach(function(n,t){Ja.set(n,dt(t))}),Go.functor=Et,Go.xhr=Ct(At),Go.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Go.csv=Go.dsv(",","text/csv"),Go.tsv=Go.dsv(" ","text/tab-separated-values"),Go.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Wa,Ga,Ka,Qa,nc,tc=ea[p(ea,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Go.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Ga?Ga.n=i:Wa=i,Ga=i,Ka||(Qa=clearTimeout(Qa),Ka=1,tc(Tt))},Go.timer.flush=function(){qt(),zt()},Go.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var ec=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);Go.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Go.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),ec[8+e/3]};var rc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,uc=Go.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Go.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ic=Go.time={},oc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){ac.setUTCDate.apply(this._,arguments)},setDay:function(){ac.setUTCDay.apply(this._,arguments)},setFullYear:function(){ac.setUTCFullYear.apply(this._,arguments)},setHours:function(){ac.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){ac.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){ac.setUTCMinutes.apply(this._,arguments)},setMonth:function(){ac.setUTCMonth.apply(this._,arguments)},setSeconds:function(){ac.setUTCSeconds.apply(this._,arguments)},setTime:function(){ac.setTime.apply(this._,arguments)}};var ac=Date.prototype;ic.year=Ht(function(n){return n=ic.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ic.years=ic.year.range,ic.years.utc=ic.year.utc.range,ic.day=Ht(function(n){var t=new oc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ic.days=ic.day.range,ic.days.utc=ic.day.utc.range,ic.dayOfYear=function(n){var t=ic.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ic[n]=Ht(function(n){return(n=ic.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ic.year(n).getDay();return Math.floor((ic.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ic[n+"s"]=e.range,ic[n+"s"].utc=e.utc.range,ic[n+"OfYear"]=function(n){var e=ic.year(n).getDay();return Math.floor((ic.dayOfYear(n)+(e+t)%7)/7)}}),ic.week=ic.sunday,ic.weeks=ic.sunday.range,ic.weeks.utc=ic.sunday.utc.range,ic.weekOfYear=ic.sundayOfYear;var cc={"-":"",_:" ",0:"0"},sc=/^\s*\d+/,lc=/^%/;Go.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var fc=Go.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Go.format=fc.numberFormat,Go.geo={},ce.prototype={s:0,t:0,add:function(n){se(n,this.t,hc),se(hc.s,this.s,this),this.s?this.t+=hc.t:this.s=hc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var hc=new ce;Go.geo.stream=function(n,t){n&&gc.hasOwnProperty(n.type)?gc[n.type](n,t):le(n,t)};var gc={Feature:function(n,t){le(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Ca+n:n,mc.lineStart=mc.lineEnd=mc.point=v}};Go.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*za,e*za]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);xe(o),o=Me(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ra*s,d=fa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ra;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ra;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=fa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;mc.point(n,e),t(n,e)}function i(){mc.lineStart()}function o(){u(v,d),mc.lineEnd(),fa(y)>Ta&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:ndc?(l=-(h=180),f=-(g=90)):y>Ta?g=90:-Ta>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Go.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e); +for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Go.geo.centroid=function(n){yc=xc=Mc=_c=bc=wc=Sc=kc=Ec=Ac=Cc=0,Go.geo.stream(n,Nc);var t=Ec,e=Ac,r=Cc,u=t*t+e*e+r*r;return qa>u&&(t=wc,e=Sc,r=kc,Ta>xc&&(t=Mc,e=_c,r=bc),u=t*t+e*e+r*r,qa>u)?[0/0,0/0]:[Math.atan2(e,t)*Ra,G(r/Math.sqrt(u))*Ra]};var yc,xc,Mc,_c,bc,wc,Sc,kc,Ec,Ac,Cc,Nc={sphere:v,point:be,lineStart:Se,lineEnd:ke,polygonStart:function(){Nc.lineStart=Ee},polygonEnd:function(){Nc.lineStart=Se}},Lc=Te(Ae,Pe,je,[-Ca,-Ca/2]),Tc=1e9;Go.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Oe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Go.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,Go.geo.albers=function(){return Go.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Go.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Go.geo.albers(),o=Go.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Go.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Ta,f+.12*s+Ta],[l-.214*s-Ta,f+.234*s-Ta]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Ta,f+.166*s+Ta],[l-.115*s-Ta,f+.234*s-Ta]]).stream(c).point,n},n.scale(1070)};var qc,zc,Rc,Dc,Pc,Uc,jc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){zc=0,jc.lineStart=Ve},polygonEnd:function(){jc.lineStart=jc.lineEnd=jc.point=v,qc+=fa(zc/2)}},Hc={point:$e,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Fc={point:Je,lineStart:We,lineEnd:Ge,polygonStart:function(){Fc.lineStart=Ke},polygonEnd:function(){Fc.point=Je,Fc.lineStart=We,Fc.lineEnd=Ge}};Go.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Go.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return qc=0,Go.geo.stream(n,u(jc)),qc},n.centroid=function(n){return Mc=_c=bc=wc=Sc=kc=Ec=Ac=Cc=0,Go.geo.stream(n,u(Fc)),Cc?[Ec/Cc,Ac/Cc]:kc?[wc/kc,Sc/kc]:bc?[Mc/bc,_c/bc]:[0/0,0/0]},n.bounds=function(n){return Pc=Uc=-(Rc=Dc=1/0),Go.geo.stream(n,u(Hc)),[[Rc,Dc],[Pc,Uc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):At,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Xe:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Go.geo.albersUsa()).context(null)},Go.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Go.geo.projection=ur,Go.geo.projectionMutator=ir,(Go.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,Go.geo.rotation=function(n){function t(t){return t=n(t[0]*za,t[1]*za),t[0]*=Ra,t[1]*=Ra,t}return n=sr(n[0]%360*za,n[1]*za,n.length>2?n[2]*za:0),t.invert=function(t){return t=n.invert(t[0]*za,t[1]*za),t[0]*=Ra,t[1]*=Ra,t},t},cr.invert=ar,Go.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=sr(-n[0]*za,-n[1]*za,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ra,n[1]*=Ra}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*za,u*za),n):t},n.precision=function(r){return arguments.length?(e=gr(t*za,(u=+r)*za),n):u},n.angle(90)},Go.geo.distance=function(n,t){var e,r=(t[0]-n[0])*za,u=n[1]*za,i=t[1]*za,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Go.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Go.range(Math.ceil(i/d)*d,u,d).map(h).concat(Go.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Go.range(Math.ceil(r/p)*p,e,p).filter(function(n){return fa(n%d)>Ta}).map(l)).concat(Go.range(Math.ceil(a/v)*v,o,v).filter(function(n){return fa(n%m)>Ta}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=vr(a,o,90),f=dr(r,e,y),h=vr(s,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ta],[180,90-Ta]]).minorExtent([[-180,-80-Ta],[180,80+Ta]])},Go.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return Go.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Go.geo.interpolate=function(n,t){return xr(n[0]*za,n[1]*za,t[0]*za,t[1]*za)},Go.geo.length=function(n){return Oc=0,Go.geo.stream(n,Ic),Oc};var Oc,Ic={sphere:v,point:v,lineStart:Mr,lineEnd:v,polygonStart:v,polygonEnd:v},Yc=_r(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Go.geo.azimuthalEqualArea=function(){return ur(Yc)}).raw=Yc;var Zc=_r(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},At);(Go.geo.azimuthalEquidistant=function(){return ur(Zc)}).raw=Zc,(Go.geo.conicConformal=function(){return Ye(br)}).raw=br,(Go.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var Vc=_r(function(n){return 1/n},Math.atan);(Go.geo.gnomonic=function(){return ur(Vc)}).raw=Vc,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-La]},(Go.geo.mercator=function(){return kr(Sr)}).raw=Sr;var $c=_r(function(){return 1},Math.asin);(Go.geo.orthographic=function(){return ur($c)}).raw=$c;var Xc=_r(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Go.geo.stereographic=function(){return ur(Xc)}).raw=Xc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-La]},(Go.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=Er,Go.geom={},Go.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Lr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Nr(a),l=Nr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ta)*Ta,y:Math.round(o(n,t)/Ta)*Ta,i:t}})}var r=Ar,u=Cr,i=r,o=u,a=es;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=lu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=Et(a),M=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.xm&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=lu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},g=-1,null==t){for(;++g=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=os.get(e)||is,r=as.get(r)||At,yu(r(e.apply(null,Ko.call(arguments,1))))},Go.interpolateHcl=Tu,Go.interpolateHsl=qu,Go.interpolateLab=zu,Go.interpolateRound=Ru,Go.transform=function(n){var t=na.createElementNS(Go.ns.prefix.svg,"g");return(Go.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Du(e?e.matrix:cs)})(n)},Du.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var cs={a:1,b:0,c:0,d:1,e:0,f:0};Go.interpolateTransform=Hu,Go.layout={},Go.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Go.event.x,n.py=Go.event.y,a.resume()}var e,r,u,i,o,a={},c=Go.dispatch("start","tick","end"),s=[1,1],l=.9,f=ss,h=ls,g=-30,p=fs,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Ju(t=Go.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Go.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Go.behavior.drag().origin(At).on("dragstart.force",Vu).on("drag.force",t).on("dragend.force",$u)),arguments.length?(this.on("mouseover.force",Xu).on("mouseout.force",Bu).call(e),void 0):e},Go.rebind(a,c,"on")};var ss=20,ls=1,fs=1/0;Go.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++fg;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=At,e=ui,r=ii,u=ri,i=ti,o=ei;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:gs.get(t)||ui,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ps.get(t)||ii,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var gs=Go.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(oi),i=n.map(ai),o=Go.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Go.range(n.length).reverse()},"default":ui}),ps=Go.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ii});Go.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=l[0]&&a<=l[1]&&(o=c[Go.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=fi,u=si;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return li(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Go.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h0&&(_i(bi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!pi(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!gi(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];xi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=vi(l,mi),h=vi(l,di),g=vi(l,yi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return xi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Go.layout.hierarchy().sort(null).value(null),e=hi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Wu(n,t)},Go.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,xi(a,function(n){n.r=+l(n.value)}),xi(a,Ai),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;xi(a,function(n){n.r+=f}),xi(a,Ai),xi(a,function(n){n.r-=f})}return Li(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Go.layout.hierarchy().sort(wi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Wu(n,e)},Go.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;xi(c,function(n){var t=n.children;t&&t.length?(n.x=zi(t),n.y=qi(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ri(c),f=Di(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return xi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Go.layout.hierarchy().sort(null).value(null),e=hi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Wu(n,t)},Go.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++ie.dx)&&(l=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Go.random.normal.apply(Go,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Go.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Go.scale={};var vs={floor:At,ceil:At};Go.scale.linear=function(){return Zi([0,1],[0,1],du,!1)};var ds={s:1,g:1,p:1,r:1,e:1};Go.scale.log=function(){return Ki(Go.scale.linear().domain([0,1]),10,!0,[1,10])};var ms=Go.format(".0e"),ys={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Go.scale.pow=function(){return Qi(Go.scale.linear(),1,[0,1])},Go.scale.sqrt=function(){return Go.scale.pow().exponent(.5)},Go.scale.ordinal=function(){return to([],{t:"range",a:[[]]})},Go.scale.category10=function(){return Go.scale.ordinal().range(xs)},Go.scale.category20=function(){return Go.scale.ordinal().range(Ms)},Go.scale.category20b=function(){return Go.scale.ordinal().range(_s)},Go.scale.category20c=function(){return Go.scale.ordinal().range(bs)};var xs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(mt),Ms=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(mt),_s=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(mt),bs=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(mt);Go.scale.quantile=function(){return eo([],[])},Go.scale.quantize=function(){return ro(0,1,[0,1])},Go.scale.threshold=function(){return uo([.5],[0,1])},Go.scale.identity=function(){return io([0,1])},Go.svg={},Go.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ws,a=u.apply(this,arguments)+ws,c=(o>a&&(c=o,o=a,a=c),a-o),s=Ca>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a); +return c>=Ss?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=oo,e=ao,r=co,u=so;return n.innerRadius=function(e){return arguments.length?(t=Et(e),n):t},n.outerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.startAngle=function(t){return arguments.length?(r=Et(t),n):r},n.endAngle=function(t){return arguments.length?(u=Et(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ws;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ws=-La,Ss=Na-Ta;Go.svg.line=function(){return lo(At)};var ks=Go.map({linear:fo,"linear-closed":ho,step:go,"step-before":po,"step-after":vo,basis:bo,"basis-open":wo,"basis-closed":So,bundle:ko,cardinal:xo,"cardinal-open":mo,"cardinal-closed":yo,monotone:To});ks.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Es=[0,2/3,1/3,0],As=[0,1/3,2/3,0],Cs=[0,1/6,2/3,1/6];Go.svg.line.radial=function(){var n=lo(qo);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},po.reverse=vo,vo.reverse=po,Go.svg.area=function(){return zo(At)},Go.svg.area.radial=function(){var n=zo(qo);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Go.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ws,l=s.call(n,u,r)+ws;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Ca)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Ro,c=co,s=so;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(s=Et(t),n):s},n},Go.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Do;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Go.svg.diagonal.radial=function(){var n=Go.svg.diagonal(),t=Do,e=n.projection;return n.projection=function(n){return arguments.length?e(Po(t=n)):t},n},Go.svg.symbol=function(){function n(n,r){return(Ns.get(t.call(this,n,r))||Ho)(e.call(this,n,r))}var t=jo,e=Uo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var Ns=Go.map({circle:Ho,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*zs)),e=t*zs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/qs),e=t*qs/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/qs),e=t*qs/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Go.svg.symbolTypes=Ns.keys();var Ls,Ts,qs=Math.sqrt(3),zs=Math.tan(30*za),Rs=[],Ds=0;Rs.call=_a.call,Rs.empty=_a.empty,Rs.node=_a.node,Rs.size=_a.size,Go.transition=function(n){return arguments.length?Ls?n.transition():n:Sa.transition()},Go.transition.prototype=Rs,Rs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Fo(u,this.id)},Rs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Rs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:du,a=Go.ns.qualify(n);return Oo(this,"attr."+n,t,a.local?i:u)},Rs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Go.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Rs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=ea.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=du(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Oo(this,"style."+n,t,u)},Rs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,ea.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Rs.text=function(n){return Oo(this,"text",n,Io)},Rs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Rs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Go.ease.apply(Go,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Rs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Rs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Rs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Ts,u=Ls;Ls=e,P(this,function(t,r,u){Ts=t.__transition__[e],n.call(t,t.__data__,r,u)}),Ts=r,Ls=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Go.dispatch("start","end"))).on(n,t)});return this},Rs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ds,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Yo(e,s,i,r)),n.push(e)}return Fo(o,i)},Go.svg.axis=function(){function n(n){n.each(function(){var n,s=Go.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):At:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ta),d=Go.transition(p.exit()).style("opacity",Ta).remove(),m=Go.transition(p.order()).style("opacity",1),y=Hi(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Go.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Zo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Zo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Vo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Vo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Go.scale.linear(),r=Ps,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Us?t+"":Ps,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ps="bottom",Us={top:1,right:1,bottom:1,left:1};Go.svg.brush=function(){function n(i){i.each(function(){var i=Go.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,At);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return js[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Go.transition(i),h=Go.transition(o);c&&(l=Hi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Hi(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Go.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),y())}function p(){32==Go.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,y())}function v(){var n=Go.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Go.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Go.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Go.select(Go.event.target),w=a.of(_,arguments),S=Go.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=Y(),L=Go.mouse(_),T=Go.select(ea).on("keydown.brush",u).on("keyup.brush",p);if(Go.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",m):T.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Go.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Go.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Hs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ls?Go.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=mu(l,t.x),r=mu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Hs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Hs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Go.rebind(n,a,"on")};var js={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Hs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Fs=ic.format=fc.timeFormat,Os=Fs.utc,Is=Os("%Y-%m-%dT%H:%M:%S.%LZ");Fs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?$o:Is,$o.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},$o.toString=Is.toString,ic.second=Ht(function(n){return new oc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ic.seconds=ic.second.range,ic.seconds.utc=ic.second.utc.range,ic.minute=Ht(function(n){return new oc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ic.minutes=ic.minute.range,ic.minutes.utc=ic.minute.utc.range,ic.hour=Ht(function(n){var t=n.getTimezoneOffset()/60;return new oc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ic.hours=ic.hour.range,ic.hours.utc=ic.hour.utc.range,ic.month=Ht(function(n){return n=ic.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ic.months=ic.month.range,ic.months.utc=ic.month.utc.range;var Ys=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Zs=[[ic.second,1],[ic.second,5],[ic.second,15],[ic.second,30],[ic.minute,1],[ic.minute,5],[ic.minute,15],[ic.minute,30],[ic.hour,1],[ic.hour,3],[ic.hour,6],[ic.hour,12],[ic.day,1],[ic.day,2],[ic.week,1],[ic.month,1],[ic.month,3],[ic.year,1]],Vs=Fs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ae]]),$s={range:function(n,t,e){return Go.range(Math.ceil(n/e)*e,+t,e).map(Bo)},floor:At,ceil:At};Zs.year=ic.year,ic.scale=function(){return Xo(Go.scale.linear(),Zs,Vs)};var Xs=Zs.map(function(n){return[n[0].utc,n[1]]}),Bs=Os.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ae]]);Xs.year=ic.year.utc,ic.scale.utc=function(){return Xo(Go.scale.linear(),Xs,Bs)},Go.text=Ct(function(n){return n.responseText}),Go.json=function(n,t){return Nt(n,"application/json",Jo,t)},Go.html=function(n,t){return Nt(n,"text/html",Wo,t)},Go.xml=Ct(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Go):"object"==typeof module&&module.exports?module.exports=Go:this.d3=Go}(); \ No newline at end of file diff --git a/web/orchestrator/public/js/discover.js b/web/orchestrator/public/js/discover.js new file mode 100644 index 00000000000..722511ac348 --- /dev/null +++ b/web/orchestrator/public/js/discover.js @@ -0,0 +1,33 @@ + +$(document).ready(function () { + $('button[data-btn=discover-instance]').unbind("click"); + $('button[data-btn=discover-instance]').click(function() { + + if (!$("#discoverHostName").val()) { + return addAlert("You must enter a host name"); + } + if (!$("#discoverPort").val()) { + return addAlert("You must enter a port"); + } + discover($("#discoverHostName").val(), $("#discoverPort").val()) + return false; + }); + $("#discoverHostName").focus(); +}); + +function discover(hostname, port) { + showLoader(); + var uri = "/api/discover/"+hostname+"/"+port; + $.get(appUrl(uri), function (operationResult) { + hideLoader(); + if (operationResult.Code == "ERROR" || operationResult.Details == null) { + addAlert(operationResult.Message) + } else { + var instance = operationResult.Details; + addInfo('Discovered ' + +instance.Key.Hostname+":"+instance.Key.Port+'' + ); + } + }, "json"); + +} \ No newline at end of file diff --git a/web/orchestrator/public/js/instance-problems.js b/web/orchestrator/public/js/instance-problems.js new file mode 100644 index 00000000000..b3d5b99964b --- /dev/null +++ b/web/orchestrator/public/js/instance-problems.js @@ -0,0 +1,69 @@ +$(document).ready(function() { + showLoader(); + + var problemsURI = "/api/problems"; + if (typeof currentClusterName != "undefined") { + problemsURI += "/" + currentClusterName(); + } + $.get(appUrl(problemsURI), function(instances) { + instances = instances || []; + $.get(appUrl("/api/maintenance"), function(maintenanceList) { + maintenanceList = maintenanceList || []; + normalizeInstances(instances, maintenanceList); + displayProblemInstances(instances); + }, "json"); + }, "json"); + + function displayProblemInstances(instances) { + hideLoader(); + + if (isAnonymized()) { + $("#instance_problems").remove(); + return; + } + + function SortByProblemOrder(instance0, instance1) { + var orderDiff = instance0.problemOrder - instance1.problemOrder; + if (orderDiff != 0) return orderDiff; + var orderDiff = instance1.ReplicationLagSeconds.Int64 - instance0.ReplicationLagSeconds.Int64; + if (orderDiff != 0) return orderDiff; + orderDiff = instance0.title.localeCompare(instance1.title); + if (orderDiff != 0) return orderDiff; + return 0; + } + instances.sort(SortByProblemOrder); + + var countProblemInstances = 0; + instances.forEach(function(instance) { + var considerInstance = instance.hasProblem + if (countProblemInstances >= 1000) { + considerInstance = false; + } + if (considerInstance) { + var li = $("
    31. "); + var instanceEl = Instance.createElement(instance).addClass("instance-problem").appendTo(li); + $("#instance_problems ul").append(li); + + renderInstanceElement(instanceEl, instance, "problems"); //popoverElement + instanceEl.click(function() { + openNodeModal(instance); + return false; + }); + if (countProblemInstances == 0) { + // First problem instance + $("#instance_problems_button").addClass("btn-" + instance.renderHint) + } + countProblemInstances += 1; + } + }); + if (countProblemInstances > 0 && (autoshowProblems() == "true") && ($.cookie("anonymize") != "true")) { + $("#instance_problems .dropdown-toggle").dropdown('toggle'); + } + if (countProblemInstances == 0) { + $("#instance_problems").hide(); + } + + $("div.popover").popover(); + $("div.popover").show(); + } +}); diff --git a/web/orchestrator/public/js/jquery-ui.min.js b/web/orchestrator/public/js/jquery-ui.min.js new file mode 100644 index 00000000000..456cd568d8f --- /dev/null +++ b/web/orchestrator/public/js/jquery-ui.min.js @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.11.4 - 2015-08-21 +* http://jqueryui.com +* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, selectable.js +* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ + +(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(t,s){var n,a,o,r=t.nodeName.toLowerCase();return"area"===r?(n=t.parentNode,a=n.name,t.href&&a&&"map"===n.nodeName.toLowerCase()?(o=e("img[usemap='#"+a+"']")[0],!!o&&i(o)):!1):(/^(input|select|textarea|button|object)$/.test(r)?!t.disabled:"a"===r?t.href||s:s)&&i(t)}function i(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var s=0,n=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,a=n.call(arguments,1),o=0,r=a.length;r>o;o++)for(i in a[o])s=a[o][i],a[o].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(a){var o="string"==typeof a,r=n.call(arguments,1),h=this;return o?this.each(function(){var i,n=e.data(this,s);return"instance"===a?(h=n,!1):n?e.isFunction(n[a])&&"_"!==a.charAt(0)?(i=n[a].apply(n,r),i!==n&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+a+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+a+"'")}):(r.length&&(a=e.widget.extend.apply(null,[a].concat(r))),this.each(function(){var t=e.data(this,s);t?(t.option(a||{}),t._init&&t._init()):e.data(this,s,new i(a,this))})),h}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
      ",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=s++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget;var a=!1;e(document).mouseup(function(){a=!1}),e.widget("ui.mouse",{version:"1.11.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!a){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,n="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),a=!0,!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button)return this._mouseUp(t);if(!t.which)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),a=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),function(){function t(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function i(t,i){return parseInt(e.css(t,i),10)||0}function s(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var n,a,o=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=e.fn.position;e.position={scrollbarWidth:function(){if(void 0!==n)return n;var t,i,s=e("
      "),a=s.children()[0];return e("body").append(s),t=a.offsetWidth,s.css("overflow","scroll"),i=a.offsetWidth,t===i&&(i=s[0].clientWidth),s.remove(),n=t-i},getScrollInfo:function(t){var i=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),s=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),n="scroll"===i||"auto"===i&&t.widthi?"left":t>0?"right":"center",vertical:0>a?"top":s>0?"bottom":"middle"};d>m&&m>r(t+i)&&(h.horizontal="center"),c>g&&g>r(s+a)&&(h.vertical="middle"),h.important=o(r(t),r(i))>o(r(s),r(a))?"horizontal":"vertical",n.using.call(this,e,h)}),u.offset(e.extend(N,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=e.left-t.collisionPosition.marginLeft,h=n-r,l=r+t.collisionWidth-a-n;t.collisionWidth>a?h>0&&0>=l?(i=e.left+h+t.collisionWidth-a-n,e.left+=h-i):e.left=l>0&&0>=h?n:h>l?n+a-t.collisionWidth:n:h>0?e.left+=h:l>0?e.left-=l:e.left=o(e.left-r,e.left)},top:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollTop:s.offset.top,a=t.within.height,r=e.top-t.collisionPosition.marginTop,h=n-r,l=r+t.collisionHeight-a-n;t.collisionHeight>a?h>0&&0>=l?(i=e.top+h+t.collisionHeight-a-n,e.top+=h-i):e.top=l>0&&0>=h?n:h>l?n+a-t.collisionHeight:n:h>0?e.top+=h:l>0?e.top-=l:e.top=o(e.top-r,e.top)}},flip:{left:function(e,t){var i,s,n=t.within,a=n.offset.left+n.scrollLeft,o=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,d=l+t.collisionWidth-o-h,c="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,f=-2*t.offset[0];0>u?(i=e.left+c+p+f+t.collisionWidth-o-a,(0>i||r(u)>i)&&(e.left+=c+p+f)):d>0&&(s=e.left-t.collisionPosition.marginLeft+c+p+f-h,(s>0||d>r(s))&&(e.left+=c+p+f))},top:function(e,t){var i,s,n=t.within,a=n.offset.top+n.scrollTop,o=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,d=l+t.collisionHeight-o-h,c="top"===t.my[1],p=c?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,f="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,m=-2*t.offset[1];0>u?(s=e.top+p+f+m+t.collisionHeight-o-a,(0>s||r(u)>s)&&(e.top+=p+f+m)):d>0&&(i=e.top-t.collisionPosition.marginTop+p+f+m-h,(i>0||d>r(i))&&(e.top+=p+f+m))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,n,o,r=document.getElementsByTagName("body")[0],h=document.createElement("div");t=document.createElement(r?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},r&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)t.style[o]=s[o];t.appendChild(h),i=r||document.documentElement,i.insertBefore(t,i.firstChild),h.style.cssText="position: absolute; left: 10.7432222px;",n=e(h).offset().left,a=n>10&&11>n,t.innerHTML="",i.removeChild(t)}()}(),e.ui.position,e.widget("ui.draggable",e.ui.mouse,{version:"1.11.4",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._setHandleClassName(),this._mouseInit()},_setOption:function(e,t){this._super(e,t),"handle"===e&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(t){var i=this.options;return this._blurActiveElement(t),this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(t){this.iframeBlocks=this.document.find(t).map(function(){var t=e(this);return e("
      ").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var i=this.document[0];if(this.handleElement.is(t.target))try{i.activeElement&&"body"!==i.activeElement.nodeName.toLowerCase()&&e(i.activeElement).blur()}catch(s){}},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===e(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(t),this.originalPosition=this.position=this._generatePosition(t,!1),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._normalizeRightBottom(),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_refreshOffsets:function(e){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:e.pageX-this.offset.left,top:e.pageY-this.offset.top}},_mouseDrag:function(t,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(t,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i=this,s=!1;return e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",t)!==!1&&i._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1},_mouseUp:function(t){return this._unblockFrames(),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),this.handleElement.is(t.target)&&this.element.focus(),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this.handleElement.addClass("ui-draggable-handle")},_removeHandleClassName:function(){this.handleElement.removeClass("ui-draggable-handle")},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper),n=s?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_isRootNode:function(e){return/(html|body)/i.test(e.tagName)||e===this.document[0]},_getParentOffset:function(){var t=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var e=this.element.position(),t=this._isRootNode(this.scrollParent[0]);return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+(t?0:this.scrollParent.scrollTop()),left:e.left-(parseInt(this.helper.css("left"),10)||0)+(t?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options,a=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,e(window).scrollLeft()+e(window).width()-this.helperProportions.width-this.margins.left,e(window).scrollTop()+(e(window).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,e(a).width()-this.helperProportions.width-this.margins.left,(e(a).height()||a.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=e(n.containment),s=i[0],s&&(t=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(e,t){t||(t=this.position);var i="absolute"===e?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:t.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:t.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(e,t){var i,s,n,a,o=this.options,r=this._isRootNode(this.scrollParent[0]),h=e.pageX,l=e.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),t&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.lefti[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,h=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a),"y"===o.axis&&(h=this.originalPageX),"x"===o.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_normalizeRightBottom:function(){"y"!==this.options.axis&&"auto"!==this.helper.css("right")&&(this.helper.width(this.helper.width()),this.helper.css("right","auto")),"x"!==this.options.axis&&"auto"!==this.helper.css("bottom")&&(this.helper.height(this.helper.height()),this.helper.css("bottom","auto"))},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i,s){var n=e.extend({},i,{item:s.element});s.sortables=[],e(s.options.connectToSortable).each(function(){var i=e(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",t,n))})},stop:function(t,i,s){var n=e.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,e.each(s.sortables,function(){var e=this;e.isOver?(e.isOver=0,s.cancelHelperRemoval=!0,e.cancelHelperRemoval=!1,e._storedCSS={position:e.placeholder.css("position"),top:e.placeholder.css("top"),left:e.placeholder.css("left")},e._mouseStop(t),e.options.helper=e.options._helper):(e.cancelHelperRemoval=!0,e._trigger("deactivate",t,n))})},drag:function(t,i,s){e.each(s.sortables,function(){var n=!1,a=this;a.positionAbs=s.positionAbs,a.helperProportions=s.helperProportions,a.offset.click=s.offset.click,a._intersectsWith(a.containerCache)&&(n=!0,e.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==a&&this._intersectsWith(this.containerCache)&&e.contains(a.element[0],this.element[0])&&(n=!1),n +})),n?(a.isOver||(a.isOver=1,s._parent=i.helper.parent(),a.currentItem=i.helper.appendTo(a.element).data("ui-sortable-item",!0),a.options._helper=a.options.helper,a.options.helper=function(){return i.helper[0]},t.target=a.currentItem[0],a._mouseCapture(t,!0),a._mouseStart(t,!0,!0),a.offset.click.top=s.offset.click.top,a.offset.click.left=s.offset.click.left,a.offset.parent.left-=s.offset.parent.left-a.offset.parent.left,a.offset.parent.top-=s.offset.parent.top-a.offset.parent.top,s._trigger("toSortable",t),s.dropped=a.element,e.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,a.fromOutside=s),a.currentItem&&(a._mouseDrag(t),i.position=a.position)):a.isOver&&(a.isOver=0,a.cancelHelperRemoval=!0,a.options._revert=a.options.revert,a.options.revert=!1,a._trigger("out",t,a._uiHash(a)),a._mouseStop(t,!0),a.options.revert=a.options._revert,a.options.helper=a.options._helper,a.placeholder&&a.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(t),i.position=s._generatePosition(t,!0),s._trigger("fromSortable",t),s.dropped=!1,e.each(s.sortables,function(){this.refreshPositions()}))})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,i,s){var n=e("body"),a=s.options;n.css("cursor")&&(a._cursor=n.css("cursor")),n.css("cursor",a.cursor)},stop:function(t,i,s){var n=s.options;n._cursor&&e("body").css("cursor",n._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("opacity")&&(a._opacity=n.css("opacity")),n.css("opacity",a.opacity)},stop:function(t,i,s){var n=s.options;n._opacity&&e(i.helper).css("opacity",n._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(e,t,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,i,s){var n=s.options,a=!1,o=s.scrollParentNotHidden[0],r=s.document[0];o!==r&&"HTML"!==o.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+o.offsetHeight-t.pageY=0;c--)h=s.snapElements[c].left-s.margins.left,l=h+s.snapElements[c].width,u=s.snapElements[c].top-s.margins.top,d=u+s.snapElements[c].height,h-m>v||g>l+m||u-m>b||y>d+m||!e.contains(s.snapElements[c].item.ownerDocument,s.snapElements[c].item)?(s.snapElements[c].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=!1):("inner"!==f.snapMode&&(n=m>=Math.abs(u-b),a=m>=Math.abs(d-y),o=m>=Math.abs(h-v),r=m>=Math.abs(l-g),n&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||a||o||r,"outer"!==f.snapMode&&(n=m>=Math.abs(u-y),a=m>=Math.abs(d-b),o=m>=Math.abs(h-g),r=m>=Math.abs(l-v),n&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.top=s._convertPositionTo("relative",{top:d-s.helperProportions.height,left:0}).top),o&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[c].snapping&&(n||a||o||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,t,e.extend(s._uiHash(),{snapItem:s.snapElements[c].item})),s.snapElements[c].snapping=n||a||o||r||p)}}),e.ui.plugin.add("draggable","stack",{start:function(t,i,s){var n,a=s.options,o=e.makeArray(e(a.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});o.length&&(n=parseInt(e(o[0]).css("zIndex"),10)||0,e(o).each(function(t){e(this).css("zIndex",n+t)}),this.css("zIndex",n+o.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i,s){var n=e(i.helper),a=s.options;n.css("zIndex")&&(a._zIndex=n.css("zIndex")),n.css("zIndex",a.zIndex)},stop:function(t,i,s){var n=s.options;n._zIndex&&e(i.helper).css("zIndex",n._zIndex)}}),e.ui.draggable,e.widget("ui.droppable",{version:"1.11.4",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=e.isFunction(s)?s:function(e){return e.is(s)},this.proportions=function(){return arguments.length?(t=arguments[0],void 0):t?t:t={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this.element.addClass("ui-droppable")},_addToManager:function(t){e.ui.ddmanager.droppables[t]=e.ui.ddmanager.droppables[t]||[],e.ui.ddmanager.droppables[t].push(this)},_splice:function(e){for(var t=0;e.length>t;t++)e[t]===this&&e.splice(t,1)},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];this._splice(t),this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,i){if("accept"===t)this.accept=e.isFunction(i)?i:function(e){return e.is(i)};else if("scope"===t){var s=e.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(t,i)},_activate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",t,this.ui(i))},_deactivate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",t,this.ui(i))},_over:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(i)))},_out:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(i)))},_drop:function(t,i){var s=i||e.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=e(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&e.ui.intersect(s,e.extend(i,{offset:i.element.offset()}),i.options.tolerance,t)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(s)),this.element):!1):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(){function e(e,t,i){return e>=t&&t+i>e}return function(t,i,s,n){if(!i.offset)return!1;var a=(t.positionAbs||t.position.absolute).left+t.margins.left,o=(t.positionAbs||t.position.absolute).top+t.margins.top,r=a+t.helperProportions.width,h=o+t.helperProportions.height,l=i.offset.left,u=i.offset.top,d=l+i.proportions().width,c=u+i.proportions().height;switch(s){case"fit":return a>=l&&d>=r&&o>=u&&c>=h;case"intersect":return a+t.helperProportions.width/2>l&&d>r-t.helperProportions.width/2&&o+t.helperProportions.height/2>u&&c>h-t.helperProportions.height/2;case"pointer":return e(n.pageY,u,i.proportions().height)&&e(n.pageX,l,i.proportions().width);case"touch":return(o>=u&&c>=o||h>=u&&c>=h||u>o&&h>c)&&(a>=l&&d>=a||r>=l&&d>=r||l>a&&r>d);default:return!1}}}(),e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,i){var s,n,a=e.ui.ddmanager.droppables[t.options.scope]||[],o=i?i.type:null,r=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(s=0;a.length>s;s++)if(!(a[s].options.disabled||t&&!a[s].accept.call(a[s].element[0],t.currentItem||t.element))){for(n=0;r.length>n;n++)if(r[n]===a[s].element[0]){a[s].proportions().height=0;continue e}a[s].visible="none"!==a[s].element.css("display"),a[s].visible&&("mousedown"===o&&a[s]._activate.call(a[s],i),a[s].offset=a[s].element.offset(),a[s].proportions({width:a[s].element[0].offsetWidth,height:a[s].element[0].offsetHeight}))}},drop:function(t,i){var s=!1;return e.each((e.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(t,i){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)})},drag:function(t,i){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,i),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,a,o=e.ui.intersect(t,this,this.options.tolerance,i),r=!o&&this.isover?"isout":o&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,a=this.element.parents(":data(ui-droppable)").filter(function(){return e(this).droppable("instance").options.scope===n}),a.length&&(s=e(a[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(t,i){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)}},e.ui.droppable,e.widget("ui.selectable",e.ui.mouse,{version:"1.11.4",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(i.options.filter,i.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),i=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("
      ")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var i=this,s=this.options;this.opos=[t.pageX,t.pageY],this.options.disabled||(this.selectees=e(s.filter,this.element[0]),this._trigger("start",t),e(s.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=e.data(this,"selectable-item");s.startselected=!0,t.metaKey||t.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",t,{unselecting:s.element}))}),e(t.target).parents().addBack().each(function(){var s,n=e.data(this,"selectable-item");return n?(s=!t.metaKey&&!t.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",t,{selecting:n.element}):i._trigger("unselecting",t,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(t){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,a=this.opos[0],o=this.opos[1],r=t.pageX,h=t.pageY;return a>r&&(i=r,r=a,a=i),o>h&&(i=h,h=o,o=i),this.helper.css({left:a,top:o,width:r-a,height:h-o}),this.selectees.each(function(){var i=e.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||a>i.right||i.top>h||o>i.bottom):"fit"===n.tolerance&&(l=i.left>a&&r>i.right&&i.top>o&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",t,{selecting:i.element}))):(i.selecting&&((t.metaKey||t.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",t,{unselecting:i.element}))),i.selected&&(t.metaKey||t.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",t,{unselecting:i.element})))))}),!1}},_mouseStop:function(t){var i=this;return this.dragged=!1,e(".ui-unselecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",t,{unselected:s.element})}),e(".ui-selecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",t,{selected:s.element})}),this._trigger("stop",t),this.helper.remove(),!1}})}); \ No newline at end of file diff --git a/web/orchestrator/public/js/jquery.cookie-1.4.1.min.js b/web/orchestrator/public/js/jquery.cookie-1.4.1.min.js new file mode 100644 index 00000000000..c0f19d8a3b4 --- /dev/null +++ b/web/orchestrator/public/js/jquery.cookie-1.4.1.min.js @@ -0,0 +1,2 @@ +/*! jquery.cookie v1.4.1 | MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}}); \ No newline at end of file diff --git a/web/orchestrator/public/js/jquery.min.js b/web/orchestrator/public/js/jquery.min.js new file mode 100644 index 00000000000..f3644431eea --- /dev/null +++ b/web/orchestrator/public/js/jquery.min.js @@ -0,0 +1,6 @@ +/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="
      ",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; + +return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
      a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/\s*$/g,ra={option:[1,""],legend:[1,"
      ","
      "],area:[1,"",""],param:[1,"",""],thead:[1,"","
      "],tr:[2,"","
      "],col:[2,"","
      "],td:[3,"","
      "],_default:k.htmlSerialize?[0,"",""]:[1,"X
      ","
      "]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?""!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("