diff --git a/artifacts/grafana-kiosk-1.0.1.tar.gz b/artifacts/grafana-kiosk-1.0.1.tar.gz
new file mode 100644
index 0000000..0668921
Binary files /dev/null and b/artifacts/grafana-kiosk-1.0.1.tar.gz differ
diff --git a/artifacts/grafana-kiosk-1.0.1.zip b/artifacts/grafana-kiosk-1.0.1.zip
new file mode 100644
index 0000000..2abe462
Binary files /dev/null and b/artifacts/grafana-kiosk-1.0.1.zip differ
diff --git a/bin/grafana-kiosk.darwin b/bin/grafana-kiosk.darwin
new file mode 100755
index 0000000..af8aa20
Binary files /dev/null and b/bin/grafana-kiosk.darwin differ
diff --git a/bin/grafana-kiosk.darwin.amd64 b/bin/grafana-kiosk.darwin.amd64
new file mode 100755
index 0000000..2dd24c3
Binary files /dev/null and b/bin/grafana-kiosk.darwin.amd64 differ
diff --git a/bin/grafana-kiosk.linux.386 b/bin/grafana-kiosk.linux.386
new file mode 100755
index 0000000..2a4fe49
Binary files /dev/null and b/bin/grafana-kiosk.linux.386 differ
diff --git a/bin/grafana-kiosk.linux.amd64 b/bin/grafana-kiosk.linux.amd64
new file mode 100755
index 0000000..9d8ab8b
Binary files /dev/null and b/bin/grafana-kiosk.linux.amd64 differ
diff --git a/bin/grafana-kiosk.linux.arm64 b/bin/grafana-kiosk.linux.arm64
new file mode 100755
index 0000000..4977941
Binary files /dev/null and b/bin/grafana-kiosk.linux.arm64 differ
diff --git a/bin/grafana-kiosk.linux.armv5 b/bin/grafana-kiosk.linux.armv5
new file mode 100755
index 0000000..1e141fd
Binary files /dev/null and b/bin/grafana-kiosk.linux.armv5 differ
diff --git a/bin/grafana-kiosk.linux.armv6 b/bin/grafana-kiosk.linux.armv6
new file mode 100755
index 0000000..b0678d7
Binary files /dev/null and b/bin/grafana-kiosk.linux.armv6 differ
diff --git a/bin/grafana-kiosk.linux.armv7 b/bin/grafana-kiosk.linux.armv7
new file mode 100755
index 0000000..fc5cdef
Binary files /dev/null and b/bin/grafana-kiosk.linux.armv7 differ
diff --git a/bin/grafana-kiosk.windows.amd64.exe b/bin/grafana-kiosk.windows.amd64.exe
new file mode 100755
index 0000000..fc25e2c
Binary files /dev/null and b/bin/grafana-kiosk.windows.amd64.exe differ
diff --git a/coverage/cover.out b/coverage/cover.out
new file mode 100644
index 0000000..2cdc8f1
--- /dev/null
+++ b/coverage/cover.out
@@ -0,0 +1,36 @@
+mode: set
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:10.24,29.2 18 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:31.78,42.16 7 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:46.2,46.16 1 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:42.16,45.3 1 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:46.16,49.17 3 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:49.17,51.4 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:39.23,42.22 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:47.2,50.25 3 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:57.2,57.43 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:42.22,46.3 3 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:50.25,56.3 4 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:61.13,62.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:66.2,81.19 11 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:86.2,87.16 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:92.2,92.25 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:96.2,96.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:99.2,99.23 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:110.2,110.20 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:122.2,124.21 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:62.21,65.3 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:81.19,84.3 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:87.16,89.13 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:92.25,94.3 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:96.26,98.3 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:100.12,101.17 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:102.14,103.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:104.18,105.23 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:106.10,107.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:111.14,112.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:113.15,114.22 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:115.14,116.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:117.10,118.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:125.13,127.92 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:128.12,130.91 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:131.17,133.70 2 0
diff --git a/coverage/coverage.html b/coverage/coverage.html
new file mode 100644
index 0000000..69ac340
--- /dev/null
+++ b/coverage/coverage.html
@@ -0,0 +1,602 @@
+
+
+
+
+
+
+
package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "net/url"
+ "os"
+
+ "github.com/grafana/grafana-kiosk/pkg/initialize"
+ "github.com/grafana/grafana-kiosk/pkg/kiosk"
+)
+
+// LoginMethod specifies the type of login to be used by the kiosk
+type LoginMethod int
+
+// Login Methods
+const (
+ ANONYMOUS LoginMethod = 0
+ LOCAL LoginMethod = 1
+ GCOM LoginMethod = 2
+)
+
+// Kiosk Modes
+const (
+ // TV will hide the sidebar but allow usage of menu
+ TV int = 0
+ // NORMAL will disable sidebar and top navigation bar
+ NORMAL int = 1
+ // DISABLED will omit kiosk option
+ DISABLED int = 2
+)
+
+var (
+ loginMethod = LOCAL
+ kioskMode = NORMAL
+)
+
+func setEnvironment() {
+ // for linux/X display must be set
+ var displayEnv = os.Getenv("DISPLAY")
+ if displayEnv == "" {
+ log.Println("DISPLAY not set, autosetting to :0.0")
+ os.Setenv("DISPLAY", ":0.0")
+ displayEnv = os.Getenv("DISPLAY")
+ }
+ log.Println("DISPLAY=", displayEnv)
+
+ var xAuthorityEnv = os.Getenv("XAUTHORITY")
+ if xAuthorityEnv == "" {
+ log.Println("XAUTHORITY not set, autosetting")
+ // use HOME of current user
+ var homeEnv = os.Getenv("HOME")
+ os.Setenv("XAUTHORITY", homeEnv+"/.Xauthority")
+ xAuthorityEnv = os.Getenv("XAUTHORITY")
+ }
+ log.Println("XAUTHORITY=", xAuthorityEnv)
+
+}
+
+func main() {
+ var Usage = func() {
+ fmt.Fprintf(os.Stderr, "Usage: %v\n", os.Args[0])
+ flag.PrintDefaults()
+ }
+ urlPtr := flag.String("URL", "https://play.grafana.org", "URL to Grafana server (Required)")
+ methodPtr := flag.String("login-method", "anon", "login method: [anon|local|gcom]")
+ usernamePtr := flag.String("username", "guest", "username (Required)")
+ passwordPtr := flag.String("password", "guest", "password (Required)")
+ // kiosk=tv includes sidebar menu
+ // kiosk no sidebar ever
+ kioskModePtr := flag.String("kiosk-mode", "full", "kiosk mode [full|tv|disabled]")
+ autoFit := flag.Bool("autofit", true, "autofit panels in kiosk mode")
+ // when the URL is a playlist, append "inactive" to the URL
+ isPlayList := flag.Bool("playlist", false, "URL is a playlist: [true|false]")
+ LXDEEnabled := flag.Bool("lxde", false, "initialize LXDE for kiosk mode")
+ LXDEHomePtr := flag.String("lxde-home", "/home/pi", "path to home directory of LXDE user running X Server")
+ flag.Parse()
+
+ // make sure the url has content
+ if *urlPtr == "" {
+ Usage()
+ os.Exit(1)
+ }
+ // validate url
+ _, err := url.ParseRequestURI(*urlPtr)
+ if err != nil {
+ Usage()
+ panic(err)
+ }
+
+ if *isPlayList == true {
+ log.Printf("playlist")
+ }
+
+ if *LXDEEnabled == true {
+ initialize.LXDE(*LXDEHomePtr)
+ }
+ switch *kioskModePtr {
+ case "tv": // NO SIDEBAR ACCESS
+ kioskMode = TV
+ case "full": // NO TOPNAV or SIDEBAR
+ kioskMode = NORMAL
+ case "disabled": // NO TOPNAV or SIDEBAR
+ kioskMode = DISABLED
+ default:
+ kioskMode = NORMAL
+ }
+
+ switch *methodPtr {
+ case "anon":
+ loginMethod = ANONYMOUS
+ case "local":
+ loginMethod = LOCAL
+ case "gcom":
+ loginMethod = GCOM
+ default:
+ loginMethod = ANONYMOUS
+ }
+
+ // for linux/X display must be set
+ setEnvironment()
+
+ switch loginMethod {
+ case LOCAL:
+ log.Printf("Launching local login kiosk")
+ kiosk.GrafanaKioskLocal(urlPtr, usernamePtr, passwordPtr, kioskMode, autoFit, isPlayList)
+ case GCOM:
+ log.Printf("Launching GCOM login kiosk")
+ kiosk.GrafanaKioskGCOM(urlPtr, usernamePtr, passwordPtr, kioskMode, autoFit, isPlayList)
+ case ANONYMOUS:
+ log.Printf("Launching ANON login kiosk")
+ kiosk.GrafanaKioskAnonymous(urlPtr, kioskMode, autoFit, isPlayList)
+ }
+}
+
+
+
package initialize
+
+import (
+ "log"
+ "os"
+ "os/exec"
+)
+
+// LXDE runs shell commands to setup LXDE for kiosk mode
+func LXDE(path string) {
+ var command = "/usr/bin/lxpanel"
+ args := []string{"--profile", "LXDE"}
+ runCommand(path, command, args, true)
+ command = "/usr/bin/pcmanfm"
+ args = []string{"--desktop", "--profile", "LXDE"}
+ runCommand(path, command, args, true)
+ command = "/usr/bin/xset"
+ runCommand(path, command, args, true)
+ args = []string{"s", "off"}
+ runCommand(path, command, args, true)
+ args = []string{"-dpms"}
+ runCommand(path, command, args, true)
+ args = []string{"s", "noblank"}
+ runCommand(path, command, args, true)
+ command = "/usr/bin/unclutter"
+ var displayEnv = os.Getenv("DISPLAY")
+ args = []string{"-display", displayEnv, "-idle", "5"}
+ go runCommand(path, command, args, true)
+}
+
+func runCommand(path string, command string, args []string, waitForEnd bool) {
+ // check if command exists
+ log.Printf("path: %v", path)
+ log.Printf("command: %v", command)
+ log.Printf("arg0: %v", args[0])
+ cmd := exec.Command(command, args...)
+ cmd.Env = append(os.Environ(),
+ "DISPLAY=:0.0",
+ "XAUTHORITY="+path+"/.Xauthority",
+ )
+ err := cmd.Start()
+ if err != nil {
+ //log.Printf(err)
+ log.Printf("Error in output, ignoring...")
+ }
+ if waitForEnd {
+ log.Printf("Waiting for command to finish...")
+ err = cmd.Wait()
+ if err != nil {
+ log.Printf("Command finished with error: %v", err)
+ }
+ }
+}
+
+
+
package kiosk
+
+import (
+ "context"
+ "io/ioutil"
+ "log"
+ "os"
+ "time"
+
+ "github.com/chromedp/chromedp"
+)
+
+// GrafanaKioskAnonymous creates a chrome-based kiosk using a local grafana-server account
+func GrafanaKioskAnonymous(urlPtr *string, kioskMode int, autoFit *bool, isPlayList *bool) {
+ dir, err := ioutil.TempDir("", "chromedp-example")
+ if err != nil {
+ panic(err)
+ }
+ defer os.RemoveAll(dir)
+
+ opts := []chromedp.ExecAllocatorOption{
+ chromedp.NoFirstRun,
+ chromedp.NoDefaultBrowserCheck,
+ // chromedp.DisableGPU, // needed?
+ chromedp.Flag("noerrdialogs", true),
+ chromedp.Flag("kiosk", true),
+ chromedp.Flag("bwsi", true),
+ chromedp.Flag("incognito", true),
+ chromedp.Flag("disable-sync", true),
+ chromedp.Flag("disable-notifications", true),
+ chromedp.Flag("disable-overlay-scrollbar", true),
+ chromedp.UserDataDir(dir),
+ }
+
+ allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
+ defer cancel()
+
+ // also set up a custom logger
+ taskCtx, cancel := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
+ defer cancel()
+
+ listenChromeEvents(taskCtx, consoleAPICall|targetCrashed)
+
+ // ensure that the browser process is started
+ if err := chromedp.Run(taskCtx); err != nil {
+ panic(err)
+ }
+
+ // Give browser time to load next page (this can be prone to failure, explore different options vs sleeping)
+ time.Sleep(2000 * time.Millisecond)
+
+ var generatedURL = GenerateURL(*urlPtr, kioskMode, autoFit, isPlayList)
+ log.Println("Navigating to ", generatedURL)
+ /*
+ Launch chrome and look for main-view element
+ */
+ if err := chromedp.Run(taskCtx,
+ chromedp.Navigate(generatedURL),
+ chromedp.WaitVisible("//div[@class=\"main-view\"]", chromedp.BySearch),
+ // wait forever (for now)
+ chromedp.WaitVisible("notnputPassword", chromedp.ByID),
+ ); err != nil {
+ panic(err)
+ }
+ log.Println("Sleep before exit...")
+ // wait here for the process to exit
+ time.Sleep(2000 * time.Millisecond)
+ log.Println("Exit...")
+
+}
+
+
+
package kiosk
+
+import (
+ "context"
+ "io/ioutil"
+ "log"
+ "os"
+ "time"
+
+ "github.com/chromedp/chromedp"
+ "github.com/chromedp/chromedp/kb"
+)
+
+// GrafanaKioskGCOM creates a chrome-based kiosk using a grafana.com authenticated account
+func GrafanaKioskGCOM(urlPtr *string, usernamePtr *string, passwordPtr *string, kioskMode int, autoFit *bool, isPlayList *bool) {
+ dir, err := ioutil.TempDir("", "chromedp-example")
+ if err != nil {
+ panic(err)
+ }
+ defer os.RemoveAll(dir)
+
+ opts := []chromedp.ExecAllocatorOption{
+ chromedp.NoFirstRun,
+ chromedp.NoDefaultBrowserCheck,
+ // chromedp.DisableGPU, // needed?
+ chromedp.Flag("noerrdialogs", true),
+ chromedp.Flag("kiosk", true),
+ chromedp.Flag("bwsi", true),
+ chromedp.Flag("incognito", true),
+ chromedp.Flag("disable-sync", true),
+ chromedp.Flag("disable-notifications", true),
+ chromedp.Flag("disable-overlay-scrollbar", true),
+ chromedp.UserDataDir(dir),
+ }
+
+ allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
+ defer cancel()
+
+ // also set up a custom logger
+ taskCtx, cancel := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
+ defer cancel()
+
+ listenChromeEvents(taskCtx, targetCrashed)
+
+ // ensure that the browser process is started
+ if err := chromedp.Run(taskCtx); err != nil {
+ panic(err)
+ }
+
+ var generatedURL = GenerateURL(*urlPtr, kioskMode, autoFit, isPlayList)
+ log.Println("Navigating to ", generatedURL)
+
+ /*
+ Launch chrome, click the grafana.com button, fill out login form and submit
+ */
+ // XPATH of grafana.com login button = //*[@href="login/grafana_com"]/i
+
+ // Click the grafana_com login button
+ if err := chromedp.Run(taskCtx,
+ chromedp.Navigate(generatedURL),
+ chromedp.WaitVisible("//*[@href=\"login/grafana_com\"]/i", chromedp.BySearch),
+ chromedp.Click("//*[@href=\"login/grafana_com\"]/..", chromedp.BySearch),
+ ); err != nil {
+ panic(err)
+ }
+ // Give browser time to load next page (this can be prone to failure, explore different options vs sleeping)
+ time.Sleep(2000 * time.Millisecond)
+ // Fill out grafana_com login page
+ if err := chromedp.Run(taskCtx,
+ chromedp.WaitVisible("//input[@name=\"login\"]", chromedp.BySearch),
+ chromedp.SendKeys("//input[@name=\"login\"]", *usernamePtr, chromedp.BySearch),
+ chromedp.SendKeys("//input[@name=\"password\"]", *passwordPtr+kb.Enter, chromedp.BySearch),
+ chromedp.WaitVisible("notinputPassword", chromedp.ByID),
+ ); err != nil {
+ panic(err)
+ }
+
+}
+
+
+
package kiosk
+
+import (
+ "context"
+ "log"
+
+ "github.com/chromedp/cdproto/inspector"
+ "github.com/chromedp/cdproto/runtime"
+ "github.com/chromedp/chromedp"
+)
+
+type chromeEvents int
+
+const (
+ consoleAPICall chromeEvents = 1 << iota
+ targetCrashed
+)
+
+func listenChromeEvents(taskCtx context.Context, events chromeEvents) {
+ chromedp.ListenTarget(taskCtx, func(ev interface{}) {
+ switch ev := ev.(type) {
+ case *runtime.EventConsoleAPICalled:
+ if events&consoleAPICall != 0 {
+ log.Printf("console.%s call:\n", ev.Type)
+ for _, arg := range ev.Args {
+ log.Printf(" %s - %s\n", arg.Type, arg.Value)
+ }
+ }
+ case *inspector.EventTargetCrashed:
+ if events&targetCrashed != 0 {
+ log.Printf("target crashed, reload...")
+ go func() {
+ chromedp.Run(taskCtx, chromedp.Reload())
+ }()
+ }
+ }
+ })
+}
+
+
+
package kiosk
+
+import (
+ "context"
+ "io/ioutil"
+ "log"
+ "os"
+ "time"
+
+ "github.com/chromedp/chromedp"
+ "github.com/chromedp/chromedp/kb"
+)
+
+// GrafanaKioskLocal creates a chrome-based kiosk using a local grafana-server account
+func GrafanaKioskLocal(urlPtr *string, usernamePtr *string, passwordPtr *string, kioskMode int, autoFit *bool, isPlayList *bool) {
+ dir, err := ioutil.TempDir("", "chromedp-example")
+ if err != nil {
+ panic(err)
+ }
+ defer os.RemoveAll(dir)
+
+ opts := []chromedp.ExecAllocatorOption{
+ chromedp.NoFirstRun,
+ chromedp.NoDefaultBrowserCheck,
+ // chromedp.DisableGPU, // needed?
+ chromedp.Flag("noerrdialogs", true),
+ chromedp.Flag("kiosk", true),
+ chromedp.Flag("bwsi", true),
+ chromedp.Flag("incognito", true),
+ chromedp.Flag("disable-sync", true),
+ chromedp.Flag("disable-notifications", true),
+ chromedp.Flag("disable-overlay-scrollbar", true),
+ chromedp.UserDataDir(dir),
+ }
+
+ allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...)
+ defer cancel()
+
+ // also set up a custom logger
+ taskCtx, cancel := chromedp.NewContext(allocCtx, chromedp.WithLogf(log.Printf))
+ defer cancel()
+
+ listenChromeEvents(taskCtx, targetCrashed)
+
+ // ensure that the browser process is started
+ if err := chromedp.Run(taskCtx); err != nil {
+ panic(err)
+ }
+
+ var generatedURL = GenerateURL(*urlPtr, kioskMode, autoFit, isPlayList)
+ log.Println("Navigating to ", generatedURL)
+ /*
+ Launch chrome and login with local user account
+
+ name=username, type=text
+ id=inputPassword, type=password, name=password
+ */
+ // Give browser time to load next page (this can be prone to failure, explore different options vs sleeping)
+ time.Sleep(2000 * time.Millisecond)
+
+ if err := chromedp.Run(taskCtx,
+ chromedp.Navigate(generatedURL),
+ chromedp.WaitVisible(`#inputPassword`, chromedp.ByID),
+ chromedp.SendKeys(`#login-view > form > div:nth-child(1) > input`, *usernamePtr, chromedp.ByID),
+ chromedp.SendKeys(`#inputPassword`, *passwordPtr, chromedp.ByID),
+ chromedp.SendKeys(`#inputPassword`, kb.Enter, chromedp.ByID),
+ chromedp.WaitVisible(`notnputPassword`, chromedp.ByID),
+ ); err != nil {
+ panic(err)
+ }
+}
+
+
+
package kiosk
+
+import (
+ "log"
+ "net/url"
+)
+
+// GenerateURL constructs URL with appropriate parameters for kiosk mode
+func GenerateURL(anURL string, kioskMode int, autoFit *bool, isPlayList *bool) string {
+ u, _ := url.ParseRequestURI(anURL)
+ q, _ := url.ParseQuery(u.RawQuery)
+ switch kioskMode {
+ case 0: // TV
+ q.Set("kiosk", "tv") // no sidebar, topnav without buttons
+ log.Printf("KioskMode: TV")
+ case 1: // FULLSCREEN
+ q.Set("kiosk", "1") // sidebar and topnav always shown
+ log.Printf("KioskMode: Fullscreen")
+ default: // disabled
+ log.Printf("KioskMode: Disabled")
+ }
+ // a playlist should also go inactive immediately
+ if *isPlayList == true {
+ q.Set("inactive", "1")
+ }
+ u.RawQuery = q.Encode()
+ if *autoFit == true {
+ u.RawQuery = u.RawQuery + "&autofitpanels"
+ }
+ return u.String()
+}
+
+
+
+
+
+
diff --git a/coverage/coverage.out b/coverage/coverage.out
new file mode 100644
index 0000000..a364d7e
--- /dev/null
+++ b/coverage/coverage.out
@@ -0,0 +1,147 @@
+mode: set
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:39.23,42.22 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:47.2,50.25 3 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:57.2,57.43 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:42.22,46.3 3 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:50.25,56.3 4 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:61.13,62.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:66.2,81.19 11 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:86.2,87.16 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:92.2,92.25 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:96.2,96.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:99.2,99.23 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:110.2,110.20 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:122.2,124.21 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:62.21,65.3 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:81.19,84.3 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:87.16,89.13 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:92.25,94.3 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:96.26,98.3 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:100.12,101.17 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:102.14,103.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:104.18,105.23 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:106.10,107.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:111.14,112.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:113.15,114.22 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:115.14,116.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:117.10,118.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:125.13,127.92 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:128.12,130.91 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:131.17,133.70 2 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:10.24,29.2 18 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:31.78,42.16 7 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:46.2,46.16 1 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:42.16,45.3 1 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:46.16,49.17 3 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:49.17,51.4 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:14.92,16.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:19.2,45.46 8 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:50.2,62.16 4 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:65.2,68.24 3 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:16.16,17.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:45.46,46.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:62.16,63.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:15.129,17.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:20.2,46.46 8 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:50.2,63.16 3 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:67.2,74.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:17.16,18.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:46.46,47.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:63.16,64.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:74.16,75.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:19.71,20.54 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:20.54,21.26 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:22.39,23.34 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:29.38,30.33 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:23.34,25.33 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:25.33,27.6 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:30.33,32.15 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:32.15,34.6 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:15.130,17.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:20.2,46.46 8 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:50.2,68.16 4 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:17.16,18.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:46.46,47.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:68.16,69.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:9.87,12.19 3 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:23.2,23.25 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:26.2,27.22 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:30.2,30.19 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:13.9,15.30 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:16.9,18.38 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:19.10,20.36 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:23.25,25.3 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:27.22,29.3 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:9.87,12.19 3 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:23.2,23.25 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:26.2,27.22 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:30.2,30.19 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:13.9,15.30 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:16.9,18.38 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:19.10,20.36 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:23.25,25.3 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/utils.go:27.22,29.3 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:39.23,42.22 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:47.2,50.25 3 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:57.2,57.43 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:42.22,46.3 3 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:50.25,56.3 4 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:61.13,62.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:66.2,81.19 11 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:86.2,87.16 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:92.2,92.25 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:96.2,96.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:99.2,99.23 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:110.2,110.20 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:122.2,124.21 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:62.21,65.3 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:81.19,84.3 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:87.16,89.13 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:92.25,94.3 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:96.26,98.3 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:100.12,101.17 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:102.14,103.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:104.18,105.23 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:106.10,107.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:111.14,112.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:113.15,114.22 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:115.14,116.21 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:117.10,118.26 1 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:125.13,127.92 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:128.12,130.91 2 0
+github.com/grafana/grafana-kiosk/pkg/cmd/grafana-kiosk/main.go:131.17,133.70 2 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:10.24,29.2 18 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:31.78,42.16 7 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:46.2,46.16 1 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:42.16,45.3 1 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:46.16,49.17 3 0
+github.com/grafana/grafana-kiosk/pkg/initialize/lxde.go:49.17,51.4 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:14.92,16.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:19.2,45.46 8 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:50.2,62.16 4 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:65.2,68.24 3 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:16.16,17.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:45.46,46.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/anonymous_login.go:62.16,63.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:15.129,17.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:20.2,46.46 8 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:50.2,63.16 3 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:67.2,74.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:17.16,18.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:46.46,47.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:63.16,64.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/grafana_com_login.go:74.16,75.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:19.71,20.54 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:20.54,21.26 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:22.39,23.34 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:29.38,30.33 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:23.34,25.33 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:25.33,27.6 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:30.33,32.15 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/listen_chrome_events.go:32.15,34.6 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:15.130,17.16 2 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:20.2,46.46 8 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:50.2,68.16 4 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:17.16,18.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:46.46,47.13 1 0
+github.com/grafana/grafana-kiosk/pkg/kiosk/local_login.go:68.16,69.13 1 0