[
  {
    "path": ".gitignore",
    "content": ".vscode/\n.env\n*_templ.go\n*_templ.txt\nbin/\nnode_modules/\ninternal/assets/public/static/css/tw.css\n.DS_Store\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2024 Tomi Haapalainen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": ".DEFAULT_GOAL := dev\n\nGOOS := \"linux\"\nGOARCH := \"amd64\"\n\ndeploy:\n\tnpx @tailwindcss/cli -i input.css -o ./internal/assets/public/static/css/tw.css --minify\n\tgo run cmd/generate/main.go\n\ttempl generate\n\tGOOS=$(GOOS) GOARCH=$(GOARCH) go build -ldflags \"-s -w\" -o bin/new-main cmd/server/main.go\n\tscp 'bin/new-main' $(user)@$(ip):/opt/goshipit/\n\tssh $(user)@$(ip) \"sudo service goshipit stop\"\n\tssh $(user)@$(ip) \"rm /opt/goshipit/main\"\n\tssh $(user)@$(ip) \"mv /opt/goshipit/new-main /opt/goshipit/main\"\n\tssh $(user)@$(ip) \"sudo service goshipit start\"\n\ngen:\n\tgo run cmd/generate/main.go\n\ntw:\n\t@npx @tailwindcss/cli -i input.css -o ./internal/assets/public/static/css/tw.css --watch\n\ndev: gen\n\t@templ generate -watch -proxyport=7332 -proxy=\"http://localhost:8080\" -open-browser=false -cmd=\"go run cmd/server/main.go\"\n"
  },
  {
    "path": "cmd/generate/main.go",
    "content": "package main\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"go/format\"\n\t\"io/fs\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/haatos/goshipit/internal/markdown\"\n\t\"github.com/haatos/goshipit/internal/model\"\n)\n\nconst (\n\tcomponentCodeMapJSONPath        = \"internal/assets/generated/component_code_map.json\"\n\tcomponentExampleCodeMapJSONPath = \"internal/assets/generated/component_example_code_map.json\"\n\tcomponentsDir                   = \"internal/views/components/\"\n\tcomponentsHandlerPath           = \"internal/handler/components.go\"\n\texamplesDir                     = \"internal/views/examples/\"\n\tgeneratedDir                    = \"internal/assets/generated\"\n\tgeneratedComponentsPath         = \"internal/assets/generated/components.go\"\n)\n\nfunc main() {\n\tgenerateComponentCodeMap()\n\tgenerateComponentExampleCodeMap()\n\tgenerateComponentMap()\n}\n\nfunc generateComponentCodeMap() {\n\tm := model.ComponentCodeMap{}\n\tif err := filepath.Walk(componentsDir, func(path string, info fs.FileInfo, err error) error {\n\t\tif !info.IsDir() && strings.HasSuffix(path, \".templ\") {\n\t\t\tif err := getComponentCode(path, info, m); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tif err := os.RemoveAll(generatedDir); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tif err := os.Mkdir(generatedDir, 0755); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tb, err := json.MarshalIndent(m, \"\", \"  \")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfg, err := os.Create(componentCodeMapJSONPath)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer fg.Close()\n\n\tif _, err := fg.Write(b); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc getComponentCode(path string, info fs.FileInfo, fmap model.ComponentCodeMap) error {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\tcomponentName := strings.TrimSuffix(info.Name(), \".templ\")\n\n\tscanner := bufio.NewScanner(f)\n\tfunction := []string{}\n\tinFunction := false\n\tdescription := []string{}\n\tinDescription := false\n\tdaisyUIURL := \"\"\n\tvar category string\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif category == \"\" {\n\t\t\tcategory = strings.TrimPrefix(line, \"// \")\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"// https://daisyui.com\") {\n\t\t\tdaisyUIURL = strings.TrimPrefix(line, \"// \")\n\t\t}\n\t\tif strings.HasPrefix(line, \"/*\") {\n\t\t\tinDescription = true\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"*/\") {\n\t\t\tinDescription = false\n\t\t\tcontinue\n\t\t}\n\t\tif inDescription {\n\t\t\tdescription = append(description, line)\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"type \") || strings.HasPrefix(line, \"templ \") {\n\t\t\tinFunction = true\n\t\t}\n\t\tif inFunction {\n\t\t\tfunction = append(function, line)\n\t\t}\n\t}\n\tif _, ok := fmap[category]; !ok {\n\t\tfmap[category] = []model.ComponentCode{}\n\t}\n\tfmap[category] = append(\n\t\tfmap[category],\n\t\tmodel.ComponentCode{\n\t\t\tName:        componentName,\n\t\t\tCode:        markdown.CodeSliceToMarkdown(function),\n\t\t\tDescription: strings.Join(description, \"\\n\"),\n\t\t\tDaisyUIURL:  daisyUIURL,\n\t\t})\n\treturn nil\n}\n\nfunc generateComponentExampleCodeMap() {\n\tm := model.ComponentExampleCodeMap{}\n\tif err := filepath.Walk(examplesDir, func(path string, info fs.FileInfo, err error) error {\n\t\tif !info.IsDir() && strings.HasSuffix(path, \".templ\") {\n\t\t\tif err := addComponentExampleToMap(m, info, path); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor comName := range m {\n\t\tfor i := range m[comName] {\n\t\t\tif err := addComponentExampleBackendParts(m, comName, i); err != nil {\n\t\t\t\tlog.Fatal(err)\n\t\t\t}\n\t\t}\n\t}\n\n\tb, err := json.MarshalIndent(m, \"\", \"  \")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfg, err := os.Create(componentExampleCodeMapJSONPath)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer fg.Close()\n\n\tif _, err := fg.Write(b); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc addComponentExampleToMap(\n\tm model.ComponentExampleCodeMap,\n\tinfo fs.FileInfo,\n\tpath string,\n) error {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\tfunctionLines := []string{}\n\tvar functionName string\n\tcomponentName := strings.TrimSuffix(info.Name(), \".templ\")\n\tm[componentName] = []model.ComponentCode{}\n\tinExample := false\n\tdescription := []string{}\n\ttitle := \"\"\n\tinDescription := false\n\n\tscanner := bufio.NewScanner(f)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif strings.HasPrefix(line, \"// example\") {\n\t\t\tif inExample {\n\t\t\t\tm[componentName] = append(\n\t\t\t\t\tm[componentName],\n\t\t\t\t\tmodel.ComponentCode{\n\t\t\t\t\t\tName:        functionName,\n\t\t\t\t\t\tCode:        markdown.CodeSliceToMarkdown(functionLines),\n\t\t\t\t\t\tTitle:       title,\n\t\t\t\t\t\tDescription: strings.Join(description, \"\\n\"),\n\t\t\t\t\t})\n\t\t\t\tfunctionName = \"\"\n\t\t\t\tfunctionLines = []string{}\n\t\t\t\tdescription = []string{}\n\t\t\t}\n\t\t\tinExample = true\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasPrefix(line, \"// \") && !strings.HasPrefix(line, \"// example\") {\n\t\t\ttitle = strings.TrimPrefix(line, \"// \")\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasPrefix(line, \"/*\") {\n\t\t\tinDescription = true\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"*/\") {\n\t\t\tinDescription = false\n\t\t\tcontinue\n\t\t}\n\t\tif inDescription {\n\t\t\tdescription = append(description, line)\n\t\t}\n\n\t\tif strings.HasPrefix(line, \"templ \") && functionName == \"\" {\n\t\t\tfunctionName = strings.TrimPrefix(line, \"templ \")\n\t\t\tfunctionName = functionName[:strings.Index(functionName, \"(\")]\n\t\t}\n\n\t\tif inExample && !inDescription {\n\t\t\tfunctionLines = append(functionLines, line)\n\t\t}\n\t}\n\n\tm[componentName] = append(\n\t\tm[componentName],\n\t\tmodel.ComponentCode{\n\t\t\tName:        functionName,\n\t\t\tCode:        markdown.CodeSliceToMarkdown(functionLines),\n\t\t\tTitle:       title,\n\t\t\tDescription: strings.Join(description, \"\\n\"),\n\t\t},\n\t)\n\treturn nil\n}\n\nfunc addComponentExampleBackendParts(\n\tm model.ComponentExampleCodeMap,\n\tcomName string,\n\tindex int,\n) error {\n\tf, err := os.Open(componentsHandlerPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\tinExampleHandler := false\n\tfunctionLines := []string{}\n\tscanner := bufio.NewScanner(f)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif strings.HasPrefix(line, fmt.Sprintf(\"// %s\", m[comName][index].Name)) {\n\t\t\tif inExampleHandler {\n\t\t\t\tinExampleHandler = false\n\t\t\t\tm[comName][index].Handler = markdown.CodeSliceToMarkdown(functionLines)\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\tinExampleHandler = true\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif inExampleHandler {\n\t\t\tfunctionLines = append(functionLines, line)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc generateComponentMap() {\n\tfunctionNames := []string{}\n\tif err := filepath.Walk(examplesDir, func(path string, info fs.FileInfo, err error) error {\n\t\tif !info.IsDir() && strings.HasSuffix(path, \".templ\") {\n\t\t\tf, err := os.Open(path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tinExample := false\n\n\t\t\tscanner := bufio.NewScanner(f)\n\t\t\tfor scanner.Scan() {\n\t\t\t\tline := scanner.Text()\n\t\t\t\tif strings.HasPrefix(line, \"// example\") {\n\t\t\t\t\tinExample = true\n\t\t\t\t}\n\n\t\t\t\tif inExample && strings.HasPrefix(line, \"templ \") {\n\t\t\t\t\tfunctionName := strings.TrimPrefix(line, \"templ \")\n\t\t\t\t\tfunctionName = functionName[:strings.Index(functionName, \"(\")]\n\t\t\t\t\tfunctionNames = append(functionNames, functionName)\n\t\t\t\t\tinExample = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\twriteGeneratedFunctions(functionNames)\n}\n\nfunc writeGeneratedFunctions(functionNames []string) {\n\t// write functions into a buffer\n\tsrc := bytes.NewBuffer(nil)\n\tsrc.WriteString(\"package generated\\n\\n\")\n\tsrc.WriteString(\"import (\\n\")\n\tsrc.WriteString(\"\\t\\\"github.com/a-h/templ\\\"\\n\")\n\tsrc.WriteString(\"\\t\\\"github.com/haatos/goshipit/internal/views/examples\\\"\\n\")\n\tsrc.WriteString(\")\\n\\n\")\n\tsrc.WriteString(\"var ExampleComponents = map[string]templ.Component{\\n\")\n\tfor _, name := range functionNames {\n\t\tfmt.Fprintf(src, \"\\t\\\"%s\\\": examples.%s(),\\n\", name, name)\n\t}\n\tsrc.WriteString(\"}\\n\")\n\n\t// format the buffer's bytes using gofmt\n\tb, err := format.Source(src.Bytes())\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// write the file\n\tfg, err := os.Create(generatedComponentsPath)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer fg.Close()\n\tif _, err := fg.Write(b); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "cmd/gsi/main.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/haatos/goshipit/internal/views\"\n)\n\nvar componentsDirParts = []string{\"internal\", \"views\", \"components\"}\n\nfunc main() {\n\tcode := run(os.Stdout, os.Stderr, os.Args)\n\tif code != 0 {\n\t\tos.Exit(code)\n\t}\n}\n\nconst usageText string = `usage: gsi <command> [<args>...]\n\ngsi - GoShip.it CLI\n\ncommands:\n  add <name>      Add a component to internal/views/components\n  remove <name>   Remove a component from internal/views/components\n  list            List all available components\n\n`\n\nfunc run(stdout, stderr io.Writer, args []string) int {\n\tif len(args) < 2 {\n\t\t_, _ = fmt.Fprint(stdout, usageText)\n\t\treturn 64\n\t}\n\n\tswitch args[1] {\n\tcase \"add\":\n\t\tif len(args) < 3 {\n\t\t\t_, _ = fmt.Fprint(stdout, usageText)\n\t\t\treturn 64\n\t\t}\n\t\tname := strings.Join(args[2:], \" \")\n\t\treturn runAddCommand(stderr, name)\n\tcase \"remove\":\n\t\tif len(args) < 3 {\n\t\t\t_, _ = fmt.Fprint(stdout, usageText)\n\t\t\treturn 64\n\t\t}\n\t\tname := strings.Join(args[2:], \" \")\n\t\treturn runRemoveCommand(stdout, name)\n\tcase \"list\":\n\t\treturn runListCommand(stdout)\n\t}\n\n\treturn 1\n}\n\nfunc runAddCommand(stderr io.Writer, name string) int {\n\tname = strings.ReplaceAll(name, \" \", \"_\")\n\tb, err := views.ComponentFS.ReadFile(\"components/\" + name + \".templ\")\n\tif err != nil {\n\t\t_, _ = fmt.Fprintf(stderr, \"component '%s' does not exist\\n\", name)\n\t\treturn 1\n\t}\n\tpackageIndex := bytes.Index(b, []byte(\"package\"))\n\tb = b[packageIndex:]\n\n\tdirPath := filepath.Join(componentsDirParts...)\n\tfileName := fmt.Sprintf(\"%s.templ\", name)\n\tfullPath := filepath.Join(dirPath, fileName)\n\n\tcomponentExists := true\n\tif _, err := os.Stat(fullPath); errors.Is(err, os.ErrNotExist) {\n\t\tcomponentExists = false\n\t}\n\n\tif componentExists {\n\t\tvar ans string\n\t\tfmt.Printf(\"Component '%s' already exists. Replace [Y/n]: \", name)\n\t\tif _, err := fmt.Scan(&ans); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tif ans == \"n\" {\n\t\t\treturn 0\n\t\t}\n\t\tfmt.Printf(\"Replacing component '%s'...\\n\", name)\n\t}\n\n\tif err := os.MkdirAll(dirPath, os.ModePerm); err != nil {\n\t\tlog.Fatal(\"err making directories '\", dirPath+\"':\", err)\n\t}\n\n\tf, err := os.Create(fullPath)\n\tif err != nil {\n\t\tlog.Fatal(\"err creating file '\", fullPath+\"':\", err)\n\t}\n\tif _, err := f.Write(b); err != nil {\n\t\tlog.Fatal(\"err writing component to '\", fullPath+\"':\", err)\n\t}\n\n\treturn 0\n}\n\nfunc runRemoveCommand(stdout io.Writer, name string) int {\n\tname = strings.ReplaceAll(name, \" \", \"_\")\n\tdirPath := filepath.Join(componentsDirParts...)\n\tfileName := fmt.Sprintf(\"%s.templ\", name)\n\ttemplFileName := fmt.Sprintf(\"%s_templ.go\", name)\n\tif err := os.Remove(filepath.Join(dirPath, fileName)); err == nil {\n\t\t_, _ = fmt.Fprintf(stdout, \"Removed '%s'\\n\", filepath.Join(dirPath, fileName))\n\t}\n\tif err := os.Remove(filepath.Join(dirPath, templFileName)); err != nil {\n\t\t_, _ = fmt.Fprintf(stdout, \"Removed '%s'\\n\", filepath.Join(dirPath, templFileName))\n\t}\n\treturn 0\n}\n\nfunc runListCommand(stdout io.Writer) int {\n\tentries, err := views.ComponentFS.ReadDir(\"components\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\t_, _ = fmt.Fprint(stdout, \"Run 'gsi add <name>' to add a component\\n\\n\")\n\tm := make(map[string][]string)\n\tfor _, entry := range entries {\n\t\tb, err := views.ComponentFS.ReadFile(filepath.Join(\"components\", entry.Name()))\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tsplit := bytes.Split(b, []byte(\"\\n\"))\n\t\tcategory := split[0]\n\t\tcategory = bytes.TrimPrefix(category, []byte(\"// \"))\n\t\tcategory = bytes.ReplaceAll(category, []byte(\"_\"), []byte(\" \"))\n\t\tcategoryStr := string(category)\n\t\tm[categoryStr] = append(m[categoryStr], strings.TrimSuffix(entry.Name(), \".templ\"))\n\t}\n\n\tkeys := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\n\tslices.Sort(keys)\n\n\tfor _, key := range keys {\n\t\t_, _ = fmt.Fprint(stdout, strings.ToUpper(key)+\"\\n\")\n\t\t_, _ = fmt.Fprint(stdout, \"=======================\\n\")\n\t\tfor _, comp := range m[key] {\n\t\t\tp := filepath.Join(\"internal\", \"views\", \"components\", comp+\".templ\")\n\t\t\t_, err := os.Stat(p)\n\t\t\texists := err == nil\n\t\t\tline := strings.ReplaceAll(comp, \"_\", \" \")\n\t\t\tif exists {\n\t\t\t\tline += \" ✓\"\n\t\t\t}\n\t\t\tline += \"\\n\"\n\n\t\t\t_, _ = fmt.Fprint(stdout, line)\n\t\t}\n\t\t_, _ = fmt.Fprint(stdout, \"\\n\")\n\t}\n\n\treturn 0\n}\n"
  },
  {
    "path": "cmd/server/main.go",
    "content": "package main\n\nimport (\n\t\"github.com/haatos/goshipit/internal\"\n\t\"github.com/haatos/goshipit/internal/assets\"\n\t\"github.com/haatos/goshipit/internal/handler\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/labstack/echo/v4/middleware\"\n\n\t_ \"github.com/mattn/go-sqlite3\"\n)\n\nfunc main() {\n\tinternal.ReadDotenv()\n\tinternal.Settings = internal.NewSettings()\n\n\te := echo.New()\n\te.HTTPErrorHandler = handler.ErrorHandler\n\tloggerFormat := \"${method} ${uri} [${status}] (${latency_human}) | ${short_file}:${line} | ${message}\\n\"\n\te.Logger.SetHeader(loggerFormat)\n\n\tconfig := internal.GetRateLimiterConfig()\n\te.Use(middleware.RateLimiterWithConfig(config))\n\n\te.Use(\n\t\tmiddleware.LoggerWithConfig(middleware.LoggerConfig{\n\t\t\tFormat: loggerFormat,\n\t\t}),\n\t\tmiddleware.GzipWithConfig(middleware.GzipConfig{\n\t\t\tSkipper: middleware.DefaultSkipper,\n\t\t\tLevel:   3,\n\t\t}),\n\t)\n\n\tpublicFS := echo.MustSubFS(assets.PublicFS, \"public\")\n\te.StaticFS(\"/\", publicFS)\n\n\te.GET(\"/\", handler.GetIndexPage)\n\te.GET(\"/about\", handler.GetAboutPage)\n\te.GET(\"/get-started\", handler.GetGettingStartedPage)\n\te.GET(\"/types\", handler.GetTypesPage)\n\te.GET(\"/cli\", handler.GetCLIPage)\n\te.GET(\"/component-anchors\", handler.GetComponentAnchors)\n\te.GET(\"/privacy\", handler.GetPrivacyPolicyPage)\n\te.GET(\"/terms-of-service\", handler.GetTermsOfServicePage)\n\n\te.GET(\"/components/:category/:name\", handler.GetComponentPage)\n\te.GET(\"/components/search\", handler.GetComponentSearch)\n\n\t// handlers for component examples\n\te.POST(\"/validate/string/:name\", handler.PostValidateString)\n\te.GET(\"/infinite-scroll\", handler.GetInfiniteScrollExample)\n\te.GET(\"/infinite-scroll-rows\", handler.GetInfiniteScrollExampleRows)\n\te.GET(\"/active-search\", handler.GetActiveSearchExample)\n\te.GET(\"/lazy-load\", handler.GetLazyLoadExample)\n\te.GET(\"/models\", handler.GetCascadingSelectExample)\n\te.GET(\"/pagination-pages\", handler.GetPaginationExamplePage)\n\te.POST(\"/combobox/:name/:value\", handler.PostCombobox)\n\te.POST(\"/combobox-submit/:name\", handler.PostComboboxSubmit)\n\te.DELETE(\"/modal-confirm\", handler.DeleteModalExample)\n\te.POST(\"/datepicker/select\", handler.PostDatePickerSelectDay)\n\te.GET(\"/datepicker\", handler.GetDatePicker)\n\te.GET(\"/datepicker/monthpicker\", handler.GetDatePickerMonthPicker)\n\te.GET(\"/datepicker/yearpicker\", handler.GetDatePickerYearPicker)\n\te.GET(\"/timeslotpicker\", handler.GetTimeSlotPicker)\n\te.POST(\"/timeslotpicker/reserve\", handler.PostTimeSlotPickerReserve)\n\t// handlers for component examples\n\n\tinternal.GracefulShutdown(e, internal.Settings.Port)\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/haatos/goshipit\n\ngo 1.24\n\nrequire (\n\tgithub.com/PuerkitoBio/goquery v1.10.1\n\tgithub.com/a-h/templ v0.3.1001\n\tgithub.com/alecthomas/chroma v0.10.0\n\tgithub.com/labstack/echo/v4 v4.12.0\n\tgithub.com/labstack/gommon v0.4.2\n\tgithub.com/mattn/go-sqlite3 v1.14.24\n\tgithub.com/russross/blackfriday v1.6.0\n\tgolang.org/x/time v0.7.0\n)\n\nrequire (\n\tgithub.com/andybalholm/cascadia v1.3.3 // indirect\n\tgithub.com/dlclark/regexp2 v1.11.4 // indirect\n\tgithub.com/golang-jwt/jwt v3.2.2+incompatible // indirect\n\tgithub.com/mattn/go-colorable v0.1.13 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/valyala/bytebufferpool v1.0.0 // indirect\n\tgithub.com/valyala/fasttemplate v1.2.2 // indirect\n\tgolang.org/x/crypto v0.40.0 // indirect\n\tgolang.org/x/net v0.42.0 // indirect\n\tgolang.org/x/sys v0.34.0 // indirect\n\tgolang.org/x/text v0.27.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/PuerkitoBio/goquery v1.10.1 h1:Y8JGYUkXWTGRB6Ars3+j3kN0xg1YqqlwvdTV8WTFQcU=\ngithub.com/PuerkitoBio/goquery v1.10.1/go.mod h1:IYiHrOMps66ag56LEH7QYDDupKXyo5A8qrjIx3ZtujY=\ngithub.com/a-h/templ v0.3.943 h1:o+mT/4yqhZ33F3ootBiHwaY4HM5EVaOJfIshvd5UNTY=\ngithub.com/a-h/templ v0.3.943/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=\ngithub.com/a-h/templ v0.3.960 h1:trshEpGa8clF5cdI39iY4ZrZG8Z/QixyzEyUnA7feTM=\ngithub.com/a-h/templ v0.3.960/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=\ngithub.com/a-h/templ v0.3.977 h1:kiKAPXTZE2Iaf8JbtM21r54A8bCNsncrfnokZZSrSDg=\ngithub.com/a-h/templ v0.3.977/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=\ngithub.com/a-h/templ v0.3.1001 h1:yHDTgexACdJttyiyamcTHXr2QkIeVF1MukLy44EAhMY=\ngithub.com/a-h/templ v0.3.1001/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=\ngithub.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=\ngithub.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=\ngithub.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=\ngithub.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=\ngithub.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=\ngithub.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=\ngithub.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=\ngithub.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=\ngithub.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=\ngithub.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=\ngithub.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=\ngithub.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=\ngithub.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=\ngithub.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=\ngithub.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=\ngithub.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=\ngithub.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=\ngolang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=\ngolang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=\ngolang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=\ngolang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=\ngolang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=\ngolang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=\ngolang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=\ngolang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=\ngolang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=\ngolang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=\ngolang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=\ngolang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=\ngolang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=\ngolang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=\ngolang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=\ngolang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=\ngolang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=\ngolang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=\ngolang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=\ngolang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=\ngolang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=\ngolang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=\ngolang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=\ngolang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "input.css",
    "content": "@import \"tailwindcss\";\n@plugin \"@tailwindcss/typography\";\n@source \"./internal/views/**/*.templ\";\n@plugin \"daisyui\" {\n  themes:\n    light --default,\n    night --prefersdark;\n}\n"
  },
  {
    "path": "internal/assets/content/cli.md",
    "content": "# CLI\n\n## Installation\n\n```\ngo install github.com/haatos/cmd/gsi\n```\n\nThen run `gsi` in your terminal to see a list of commands:\n\n```\nusage: gsi <command> [<args>...]\n\ngsi - GoShip.it CLI\n\ncommands:\n  add <name>      Add a component to internal/views/components\n  remove <name>   Remove a component from internal/views/components\n  list            List all available components\n```\n\nUse the CLI at the root of your application. New components will be added to `internal/views/components/`.\n"
  },
  {
    "path": "internal/assets/content/getting_started.md",
    "content": "# Getting started\n\nTo get started with goship.it in a new project using _Echo_ router:\n\n- Create a new folder for your project\n- Initialize the module by running\n  - `go mod init github.com/my/package`\n  - replace the package with your own repository!\n- Get Go modules:\n  - `go get -u github.com/labstack/echo/v4`\n  - `go get -u github.com/a-h/templ`\n- Install Templ CLI:\n  - `go install github.com/a-h/templ/cmd/templ@latest`\n- Install TailwindCSS and DaisyUI:\n  - `npm i -D tailwindcss @tailwindcss/cli @tailwindcss/typography daisyui@latest`\n- Create `input.css` at the root of the project with the following contents:\n\n```input.css\n@import \"tailwindcss\" source(none);\n@plugin \"@tailwindcss/typography\";\n@source \"./internal/views/**/*.templ\";\n@plugin \"daisyui\" {\n    themes:\n        light --default,\n        dark --prefersdark;\n}\n@plugin \"daisyui/theme\" {\n    name: \"light\";\n    default: true;\n    prefersdark: false;\n    color-scheme: \"light\";\n    --color-base-100: oklch(92% 0 0);\n    --color-base-200: oklch(87% 0 0);\n    --color-base-300: oklch(70% 0 0);\n    --color-base-content: oklch(0% 0 0);\n    --color-primary: oklch(55% 0.135 66.442);\n    --color-primary-content: oklch(98% 0.018 155.826);\n    --color-secondary: oklch(53% 0.157 131.589);\n    --color-secondary-content: oklch(98% 0.031 120.757);\n    --color-accent: oklch(64% 0.222 41.116);\n    --color-accent-content: oklch(98% 0.016 73.684);\n    --color-neutral: oklch(43% 0 0);\n    --color-neutral-content: oklch(98% 0 0);\n    --color-info: oklch(52% 0.105 223.128);\n    --color-info-content: oklch(98% 0.019 200.873);\n    --color-success: oklch(50% 0.118 165.612);\n    --color-success-content: oklch(98% 0.018 155.826);\n    --color-warning: oklch(55% 0.195 38.402);\n    --color-warning-content: oklch(98% 0.016 73.684);\n    --color-error: oklch(52% 0.223 3.958);\n    --color-error-content: oklch(97% 0.014 343.198);\n    --radius-selector: 0.5rem;\n    --radius-field: 0.5rem;\n    --radius-box: 0.5rem;\n    --size-selector: 0.28125rem;\n    --size-field: 0.28125rem;\n    --border: 1px;\n    --depth: 1;\n    --noise: 0;\n}\n@plugin \"daisyui/theme\" {\n    name: \"dark\";\n    default: false;\n    prefersdark: true;\n    color-scheme: \"dark\";\n    --color-base-100: oklch(26% 0 0);\n    --color-base-200: oklch(20% 0 0);\n    --color-base-300: oklch(14% 0 0);\n    --color-base-content: oklch(97% 0 0);\n    --color-primary: oklch(79% 0.184 86.047);\n    --color-primary-content: oklch(28% 0.066 53.813);\n    --color-secondary: oklch(64% 0.2 131.684);\n    --color-secondary-content: oklch(98% 0.031 120.757);\n    --color-accent: oklch(64% 0.222 41.116);\n    --color-accent-content: oklch(98% 0.016 73.684);\n    --color-neutral: oklch(14% 0 0);\n    --color-neutral-content: oklch(98% 0 0);\n    --color-info: oklch(71% 0.143 215.221);\n    --color-info-content: oklch(98% 0.019 200.873);\n    --color-success: oklch(72% 0.219 149.579);\n    --color-success-content: oklch(98% 0.018 155.826);\n    --color-warning: oklch(70% 0.213 47.604);\n    --color-warning-content: oklch(98% 0.016 73.684);\n    --color-error: oklch(65% 0.241 354.308);\n    --color-error-content: oklch(97% 0.014 343.198);\n    --radius-selector: 0.5rem;\n    --radius-field: 0.5rem;\n    --radius-box: 0.5rem;\n    --size-selector: 0.28125rem;\n    --size-field: 0.28125rem;\n    --border: 1px;\n    --depth: 1;\n    --noise: 0;\n}\n```\n\n- Create `Makefile` at the base of your project with the following contents:\n\n```make\ntw:\n\t@npx @tailwindcss/cli -i input.css -o ./public/static/css/tw.css --watch\n\ndev:\n\t@templ generate -watch -proxyport=7332 -proxy=\"http://localhost:8080\" -open-browser=false -cmd=\"go run main.go\"\n```\n\n- Place the following rows in `main.go` (remember to update the components package import path to match your project):\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/my/package/internal/views/components\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nfunc main() {\n\te := echo.New()\n\n\te.Static(\"/\", \"public\")\n\n\te.GET(\"/\", func(c echo.Context) error {\n\t\taccordion := components.AccordionExample()\n\t\treturn render(c, accordion)\n\t})\n\n\te.Start(\":8080\")\n}\n\nfunc render(c echo.Context, component templ.Component) error {\n\tbuf := templ.GetBuffer()\n\tdefer templ.ReleaseBuffer(buf)\n\n\tif err := component.Render(c.Request().Context(), buf); err != nil {\n\t\treturn err\n\t}\n\treturn c.HTML(http.StatusOK, buf.String())\n}\n```\n\n- Create the accordion component `internal/views/components/accordion.templ`:\n\n```go\npackage components\n\ntype AccordionRowProps struct {\n\tLabel string\n\tType  string\n\tName  string\n}\n\ntempl AccordionRow(props AccordionRowProps) {\n\t<div class=\"collapse collapse-arrow bg-base-300 join-item\">\n\t\t<input\n\t\t\tif props.Type == \"\" {\n\t\t\t\ttype=\"checkbox\"\n\t\t\t} else {\n\t\t\t\ttype={ props.Type }\n\t\t\t}\n\t\t\tname={ props.Name }\n\t\t/>\n\t\t<div class=\"collapse-title text-xl font-medium\">{ props.Label }</div>\n\t\t<div class=\"collapse-content bg-base-200\">\n\t\t\t{ children... }\n\t\t</div>\n\t</div>\n}\n\ntempl AccordionExample() {\n\t<!DOCTYPE html>\n\t<html lang=\"en\">\n\t\t<head>\n\t\t\t<meta charset=\"UTF-8\"/>\n\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"/static/css/tw.css\"/>\n\t\t\t<title>Document</title>\n\t\t</head>\n\t\t<body class=\"w-full h-full min-h-svh\">\n\t\t\t<main>\n\t\t\t\t<div>\n\t\t\t\t\t@AccordionRow(AccordionRowProps{Label: \"Accordion row 1\", Type: \"checkbox\"}) {\n\t\t\t\t\t\t<p>This is the first content</p>\n\t\t\t\t\t}\n\t\t\t\t\t@AccordionRow(AccordionRowProps{Label: \"Accordion row 2\", Type: \"checkbox\"}) {\n\t\t\t\t\t\t<p>This is the second content</p>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</main>\n\t\t</body>\n\t</html>\n}\n```\n\nAt this point, the filetree of your project should look something like this:\n\n```sh\n.\n├── Makefile\n├── go.mod\n├── go.sum\n├── input.css\n├── internal\n│   └── views\n│       └── components\n│           └── accordion.templ\n├── main.go\n├── node_modules\n├── package-lock.json\n├── package.json\n├── public\n│   └── static\n│       └── css\n│           └── tw.css\n└── tailwind.config.js\n```\n\nIf you are using VSCode as your IDE, you should also add a `.vscode/settings.json` with the following contents (or place these settings in some other VSCode configuration file):\n\n```json\n{\n  \"[templ]\": {\n    \"editor.formatOnSave\": true,\n    \"editor.defaultFormatter\": \"a-h.templ\"\n  },\n  \"tailwindCSS.includeLanguages\": {\n    \"templ\": \"html\"\n  },\n  \"emmet.includeLanguages\": {\n    \"templ\": \"html\"\n  }\n}\n```\n\nThese will enable TailwindCSS autocompletions and HTML element autocompletions (emmet), as well as automatically formatting `.templ` files when saving.\n\nFinally, you can run the example application by running `make tw` and `make dev` in two separate terminals. The site with the accordion should now be visible at http://localhost:8080.\n"
  },
  {
    "path": "internal/assets/content/types.md",
    "content": "# Types\n\n## Introduction\n\nMost components use a struct as the input argument. This provides a convenient way to pass default values to the components; struct fields initialize to the respective type's default value. We can use this feature to make some of the fields of a struct optional to make initialization less cumbersome. For example, we can pass the `components.AnchorProps` argument to an anchor element, `<a>`:\n\n```go\npackage components\n\ntype AnchorProps struct {\n\tHref      string\n\tLabel     string\n\tLeftIcon  templ.Component\n\tRightIcon templ.Component\n\tAttrs     templ.Attributes\n\tClass     string\n}\n\ntempl Anchor(props AnchorProps) {\n\t<a\n\t\tif props.Href != \"\" {\n\t\t\thref={ templ.SafeURL(props.Href) }\n\t\t}\n\t\tclass={ \"group flex items-center cursor-pointer\", props.Class }\n\t\t{ props.Attrs... }\n\t>\n\t\tif props.LeftIcon != nil {\n\t\t\t<div class=\"inline-block mr-1\">\n\t\t\t\t@props.LeftIcon\n\t\t\t</div>\n\t\t}\n\t\t{ props.Label }\n\t\tif props.RightIcon != nil {\n\t\t\t<div class=\"inline-block ml-1\">\n\t\t\t\t@props.RightIcon\n\t\t\t</div>\n\t\t}\n\t</a>\n}\n```\n\nHere we can define the anchor element to optionally have an `href` attribute, or if we choose, a `hx-get` instead:\n\n```go\n@components.Anchor(components.AnchorProps{Href: \"/\"})\n@components.Anchor(components.AnchorProps{Attrs: templ.Attributes{\"hx-get\": \"/\"}})\n```\n\n## Deprecated types\n\n```go\npackage model\n\nimport (\n\t\"time\"\n\n\t\"github.com/a-h/templ\"\n)\n\ntype Accordion struct {\n\tLabel string\n\tType  string\n\tName  string\n}\n\ntype ActiveSearchInput struct {\n\tID     string\n\tURL    string\n\tTarget string\n\tInput  Input\n}\n\ntype Anchor struct {\n\tHref      string\n\tLabel     string\n\tLeftIcon  templ.Component\n\tRightIcon templ.Component\n\tAttrs     templ.Attributes\n\tClass     string\n}\n\ntype Avatar struct {\n\tAvatarClass      string\n\tContainerClass   string\n\tSource           string\n\tPlaceholder      string\n\tPlaceholderClass string\n}\n\ntype Banner struct {\n\tTitle                 templ.Component\n\tDescription           string\n\tCallToAction          Button\n\tSecondaryCallToAction Button\n}\n\ntype Button struct {\n\tLabel string\n\tAttrs templ.Attributes\n}\n\ntype Card struct {\n\tTitle   string\n\tContent string\n\tSource  string\n\tAlt     string\n\tClass   string\n}\n\ntype Chat struct {\n\tMessages []ChatMessage\n}\n\ntype ChatMessage struct {\n\tAvatarURL string\n\tSender    string\n\tTime      string\n\tMessage   string\n\tFooter    string\n\tLocation  string\n\tClass     string\n}\n\ntype Checkbox struct {\n\tID      string\n\tBefore  string\n\tAfter   string\n\tName    string\n\tChecked bool\n\tClass   string\n\tAttrs   templ.Attributes\n}\n\ntype Collapse struct {\n\tClass        string\n\tTitle        string\n\tTitleClass   string\n\tContentClass string\n}\n\ntype Combobox struct {\n\tLabel    string\n\tName     string\n\tURL      string\n\tOptions  []string\n\tSelected []string\n}\n\ntype CompanyInfo struct {\n\tIcon        templ.Component\n\tName        string\n\tDescription string\n\tCopyright   string\n}\n\ntype DatePicker struct {\n\tYear        int\n\tMonth       int\n\tSelected    time.Time\n\tStartOfWeek time.Weekday\n}\n\nfunc (dp DatePicker) Days() []time.Time {\n\tdays := make([]time.Time, 0, 31)\n\tnow := time.Now().UTC()\n\tstart := time.Date(dp.Year, time.Month(dp.Month), 1, 0, 0, 0, 0, now.Location())\n\tend := start.AddDate(0, 1, -1)\n\tfor end.Weekday() != dp.StartOfWeek {\n\t\tend = end.AddDate(0, 0, 1)\n\t}\n\tend = end.AddDate(0, 0, -1)\n\n\tfor start.Weekday() != dp.StartOfWeek {\n\t\tstart = start.AddDate(0, 0, -1)\n\t}\n\tfor !start.After(end) {\n\t\tdays = append(days, start)\n\t\tstart = start.AddDate(0, 0, 1)\n\t}\n\treturn days\n}\n\nfunc (dp DatePicker) Months() []time.Time {\n\tmonths := make([]time.Time, 12)\n\tfor i := 1; i <= 12; i++ {\n\t\tdt := time.Date(dp.Year, time.Month(i), 1, 0, 0, 0, 0, time.Now().Location())\n\t\tmonths[i-1] = dt\n\t}\n\treturn months\n}\n\ntype Dropdown struct {\n\tLabel     string\n\tClass     string\n\tListClass string\n\tItems     []DropdownItem\n}\n\ntype DropdownItem struct {\n\tLabel string\n\tAttrs templ.Attributes\n}\n\ntype Feature struct {\n\tIcon        templ.Component\n\tTitle       string\n\tDescription string\n\tURL         string\n}\n\ntype Image struct {\n\tSource string\n\tAlt    string\n}\n\ntype Input struct {\n\tID              string\n\tType            string // defaults to \"text\"\n\tLabel           string\n\tName            string\n\tValue           string\n\tPlaceholder     string\n\tErr             string\n\tAttrs           templ.Attributes\n\tClass           string\n\tIcon            templ.Component\n\tDisabled        bool\n\tDisabledMessage string\n\tRequired        bool\n}\n\ntype PaginationItem struct {\n\tURL      string\n\tPage     int\n\tLow      int\n\tHigh     int\n\tMaxPages int\n}\n\ntype Price struct {\n\tTitle            string\n\tDescription      string\n\tPrice            string\n\tPer              string\n\tIncludedFeatures []string\n\tExcludedFeatures []string\n\tCallToAction     Button\n\tFooter           templ.Component\n}\n\ntype Radio struct {\n\tName   string\n\tValues map[string]string\n\tClass  string\n}\n\ntype Range struct {\n\tID    string\n\tLabel string\n\tName  string\n\tValue int\n\tMin   int\n\tMax   int\n\tStep  int\n\tClass string\n}\n\ntype Rating struct {\n\tName  string\n\tMin   int\n\tMax   int\n\tClass string\n\tValue int\n}\n\ntype Script struct {\n\tSource string\n\tDefer  bool\n}\n\ntype Select struct {\n\tID      string\n\tLabel   string\n\tName    string\n\tOptions []SelectOption\n\tAttrs   templ.Attributes\n\tClass   string\n}\n\ntype SelectOption struct {\n\tLabel    string\n\tValue    string\n\tSelected bool\n\tDisabled bool\n}\n\ntype Stat struct {\n\tTitle       string\n\tValue       string\n\tDescription string\n}\n\ntype Status struct {\n\tCode         int\n\tTitle        string\n\tDescription  string\n\tReturnButton Button\n}\n\ntype Swap struct {\n\tOn    templ.Component\n\tOff   templ.Component\n\tClass string\n}\n\ntype Tabs struct {\n\tName         string\n\tClass        string\n\tTabs         []Tab\n\tContentClass string\n}\n\ntype Tab struct {\n\tLabel   string\n\tContent templ.Component\n}\n\ntype Testimonial struct {\n\tAvatar  templ.Component\n\tName    string\n\tRating  int\n\tContent string\n}\n\ntype Textarea struct {\n\tID          string\n\tLabel       string\n\tName        string\n\tPlaceholder string\n\tValue       string\n\tRows        int\n\tErr         string\n\tClass       string\n\tAttrs       templ.Attributes\n}\n\ntype TimelineItem struct {\n\tStart  string\n\tMiddle templ.Component\n\tEnd    string\n}\n\ntype Toast struct {\n\tName       string\n\tToastClass string\n\tAlertClass string\n}\n\ntype Toggle struct {\n\tID        string\n\tBefore    string\n\tAfter     string\n\tName      string\n\tChecked   bool\n\tClass     string\n\tHighlight bool\n\tAttrs     templ.Attributes\n}\n\ntype Tooltip struct {\n\tTip   string\n\tClass string\n}\n```\n"
  },
  {
    "path": "internal/assets/embed.go",
    "content": "package assets\n\nimport \"embed\"\n\n//go:embed public/*\nvar PublicFS embed.FS\n\n//go:embed content/*\nvar ContentFS embed.FS\n\n//go:embed generated/*\nvar GeneratedFS embed.FS\n"
  },
  {
    "path": "internal/assets/generated/component_code_map.json",
    "content": "{\n  \"actions\": [\n    {\n      \"name\": \"dropdown\",\n      \"code\": \"```go\\ntype DropdownProps struct {\\n\\tLabel     string\\n\\tClass     string\\n\\tListClass string\\n\\tItems     []DropdownItem\\n}\\n\\ntype DropdownItem struct {\\n\\tLabel string\\n\\tAttrs templ.Attributes\\n}\\n\\ntempl Dropdown(props DropdownProps) {\\n\\t\\u003cdetails class={ \\\"dropdown\\\", props.Class }\\u003e\\n\\t\\t\\u003csummary class=\\\"btn m-1\\\"\\u003e{ props.Label }\\u003c/summary\\u003e\\n\\t\\t\\u003cul class={ \\\"menu dropdown-content\\\", props.ListClass }\\u003e\\n\\t\\t\\tfor _, di := range props.Items {\\n\\t\\t\\t\\t\\u003cli\\u003e\\u003ca { di.Attrs... }\\u003e{ di.Label }\\u003c/a\\u003e\\u003c/li\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/ul\\u003e\\n\\t\\u003c/details\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/dropdown\"\n    },\n    {\n      \"name\": \"fab\",\n      \"code\": \"```go\\ntype FABProps struct {\\n\\tClass       string\\n\\tToggle      any // string or templ.Component\\n\\tToggleClass string\\n\\tClose       templ.Component\\n\\tMainAction  templ.Component\\n}\\n\\ntempl FAB(props FABProps) {\\n\\t\\u003cdiv class={ \\\"fab\\\", props.Class }\\u003e\\n\\t\\t\\u003cdiv tabindex=\\\"0\\\" role=\\\"button\\\" class={ \\\"btn\\\", props.ToggleClass }\\u003e\\n\\t\\t\\tif t, ok := props.Toggle.(string); ok {\\n\\t\\t\\t\\t{ t }\\n\\t\\t\\t} else {\\n\\t\\t\\t\\t@props.Toggle.(templ.Component)\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\tif props.Close != nil {\\n\\t\\t\\t\\u003cdiv class=\\\"fab-close\\\"\\u003e\\n\\t\\t\\t\\t@props.Close\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\tif props.MainAction != nil {\\n\\t\\t\\t\\u003cdiv class=\\\"fab-main-action\\\"\\u003e\\n\\t\\t\\t\\t@props.MainAction\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\t{ children... }\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/fab\"\n    },\n    {\n      \"name\": \"modal\",\n      \"code\": \"```go\\ntype ModalProps struct {\\n\\tID    string\\n\\tLabel any\\n}\\n\\ntempl Modal(props ModalProps) {\\n\\t@modalWrapper(\\n\\t\\tprops,\\n\\t\\ttempl.Attributes{\\\"onclick\\\": fmt.Sprintf(\\\"%s.showModal()\\\", props.ID)},\\n\\t) {\\n\\t\\t{ children... }\\n\\t}\\n}\\n\\ntempl modalWrapper(props ModalProps, attrs templ.Attributes) {\\n\\t// you can use a string or a templ.Component as the 'label'\\n\\t// of the modal button\\n\\tif s, ok := props.Label.(string); ok {\\n\\t\\t\\u003cdiv class=\\\"btn\\\" { attrs... }\\u003e\\n\\t\\t\\t{ s }\\n\\t\\t\\u003c/div\\u003e\\n\\t} else if c, ok := props.Label.(templ.Component); ok {\\n\\t\\t@c\\n\\t}\\n\\t\\u003cdialog id={ props.ID } class=\\\"modal\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"modal-box\\\"\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cform method=\\\"dialog\\\" class=\\\"modal-backdrop\\\"\\u003e\\n\\t\\t\\t\\u003cbutton\\u003eclose\\u003c/button\\u003e\\n\\t\\t\\u003c/form\\u003e\\n\\t\\u003c/dialog\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/modal\"\n    },\n    {\n      \"name\": \"swap\",\n      \"code\": \"```go\\ntype SwapProps struct {\\n\\tOn    templ.Component\\n\\tOff   templ.Component\\n\\tClass string\\n}\\n\\ntempl Swap(props SwapProps) {\\n\\t\\u003clabel class={ \\\"swap\\\", props.Class }\\u003e\\n\\t\\t\\u003cinput type=\\\"checkbox\\\"/\\u003e\\n\\t\\t\\u003cdiv class=\\\"swap-on\\\"\\u003e\\n\\t\\t\\t@props.On\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"swap-off\\\"\\u003e\\n\\t\\t\\t@props.Off\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/label\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/swap\"\n    }\n  ],\n  \"data_display\": [\n    {\n      \"name\": \"accordion\",\n      \"code\": \"```go\\ntype AccordionRowProps struct {\\n\\tLabel string\\n\\tType  string\\n\\tName  string\\n}\\n\\ntempl AccordionRow(props AccordionRowProps) {\\n\\t\\u003cdiv class=\\\"collapse collapse-arrow bg-base-300 join-item\\\"\\u003e\\n\\t\\t\\u003cinput\\n\\t\\t\\tif props.Type == \\\"\\\" {\\n\\t\\t\\t\\ttype=\\\"checkbox\\\"\\n\\t\\t\\t} else {\\n\\t\\t\\t\\ttype={ props.Type }\\n\\t\\t\\t}\\n\\t\\t\\tname={ props.Name }\\n\\t\\t/\\u003e\\n\\t\\t\\u003cdiv class=\\\"collapse-title text-xl font-medium\\\"\\u003e{ props.Label }\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"collapse-content bg-base-200\\\"\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/accordion\"\n    },\n    {\n      \"name\": \"active_search\",\n      \"code\": \"```go\\ntype ActiveSearchInputProps struct {\\n\\tID         string\\n\\tURL        string\\n\\tTarget     string\\n\\tInputProps InputProps\\n}\\n\\ntempl ActiveSearchInput(props ActiveSearchInputProps) {\\n\\t\\u003cdiv class=\\\"w-full flex space-x-2 items-center\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"flex items-center gap-2 w-full max-w-xs\\\"\\u003e\\n\\t\\t\\t\\u003cform\\n\\t\\t\\t\\tid={ props.ID }\\n\\t\\t\\t\\thx-get={ props.URL }\\n\\t\\t\\t\\thx-target={ props.Target }\\n\\t\\t\\t\\thx-swap=\\\"innerHTML\\\"\\n\\t\\t\\t\\thx-trigger={ fmt.Sprintf(\\\"keyup from:input[name=%s] delay:500ms, search\\\", props.InputProps.Name) }\\n\\t\\t\\t\\thx-indicator={ fmt.Sprintf(\\\"#%s\\\", props.ID) }\\n\\t\\t\\t\\tclass=\\\"w-full relative\\\"\\n\\t\\t\\t\\u003e\\n\\t\\t\\t\\t@Input(props.InputProps)\\n\\t\\t\\t\\t\\u003cdiv class=\\\"absolute -right-8 top-2\\\"\\u003e\\n\\t\\t\\t\\t\\t\\u003cspan id={ props.ID } class=\\\"htmx-indicator loading loading-sm loading-spinner\\\"\\u003e\\u003c/span\\u003e\\n\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\u003c/form\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"avatar\",\n      \"code\": \"```go\\ntype AvatarProps struct {\\n\\tAvatarClass      string\\n\\tContainerClass   string\\n\\tSource           string\\n\\tPlaceholder      string\\n\\tPlaceholderClass string\\n}\\n\\ntempl Avatar(props AvatarProps) {\\n\\t\\u003cdiv class={ \\\"avatar\\\", props.AvatarClass }\\u003e\\n\\t\\t\\u003cdiv class={ props.ContainerClass }\\u003e\\n\\t\\t\\t\\u003cimg src={ props.Source }/\\u003e\\n\\t\\t\\tif props.Placeholder != \\\"\\\" {\\n\\t\\t\\t\\t\\u003cspan class={ props.PlaceholderClass }\\u003e{ props.Placeholder }\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl AvatarGroup(class string) {\\n\\t\\u003cdiv class={ \\\"avatar-group rtl:space-x-reverse\\\", class }\\u003e\\n\\t\\t{ children... }\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/avatar\"\n    },\n    {\n      \"name\": \"card\",\n      \"code\": \"```go\\ntype CardProps struct {\\n\\tTitle   string\\n\\tContent string\\n\\tSource  string\\n\\tAlt     string\\n\\tClass   string\\n}\\n\\ntempl Card(props CardProps) {\\n\\t\\u003cdiv class={ \\\"card\\\", props.Class }\\u003e\\n\\t\\tif props.Source != \\\"\\\" {\\n\\t\\t\\t\\u003cfigure\\u003e\\n\\t\\t\\t\\t\\u003cimg src={ props.Source } alt={ props.Alt }/\\u003e\\n\\t\\t\\t\\u003c/figure\\u003e\\n\\t\\t}\\n\\t\\t\\u003cdiv class=\\\"card-body\\\"\\u003e\\n\\t\\t\\t\\u003ch2 class=\\\"card-title\\\"\\u003e{ props.Title }\\u003c/h2\\u003e\\n\\t\\t\\t\\u003cp\\u003e{ props.Content }\\u003c/p\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"card-actions justify-end\\\"\\u003e\\n\\t\\t\\t\\t{ children... }\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/card\"\n    },\n    {\n      \"name\": \"carousel\",\n      \"code\": \"```go\\ntype CarouselProps []CarouselProp\\n\\ntype CarouselProp struct {\\n\\tSource string\\n\\tAlt    string\\n}\\n\\ntempl Carousel(props CarouselProps) {\\n\\t\\u003cdiv class=\\\"carousel carousel-center rounded-box\\\"\\u003e\\n\\t\\tfor _, prop := range props {\\n\\t\\t\\t\\u003cdiv class=\\\"carousel-item [\\u0026:not(:last-child)]:border-r border-r-base-300\\\"\\u003e\\n\\t\\t\\t\\t\\u003cimg class=\\\"max-w-xs\\\" src={ prop.Source } alt={ prop.Alt }/\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/carousel\"\n    },\n    {\n      \"name\": \"chat\",\n      \"code\": \"```go\\ntype ChatProps []ChatMessageProps\\n\\ntype ChatMessageProps struct {\\n\\tAvatarURL string\\n\\tSender    string\\n\\tTime      string\\n\\tMessage   string\\n\\tFooter    string\\n\\tLocation  string\\n\\tClass     string\\n}\\n\\ntempl Chat(props ChatProps) {\\n\\tfor _, prop := range props {\\n\\t\\t@ChatMessage(prop)\\n\\t}\\n}\\n\\ntempl ChatMessage(props ChatMessageProps) {\\n\\t\\u003cdiv\\n\\t\\tclass={\\n\\t\\t\\t\\\"chat\\\",\\n\\t\\t\\ttempl.KV(\\\"chat-start\\\", props.Location == \\\"start\\\"),\\n\\t\\t\\ttempl.KV(\\\"chat-end\\\", props.Location == \\\"end\\\"),\\n\\t\\t}\\n\\t\\u003e\\n\\t\\tif props.AvatarURL != \\\"\\\" {\\n\\t\\t\\t@Avatar(AvatarProps{ContainerClass: \\\"chat-image w-10 rounded-full\\\", Source: props.AvatarURL})\\n\\t\\t}\\n\\t\\t\\u003cdiv class=\\\"chat-header\\\"\\u003e\\n\\t\\t\\t{ props.Sender }\\n\\t\\t\\t\\u003ctime class=\\\"text-xs opacity-50\\\"\\u003e{ props.Time }\\u003c/time\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class={ \\\"chat-bubble\\\", props.Class }\\u003e\\n\\t\\t\\t{ props.Message }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"chat-footer\\\"\\u003e\\n\\t\\t\\t{ props.Footer }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/chat\"\n    },\n    {\n      \"name\": \"collapse\",\n      \"code\": \"```go\\ntype CollapseProps struct {\\n\\tClass        string\\n\\tTitle        string\\n\\tTitleClass   string\\n\\tContentClass string\\n}\\n\\ntempl Collapse(props CollapseProps) {\\n\\t\\u003cdiv\\n\\t\\ttabindex=\\\"0\\\"\\n\\t\\tclass={ \\\"collapse\\\", props.Class }\\n\\t\\u003e\\n\\t\\t\\u003cinput type=\\\"checkbox\\\"/\\u003e\\n\\t\\t\\u003cdiv class={ \\\"collapse-title\\\", props.TitleClass }\\u003e\\n\\t\\t\\t{ props.Title }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class={ \\\"collapse-content\\\", props.ContentClass }\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/collapse\"\n    },\n    {\n      \"name\": \"countdown\",\n      \"code\": \"```go\\ntype CountdownProps struct {\\n\\tExpires time.Time\\n\\tDays    bool\\n\\tHours   bool\\n\\tMinutes bool\\n\\tSeconds bool\\n}\\n\\ntempl Countdown(props CountdownProps) {\\n\\t{{ spanID := time.Now().UnixNano() }}\\n\\t\\u003cdiv class=\\\"grid auto-cols-max grid-flow-col gap-5 text-center\\\"\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"hidden\\\", !props.Days),\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"countdown font-mono text-5xl\\\"\\u003e\\n\\t\\t\\t\\t\\u003cspan id={ fmt.Sprintf(\\\"span-days-%d\\\", spanID) } style=\\\"--value:15;\\\" aria-live=\\\"polite\\\" aria-label=\\\"15\\\"\\u003e15\\u003c/span\\u003e\\n\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\tdays\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"hidden\\\", !props.Hours),\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"countdown font-mono text-5xl\\\"\\u003e\\n\\t\\t\\t\\t\\u003cspan id={ fmt.Sprintf(\\\"span-hours-%d\\\", spanID) } style=\\\"--value:10;\\\" aria-live=\\\"polite\\\" aria-label=\\\"10\\\"\\u003e10\\u003c/span\\u003e\\n\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\thours\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"hidden\\\", !props.Minutes),\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"countdown font-mono text-5xl\\\"\\u003e\\n\\t\\t\\t\\t\\u003cspan id={ fmt.Sprintf(\\\"span-minutes-%d\\\", spanID) } style=\\\"--value:24;\\\" aria-live=\\\"polite\\\" aria-label=\\\"24\\\"\\u003e24\\u003c/span\\u003e\\n\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\tmin\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"hidden\\\", !props.Seconds),\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"countdown font-mono text-5xl\\\"\\u003e\\n\\t\\t\\t\\t\\u003cspan id={ fmt.Sprintf(\\\"span-seconds-%d\\\", spanID) } style=\\\"--value:59;\\\" aria-live=\\\"polite\\\" aria-label=\\\"59\\\"\\u003e59\\u003c/span\\u003e\\n\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\tsec\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cscript data-expires={ props.Expires.Format(\\\"2006-01-02T15:04:05Z\\\") } data-id={ spanID }\\u003e\\n            var intervalId = null;\\n\\n            function updateTimes(expires, days, hours, minutes, seconds) {\\n                let expiresDate = Date.parse(expires);\\n                let now = new Date()\\n                let diffMs = Math.abs(expiresDate - now.getTime());\\n                let totalSeconds = diffMs / 1000;\\n\\n                if (now.getTime() \\u003e= expiresDate) {\\n                    clearInterval(intervalId);\\n                    return\\n                }\\n\\n                const daysRemaining = Math.floor(diffMs / (1000 * 60 * 60 * 24))\\n                diffMs -= daysRemaining * (1000 * 60 * 60 *24)\\n                days.setAttribute(\\\"style\\\", `--value:${daysRemaining};`)\\n\\n                const hoursRemaining = Math.floor(diffMs / (1000 * 60 * 60));\\n                diffMs -= hoursRemaining * (1000 * 60 * 60)\\n                hours.setAttribute(\\\"style\\\", `--value:${hoursRemaining};`)\\n\\n                const minutesRemaining = Math.floor(diffMs / (1000 * 60));\\n                diffMs -= minutesRemaining * (1000 * 60);\\n                minutes.setAttribute(\\\"style\\\", `--value:${minutesRemaining};`)\\n\\n                const secondsRemaining = Math.floor(diffMs / 1000);\\n                seconds.setAttribute(\\\"style\\\", `--value:${secondsRemaining};`)\\n            }\\n\\n            function startUpdatingTimes(expires, days, hours, minutes, seconds) {\\n                updateTimes(expires, days, hours, minutes, seconds);\\n                intervalId = setInterval(() =\\u003e updateTimes(expires, days, hours, minutes, seconds), 1000);\\n            }\\n\\n            ((expires) =\\u003e {\\n                let days = document.getElementById(`span-days-${document.currentScript.getAttribute(\\\"data-id\\\")}`);\\n                let hours = document.getElementById(`span-hours-${document.currentScript.getAttribute(\\\"data-id\\\")}`);\\n                let minutes = document.getElementById(`span-minutes-${document.currentScript.getAttribute(\\\"data-id\\\")}`);\\n                let seconds = document.getElementById(`span-seconds-${document.currentScript.getAttribute(\\\"data-id\\\")}`);\\n                startUpdatingTimes(expires, days, hours, minutes, seconds);\\n            })(document.currentScript.getAttribute(\\\"data-expires\\\"))\\n        \\u003c/script\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"diff\",\n      \"code\": \"```go\\ntype DiffProps struct {\\n\\tWidth  int\\n\\tHeight int\\n\\tImage1 DiffImage\\n\\tImage2 DiffImage\\n}\\n\\ntype DiffImage struct {\\n\\tSource string\\n\\tAlt    string\\n}\\n\\ntempl Diff(props DiffProps) {\\n\\t\\u003cdiv class={ \\\"diff\\\", fmt.Sprintf(\\\"aspect-[%d/%d]\\\", props.Width, props.Height) }\\u003e\\n\\t\\t\\u003cdiv class=\\\"diff-item-1\\\"\\u003e\\n\\t\\t\\t\\u003cimg alt={ props.Image1.Alt } src={ props.Image1.Source }/\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"diff-item-2\\\"\\u003e\\n\\t\\t\\t\\u003cimg alt={ props.Image2.Alt } src={ props.Image2.Source }/\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"diff-resizer\\\"\\u003e\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/diff\"\n    },\n    {\n      \"name\": \"features\",\n      \"code\": \"```go\\ntype FeaturesProps struct {\\n\\tTitle    string\\n\\tFeatures []FeatureProps\\n}\\n\\ntype FeatureProps struct {\\n\\tIcon        templ.Component\\n\\tTitle       string\\n\\tDescription string\\n\\tURL         string\\n}\\n\\ntempl Features(props FeaturesProps) {\\n\\t\\u003cdiv class=\\\"py-12 px-4\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"max-w-screen-xl mx-auto text-base-content/80\\\"\\u003e\\n\\t\\t\\tif props.Title != \\\"\\\" {\\n\\t\\t\\t\\t\\u003ch2 class=\\\"sm:text-4xl text-2xl font-bold text-center mb-16\\\"\\u003e{ props.Title }\\u003c/h2\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cdiv class=\\\"grid lg:grid-cols-3 md:grid-cols-2 gap-12 max-md:max-w-lg mx-auto\\\"\\u003e\\n\\t\\t\\t\\tfor _, feature := range props.Features {\\n\\t\\t\\t\\t\\t@Feature(feature)\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl Feature(feature FeatureProps) {\\n\\t\\u003cdiv\\n\\t\\tclass={\\n\\t\\t\\t\\\"flex flex-col justify-between items-center rounded-box group p-8 text-center\\\",\\n\\t\\t\\t\\\"hover:bg-base-300 hover:text-base-content hover:shadow-xl transition-all duration-300\\\",\\n\\t\\t}\\n\\t\\u003e\\n\\t\\t@feature.Icon\\n\\t\\tif feature.Title != \\\"\\\" {\\n\\t\\t\\t\\u003ch3 class=\\\"text-xl font-semibold mb-3\\\"\\u003e{ feature.Title }\\u003c/h3\\u003e\\n\\t\\t}\\n\\t\\t\\u003cp class=\\\"text-base-content/70 group-hover:text-base-content text-sm\\\"\\u003e{ feature.Description }\\u003c/p\\u003e\\n\\t\\tif feature.URL != \\\"\\\" {\\n\\t\\t\\t\\u003ca href={ templ.SafeURL(feature.URL) } class=\\\"mt-2 link link-primary\\\"\\u003eLearn more\\u003c/a\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"hover_3d_card\",\n      \"code\": \"```go\\ntempl Hover3DCard() {\\n\\t\\u003cdiv class=\\\"hover-3d\\\"\\u003e\\n\\t\\t{ children... }\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\u003e\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"infinite_scroll\",\n      \"code\": \"```go\\ntempl InfiniteScrollTable(rows []templ.Component) {\\n\\t@Table(\\n\\t\\t[]templ.Component{PlainText(\\\"Name\\\"), PlainText(\\\"Email\\\")},\\n\\t\\trows,\\n\\t\\tnil,\\n\\t)\\n\\t\\u003cdiv class=\\\"flex justify-center\\\"\\u003e\\u003cspan id=\\\"spinner\\\" class=\\\"htmx-indicator loading loading-spinner\\\"\\u003e\\u003c/span\\u003e\\u003c/div\\u003e\\n}\\n\\ntempl InfiniteScrollRows(rows []templ.Component) {\\n\\tfor _, r := range rows {\\n\\t\\t@r\\n\\t}\\n}\\n\\ntempl InfiniteScrollRow(name, email string, page int, hasMore bool) {\\n\\t\\u003ctr\\n\\t\\tif hasMore {\\n\\t\\t\\thx-get={ fmt.Sprintf(\\\"/infinite-scroll-rows?page=%d\\\", page+1) }\\n\\t\\t\\thx-target=\\\"this\\\"\\n\\t\\t\\thx-trigger=\\\"intersect once\\\"\\n\\t\\t\\thx-swap=\\\"afterend\\\"\\n\\t\\t\\thx-indicator=\\\"#spinner\\\"\\n\\t\\t}\\n\\t\\u003e\\n\\t\\t\\u003ctd\\u003e{ name }\\u003c/td\\u003e\\n\\t\\t\\u003ctd\\u003e{ email }\\u003c/td\\u003e\\n\\t\\u003c/tr\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"lazy_load\",\n      \"code\": \"```go\\ntempl LazyLoad(url string) {\\n\\t\\u003cdiv\\n\\t\\thx-get={ url }\\n\\t\\thx-trigger=\\\"load\\\"\\n\\t\\thx-target=\\\"this\\\"\\n\\t\\tclass=\\\"flex justify-center items-center py-8\\\"\\n\\t\\u003e\\n\\t\\t\\u003cspan class=\\\"loading loading-spinner\\\"\\u003e\\u003c/span\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"pricing\",\n      \"code\": \"```go\\ntype PricingProps struct {\\n\\tChecked bool\\n\\tPrices  []PriceProps\\n}\\n\\ntype PriceProps struct {\\n\\tTitle            string\\n\\tDescription      string\\n\\tPriceMonthly     string\\n\\tPerMonthly       string\\n\\tPriceAnnually    string\\n\\tPerAnnually      string\\n\\tPerUser          bool\\n\\tPromotion        string\\n\\tIncludedFeatures []string\\n\\tExcludedFeatures []string\\n\\tCallToAction     PriceButtonProps\\n\\tFooter           templ.Component\\n}\\n\\ntype PriceButtonProps struct {\\n\\tLabel string\\n\\tAttrs templ.Attributes\\n}\\n\\n// NOTE: Requires Alpine.js\\ntempl Pricing(props PricingProps) {\\n\\t\\u003cscript src=\\\"/static/js/alpine.js\\\" defer\\u003e\\u003c/script\\u003e\\n\\t\\u003cdiv x-data=\\\"{ yearly: true }\\\" class=\\\"w-full mx-auto py-8 max-w-screen-xl\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"max-w-xs mx-auto my-6\\\"\\u003e\\n\\t\\t\\t@Toggle(ToggleProps{\\n\\t\\t\\t\\tBefore:    \\\"Billed monthly\\\",\\n\\t\\t\\t\\tAfter:     \\\"Billed annually\\\",\\n\\t\\t\\t\\tName:      \\\"period\\\",\\n\\t\\t\\t\\tChecked:   props.Checked,\\n\\t\\t\\t\\tHighlight: true,\\n\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\\"x-on:click\\\": \\\"yearly = !yearly\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t})\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t@PriceGrid(props.Prices)\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl PriceGrid(prices []PriceProps) {\\n\\t\\u003cdiv\\n\\t\\tid=\\\"price-grid\\\"\\n\\t\\tclass={ \\\"grid auto-cols-fr grid-flow-row lg:grid-flow-col pt-4 w-full mx-auto gap-4\\\",\\n            templ.KV(\\\"gap-8\\\", slices.ContainsFunc(prices, func(pp PriceProps) bool {\\n                    return pp.Promotion != \\\"\\\"\\n                })) }\\n\\t\\u003e\\n\\t\\tfor i := range prices {\\n\\t\\t\\t@Price(prices[i], nil)\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl Price(price PriceProps, footer templ.Component) {\\n\\t\\u003cdiv class={ \\\"relative\\\", templ.KV(\\\"scale-110\\\", price.Promotion != \\\"\\\") }\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"card rounded-box w-full max-w-xs p-6 mx-auto shadow-xl shadow-base-300\\\",\\n\\t\\t\\t\\t\\\"bg-gradient-to-br from-base-200 dark:from-base-300 via-base-100 to-base-200 dark:to-base-300\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"ring-base-content/60\\\", price.Promotion == \\\"\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"ring-1 ring-accent\\\", price.Promotion != \\\"\\\"),\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\tif price.Promotion != \\\"\\\" {\\n\\t\\t\\t\\t\\u003cspan class=\\\"absolute top-0 right-0 bg-accent px-2 rounded-tr-box rounded-bl-box\\\"\\u003e\\n\\t\\t\\t\\t\\t{ price.Promotion }\\n\\t\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cdiv class=\\\"card-title text-2xl mt-8\\\"\\u003e\\n\\t\\t\\t\\t\\u003ch2 class=\\\"mx-auto\\\"\\u003e{ price.Title }\\u003c/h2\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\u003cp x-show=\\\"yearly\\\" class=\\\"text-center text-3xl font-bold mt-8\\\"\\u003e\\n\\t\\t\\t\\t{ price.PriceAnnually }\\n\\t\\t\\t\\t\\u003cspan class=\\\"text-xs font-normal\\\"\\u003e\\n\\t\\t\\t\\t\\t{ price.PerAnnually }\\n\\t\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\t\\tif price.PerUser {\\n\\t\\t\\t\\t\\t\\u003cspan class=\\\"text-sm font-normal\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t{ \\\" / user\\\" }\\n\\t\\t\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\u003cp x-show=\\\"!yearly\\\" class=\\\"text-center text-3xl font-bold mt-8\\\"\\u003e\\n\\t\\t\\t\\t{ price.PriceMonthly } \\u003cspan class=\\\"text-xs font-normal\\\"\\u003e{ price.PerMonthly }\\u003c/span\\u003e\\n\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\u003cbutton { price.CallToAction.Attrs... }\\u003e\\n\\t\\t\\t\\t{ price.CallToAction.Label }\\n\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"text-sm mt-8\\\"\\u003e\\n\\t\\t\\t\\t\\u003cul class=\\\"space-y-4\\\"\\u003e\\n\\t\\t\\t\\t\\tfor i := range price.IncludedFeatures {\\n\\t\\t\\t\\t\\t\\t\\u003cli class=\\\"flex items-center space-x-2\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003csvg class=\\\"w-4 h-4\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003cpath class=\\\"fill-base-content\\\" fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" d=\\\"M21.5821 5.54289C21.9726 5.93342 21.9726 6.56658 21.5821 6.95711L10.2526 18.2867C9.86452 18.6747 9.23627 18.6775 8.84475 18.293L2.29929 11.8644C1.90527 11.4774 1.89956 10.8443 2.28655 10.4503C2.67354 10.0562 3.30668 10.0505 3.70071 10.4375L9.53911 16.1717L20.1679 5.54289C20.5584 5.15237 21.1916 5.15237 21.5821 5.54289Z\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cspan\\u003e{ price.IncludedFeatures[i] }\\u003c/span\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003c/li\\u003e\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003c/ul\\u003e\\n\\t\\t\\t\\tif len(price.ExcludedFeatures) \\u003e 0 {\\n\\t\\t\\t\\t\\t\\u003cdiv class=\\\"divider !my-2\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003cul class=\\\"space-y-4\\\"\\u003e\\n\\t\\t\\t\\t\\tfor i := range price.ExcludedFeatures {\\n\\t\\t\\t\\t\\t\\t\\u003cli class=\\\"flex items-center space-x-2 pl-6\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cspan class=\\\"text-base-content/50\\\"\\u003e{ price.ExcludedFeatures[i] }\\u003c/span\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003c/li\\u003e\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003c/ul\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\tif footer != nil {\\n\\t\\t\\t\\t@footer\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"stats\",\n      \"code\": \"```go\\ntype StatProps struct {\\n\\tTitle       string\\n\\tValue       string\\n\\tDescription string\\n}\\n\\ntempl Stats() {\\n\\t\\u003cdiv class=\\\"stats stats-horizontal shadow-sm\\\"\\u003e\\n\\t\\t{ children... }\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl Stat(props StatProps) {\\n\\t\\u003cdiv class=\\\"stat\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"stat-title\\\"\\u003e{ props.Title }\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"stat-value\\\"\\u003e{ props.Value }\\u003c/div\\u003e\\n\\t\\tif props.Description != \\\"\\\" {\\n\\t\\t\\t\\u003cdiv class=\\\"stat-desc\\\"\\u003e{ props.Description }\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\t\\u003cdiv class=\\\"stat-actions\\\"\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/stat\"\n    },\n    {\n      \"name\": \"table\",\n      \"code\": \"```go\\ntempl Table(headers []templ.Component, rows []templ.Component, attrs templ.Attributes) {\\n\\t\\u003cdiv class=\\\"overflow-x-auto\\\"\\u003e\\n\\t\\t\\u003ctable { attrs... } class=\\\"table\\\"\\u003e\\n\\t\\t\\t\\u003cthead\\u003e\\n\\t\\t\\t\\t\\u003ctr\\u003e\\n\\t\\t\\t\\t\\tfor _, header := range headers {\\n\\t\\t\\t\\t\\t\\t\\u003cth\\u003e\\n\\t\\t\\t\\t\\t\\t\\t@header\\n\\t\\t\\t\\t\\t\\t\\u003c/th\\u003e\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003c/tr\\u003e\\n\\t\\t\\t\\u003c/thead\\u003e\\n\\t\\t\\t\\u003ctbody\\u003e\\n\\t\\t\\t\\tfor _, trow := range rows {\\n\\t\\t\\t\\t\\t@trow\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003c/tbody\\u003e\\n\\t\\t\\u003c/table\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\n// Component to use as plain text when\\n// templ.Component is used as argument\\ntempl PlainText(content string) {\\n\\t{ content }\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/table\"\n    },\n    {\n      \"name\": \"testimonial\",\n      \"code\": \"```go\\ntype TestimonialProps []TestimonialProp\\n\\ntype TestimonialProp struct {\\n\\tAvatar  templ.Component\\n\\tName    string\\n\\tRating  int\\n\\tContent string\\n}\\n\\ntempl TestimonialGrid(title string, props TestimonialProps) {\\n\\t\\u003csection\\u003e\\n\\t\\t\\u003cdiv class=\\\"mx-auto max-w-screen-xl px-4 py-12 sm:px-6 lg:px-8 lg:py-16\\\"\\u003e\\n\\t\\t\\t\\u003ch2 class=\\\"text-center text-4xl font-bold tracking-tight sm:text-5xl\\\"\\u003e\\n\\t\\t\\t\\t{ title }\\n\\t\\t\\t\\u003c/h2\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"mt-8 [column-fill:_balance] sm:columns-2 sm:gap-6 lg:columns-3 lg:gap-8\\\"\\u003e\\n\\t\\t\\t\\tfor i := range props {\\n\\t\\t\\t\\t\\t\\u003cdiv class=\\\"mb-8 sm:break-inside-avoid\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003cblockquote class=\\\"rounded-lg bg-base-300 p-6 shadow-sm sm:p-8\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cdiv class=\\\"flex items-center gap-4\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\tif props[i].Avatar != nil {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t@props[i].Avatar\\n\\t\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003cdiv\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t@RatingDisplay(RatingProps{\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tName:  fmt.Sprintf(\\\"review-rating-%d\\\", i),\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tMin:   1,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tMax:   5,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tValue: props[i].Rating,\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t})\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\u003cp class=\\\"mt-0.5 text-lg font-medium\\\"\\u003e{ props[i].Name }\\u003c/p\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cp class=\\\"mt-4\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t{ props[i].Content }\\n\\t\\t\\t\\t\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003c/blockquote\\u003e\\n\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/section\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"text_rotate\",\n      \"code\": \"```go\\ntype TextRotateProps struct {\\n\\tClass string\\n\\tItems []TextRotateItem\\n}\\n\\ntype TextRotateItem struct {\\n\\tText  string\\n\\tClass string\\n}\\n\\ntempl TextRotate(props TextRotateProps) {\\n\\t\\u003cspan class={ \\\"text-rotate\\\", props.Class }\\u003e\\n\\t\\t\\u003cspan\\u003e\\n\\t\\t\\tfor _, item := range props.Items {\\n\\t\\t\\t\\t\\u003cspan class={ item.Class }\\u003e{ item.Text }\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/span\\u003e\\n\\t\\u003c/span\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"timeline\",\n      \"code\": \"```go\\ntype TimelineProps []TimelineProp\\n\\ntype TimelineProp struct {\\n\\tStart  string\\n\\tMiddle templ.Component\\n\\tEnd    string\\n}\\n\\ntempl Timeline(props TimelineProps) {\\n\\t\\u003cul class=\\\"timeline\\\"\\u003e\\n\\t\\tfor i, prop := range props {\\n\\t\\t\\t\\u003cli\\u003e\\n\\t\\t\\t\\tif i \\u003e 0 {\\n\\t\\t\\t\\t\\t\\u003chr/\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif prop.Start != \\\"\\\" {\\n\\t\\t\\t\\t\\t\\u003cdiv class=\\\"timeline-start\\\"\\u003e{ prop.Start }\\u003c/div\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif prop.Middle != nil {\\n\\t\\t\\t\\t\\t\\u003cdiv class=\\\"timeline-middle\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t@prop.Middle\\n\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif prop.End != \\\"\\\" {\\n\\t\\t\\t\\t\\t\\u003cdiv class=\\\"timeline-end\\\"\\u003e{ prop.End }\\u003c/div\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif i \\u003c len(props) - 1 {\\n\\t\\t\\t\\t\\t\\u003chr/\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003c/li\\u003e\\n\\t\\t}\\n\\t\\u003c/ul\\u003e\\n}\\n\\ntempl TimelineCheckbox(checked bool) {\\n\\t\\u003csvg\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\tviewBox=\\\"0 0 20 20\\\"\\n\\t\\tfill=\\\"currentColor\\\"\\n\\t\\tclass={ \\\"h-5 w-5\\\", templ.KV(\\\"fill-primary\\\", checked) }\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\tfill-rule=\\\"evenodd\\\"\\n\\t\\t\\td=\\\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\\\"\\n\\t\\t\\tclip-rule=\\\"evenodd\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/timeline\"\n    }\n  ],\n  \"data_input\": [\n    {\n      \"name\": \"checkbox\",\n      \"code\": \"```go\\ntype CheckboxProps struct {\\n\\tID      string\\n\\tBefore  string\\n\\tAfter   string\\n\\tName    string\\n\\tChecked bool\\n\\tClass   string\\n\\tAttrs   templ.Attributes\\n\\tSize    string\\n}\\n\\ntempl Checkbox(props CheckboxProps) {\\n\\t\\u003clabel class=\\\"label justify-center cursor-pointer\\\"\\u003e\\n\\t\\tif props.Before != \\\"\\\" {\\n\\t\\t\\t\\u003cspan\\n\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\ttempl.KV(\\\"text-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"text-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"text-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"text-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t\\t\\\"mr-2\\\",\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003e\\n\\t\\t\\t\\t{ props.Before }\\n\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t}\\n\\t\\t\\u003cinput\\n\\t\\t\\t{ props.Attrs... }\\n\\t\\t\\tif props.ID != \\\"\\\" {\\n\\t\\t\\t\\tid={ props.ID }\\n\\t\\t\\t}\\n\\t\\t\\ttype=\\\"checkbox\\\"\\n\\t\\t\\tname={ props.Name }\\n\\t\\t\\tif props.Checked {\\n\\t\\t\\t\\tchecked=\\\"checked\\\"\\n\\t\\t\\t}\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"checkbox\\\", props.Class,\\n\\t\\t\\t\\ttempl.KV(\\\"checkbox-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"checkbox-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"checkbox-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"checkbox-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t}\\n\\t\\t/\\u003e\\n\\t\\tif props.After != \\\"\\\" {\\n\\t\\t\\t\\u003cspan class=\\\"ml-2\\\"\\u003e\\n\\t\\t\\t\\t{ props.After }\\n\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t}\\n\\t\\u003c/label\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/checkbox\"\n    },\n    {\n      \"name\": \"combobox\",\n      \"code\": \"```go\\ntype ComboboxProps struct {\\n\\tLabel    string\\n\\tName     string\\n\\tURL      string\\n\\tOptions  []string\\n\\tSelected []string\\n}\\n\\ntempl Combobox(props ComboboxProps) {\\n\\t\\u003cdetails class=\\\"dropdown w-full max-w-md min-h-8\\\"\\u003e\\n\\t\\t\\u003csummary\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"cursor-pointer flex space-x-2 w-full rounded-box\\\",\\n\\t\\t\\t\\t\\\"border border-base-content py-1 px-2\\\",\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"text-sm text-nowrap\\\"\\u003e{ props.Label }\\u003c/span\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"w-full flex items-center space-x-1\\\"\\u003e\\n\\t\\t\\t\\t\\u003cdiv\\n\\t\\t\\t\\t\\tid={ fmt.Sprintf(\\\"%s_selections\\\", props.Name) }\\n\\t\\t\\t\\t\\tclass=\\\"w-full grid-flow-col-dense\\\"\\n\\t\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\tfor _, s := range props.Selected {\\n\\t\\t\\t\\t\\t\\t@ComboBadge(props.Name, s)\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/summary\\u003e\\n\\t\\t\\u003cul class=\\\"menu dropdown-content bg-base-200 rounded-box z-50 p-2 shadow-sm\\\"\\u003e\\n\\t\\t\\tfor _, opt := range props.Options {\\n\\t\\t\\t\\t\\u003cli\\u003e\\n\\t\\t\\t\\t\\t\\u003clabel class=\\\"label cursor-pointer space-x-2\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003cspan class=\\\"label-text\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t{ opt }\\n\\t\\t\\t\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\t\\t\\t\\thx-post={ fmt.Sprintf(props.URL, props.Name, url.PathEscape(opt)) }\\n\\t\\t\\t\\t\\t\\t\\thx-target={ fmt.Sprintf(\\\"#%s_selections\\\", props.Name) }\\n\\t\\t\\t\\t\\t\\t\\thx-swap=\\\"beforeend\\\"\\n\\t\\t\\t\\t\\t\\t\\ttype=\\\"checkbox\\\"\\n\\t\\t\\t\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\t\\t\\t\\tclass={ \\\"checkbox\\\" }\\n\\t\\t\\t\\t\\t\\t/\\u003e\\n\\t\\t\\t\\t\\t\\u003c/label\\u003e\\n\\t\\t\\t\\t\\u003c/li\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/ul\\u003e\\n\\t\\t\\u003cscript data-checkbox-name={ props.Name } type=\\\"text/javascript\\\"\\u003e\\n\\t\\t\\tvar name = document.currentScript.getAttribute(\\\"data-checkbox-name\\\");\\n\\t\\t\\t((name) =\\u003e {\\n\\t\\t\\t\\tdocument.addEventListener(\\\"htmx:configRequest\\\", (evt) =\\u003e {\\n\\t\\t\\t\\t\\tif (evt.target.getAttribute(\\\"name\\\") === name \\u0026\\u0026 !evt.target.checked) {\\n\\t\\t\\t\\t\\t\\t// prevent htmx request when checkbox is unchecked\\n\\t\\t\\t\\t\\t\\tevt.preventDefault()\\n\\n\\t\\t\\t\\t\\t\\t// remove from selected elements\\n\\t\\t\\t\\t\\t\\tlet label = evt.target.closest(\\\"label\\\")\\n\\t\\t\\t\\t\\t\\tif (label !== null \\u0026\\u0026 label !== undefined) {\\n\\t\\t\\t\\t\\t\\t\\tlet span = label.querySelector(\\\"span.label-text\\\")\\n\\t\\t\\t\\t\\t\\t\\tlet value = span.innerText\\n\\t\\t\\t\\t\\t\\t\\tlet input = document.querySelector(`input[value=\\\"${value}\\\"]`)\\n\\t\\t\\t\\t\\t\\t\\tif (input.getAttribute(\\\"name\\\") === name) {\\n\\t\\t\\t\\t\\t\\t\\t\\tinput.closest(\\\"div\\\").remove()\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t})\\n\\t\\t\\t})(name);\\n\\t\\t\\u003c/script\\u003e\\n\\t\\u003c/details\\u003e\\n}\\n\\ntempl ComboBadge(name, value string) {\\n\\t\\u003cdiv class=\\\"ml-2 badge badge-neutral p-1 text-nowrap select-none\\\"\\u003e\\n\\t\\t\\u003cinput type=\\\"hidden\\\" name={ name } value={ value }/\\u003e\\n\\t\\t\\u003cspan\\u003e{ value }\\u003c/span\\u003e\\n\\t\\t\\u003cbutton\\n\\t\\t\\tonclick=\\\"uncheckAndRemoveBadge(event)\\\"\\n\\t\\t\\tclass=\\\"ml-1 btn btn-xs btn-circle btn-ghost\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t@crossIcon()\\n\\t\\t\\u003c/button\\u003e\\n\\t\\t\\u003cscript\\u003e\\n\\t\\t\\tfunction uncheckAndRemoveBadge(evt) {\\n\\t\\t\\t\\tvar div = evt.target.parentElement\\n\\t\\t\\t\\twhile (div.nodeName !== \\\"DIV\\\") {\\n\\t\\t\\t\\t\\tdiv = div.parentElement\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tlet input = div.querySelector(\\\"input[type=hidden]\\\")\\n\\t\\t\\t\\tlet name = input.getAttribute(\\\"name\\\")\\n\\t\\t\\t\\tlet labelText = input.value\\n\\n\\t\\t\\t\\tlet details = div.closest(\\\"details\\\")\\n\\t\\t\\t\\tlet ul = details.querySelector(\\\"ul\\\")\\n\\t\\t\\t\\tlet checkboxes = ul.querySelectorAll(`input[name=\\\"${name}\\\"]`)\\n\\t\\t\\t\\tcheckboxes.forEach((cb) =\\u003e {\\n\\t\\t\\t\\t\\tif (cb.checked) {\\n\\t\\t\\t\\t\\t\\tlet label = cb.parentElement\\n\\t\\t\\t\\t\\t\\tlabel.querySelectorAll(\\\"span.label-text\\\").forEach((el) =\\u003e {\\n\\t\\t\\t\\t\\t\\t\\tif (el.innerHTML === labelText) {\\n\\t\\t\\t\\t\\t\\t\\t\\tcb.checked = false\\n\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t})\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t})\\n\\t\\t\\t\\tdiv.remove()\\n\\t\\t\\t}\\n\\t\\t\\u003c/script\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl crossIcon() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"h-3 w-3\\\"\\n\\t\\tviewBox=\\\"0 0 25 25\\\"\\n\\t\\tversion=\\\"1.1\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\txmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\"\\n\\t\\txmlns:sketch=\\\"http://www.bohemiancoding.com/sketch/ns\\\"\\n\\t\\u003e\\n\\t\\t\\u003cg stroke=\\\"none\\\" stroke-width=\\\"1\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" sketch:type=\\\"MSPage\\\"\\u003e\\n\\t\\t\\t\\u003cg class=\\\"fill-base-content\\\" id=\\\"Icon-Set-Filled\\\" sketch:type=\\\"MSLayerGroup\\\" transform=\\\"translate(-469.000000, -1041.000000)\\\"\\u003e\\n\\t\\t\\t\\t\\u003cpath d=\\\"M487.148,1053.48 L492.813,1047.82 C494.376,1046.26 494.376,1043.72 492.813,1042.16 C491.248,1040.59 488.712,1040.59 487.148,1042.16 L481.484,1047.82 L475.82,1042.16 C474.257,1040.59 471.721,1040.59 470.156,1042.16 C468.593,1043.72 468.593,1046.26 470.156,1047.82 L475.82,1053.48 L470.156,1059.15 C468.593,1060.71 468.593,1063.25 470.156,1064.81 C471.721,1066.38 474.257,1066.38 475.82,1064.81 L481.484,1059.15 L487.148,1064.81 C488.712,1066.38 491.248,1066.38 492.813,1064.81 C494.376,1063.25 494.376,1060.71 492.813,1059.15 L487.148,1053.48\\\" sketch:type=\\\"MSShapeGroup\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\u003c/g\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"date_picker\",\n      \"code\": \"```go\\ntype DatePickerProps struct {\\n\\tYear        int\\n\\tMonth       int\\n\\tSelected    time.Time\\n\\tStartOfWeek time.Weekday\\n}\\n\\nfunc (props DatePickerProps) Days() []time.Time {\\n\\tdays := make([]time.Time, 0, 31)\\n\\tnow := time.Now().UTC()\\n\\tstart := time.Date(props.Year, time.Month(props.Month), 1, 0, 0, 0, 0, now.Location())\\n\\tend := start.AddDate(0, 1, -1)\\n\\tfor end.Weekday() != props.StartOfWeek {\\n\\t\\tend = end.AddDate(0, 0, 1)\\n\\t}\\n\\tend = end.AddDate(0, 0, -1)\\n\\n\\tfor start.Weekday() != props.StartOfWeek {\\n\\t\\tstart = start.AddDate(0, 0, -1)\\n\\t}\\n\\tfor !start.After(end) {\\n\\t\\tdays = append(days, start)\\n\\t\\tstart = start.AddDate(0, 0, 1)\\n\\t}\\n\\treturn days\\n}\\n\\nfunc (props DatePickerProps) Months() []time.Time {\\n\\tmonths := make([]time.Time, 12)\\n\\tfor i := 1; i \\u003c= 12; i++ {\\n\\t\\tdt := time.Date(props.Year, time.Month(i), 1, 0, 0, 0, 0, time.Now().Location())\\n\\t\\tmonths[i-1] = dt\\n\\t}\\n\\treturn months\\n}\\n\\ntempl DatePicker(props DatePickerProps) {\\n\\t{{ utcNow := time.Now().UTC() }}\\n\\t{{ days := props.Days() }}\\n\\t\\u003cdiv\\n\\t\\tname=\\\"datepicker-div\\\"\\n\\t\\tclass=\\\"flex flex-col space-y-1 w-[300px] h-[405px]\\\"\\n\\t\\u003e\\n\\t\\t\\u003cdiv class=\\\"flex space-x-1\\\"\\u003e\\n\\t\\t\\t\\u003cbutton\\n\\t\\t\\t\\thx-get={ fmt.Sprintf(\\\"/datepicker?year=%d\\u0026month=%d\\\", props.Year, props.Month-1) }\\n\\t\\t\\t\\thx-target=\\\"div[name=datepicker-div]\\\"\\n\\t\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\t\\tclass=\\\"btn btn-square btn-sm\\\"\\n\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\u003csvg class=\\\"h-3 w-3\\\" viewBox=\\\"-5.5 0 26 26\\\" version=\\\"1.1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" xmlns:sketch=\\\"http://www.bohemiancoding.com/sketch/ns\\\"\\u003e\\n\\t\\t\\t\\t\\t\\u003cg id=\\\"Page-1\\\" stroke=\\\"none\\\" stroke-width=\\\"1\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" sketch:type=\\\"MSPage\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003cg class=\\\"fill-base-content\\\" id=\\\"Icon-Set-Filled\\\" sketch:type=\\\"MSLayerGroup\\\" transform=\\\"translate(-423.000000, -1196.000000)\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cpath d=\\\"M428.115,1209 L437.371,1200.6 C438.202,1199.77 438.202,1198.43 437.371,1197.6 C436.541,1196.76 435.194,1196.76 434.363,1197.6 L423.596,1207.36 C423.146,1207.81 422.948,1208.41 422.985,1209 C422.948,1209.59 423.146,1210.19 423.596,1210.64 L434.363,1220.4 C435.194,1221.24 436.541,1221.24 437.371,1220.4 C438.202,1219.57 438.202,1218.23 437.371,1217.4 L428.115,1209\\\" id=\\\"chevron-left\\\" sketch:type=\\\"MSShapeGroup\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\t\\u003cdetails class=\\\"dropdown w-full max-w-[300px]\\\"\\u003e\\n\\t\\t\\t\\t\\u003csummary class=\\\"btn btn-sm w-full\\\"\\u003e{ fmt.Sprintf(\\\"%d\\\", props.Year) }\\u003c/summary\\u003e\\n\\t\\t\\t\\t\\u003cdiv\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\t\\\"menu dropdown-content grid grid-cols-3 gap-1\\\",\\n\\t\\t\\t\\t\\t\\t\\\"w-full max-w-[300px] p-1 bg-base-300 rounded-b-box\\\",\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\thx-get={ fmt.Sprintf(\\\"/datepicker/yearpicker?year=%d\\\", props.Year) }\\n\\t\\t\\t\\t\\thx-trigger=\\\"datePickerDropdownClosed from:body\\\"\\n\\t\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\t@DatePickerYearPicker(props)\\n\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\u003cscript\\u003e\\n                    ((details)=\\u003e{\\n                        details.querySelector(\\\"summary\\\").addEventListener(\\\"click\\\", (evt) =\\u003e {\\n                            if (details.hasAttribute(\\\"open\\\")) {\\n                                    let event = new Event(\\\"datePickerDropdownClosed\\\");\\n                                    document.querySelector(\\\"body\\\").dispatchEvent(event);\\n                                }\\n                        })\\n                    })(document.currentScript.parentElement)\\n                \\u003c/script\\u003e\\n\\t\\t\\t\\u003c/details\\u003e\\n\\t\\t\\t\\u003cbutton\\n\\t\\t\\t\\thx-get={ fmt.Sprintf(\\\"/datepicker?year=%d\\u0026month=%d\\\", props.Year, props.Month+1) }\\n\\t\\t\\t\\thx-target=\\\"div[name=datepicker-div]\\\"\\n\\t\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\t\\tclass=\\\"btn btn-square btn-sm\\\"\\n\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\u003csvg class=\\\"h-3 w-3\\\" viewBox=\\\"-5.5 0 26 26\\\" version=\\\"1.1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\" xmlns:sketch=\\\"http://www.bohemiancoding.com/sketch/ns\\\"\\u003e\\n\\t\\t\\t\\t\\t\\u003cg id=\\\"Page-1\\\" stroke=\\\"none\\\" stroke-width=\\\"1\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" sketch:type=\\\"MSPage\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003cg class=\\\"fill-base-content\\\" id=\\\"Icon-Set-Filled\\\" sketch:type=\\\"MSLayerGroup\\\" transform=\\\"translate(-474.000000, -1196.000000)\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cpath d=\\\"M488.404,1207.36 L477.637,1197.6 C476.806,1196.76 475.459,1196.76 474.629,1197.6 C473.798,1198.43 473.798,1199.77 474.629,1200.6 L483.885,1209 L474.629,1217.4 C473.798,1218.23 473.798,1219.57 474.629,1220.4 C475.459,1221.24 476.806,1221.24 477.637,1220.4 L488.404,1210.64 C488.854,1210.19 489.052,1209.59 489.015,1209 C489.052,1208.41 488.854,1207.81 488.404,1207.36\\\" id=\\\"chevron-right\\\" sketch:type=\\\"MSShapeGroup\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"grid grid-cols-7 gap-1 text-sm text-base-content/75\\\"\\u003e\\n\\t\\t\\tif props.StartOfWeek == time.Sunday {\\n\\t\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eSu\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eMo\\u003c/span\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eTu\\u003c/span\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eWe\\u003c/span\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eTh\\u003c/span\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eFr\\u003c/span\\u003e\\n\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eSa\\u003c/span\\u003e\\n\\t\\t\\tif props.StartOfWeek == time.Monday {\\n\\t\\t\\t\\t\\u003cspan class=\\\"text-center\\\"\\u003eSu\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass=\\\"grid grid-cols-7 gap-1\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t@DatePickerInput(props.Selected)\\n\\t\\t\\tfor _, d := range days {\\n\\t\\t\\t\\t\\u003cbutton\\n\\t\\t\\t\\t\\tname=\\\"datepicker-day-btn\\\"\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\t\\\"btn btn-square border shadow-md shadow-base-300 h-10 w-10 p-3\\\",\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-primary\\\", d.Year() == utcNow.Year() \\u0026\\u0026 d.Month() == utcNow.Month() \\u0026\\u0026 utcNow.Day() == d.Day()),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"btn-ghost\\\", d.Month() == time.Month(props.Month)),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"btn-neutral\\\", d.Month() != time.Month(props.Month)),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"border-primary bg-base-300\\\", !props.Selected.IsZero() \\u0026\\u0026 d.Day() == props.Selected.Day()),\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\thx-post={ \\\"/datepicker/select?date=\\\" + d.Format(\\\"2006-01-02\\\") }\\n\\t\\t\\t\\t\\thx-target=\\\"#datepicker-input\\\"\\n\\t\\t\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\t\\t\\tif d.Month() != time.Month(props.Month) {\\n\\t\\t\\t\\t\\t\\tdisabled\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\tif d.Day() == 1 {\\n\\t\\t\\t\\t\\t\\t{ d.Format(\\\"Jan \\\") }\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t{ d.Format(\\\"2\\\") }\\n\\t\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cscript\\u003e\\n                function addDayButtonEventHandler() {\\n                    document.querySelectorAll(\\\"button[name=datepicker-day-btn]\\\").forEach((btn) =\\u003e {\\n                        btn.addEventListener(\\\"click\\\", () =\\u003e {\\n                            document.querySelectorAll(\\\"button[name=datepicker-day-btn]\\\").forEach((el) =\\u003e {\\n                                el.classList.remove(\\\"border-primary\\\", \\\"bg-base-300\\\")\\n                            })\\n                            btn.classList.add(\\\"border-primary\\\", \\\"bg-base-300\\\")\\n                        })\\n                    })\\n                }\\n                document.addEventListener(\\\"htmx:afterSettle\\\", () =\\u003e {\\n                    addDayButtonEventHandler();\\n                })\\n                document.addEventListener(\\\"DOMContentLoaded\\\", () =\\u003e {\\n                    addDayButtonEventHandler();\\n                })\\n            \\u003c/script\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl DatePickerInput(d time.Time) {\\n\\t\\u003cinput id=\\\"datepicker-input\\\" type=\\\"hidden\\\" name=\\\"date\\\" value={ d.Format(\\\"2006-01-02\\\") }/\\u003e\\n}\\n\\ntempl DatePickerYearPicker(props DatePickerProps) {\\n\\t{{ utcNow := time.Now().UTC() }}\\n\\tfor i := range 12 {\\n\\t\\t\\u003cbutton\\n\\t\\t\\tclass=\\\"btn btn-sm border\\\"\\n\\t\\t\\thx-get={ fmt.Sprintf(\\\"/datepicker/monthpicker?year=%d\\\", props.Year-(12-i)) }\\n\\t\\t\\thx-target=\\\"closest div\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t{ fmt.Sprintf(\\\"%d\\\", props.Year-(12-i)) }\\n\\t\\t\\u003c/button\\u003e\\n\\t}\\n\\t\\u003cbutton\\n\\t\\tclass=\\\"btn btn-sm border col-span-3\\\"\\n\\t\\thx-get={ fmt.Sprintf(\\\"/datepicker/monthpicker?year=%d\\\", utcNow.Year()) }\\n\\t\\thx-target=\\\"closest div\\\"\\n\\t\\u003e\\n\\t\\t{ fmt.Sprintf(\\\"%d\\\", utcNow.Year()) }\\n\\t\\u003c/button\\u003e\\n}\\n\\ntempl DatePickerMonthPicker(props DatePickerProps) {\\n\\t{{ months := props.Months() }}\\n\\tfor _, m := range months {\\n\\t\\t\\u003cbutton\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"btn btn-sm border\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"border-primary\\\", m.Month() == time.Month(props.Month)),\\n\\t\\t\\t}\\n\\t\\t\\thx-get={ fmt.Sprintf(\\\"/datepicker?year=%d\\u0026month=%d\\\", props.Year, m.Month()) }\\n\\t\\t\\thx-target=\\\"div[name=datepicker-div]\\\"\\n\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t{ m.Format(\\\"Jan\\\") }\\n\\t\\t\\u003c/button\\u003e\\n\\t}\\n}\\n```\"\n    },\n    {\n      \"name\": \"file_input\",\n      \"code\": \"```go\\ntype FileInputProps struct {\\n\\tName            string\\n\\tLabel           string\\n\\tValue           string\\n\\tDescription     string\\n\\tAttrs           templ.Attributes\\n\\tDisabledMessage string\\n\\tRequired        bool\\n\\tSize            string\\n}\\n\\ntempl FileInput(props FileInputProps) {\\n\\t\\u003cfieldset\\n\\t\\tclass=\\\"fieldset tooltip tooltip-top w-full\\\"\\n\\t\\tif props.DisabledMessage != \\\"\\\" {\\n\\t\\t\\tdata-tip={ props.DisabledMessage }\\n\\t\\t}\\n\\t\\u003e\\n\\t\\tif props.Label != \\\"\\\" {\\n\\t\\t\\t\\u003clegend class=\\\"fieldset-legend\\\"\\u003e{ props.Label }\\u003c/legend\\u003e\\n\\t\\t}\\n\\t\\t\\u003cinput\\n\\t\\t\\ttype=\\\"file\\\"\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"file-input w-full\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"file-input-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"file-input-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"file-input-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"file-input-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t}\\n\\t\\t\\tname={ props.Name }\\n\\t\\t\\tif props.DisabledMessage != \\\"\\\" {\\n\\t\\t\\t\\tdisabled\\n\\t\\t\\t}\\n\\t\\t\\t{ props.Attrs... }\\n\\t\\t/\\u003e\\n\\t\\tif props.Description != \\\"\\\" {\\n\\t\\t\\t\\u003clabel class=\\\"fieldset-label\\\"\\u003e{ props.Description }\\u003c/label\\u003e\\n\\t\\t}\\n\\t\\u003c/fieldset\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/file-input\"\n    },\n    {\n      \"name\": \"input\",\n      \"code\": \"```go\\ntype InputProps struct {\\n\\t// common\\n\\tName            string\\n\\tLabel           string\\n\\tType            string // defaults to \\\"text\\\"\\n\\tValue           string\\n\\tPlaceholder     string\\n\\tDescription     string\\n\\tError           string\\n\\tDisabledMessage string\\n\\tSize            string // xs sm lg xl, default: md\\n\\tRequired        bool\\n\\tIcon            templ.Component\\n\\tAttrs           templ.Attributes\\n\\n\\t// text input\\n\\tMinLength     string\\n\\tMaxLength     string\\n\\tPattern       string\\n\\tValidatorHint string\\n\\n\\t// integer/decimal input\\n\\tMin string\\n\\tMax string\\n\\n\\t// decimal input\\n\\tStep string\\n}\\n\\ntempl Input(props InputProps) {\\n\\t\\u003cfieldset class=\\\"fieldset\\\"\\u003e\\n\\t\\tif props.Label != \\\"\\\" {\\n\\t\\t\\t\\u003clegend class=\\\"fieldset-legend\\\"\\u003e{ props.Label }\\u003c/legend\\u003e\\n\\t\\t}\\n\\t\\t\\u003clabel\\n\\t\\t\\tfor={ props.Name }\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"input validator tooltip tooltip-top\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"tooltip tooltip-top\\\", props.DisabledMessage != \\\"\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"input-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"input-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"input-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"input-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t}\\n\\t\\t\\tif props.DisabledMessage != \\\"\\\" {\\n\\t\\t\\t\\tdata-tip={ props.DisabledMessage }\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\tif props.Icon != nil {\\n\\t\\t\\t\\t@props.Icon\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\tif props.Type == \\\"\\\" {\\n\\t\\t\\t\\t\\ttype=\\\"text\\\"\\n\\t\\t\\t\\t} else {\\n\\t\\t\\t\\t\\ttype={ props.Type }\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tvalue={ props.Value }\\n\\t\\t\\t\\tplaceholder={ props.Placeholder }\\n\\t\\t\\t\\tif props.Required {\\n\\t\\t\\t\\t\\trequired\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif props.Pattern != \\\"\\\" {\\n\\t\\t\\t\\t\\tpattern={ props.Pattern }\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif props.ValidatorHint != \\\"\\\" {\\n\\t\\t\\t\\t\\ttitle={ props.ValidatorHint }\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif props.DisabledMessage != \\\"\\\" {\\n\\t\\t\\t\\t\\tdisabled\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t{ props.Attrs... }\\n\\t\\t\\t/\\u003e\\n\\t\\t\\u003c/label\\u003e\\n\\t\\tif props.Description != \\\"\\\" {\\n\\t\\t\\t\\u003cdiv class=\\\"label\\\"\\u003e{ props.Description }\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\tif props.Error != \\\"\\\" {\\n\\t\\t\\t\\u003cp class=\\\"text-xs text-error max-w-xs\\\"\\u003e{ props.Error }\\u003c/p\\u003e\\n\\t\\t}\\n\\t\\tif props.ValidatorHint != \\\"\\\" {\\n\\t\\t\\t\\u003cp class=\\\"validator-hint hidden text-xs max-w-xs !mt-0\\\"\\u003e{ props.ValidatorHint }\\u003c/p\\u003e\\n\\t\\t}\\n\\t\\u003c/fieldset\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"radio\",\n      \"code\": \"```go\\ntype RadioProps struct {\\n\\tName   string\\n\\tValues map[string]string\\n\\tClass  string\\n\\tSize   string\\n}\\n\\ntempl Radio(props RadioProps) {\\n\\t\\u003cdiv class=\\\"space-y-2 w-full\\\"\\u003e\\n\\t\\tfor l, v := range props.Values {\\n\\t\\t\\t\\u003clabel for={ props.Name } class=\\\"label cursor-pointer grid grid-cols-7\\\"\\u003e\\n\\t\\t\\t\\t\\u003cspan\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\t\\\"col-span-6 text-wrap\\\",\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003e{ l }\\u003c/span\\u003e\\n\\t\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\t\\ttype=\\\"radio\\\"\\n\\t\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\t\\tvalue={ v }\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\t\\\"radio col-span-1\\\", props.Class,\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"radio-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"radio-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"radio-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"radio-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t/\\u003e\\n\\t\\t\\t\\u003c/label\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/radio\"\n    },\n    {\n      \"name\": \"range\",\n      \"code\": \"```go\\ntype RangeProps struct {\\n\\tID    string\\n\\tLabel string\\n\\tName  string\\n\\tValue int\\n\\tMin   int\\n\\tMax   int\\n\\tStep  int\\n\\tClass string\\n\\tSize  string\\n}\\n\\n// Note: usage requires alpine.js\\ntempl Range(props RangeProps) {\\n\\t\\u003cscript src=\\\"/static/js/alpine.js\\\" defer\\u003e\\u003c/script\\u003e\\n\\t\\u003cdiv class=\\\"form-control\\\"\\u003e\\n\\t\\t\\u003clabel\\n\\t\\t\\tclass=\\\"label space-x-1\\\"\\n\\t\\t\\tx-data={ fmt.Sprintf(\\\"{ value: %d }\\\", props.Value) }\\n\\t\\t\\u003e\\n\\t\\t\\tif props.Label != \\\"\\\" {\\n\\t\\t\\t\\t\\u003cspan\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003e{ props.Label }\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\ttype=\\\"range\\\"\\n\\t\\t\\t\\tif props.ID != \\\"\\\" {\\n\\t\\t\\t\\t\\tid={ props.ID }\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\tmin={ fmt.Sprintf(\\\"%d\\\", props.Min) }\\n\\t\\t\\t\\tmax={ fmt.Sprintf(\\\"%d\\\", props.Max) }\\n\\t\\t\\t\\tx-model=\\\"value\\\"\\n\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\\"range\\\", props.Class,\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tstep={ fmt.Sprintf(\\\"%d\\\", props.Step) }\\n\\t\\t\\t/\\u003e\\n\\t\\t\\t\\u003cdiv x-text=\\\"value\\\" class=\\\"w-full max-w-7\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003c/label\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\n// Note: usage requires datastar.js\\ntempl DatastarRange(props RangeProps) {\\n\\t\\u003cscript type=\\\"module\\\" src=\\\"/static/js/datastar.js\\\"\\u003e\\u003c/script\\u003e\\n\\t\\u003cdiv class=\\\"form-control\\\"\\u003e\\n\\t\\t\\u003clabel\\n\\t\\t\\tclass=\\\"label space-x-1\\\"\\n\\t\\t\\tdata-signals={ fmt.Sprintf(\\\"{value: %d}\\\", props.Value) }\\n\\t\\t\\u003e\\n\\t\\t\\tif props.Label != \\\"\\\" {\\n\\t\\t\\t\\t\\u003cspan\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003e{ props.Label }\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\ttype=\\\"range\\\"\\n\\t\\t\\t\\tif props.ID != \\\"\\\" {\\n\\t\\t\\t\\t\\tid={ props.ID }\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\tmin={ fmt.Sprintf(\\\"%d\\\", props.Min) }\\n\\t\\t\\t\\tmax={ fmt.Sprintf(\\\"%d\\\", props.Max) }\\n\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\\"range\\\", props.Class,\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"range-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tstep={ fmt.Sprintf(\\\"%d\\\", props.Step) }\\n\\t\\t\\t\\tdata-bind-value\\n\\t\\t\\t/\\u003e\\n\\t\\t\\t\\u003cdiv\\n\\t\\t\\t\\tclass=\\\"w-full max-w-7\\\"\\n\\t\\t\\t\\tdata-text=\\\"$value\\\"\\n\\t\\t\\t\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003c/label\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/range\"\n    },\n    {\n      \"name\": \"rating\",\n      \"code\": \"```go\\ntype RatingProps struct {\\n\\tName  string\\n\\tMin   int\\n\\tMax   int\\n\\tClass string\\n\\tValue int\\n}\\n\\ntempl Rating(props RatingProps) {\\n\\t\\u003cdiv class=\\\"rating\\\"\\u003e\\n\\t\\tfor i := props.Min; i \\u003c= props.Max; i++ {\\n\\t\\t\\tif i == 0 {\\n\\t\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\t\\ttype=\\\"radio\\\"\\n\\t\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\t\\tvalue={ fmt.Sprintf(\\\"%d\\\", i) }\\n\\t\\t\\t\\t\\tclass=\\\"rating-hidden\\\"\\n\\t\\t\\t\\t/\\u003e\\n\\t\\t\\t} else {\\n\\t\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\t\\ttype=\\\"radio\\\"\\n\\t\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\t\\tvalue={ fmt.Sprintf(\\\"%d\\\", i) }\\n\\t\\t\\t\\t\\tclass={ \\\"mask mask-star-2 bg-yellow-400\\\", props.Class }\\n\\t\\t\\t\\t\\tif i+1 == props.Max {\\n\\t\\t\\t\\t\\t\\tchecked=\\\"checked\\\"\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t/\\u003e\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl RatingDisplay(props RatingProps) {\\n\\t\\u003cdiv class=\\\"rating\\\"\\u003e\\n\\t\\tfor i := props.Min; i \\u003c= props.Max; i++ {\\n\\t\\t\\tif i == 0 {\\n\\t\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\t\\ttype=\\\"radio\\\"\\n\\t\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\t\\tvalue={ fmt.Sprintf(\\\"%d\\\", i) }\\n\\t\\t\\t\\t\\tclass=\\\"rating-hidden cursor-default\\\"\\n\\t\\t\\t\\t\\tdisabled\\n\\t\\t\\t\\t/\\u003e\\n\\t\\t\\t} else {\\n\\t\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\t\\ttype=\\\"radio\\\"\\n\\t\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\t\\tvalue={ fmt.Sprintf(\\\"%d\\\", i) }\\n\\t\\t\\t\\t\\tclass={ \\\"mask mask-star-2 bg-accent cursor-default\\\", props.Class }\\n\\t\\t\\t\\t\\tif i == props.Value {\\n\\t\\t\\t\\t\\t\\tchecked=\\\"checked\\\"\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\tdisabled\\n\\t\\t\\t\\t/\\u003e\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/rating\"\n    },\n    {\n      \"name\": \"select\",\n      \"code\": \"```go\\ntype SelectProps struct {\\n\\tID          string\\n\\tLabel       string\\n\\tName        string\\n\\tDescription string\\n\\tClass       string\\n\\tSize        string\\n\\tRequired    bool\\n\\tOptions     []SelectOption\\n\\tAttrs       templ.Attributes\\n}\\n\\ntype SelectOption struct {\\n\\tLabel    string\\n\\tValue    string\\n\\tSelected bool\\n\\tDisabled bool\\n}\\n\\ntempl Select(props SelectProps) {\\n\\t\\u003cfieldset class=\\\"fieldset\\\"\\u003e\\n\\t\\tif props.Label != \\\"\\\" {\\n\\t\\t\\t\\u003clegend class=\\\"fieldset-legend\\\"\\u003e{ props.Label }\\u003c/legend\\u003e\\n\\t\\t}\\n\\t\\t\\u003cselect\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"select w-full\\\",\\n\\t\\t\\t\\tprops.Class,\\n\\t\\t\\t\\ttempl.KV(\\\"select-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"select-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"select-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"select-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t}\\n\\t\\t\\tif props.ID != \\\"\\\" {\\n\\t\\t\\t\\tid={ props.ID }\\n\\t\\t\\t}\\n\\t\\t\\tname={ props.Name }\\n\\t\\t\\tif props.Required {\\n\\t\\t\\t\\trequired\\n\\t\\t\\t}\\n\\t\\t\\t{ props.Attrs... }\\n\\t\\t\\u003e\\n\\t\\t\\t@SelectOptions(props.Options)\\n\\t\\t\\u003c/select\\u003e\\n\\t\\tif props.Description != \\\"\\\" {\\n\\t\\t\\t\\u003cspan class=\\\"label\\\"\\u003e{ props.Description }\\u003c/span\\u003e\\n\\t\\t}\\n\\t\\u003c/fieldset\\u003e\\n}\\n\\ntempl SelectOptions(options []SelectOption) {\\n\\tfor i := range options {\\n\\t\\t\\u003coption\\n\\t\\t\\tif options[i].Selected {\\n\\t\\t\\t\\tselected\\n\\t\\t\\t}\\n\\t\\t\\tif options[i].Disabled {\\n\\t\\t\\t\\tdisabled\\n\\t\\t\\t}\\n\\t\\t\\tvalue={ options[i].Value }\\n\\t\\t\\u003e\\n\\t\\t\\t{ options[i].Label }\\n\\t\\t\\u003c/option\\u003e\\n\\t}\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/select\"\n    },\n    {\n      \"name\": \"textarea\",\n      \"code\": \"```go\\ntype TextareaProps struct {\\n\\tID          string\\n\\tLabel       string\\n\\tName        string\\n\\tPlaceholder string\\n\\tValue       string\\n\\tDescription string\\n\\tErr         string\\n\\tClass       string\\n\\tSize        string\\n\\tRequired    bool\\n\\tRows        int\\n\\tAttrs       templ.Attributes\\n}\\n\\ntempl Textarea(props TextareaProps) {\\n\\t\\u003cfieldset class=\\\"fieldset\\\"\\u003e\\n\\t\\tif props.Label != \\\"\\\" {\\n\\t\\t\\t\\u003clegend class=\\\"fieldset-legend\\\"\\u003e{ props.Label }\\u003c/legend\\u003e\\n\\t\\t}\\n\\t\\t\\u003ctextarea\\n\\t\\t\\t{ props.Attrs... }\\n\\t\\t\\tif props.ID != \\\"\\\" {\\n\\t\\t\\t\\tid={ props.ID }\\n\\t\\t\\t}\\n\\t\\t\\tname={ props.Name }\\n\\t\\t\\tplaceholder={ props.Placeholder }\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"textarea\\\",\\n\\t\\t\\t\\tprops.Class,\\n\\t\\t\\t\\ttempl.KV(\\\"textarea-error\\\", props.Err != \\\"\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"textarea-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"textarea-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"textarea-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\ttempl.KV(\\\"textarea-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t}\\n\\t\\t\\tif props.Rows \\u003e 0 {\\n\\t\\t\\t\\trows={ fmt.Sprintf(\\\"%d\\\", props.Rows) }\\n\\t\\t\\t} else {\\n\\t\\t\\t\\trows=\\\"3\\\"\\n\\t\\t\\t}\\n\\t\\t\\tif props.Required {\\n\\t\\t\\t\\trequired\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\t{ props.Value }\\n\\t\\t\\u003c/textarea\\u003e\\n\\t\\tif props.Description != \\\"\\\" {\\n\\t\\t\\t\\u003cdiv class=\\\"label\\\"\\u003e{ props.Description }\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\t\\u003cdiv class=\\\"h-6 !p-0 fieldset-label text-error text-sm\\\"\\u003e{ props.Err }\\u003c/div\\u003e\\n\\t\\u003c/fieldset\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/textarea\"\n    },\n    {\n      \"name\": \"time_slot_picker\",\n      \"code\": \"```go\\ntype TimeSlotPickerProps struct {\\n\\tID          string\\n\\tCurrentDate time.Time\\n\\tTimeSlots   []TimeSlot\\n\\tPickerURL   string\\n\\tReserveURL  string\\n}\\n\\ntype TimeSlot struct {\\n\\tStart time.Time\\n\\tEnd   time.Time\\n}\\n\\nfunc (x *TimeSlotPickerProps) Days() []time.Time {\\n\\tdate := time.Date(x.CurrentDate.Year(), x.CurrentDate.Month(), x.CurrentDate.Day(), 0, 0, 0, 0, x.CurrentDate.Location())\\n\\tdates := make([]time.Time, 7)\\n\\tdates[0] = date\\n\\tfor i := range 6 {\\n\\t\\tdate = date.Add(24 * time.Hour)\\n\\t\\tdates[i+1] = date\\n\\t}\\n\\treturn dates\\n}\\n\\nfunc (x *TimeSlotPickerProps) GetSlots(day time.Time) []TimeSlot {\\n\\tslots := make([]TimeSlot, 0)\\n\\tnow := time.Now().UTC()\\n\\tnow = time.Date(\\n\\t\\tnow.Year(), now.Month(), now.Day(),\\n\\t\\tnow.Hour(), 0, 0, 0,\\n\\t\\tnow.Location()).Add(time.Duration(24-now.Hour()) * time.Hour)\\n\\tfor _, s := range x.TimeSlots {\\n\\t\\tif s.Start.After(now) \\u0026\\u0026 s.Start.Format(\\\"20060102\\\") == day.Format(\\\"20060102\\\") {\\n\\t\\t\\tslots = append(slots, s)\\n\\t\\t}\\n\\t}\\n\\treturn slots\\n}\\n\\ntempl TimeSlotPicker(props TimeSlotPickerProps) {\\n\\t\\u003cdiv id={ props.ID } class=\\\"p-4\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"grid grid-cols-7 gap-1 h-[500px] w-full max-w-screen-xl\\\"\\u003e\\n\\t\\t\\tfor _, day := range props.Days() {\\n\\t\\t\\t\\t@timeSlotPickerDay(props, day)\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t@timeSlotPickerControls(props)\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl timeSlotPickerDay(props TimeSlotPickerProps, day time.Time) {\\n\\t\\u003cdiv\\n\\t\\tclass={\\n\\t\\t\\t\\\"flex flex-col space-y-2 border border-base-content rounded-box text-sm overflow-y-auto\\\",\\n\\t\\t\\ttempl.KV(\\\"border-primary\\\", time.Now().UTC().Format(\\\"20060102\\\") == day.Format(\\\"20060102\\\")),\\n\\t\\t}\\n\\t\\u003e\\n\\t\\t\\u003cdiv class=\\\"text-center pt-1\\\"\\u003e\\n\\t\\t\\t\\u003cspan\\u003e{ day.Format(\\\"Mon Jan 02\\\") }\\u003c/span\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"divider !my-0 !py-0\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cul class=\\\"space-y-1\\\"\\u003e\\n\\t\\t\\tfor _, slot := range props.GetSlots(day) {\\n\\t\\t\\t\\t{{ slotName := \\\"time_slot_\\\" + slot.Start.Format(\\\"200601021504\\\") }}\\n\\t\\t\\t\\t@Modal(ModalProps{\\n\\t\\t\\t\\t\\tID: slotName,\\n\\t\\t\\t\\t\\tLabel: timeSlotButton(\\n\\t\\t\\t\\t\\t\\tslot,\\n\\t\\t\\t\\t\\t\\ttempl.Attributes{\\\"onclick\\\": slotName + \\\".showModal()\\\"},\\n\\t\\t\\t\\t\\t),\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t) {\\n\\t\\t\\t\\t\\t@timeSlotModalContent(slot, slotName, props.ReserveURL)\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\u003c/ul\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl timeSlotButton(slot TimeSlot, attrs templ.Attributes) {\\n\\t\\u003cbutton class=\\\"btn btn-sm btn-ghost w-full\\\" { attrs... }\\u003e\\n\\t\\t{ slot.Start.Format(\\\"15:04\\\") } - { slot.End.Format(\\\"15:04\\\") }\\n\\t\\u003c/button\\u003e\\n}\\n\\ntempl timeSlotModalContent(slot TimeSlot, slotName, reserveURL string) {\\n\\t\\u003cdiv\\u003e\\n\\t\\t\\u003cdiv class=\\\"flex items-center space-x-2\\\"\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"flex justify-center items-center\\\"\\u003e\\n\\t\\t\\t\\t\\u003csvg\\n\\t\\t\\t\\t\\tclass=\\\"h-8 w-8\\\"\\n\\t\\t\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12Z\\\" stroke-width=\\\"1.5\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M10.125 8.875C10.125 7.83947 10.9645 7 12 7C13.0355 7 13.875 7.83947 13.875 8.875C13.875 9.56245 13.505 10.1635 12.9534 10.4899C12.478 10.7711 12 11.1977 12 11.75V13\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\t\\t\\u003ccircle class=\\\"fill-current\\\" cx=\\\"12\\\" cy=\\\"16\\\" r=\\\"1\\\"\\u003e\\u003c/circle\\u003e\\n\\t\\t\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\u003cp class=\\\"col-span-7\\\"\\u003e\\n\\t\\t\\t\\tReserve a time slot \\u003cb\\u003e{ slot.Start.Format(\\\"15:04\\\") }\\u003c/b\\u003e - \\u003cb\\u003e{ slot.End.Format(\\\"15:04\\\") }\\u003c/b\\u003e, \\u003cb\\u003e{ slot.Start.Format(\\\"Monday January 02\\\") }\\u003c/b\\u003e?\\n\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"flex justify-between items-center mt-8\\\"\\u003e\\n\\t\\t\\t\\u003cbutton\\n\\t\\t\\t\\tid=\\\"modal-confirm-reservation\\\"\\n\\t\\t\\t\\tclass=\\\"btn btn-sm btn-primary\\\"\\n\\t\\t\\t\\thx-post={ reserveURL + \\\"?start=\\\" + slot.Start.Format(\\\"2006-01-02-15-04\\\") + \\\"\\u0026end=\\\" + slot.End.Format(\\\"2006-01-02-15-04\\\") }\\n\\t\\t\\t\\u003e\\n\\t\\t\\t\\tReserve\\n\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-sm\\\" { templ.Attributes{\\\"onclick\\\": slotName + \\\".close()\\\"}... }\\u003e\\n\\t\\t\\t\\tCancel\\n\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cscript\\u003e\\n            ((modal) =\\u003e {\\n                document.addEventListener(\\\"htmx:afterRequest\\\", (evt) =\\u003e {\\n                    if (evt.detail.elt.id === \\\"modal-confirm-reservation\\\" \\u0026\\u0026 evt.detail.successful) {\\n                        modal.close()\\n                    }\\n                })\\n            })(document.currentScript.closest(\\\"dialog.modal\\\"))\\n        \\u003c/script\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl timeSlotPickerControls(props TimeSlotPickerProps) {\\n\\t\\u003cdiv class=\\\"flex justify-between items-center py-2\\\"\\u003e\\n\\t\\t\\u003cbutton\\n\\t\\t\\thx-get={ props.PickerURL + \\\"?date=\\\" + props.CurrentDate.Add(time.Duration(-7*24)*time.Hour).Format(\\\"2006-01-02\\\") }\\n\\t\\t\\thx-target={ \\\"#\\\" + props.ID }\\n\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\tclass={ \\\"btn btn-ghost btn-sm disabled:opacity-50\\\", }\\n\\t\\t\\tif props.CurrentDate.Format(\\\"2006-01-02\\\") == time.Now().UTC().Format(\\\"2006-01-02\\\") {\\n\\t\\t\\t\\tdisabled\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\t@chevronLeft()\\n\\t\\t\\u003c/button\\u003e\\n\\t\\t\\u003cbutton\\n\\t\\t\\thx-get={ props.PickerURL + \\\"?date=\\\" + props.CurrentDate.Add(time.Duration(7*24)*time.Hour).Format(\\\"2006-01-02\\\") }\\n\\t\\t\\thx-target={ \\\"#\\\" + props.ID }\\n\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\tclass=\\\"btn btn-ghost btn-sm\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t@chevronRight()\\n\\t\\t\\u003c/button\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl chevronLeft() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"h-6 w-6\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tfill=\\\"none\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-base-content\\\" d=\\\"M15 6L9 12L15 18\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl chevronRight() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"h-6 w-6\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tfill=\\\"none\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-base-content\\\" d=\\\"M9 6L15 12L9 18\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"toggle\",\n      \"code\": \"```go\\ntype ToggleProps struct {\\n\\tID        string\\n\\tBefore    string\\n\\tAfter     string\\n\\tName      string\\n\\tChecked   bool\\n\\tClass     string\\n\\tHighlight bool\\n\\tAttrs     templ.Attributes\\n\\tSize      string\\n}\\n\\ntempl Toggle(props ToggleProps) {\\n\\t\\u003cdiv class=\\\"flex justify-center\\\"\\u003e\\n\\t\\t\\u003clabel class=\\\"label cursor-pointer space-x-2 mx-auto\\\"\\u003e\\n\\t\\t\\tif props.Before != \\\"\\\" {\\n\\t\\t\\t\\t\\u003cspan\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-primary\\\", props.Highlight \\u0026\\u0026 !props.Checked),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\t{ props.Before }\\n\\t\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\t{ props.Attrs... }\\n\\t\\t\\t\\ttype=\\\"checkbox\\\"\\n\\t\\t\\t\\tif props.ID != \\\"\\\" {\\n\\t\\t\\t\\t\\tid={ props.ID }\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\\"toggle\\\", props.Class,\\n\\t\\t\\t\\t\\ttempl.KV(\\\"toggle-xs\\\", props.Size == \\\"xs\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"toggle-sm\\\", props.Size == \\\"sm\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"toggle-lg\\\", props.Size == \\\"lg\\\"),\\n\\t\\t\\t\\t\\ttempl.KV(\\\"toggle-xl\\\", props.Size == \\\"xl\\\"),\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif props.Checked {\\n\\t\\t\\t\\t\\tchecked=\\\"checked\\\"\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif props.Highlight {\\n\\t\\t\\t\\t\\tonclick=\\\"toggler(event)\\\"\\n\\t\\t\\t\\t}\\n\\t\\t\\t/\\u003e\\n\\t\\t\\tif props.After != \\\"\\\" {\\n\\t\\t\\t\\t\\u003cspan\\n\\t\\t\\t\\t\\tclass={\\n\\t\\t\\t\\t\\t\\t\\\"label-text\\\",\\n\\t\\t\\t\\t\\t\\ttempl.KV(\\\"text-primary\\\", props.Highlight \\u0026\\u0026 props.Checked),\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\t{ props.After }\\n\\t\\t\\t\\t\\u003c/span\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/label\\u003e\\n\\t\\tif props.Highlight {\\n\\t\\t\\t\\u003cscript\\u003e\\n                function toggler(evt) {\\n                    evt.target.previousElementSibling.classList.toggle(\\\"text-primary\\\")\\n                    evt.target.nextElementSibling.classList.toggle(\\\"text-primary\\\")\\n                }\\n            \\u003c/script\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/toggle\"\n    }\n  ],\n  \"feedback\": [\n    {\n      \"name\": \"alert\",\n      \"code\": \"```go\\ntempl Alert(class string) {\\n\\t\\u003cdiv role=\\\"alert\\\" class={ \\\"alert\\\", class }\\u003e\\n\\t\\t{ children... }\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl AlertInfo(message string) {\\n\\t@Alert(\\\"alert-info\\\") {\\n\\t\\t\\u003csvg\\n\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\tclass=\\\"stroke-info-content h-6 w-6 shrink-0\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\t\\td=\\\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\u003cspan\\u003e{ message }\\u003c/span\\u003e\\n\\t\\t{ children... }\\n\\t}\\n}\\n\\ntempl AlertSuccess(message string) {\\n\\t@Alert(\\\"alert-success\\\") {\\n\\t\\t\\u003csvg\\n\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\tclass=\\\"stroke-success-content h-6 w-6 shrink-0\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\t\\td=\\\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\u003cspan\\u003e{ message }\\u003c/span\\u003e\\n\\t\\t{ children... }\\n\\t}\\n}\\n\\ntempl AlertWarning(message string) {\\n\\t@Alert(\\\"alert-warning\\\") {\\n\\t\\t\\u003csvg\\n\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\tclass=\\\"stroke-warning-content h-6 w-6 shrink-0\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\t\\td=\\\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\u003cspan\\u003e{ message }\\u003c/span\\u003e\\n\\t\\t{ children... }\\n\\t}\\n}\\n\\ntempl AlertError(message string) {\\n\\t@Alert(\\\"alert-error\\\") {\\n\\t\\t\\u003csvg\\n\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\tclass=\\\"stroke-error-content h-6 w-6 shrink-0\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\t\\td=\\\"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\u003cspan\\u003e{ message }\\u003c/span\\u003e\\n\\t\\t{ children... }\\n\\t}\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/alert\"\n    },\n    {\n      \"name\": \"skeleton\",\n      \"code\": \"```go\\ntempl Skeleton() {\\n\\t\\u003cdiv class=\\\"flex flex-col gap-4\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"skeleton h-32 w-full\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"skeleton h-4 w-28\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"skeleton h-4 w-full\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"skeleton h-4 w-full\\\"\\u003e\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/skeleton\"\n    },\n    {\n      \"name\": \"status\",\n      \"code\": \"```go\\ntype StatusProps struct {\\n\\tCode              int\\n\\tTitle             string\\n\\tDescription       string\\n\\tReturnButtonLabel string\\n\\tReturnButtonAttrs templ.Attributes\\n}\\n\\ntempl Status(props StatusProps) {\\n\\t\\u003csection class=\\\"grid min-h-dvh place-content-center px-4\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"text-center\\\"\\u003e\\n\\t\\t\\t\\u003ch1 class=\\\"text-9xl font-black text-base-content/70\\\"\\u003e\\n\\t\\t\\t\\t{ fmt.Sprintf(\\\"%d\\\", props.Code) }\\n\\t\\t\\t\\u003c/h1\\u003e\\n\\t\\t\\t\\u003cp class=\\\"text-2xl font-bold tracking-tight text-base-content sm:text-4xl\\\"\\u003e\\n\\t\\t\\t\\t{ props.Title }\\n\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\u003cp class=\\\"mt-4 text-base-content/70\\\"\\u003e\\n\\t\\t\\t\\t{ props.Description }\\n\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\u003ca\\n\\t\\t\\t\\t{ props.ReturnButtonAttrs... }\\n\\t\\t\\t\\tclass=\\\"mt-4 btn btn-primary\\\"\\n\\t\\t\\t\\u003e\\n\\t\\t\\t\\t{ props.ReturnButtonLabel }\\n\\t\\t\\t\\u003c/a\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/section\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"toast\",\n      \"code\": \"```go\\ntype ToastProps struct {\\n\\tName       string\\n\\tToastClass string\\n\\tAlertClass string\\n}\\n\\ntempl Toast(props ToastProps) {\\n\\t\\u003cdiv name={ props.Name } class={ \\\"toast\\\", props.ToastClass }\\u003e\\n\\t\\t\\u003cdiv class={ \\\"alert\\\", props.AlertClass }\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/toast\"\n    },\n    {\n      \"name\": \"tooltip\",\n      \"code\": \"```go\\ntype TooltipProps struct {\\n\\tTip   string\\n\\tClass string\\n}\\n\\ntempl Tooltip(props TooltipProps) {\\n\\t\\u003cdiv class={ \\\"tooltip\\\", props.Class } data-tip={ props.Tip }\\u003e\\n\\t\\t{ children... }\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/tooltip\"\n    }\n  ],\n  \"layout\": [\n    {\n      \"name\": \"banner\",\n      \"code\": \"```go\\ntype BannerProps struct {\\n\\tTitle       templ.Component\\n\\tDescription string\\n}\\n\\ntempl Banner(props BannerProps) {\\n\\t\\u003csection\\u003e\\n\\t\\t\\u003cdiv class=\\\"mx-auto max-w-screen-xl px-4 py-32 lg:flex lg:items-center\\\"\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"mx-auto max-w-xl text-center\\\"\\u003e\\n\\t\\t\\t\\t@props.Title\\n\\t\\t\\t\\t\\u003cp class=\\\"mt-4 sm:text-xl/relaxed\\\"\\u003e\\n\\t\\t\\t\\t\\t{ props.Description }\\n\\t\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\t\\u003cdiv class=\\\"mt-8 flex flex-wrap justify-center gap-4\\\"\\u003e\\n\\t\\t\\t\\t\\t// call to action\\n\\t\\t\\t\\t\\t{ children... }\\n\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/section\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"drawer\",\n      \"code\": \"```go\\ntempl Drawer(toggle templ.Component, sidebar templ.Component) {\\n\\t\\u003cdiv class=\\\"drawer\\\"\\u003e\\n\\t\\t\\u003cinput id=\\\"my-drawer\\\" type=\\\"checkbox\\\" class=\\\"drawer-toggle\\\"/\\u003e\\n\\t\\t\\u003cdiv class=\\\"drawer-content\\\"\\u003e\\n\\t\\t\\t\\u003clabel for=\\\"my-drawer\\\" class=\\\"btn btn-primary drawer-button\\\"\\u003e\\n\\t\\t\\t\\t@toggle\\n\\t\\t\\t\\u003c/label\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"drawer-side\\\"\\u003e\\n\\t\\t\\t\\u003clabel for=\\\"my-drawer\\\" aria-label=\\\"close sidebar\\\" class=\\\"drawer-overlay\\\"\\u003e\\u003c/label\\u003e\\n\\t\\t\\t\\u003cul class=\\\"menu bg-base-200 text-base-content min-h-full w-80 p-4\\\"\\u003e\\n\\t\\t\\t\\t@sidebar\\n\\t\\t\\t\\u003c/ul\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/drawer\"\n    },\n    {\n      \"name\": \"footer\",\n      \"code\": \"```go\\ntype FooterProps struct {\\n\\tIcon        templ.Component\\n\\tName        string\\n\\tDescription string\\n\\tCopyright   string\\n\\tAnchors     []AnchorProps\\n}\\n\\ntempl Footer(props FooterProps) {\\n\\t\\u003cfooter class=\\\"footer bg-base-200 text-base-content p-10 mt-24\\\"\\u003e\\n\\t\\t{ children... }\\n\\t\\u003c/footer\\u003e\\n\\t\\u003cfooter class=\\\"footer bg-base-200 text-base-content border-base-300 border-t px-10 py-4\\\"\\u003e\\n\\t\\t\\u003caside class=\\\"grid-flow-col items-center\\\"\\u003e\\n\\t\\t\\tif props.Icon != nil {\\n\\t\\t\\t\\t\\u003cdiv class=\\\"w-6 h-6\\\"\\u003e\\n\\t\\t\\t\\t\\t@props.Icon\\n\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cp\\u003e\\n\\t\\t\\t\\tif props.Copyright != \\\"\\\" {\\n\\t\\t\\t\\t\\t\\u003cspan\\u003e\\u0026copy; { props.Copyright }\\u003c/span\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t{ props.Name }\\n\\t\\t\\t\\t\\u003cbr/\\u003e\\n\\t\\t\\t\\t{ props.Description }\\n\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\u003c/aside\\u003e\\n\\t\\t\\u003cnav class=\\\"md:place-self-center md:justify-self-end\\\"\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"grid grid-flow-col gap-4\\\"\\u003e\\n\\t\\t\\t\\tfor _, anchor := range props.Anchors {\\n\\t\\t\\t\\t\\t@Anchor(anchor)\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/nav\\u003e\\n\\t\\u003c/footer\\u003e\\n}\\n\\ntempl FooterNav(title string, links []AnchorProps) {\\n\\t\\u003cnav\\u003e\\n\\t\\t\\u003ch6 class=\\\"footer-title\\\"\\u003e{ title }\\u003c/h6\\u003e\\n\\t\\tfor _, link := range links {\\n\\t\\t\\t\\u003ca { link.Attrs... } class=\\\"link link-hover\\\"\\u003e{ link.Label }\\u003c/a\\u003e\\n\\t\\t}\\n\\t\\u003c/nav\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/footer\"\n    },\n    {\n      \"name\": \"hero\",\n      \"code\": \"```go\\ntype HeroProps struct {\\n\\tSource  string\\n\\tAlt     string\\n\\tReverse bool\\n\\tClass   string\\n}\\n\\ntempl Hero(props HeroProps) {\\n\\t\\u003cdiv class={ \\\"hero\\\", props.Class }\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass={\\n\\t\\t\\t\\t\\\"hero-content\\\",\\n\\t\\t\\t\\t\\\"flex-col\\\",\\n\\t\\t\\t\\ttempl.KV(\\\"xl:flex-row\\\", !props.Reverse),\\n\\t\\t\\t\\ttempl.KV(\\\"xl:flex-row-reverse\\\", props.Reverse),\\n\\t\\t\\t}\\n\\t\\t\\u003e\\n\\t\\t\\tif props.Source != \\\"\\\" {\\n\\t\\t\\t\\t\\u003cimg\\n\\t\\t\\t\\t\\tsrc={ props.Source }\\n\\t\\t\\t\\t\\talt={ props.Alt }\\n\\t\\t\\t\\t\\tclass=\\\"max-w-sm rounded-box shadow-2xl\\\"\\n\\t\\t\\t\\t/\\u003e\\n\\t\\t\\t}\\n\\t\\t\\t\\u003cdiv\\u003e\\n\\t\\t\\t\\t{ children... }\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/hero\"\n    }\n  ],\n  \"navigation\": [\n    {\n      \"name\": \"anchor\",\n      \"code\": \"```go\\ntype AnchorProps struct {\\n\\tHref      string\\n\\tLabel     string\\n\\tLeftIcon  templ.Component\\n\\tRightIcon templ.Component\\n\\tAttrs     templ.Attributes\\n\\tClass     string\\n}\\n\\ntempl Anchor(props AnchorProps) {\\n\\t\\u003ca\\n\\t\\tif props.Href != \\\"\\\" {\\n\\t\\t\\thref={ templ.SafeURL(props.Href) }\\n\\t\\t}\\n\\t\\tclass={ \\\"group items-center cursor-pointer\\\", props.Class }\\n\\t\\t{ props.Attrs... }\\n\\t\\u003e\\n\\t\\tif props.LeftIcon != nil {\\n\\t\\t\\t@props.LeftIcon\\n\\t\\t}\\n\\t\\t{ props.Label }\\n\\t\\tif props.RightIcon != nil {\\n\\t\\t\\t@props.RightIcon\\n\\t\\t}\\n\\t\\u003c/a\\u003e\\n}\\n```\"\n    },\n    {\n      \"name\": \"breadcrumbs\",\n      \"code\": \"```go\\ntype BreadcrumbsProps []BreadcrumbsProp\\n\\ntype BreadcrumbsProp struct {\\n\\tLabel string\\n\\tAttrs templ.Attributes\\n}\\n\\ntempl Breadcrumbs(props BreadcrumbsProps) {\\n\\t\\u003cdiv class=\\\"breadcrumbs text-sm\\\"\\u003e\\n\\t\\t\\u003cul\\u003e\\n\\t\\t\\tfor i, prop := range props {\\n\\t\\t\\t\\t\\u003cli class=\\\"select-none\\\"\\u003e\\n\\t\\t\\t\\t\\tif i \\u003c len(props) - 1 {\\n\\t\\t\\t\\t\\t\\t\\u003ca { prop.Attrs... }\\u003e{ prop.Label }\\u003c/a\\u003e\\n\\t\\t\\t\\t\\t} else {\\n\\t\\t\\t\\t\\t\\t{ prop.Label }\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003c/li\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/ul\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/breadcrumbs\"\n    },\n    {\n      \"name\": \"menu\",\n      \"code\": \"```go\\ntype MenuProps struct {\\n\\tTitle string\\n\\tClass string\\n}\\n\\ntempl Menu(props MenuProps) {\\n\\t\\u003cul class={ \\\"menu\\\", props.Class }\\u003e\\n\\t\\tif props.Title != \\\"\\\" {\\n\\t\\t\\t\\u003ch2 class=\\\"font-bold\\\"\\u003e{ props.Title }\\u003c/h2\\u003e\\n\\t\\t}\\n\\t\\t{ children... }\\n\\t\\u003c/ul\\u003e\\n}\\n\\ntype MenuItemProps struct {\\n\\tLabel     string\\n\\tAttrs     templ.Attributes\\n\\tIcon      templ.Component\\n\\tIconAfter bool\\n}\\n\\ntempl MenuItem(props MenuItemProps) {\\n\\t\\u003cli\\u003e\\n\\t\\t\\u003ca { props.Attrs... }\\u003e\\n\\t\\t\\tif props.Icon != nil \\u0026\\u0026 !props.IconAfter {\\n\\t\\t\\t\\t@props.Icon\\n\\t\\t\\t}\\n\\t\\t\\t{ props.Label }\\n\\t\\t\\tif props.Icon != nil \\u0026\\u0026 props.IconAfter {\\n\\t\\t\\t\\t@props.Icon\\n\\t\\t\\t}\\n\\t\\t\\u003c/a\\u003e\\n\\t\\t\\u003cul\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\u003c/ul\\u003e\\n\\t\\u003c/li\\u003e\\n}\\n\\ntype SubmenuProps struct {\\n\\tTitle     string\\n\\tAttrs     templ.Attributes\\n\\tIcon      templ.Component\\n\\tIconAfter bool\\n}\\n\\ntempl Submenu(props SubmenuProps) {\\n\\t\\u003cli\\u003e\\n\\t\\t\\u003cdetails { props.Attrs... }\\u003e\\n\\t\\t\\t\\u003csummary\\u003e\\n\\t\\t\\t\\tif props.Icon != nil \\u0026\\u0026 !props.IconAfter {\\n\\t\\t\\t\\t\\t@props.Icon\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t{ props.Title }\\n\\t\\t\\t\\tif props.Icon != nil \\u0026\\u0026 props.IconAfter {\\n\\t\\t\\t\\t\\t@props.Icon\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\u003c/summary\\u003e\\n\\t\\t\\t\\u003cul\\u003e\\n\\t\\t\\t\\t{ children... }\\n\\t\\t\\t\\u003c/ul\\u003e\\n\\t\\t\\u003c/details\\u003e\\n\\t\\u003c/li\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/menu\"\n    },\n    {\n      \"name\": \"pagination\",\n      \"code\": \"```go\\ntype PaginationProps struct {\\n\\tURL      string\\n\\tPage     int\\n\\tLow      int\\n\\tHigh     int\\n\\tMaxPages int\\n}\\n\\ntempl Pagination(id string, props PaginationProps) {\\n\\t\\u003cdiv id={ id }\\u003e\\n\\t\\t\\u003c!-- paginated content goes here --\\u003e\\n\\t\\t{ children... }\\n\\t\\t\\u003c!-- --\\u003e\\n\\t\\t\\u003cdiv class=\\\"join\\\"\\u003e\\n\\t\\t\\t@PaginationButton(id, props.URL, 1, props.Page == 1) {\\n\\t\\t\\t\\t@AnglesLeft()\\n\\t\\t\\t}\\n\\t\\t\\t@PaginationButton(id, props.URL, props.Page-1, props.Page == 1) {\\n\\t\\t\\t\\t@ChevronLeft()\\n\\t\\t\\t}\\n\\t\\t\\tfor i := props.Low; i \\u003c= props.High; i++ {\\n\\t\\t\\t\\t@PaginationButton(id, props.URL, i+1, props.Page == i+1) {\\n\\t\\t\\t\\t\\t{ fmt.Sprintf(\\\"%d\\\", i+1) }\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\t@PaginationButton(id, props.URL, props.Page+1, props.Page == props.MaxPages) {\\n\\t\\t\\t\\t@ChevronRight()\\n\\t\\t\\t}\\n\\t\\t\\t@PaginationButton(id, props.URL, props.MaxPages, props.Page == props.MaxPages) {\\n\\t\\t\\t\\t@AnglesRight()\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl PaginationButton(id, url string, urlPage int, disabled bool) {\\n\\t\\u003cbutton\\n\\t\\tif url != \\\"\\\" {\\n\\t\\t\\thx-get={ fmt.Sprintf(\\\"%s?page=%d\\\", url, urlPage) }\\n\\t\\t\\thx-target={ fmt.Sprintf(\\\"#%s\\\", id) }\\n\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t}\\n\\t\\tclass={\\n\\t\\t\\t\\\"join-item btn btn-square disabled:opacity-40\\\",\\n\\t\\t\\ttempl.KV(\\\"btn-disabled\\\", disabled),\\n\\t\\t}\\n\\t\\tif disabled {\\n\\t\\t\\tdisabled\\n\\t\\t}\\n\\t\\u003e\\n\\t\\t{ children... }\\n\\t\\u003c/button\\u003e\\n}\\n\\ntempl AnglesRight() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"w-4 h-4\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tfill=\\\"none\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\td=\\\"M6 17L11 12L6 7M13 17L18 12L13 7\\\"\\n\\t\\t\\tclass=\\\"stroke-base-content\\\"\\n\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl AnglesLeft() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"w-4 h-4\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tfill=\\\"none\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\td=\\\"M18 17L13 12L18 7M11 17L6 12L11 7\\\"\\n\\t\\t\\tclass=\\\"stroke-base-content\\\"\\n\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl ChevronRight() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"w-4 h-4\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tfill=\\\"none\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\td=\\\"M9 6L15 12L9 18\\\"\\n\\t\\t\\tclass=\\\"stroke-base-content\\\"\\n\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl ChevronLeft() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"w-4 h-4\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tfill=\\\"none\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\td=\\\"M15 6L9 12L15 18\\\"\\n\\t\\t\\tclass=\\\"stroke-base-content\\\"\\n\\t\\t\\tstroke-width=\\\"2\\\"\\n\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/pagination\"\n    },\n    {\n      \"name\": \"steps\",\n      \"code\": \"```go\\ntype StepProps struct {\\n\\tLabel string\\n\\tDone  bool\\n\\tAttrs templ.Attributes\\n}\\n\\ntempl Steps() {\\n\\t\\u003cul class=\\\"steps\\\"\\u003e\\n\\t\\t{ children... }\\n\\t\\u003c/ul\\u003e\\n}\\n\\ntempl Step(props StepProps) {\\n\\t\\u003cli\\n\\t\\tclass={ \\\"step\\\", templ.KV(\\\"step-primary\\\", props.Done) }\\n\\t\\u003e\\n\\t\\t\\u003ca { props.Attrs... }\\u003e{ props.Label }\\u003c/a\\u003e\\n\\t\\u003c/li\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/steps\"\n    },\n    {\n      \"name\": \"tabs\",\n      \"code\": \"```go\\ntype TabsProps struct {\\n\\tName         string\\n\\tClass        string\\n\\tTabs         []TabProps\\n\\tContentClass string\\n}\\n\\ntype TabProps struct {\\n\\tLabel   string\\n\\tContent templ.Component\\n}\\n\\ntempl Tabs(props TabsProps) {\\n\\t\\u003cdiv role=\\\"tablist\\\" class={ \\\"tabs\\\", props.Class }\\u003e\\n\\t\\tfor i, tab := range props.Tabs {\\n\\t\\t\\t\\u003cinput\\n\\t\\t\\t\\ttype=\\\"radio\\\"\\n\\t\\t\\t\\tname={ props.Name }\\n\\t\\t\\t\\trole=\\\"tab\\\"\\n\\t\\t\\t\\tclass=\\\"tab\\\"\\n\\t\\t\\t\\taria-label={ tab.Label }\\n\\t\\t\\t\\tif i == 0 {\\n\\t\\t\\t\\t\\tchecked=\\\"checked\\\"\\n\\t\\t\\t\\t}\\n\\t\\t\\t/\\u003e\\n\\t\\t\\t\\u003cdiv class={ \\\"tab-content\\\", props.ContentClass }\\u003e\\n\\t\\t\\t\\t@tab.Content\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"daisy_ui_url\": \"https://daisyui.com/components/tab\"\n    }\n  ]\n}"
  },
  {
    "path": "internal/assets/generated/component_example_code_map.json",
    "content": "{\n  \"accordion\": [\n    {\n      \"name\": \"AccordionWithCheckbox\",\n      \"code\": \"```go\\n\\ntempl AccordionWithCheckbox() {\\n\\t\\u003cdiv class=\\\"w-full flex join join-vertical pt-4\\\"\\u003e\\n\\t\\t@components.AccordionRow(components.AccordionRowProps{Label: \\\"Label 1\\\", Name: \\\"accordion-example-1\\\"}) {\\n\\t\\t\\t\\u003cp class=\\\"pt-4\\\"\\u003eLabel 1 content\\u003c/p\\u003e\\n\\t\\t}\\n\\t\\t@components.AccordionRow(components.AccordionRowProps{Label: \\\"Label 2\\\", Name: \\\"accordion-example-2\\\"}) {\\n\\t\\t\\t\\u003ch2 class=\\\"text-xl font-bold py-4\\\"\\u003eContent 2\\u003c/h2\\u003e\\n\\t\\t\\t\\u003cp\\u003eLabel 2 content\\u003c/p\\u003e\\n\\t\\t}\\n\\t\\t@components.AccordionRow(components.AccordionRowProps{Label: \\\"Label 3\\\", Name: \\\"accordion-example-3\\\"}) {\\n\\t\\t\\t\\u003ch2 class=\\\"text-xl font-bold py-4\\\"\\u003eContent 3\\u003c/h2\\u003e\\n\\t\\t\\t\\u003cul class=\\\"list-disc [\\u0026\\u003eli]:ml-4\\\"\\u003e\\n\\t\\t\\t\\t\\u003cli\\u003eItem 1\\u003c/li\\u003e\\n\\t\\t\\t\\t\\u003cli\\u003eItem 2\\u003c/li\\u003e\\n\\t\\t\\t\\t\\u003cli\\u003eItem 3\\u003c/li\\u003e\\n\\t\\t\\t\\u003c/ul\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"description\": \"Accordion with input type 'checkbox': multiple rows can be open at a time.\"\n    },\n    {\n      \"name\": \"AccordionWithRadio\",\n      \"code\": \"```go\\n\\ntempl AccordionWithRadio() {\\n\\t\\u003cdiv class=\\\"w-full flex join join-vertical pt-4\\\"\\u003e\\n\\t\\t@components.AccordionRow(components.AccordionRowProps{Label: \\\"Label 1\\\", Name: \\\"accordion-example-2\\\", Type: \\\"radio\\\"}) {\\n\\t\\t\\t\\u003cp class=\\\"pt-4\\\"\\u003eLabel 1 content\\u003c/p\\u003e\\n\\t\\t}\\n\\t\\t@components.AccordionRow(components.AccordionRowProps{Label: \\\"Label 2\\\", Name: \\\"accordion-example-2\\\", Type: \\\"radio\\\"}) {\\n\\t\\t\\t\\u003ch2 class=\\\"text-xl font-bold py-4\\\"\\u003eContent 2\\u003c/h2\\u003e\\n\\t\\t\\t\\u003cp\\u003eLabel 2 content\\u003c/p\\u003e\\n\\t\\t}\\n\\t\\t@components.AccordionRow(components.AccordionRowProps{Label: \\\"Label 3\\\", Name: \\\"accordion-example-2\\\", Type: \\\"radio\\\"}) {\\n\\t\\t\\t\\u003ch2 class=\\\"text-xl font-bold py-4\\\"\\u003eContent 3\\u003c/h2\\u003e\\n\\t\\t\\t\\u003cul class=\\\"list-disc [\\u0026\\u003eli]:ml-4\\\"\\u003e\\n\\t\\t\\t\\t\\u003cli\\u003eItem 1\\u003c/li\\u003e\\n\\t\\t\\t\\t\\u003cli\\u003eItem 2\\u003c/li\\u003e\\n\\t\\t\\t\\t\\u003cli\\u003eItem 3\\u003c/li\\u003e\\n\\t\\t\\t\\u003c/ul\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"description\": \"Accordion with input type 'radio': only a single row can be open at a time.\"\n    }\n  ],\n  \"active_search\": [\n    {\n      \"name\": \"ActiveSearchExampleTable\",\n      \"code\": \"```go\\ntempl ActiveSearchExampleTable() {\\n\\t\\u003cdiv class=\\\"h-[600px]\\\"\\u003e\\n\\t\\t@ActiveSearchExample(\\n\\t\\t\\t\\\"active-search-example-table\\\",\\n\\t\\t\\t[]templ.Component{\\n\\t\\t\\t\\tcomponents.PlainText(\\\"First name\\\"),\\n\\t\\t\\t\\tcomponents.PlainText(\\\"Last name\\\"),\\n\\t\\t\\t\\tcomponents.PlainText(\\\"Email\\\"),\\n\\t\\t\\t},\\n\\t\\t\\tactiveSearchTableDataComponents(),\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl ActiveSearchExample(id string, headers []templ.Component, rows []templ.Component) {\\n\\t\\u003cdiv class=\\\"py-8\\\"\\u003e\\n\\t\\t@components.ActiveSearchInput(\\n\\t\\t\\tcomponents.ActiveSearchInputProps{\\n\\t\\t\\t\\tID:     \\\"active-search-example-input\\\",\\n\\t\\t\\t\\tURL:    \\\"/active-search\\\",\\n\\t\\t\\t\\tTarget: fmt.Sprintf(\\\"#%s \\u003e tbody\\\", id),\\n\\t\\t\\t\\tInputProps: components.InputProps{\\n\\t\\t\\t\\t\\tIcon:        searchIcon(),\\n\\t\\t\\t\\t\\tName:        \\\"active-search-example\\\",\\n\\t\\t\\t\\t\\tType:        \\\"search\\\",\\n\\t\\t\\t\\t\\tPlaceholder: \\\"Filter table...\\\",\\n\\t\\t\\t\\t\\tSize:        \\\"sm\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t})\\n\\t\\t@components.Table(\\n\\t\\t\\theaders,\\n\\t\\t\\tactiveSearchTableDataComponents(),\\n\\t\\t\\ttempl.Attributes{\\\"id\\\": \\\"active-search-example-table\\\"},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl searchIcon() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"w-5 h-5\\\"\\n\\t\\tviewBox=\\\"0 0 32 32\\\"\\n\\t\\tversion=\\\"1.1\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\txmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\"\\n\\t\\txmlns:sketch=\\\"http://www.bohemiancoding.com/sketch/ns\\\"\\n\\t\\u003e\\n\\t\\t\\u003cg stroke=\\\"none\\\" stroke-width=\\\"1\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" sketch:type=\\\"MSPage\\\"\\u003e\\n\\t\\t\\t\\u003cg class=\\\"fill-base-content/60\\\" id=\\\"Icon-Set\\\" sketch:type=\\\"MSLayerGroup\\\" transform=\\\"translate(-256.000000, -1139.000000)\\\"\\u003e\\n\\t\\t\\t\\t\\u003cpath d=\\\"M269.46,1163.45 C263.17,1163.45 258.071,1158.44 258.071,1152.25 C258.071,1146.06 263.17,1141.04 269.46,1141.04 C275.75,1141.04 280.85,1146.06 280.85,1152.25 C280.85,1158.44 275.75,1163.45 269.46,1163.45 L269.46,1163.45 Z M287.688,1169.25 L279.429,1161.12 C281.591,1158.77 282.92,1155.67 282.92,1152.25 C282.92,1144.93 276.894,1139 269.46,1139 C262.026,1139 256,1144.93 256,1152.25 C256,1159.56 262.026,1165.49 269.46,1165.49 C272.672,1165.49 275.618,1164.38 277.932,1162.53 L286.224,1170.69 C286.629,1171.09 287.284,1171.09 287.688,1170.69 C288.093,1170.3 288.093,1169.65 287.688,1169.25 L287.688,1169.25 Z\\\" id=\\\"search\\\" sketch:type=\\\"MSShapeGroup\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\u003c/g\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\nfunc activeSearchTableDataComponents() []templ.Component {\\n\\tcoms := make([]templ.Component, len(ActiveSearchTableData))\\n\\tfor i := range ActiveSearchTableData {\\n\\t\\tcoms[i] = ActiveSearchTableRow(\\n\\t\\t\\tActiveSearchTableData[i].FirstName,\\n\\t\\t\\tActiveSearchTableData[i].LastName,\\n\\t\\t\\tActiveSearchTableData[i].Email)\\n\\t}\\n\\treturn coms\\n}\\n\\nvar ActiveSearchTableData = []struct {\\n\\tFirstName string\\n\\tLastName  string\\n\\tEmail     string\\n}{\\n\\t{FirstName: \\\"John\\\", LastName: \\\"Smith\\\", Email: \\\"john.smith@email.com\\\"},\\n\\t{FirstName: \\\"Emily\\\", LastName: \\\"Johnson\\\", Email: \\\"emily.johnson@email.com\\\"},\\n\\t{FirstName: \\\"Michael\\\", LastName: \\\"Brown\\\", Email: \\\"michael.brown@email.com\\\"},\\n\\t{FirstName: \\\"Jessica\\\", LastName: \\\"Williams\\\", Email: \\\"jessica.williams@email.com\\\"},\\n\\t{FirstName: \\\"David\\\", LastName: \\\"Jones\\\", Email: \\\"david.jones@email.com\\\"},\\n\\t{FirstName: \\\"Sarah\\\", LastName: \\\"Miller\\\", Email: \\\"sarah.miller@email.com\\\"},\\n\\t{FirstName: \\\"Christopher\\\", LastName: \\\"Davis\\\", Email: \\\"chris.davis@email.com\\\"},\\n\\t{FirstName: \\\"Amanda\\\", LastName: \\\"Wilson\\\", Email: \\\"amanda.wilson@email.com\\\"},\\n\\t{FirstName: \\\"James\\\", LastName: \\\"Taylor\\\", Email: \\\"james.taylor@email.com\\\"},\\n\\t{FirstName: \\\"Laura\\\", LastName: \\\"Moore\\\", Email: \\\"laura.moore@email.com\\\"},\\n}\\n\\ntempl ActiveSearchTableRows(rows []templ.Component) {\\n\\tfor _, r := range rows {\\n\\t\\t@r\\n\\t}\\n}\\n\\ntempl ActiveSearchTableRow(firstName, lastName, email string) {\\n\\t\\u003ctr\\u003e\\n\\t\\t\\u003ctd\\u003e{ firstName }\\u003c/td\\u003e\\n\\t\\t\\u003ctd\\u003e{ lastName }\\u003c/td\\u003e\\n\\t\\t\\u003ctd\\u003e{ email }\\u003c/td\\u003e\\n\\t\\u003c/tr\\u003e\\n}\\n```\",\n      \"handler\": \"```go\\nfunc GetActiveSearchExample(c echo.Context) error {\\n\\ttime.Sleep(500 * time.Millisecond)\\n\\n\\tsearch := strings.ToLower(strings.TrimSpace(c.FormValue(\\\"active-search-example\\\")))\\n\\n\\tout := make([]templ.Component, 0, len(examples.ActiveSearchTableData))\\n\\n\\tfor _, rowData := range examples.ActiveSearchTableData {\\n\\t\\tif search == \\\"\\\" || (strings.Contains(strings.ToLower(rowData.FirstName), search) ||\\n\\t\\t\\tstrings.Contains(strings.ToLower(rowData.LastName), search) ||\\n\\t\\t\\tstrings.Contains(strings.ToLower(rowData.Email), search)) {\\n\\t\\t\\tout = append(out, examples.ActiveSearchTableRow(\\n\\t\\t\\t\\trowData.FirstName, rowData.LastName, rowData.Email))\\n\\t\\t}\\n\\t}\\n\\n\\treturn render(c, http.StatusOK, examples.ActiveSearchTableRows(out))\\n}\\n\\n```\",\n      \"title\": \"Active search input for a table\"\n    }\n  ],\n  \"alert\": [\n    {\n      \"name\": \"AlertInfoExample\",\n      \"code\": \"```go\\ntempl AlertInfoExample() {\\n\\t\\u003cdiv class=\\\"max-w-md mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.AlertInfo(\\n\\t\\t\\t\\\"Your profile has been successfully updated. Please review your changes.\\\",\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Info-type alert\"\n    },\n    {\n      \"name\": \"AlertSuccessExample\",\n      \"code\": \"```go\\ntempl AlertSuccessExample() {\\n\\t\\u003cdiv class=\\\"max-w-md mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.AlertSuccess(\\n\\t\\t\\t\\\"Your payment was processed successfully! Thank you for your purchase.\\\",\\n\\t\\t) {\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-sm\\\"\\u003eOK\\u003c/button\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Success-type alert\"\n    },\n    {\n      \"name\": \"AlertWarningExample\",\n      \"code\": \"```go\\ntempl AlertWarningExample() {\\n\\t\\u003cdiv class=\\\"max-w-md mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.AlertWarning(\\n\\t\\t\\t\\\"Your password will expire in 7 days. Please update it to avoid any disruptions.\\\",\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Warning-type alert\"\n    },\n    {\n      \"name\": \"AlertErrorExample\",\n      \"code\": \"```go\\ntempl AlertErrorExample() {\\n\\t\\u003cdiv class=\\\"max-w-md mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.AlertError(\\n\\t\\t\\t\\\"Failed to connect to the server. Please try again later or contact support if the issue persists.\\\",\\n\\t\\t) {\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-sm\\\"\\u003eOK\\u003c/button\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Error-type alert\"\n    }\n  ],\n  \"anchor\": [\n    {\n      \"name\": \"BasicAnchor\",\n      \"code\": \"```go\\ntempl BasicAnchor() {\\n\\t@components.Anchor(components.AnchorProps{\\n\\t\\tLabel: \\\"Basic anchor\\\",\\n\\t\\tClass: \\\"link\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"Basic anchor\"\n    },\n    {\n      \"name\": \"PrimaryAnchor\",\n      \"code\": \"```go\\ntempl PrimaryAnchor() {\\n\\t@components.Anchor(components.AnchorProps{\\n\\t\\tLabel: \\\"Primary anchor\\\",\\n\\t\\tClass: \\\"link link-primary\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"Primary anchor\"\n    },\n    {\n      \"name\": \"AnchorWithIcon\",\n      \"code\": \"```go\\ntempl AnchorWithIcon() {\\n\\t@components.Anchor(components.AnchorProps{\\n\\t\\tLabel:    \\\"GitHub profile\\\",\\n\\t\\tLeftIcon: GithubIcon(),\\n\\t\\tClass:    \\\"link\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"Anchor with icon\"\n    },\n    {\n      \"name\": \"SocialAnchors\",\n      \"code\": \"```go\\ntempl SocialAnchors() {\\n\\t\\u003cdiv class=\\\"mx-auto\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"flex space-x-4\\\"\\u003e\\n\\t\\t\\t@components.Anchor(components.AnchorProps{LeftIcon: XIcon()})\\n\\t\\t\\t@components.Anchor(components.AnchorProps{LeftIcon: YoutubeIcon()})\\n\\t\\t\\t@components.Anchor(components.AnchorProps{LeftIcon: FacebookIcon()})\\n\\t\\t\\t@components.Anchor(components.AnchorProps{LeftIcon: GithubIcon()})\\n\\t\\t\\t@components.Anchor(components.AnchorProps{LeftIcon: LinkedInIcon()})\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl XIcon() {\\n\\t\\u003csvg\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\tx=\\\"0px\\\"\\n\\t\\ty=\\\"0px\\\"\\n\\t\\tviewBox=\\\"0 0 50 50\\\"\\n\\t\\tclass=\\\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath d=\\\"M 5.9199219 6 L 20.582031 27.375 L 6.2304688 44 L 9.4101562 44 L 21.986328 29.421875 L 31.986328 44 L 44 44 L 28.681641 21.669922 L 42.199219 6 L 39.029297 6 L 27.275391 19.617188 L 17.933594 6 L 5.9199219 6 z M 9.7167969 8 L 16.880859 8 L 40.203125 42 L 33.039062 42 L 9.7167969 8 z\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl YoutubeIcon() {\\n\\t\\u003csvg\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tclass=\\\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\td=\\\"M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl FacebookIcon() {\\n\\t\\u003csvg\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tclass=\\\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\td=\\\"M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl GithubIcon() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"h-6 w-6 inline-block mr-1\\\"\\n\\t\\tviewBox=\\\"0 0 20 20\\\"\\n\\t\\tversion=\\\"1.1\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\txmlns:xlink=\\\"http://www.w3.org/1999/xlink\\\"\\n\\t\\u003e\\n\\t\\t\\u003cg stroke=\\\"none\\\" stroke-width=\\\"1\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\"\\u003e\\n\\t\\t\\t\\u003cg class=\\\"fill-base-content/80 hover:fill-base-content group-hover:fill-base-content\\\" id=\\\"Dribbble-Light-Preview\\\" transform=\\\"translate(-140.000000, -7559.000000)\\\"\\u003e\\n\\t\\t\\t\\t\\u003cg id=\\\"icons\\\" transform=\\\"translate(56.000000, 160.000000)\\\"\\u003e\\n\\t\\t\\t\\t\\t\\u003cpath d=\\\"M94,7399 C99.523,7399 104,7403.59 104,7409.253 C104,7413.782 101.138,7417.624 97.167,7418.981 C96.66,7419.082 96.48,7418.762 96.48,7418.489 C96.48,7418.151 96.492,7417.047 96.492,7415.675 C96.492,7414.719 96.172,7414.095 95.813,7413.777 C98.04,7413.523 100.38,7412.656 100.38,7408.718 C100.38,7407.598 99.992,7406.684 99.35,7405.966 C99.454,7405.707 99.797,7404.664 99.252,7403.252 C99.252,7403.252 98.414,7402.977 96.505,7404.303 C95.706,7404.076 94.85,7403.962 94,7403.958 C93.15,7403.962 92.295,7404.076 91.497,7404.303 C89.586,7402.977 88.746,7403.252 88.746,7403.252 C88.203,7404.664 88.546,7405.707 88.649,7405.966 C88.01,7406.684 87.619,7407.598 87.619,7408.718 C87.619,7412.646 89.954,7413.526 92.175,7413.785 C91.889,7414.041 91.63,7414.493 91.54,7415.156 C90.97,7415.418 89.522,7415.871 88.63,7414.304 C88.63,7414.304 88.101,7413.319 87.097,7413.247 C87.097,7413.247 86.122,7413.234 87.029,7413.87 C87.029,7413.87 87.684,7414.185 88.139,7415.37 C88.139,7415.37 88.726,7417.2 91.508,7416.58 C91.513,7417.437 91.522,7418.245 91.522,7418.489 C91.522,7418.76 91.338,7419.077 90.839,7418.982 C86.865,7417.627 84,7413.783 84,7409.253 C84,7403.59 88.478,7399 94,7399\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\t\\u003c/g\\u003e\\n\\t\\t\\u003c/g\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl LinkedInIcon() {\\n\\t\\u003csvg\\n\\t\\tclass=\\\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\\\"\\n\\t\\tviewBox=\\\"0 0 32 32\\\"\\n\\t\\tversion=\\\"1.1\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath d=\\\"M28.778 1.004h-25.56c-0.008-0-0.017-0-0.027-0-1.199 0-2.172 0.964-2.186 2.159v25.672c0.014 1.196 0.987 2.161 2.186 2.161 0.010 0 0.019-0 0.029-0h25.555c0.008 0 0.018 0 0.028 0 1.2 0 2.175-0.963 2.194-2.159l0-0.002v-25.67c-0.019-1.197-0.994-2.161-2.195-2.161-0.010 0-0.019 0-0.029 0h0.001zM9.9 26.562h-4.454v-14.311h4.454zM7.674 10.293c-1.425 0-2.579-1.155-2.579-2.579s1.155-2.579 2.579-2.579c1.424 0 2.579 1.154 2.579 2.578v0c0 0.001 0 0.002 0 0.004 0 1.423-1.154 2.577-2.577 2.577-0.001 0-0.002 0-0.003 0h0zM26.556 26.562h-4.441v-6.959c0-1.66-0.034-3.795-2.314-3.795-2.316 0-2.669 1.806-2.669 3.673v7.082h-4.441v-14.311h4.266v1.951h0.058c0.828-1.395 2.326-2.315 4.039-2.315 0.061 0 0.121 0.001 0.181 0.003l-0.009-0c4.5 0 5.332 2.962 5.332 6.817v7.855z\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\",\n      \"title\": \"Socials anchors\"\n    }\n  ],\n  \"avatar\": [\n    {\n      \"name\": \"MultipleAvatarSizes\",\n      \"code\": \"```go\\ntempl MultipleAvatarSizes() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center space-x-4 pt-4\\\"\\u003e\\n\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\tContainerClass: \\\"rounded w-8\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\tContainerClass: \\\"rounded w-12\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\tContainerClass: \\\"rounded w-16\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\tContainerClass: \\\"rounded w-20\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\tContainerClass: \\\"rounded w-24\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Multiple avatar sizes\"\n    },\n    {\n      \"name\": \"GroupOfAvatars\",\n      \"code\": \"```go\\ntempl GroupOfAvatars() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center space-x-4 pt-4\\\"\\u003e\\n\\t\\t@components.AvatarGroup(\\\"-space-x-8\\\") {\\n\\t\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\tContainerClass: \\\"rounded-full w-12\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\tContainerClass: \\\"rounded-full w-12\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\tContainerClass: \\\"rounded-full w-12\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\tContainerClass: \\\"rounded-full w-12\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\tContainerClass: \\\"rounded-full w-12\\\", Source: \\\"/static/images/avatar.jpg\\\"})\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Avatar group\"\n    },\n    {\n      \"name\": \"OnlineAndOffline\",\n      \"code\": \"```go\\ntempl OnlineAndOffline() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center space-x-4 pt-4\\\"\\u003e\\n\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\tAvatarClass:    \\\"avatar-online\\\",\\n\\t\\t\\tContainerClass: \\\"rounded-full w-12\\\",\\n\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t})\\n\\t\\t@components.Avatar(components.AvatarProps{\\n\\t\\t\\tAvatarClass:    \\\"avatar-offline\\\",\\n\\t\\t\\tContainerClass: \\\"rounded-full w-12\\\",\\n\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t})\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Avatar with online/offline indicator\"\n    }\n  ],\n  \"banner\": [\n    {\n      \"name\": \"BannerExample\",\n      \"code\": \"```go\\ntempl BannerExample() {\\n\\t@components.Banner(components.BannerProps{\\n\\t\\tTitle: basicBannerTitle(),\\n\\t\\tDescription: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nSapiente iure non, quia perspiciatis sed temporibus quos nihil, voluptatibus tempore \\nplaceat ipsa est facilis, nobis illum in magni illo neque libero.`,\\n\\t}) {\\n\\t\\t\\u003ca class=\\\"btn btn-primary\\\"\\u003e\\n\\t\\t\\tGet started\\n\\t\\t\\u003c/a\\u003e\\n\\t\\t\\u003ca class=\\\"btn btn-neutral\\\"\\u003e\\n\\t\\t\\tLearn more\\n\\t\\t\\u003c/a\\u003e\\n\\t}\\n}\\n\\ntempl basicBannerTitle() {\\n\\t\\u003ch1 class=\\\"text-3xl font-extrabold sm:text-5xl\\\"\\u003e\\n\\t\\tLorem ipsum dolor.\\n\\t\\t\\u003cstrong class=\\\"font-extrabold text-primary sm:block\\\"\\u003eSit amet consectetur. \\u003c/strong\\u003e\\n\\t\\u003c/h1\\u003e\\n}\\n```\"\n    }\n  ],\n  \"breadcrumbs\": [\n    {\n      \"name\": \"BreadcrumbsExample\",\n      \"code\": \"```go\\ntempl BreadcrumbsExample() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Breadcrumbs(\\n\\t\\t\\tcomponents.BreadcrumbsProps{\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tLabel: \\\"Laptops\\\",\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\\"href\\\": \\\"/laptops\\\", \\\"class\\\": \\\"link\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tLabel: \\\"Macbooks\\\",\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\\"href\\\": \\\"/laptops/macbooks\\\", \\\"class\\\": \\\"link\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{Label: \\\"Macbook Pro 14\\\"},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"card\": [\n    {\n      \"name\": \"BasicCard\",\n      \"code\": \"```go\\ntempl BasicCard() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center py-4\\\"\\u003e\\n\\t\\t@components.Card(\\n\\t\\t\\tcomponents.CardProps{\\n\\t\\t\\t\\tTitle:   \\\"This is a card\\\",\\n\\t\\t\\t\\tContent: \\\"And this is the card's content.\\\",\\n\\t\\t\\t\\tClass:   \\\"bg-base-100 w-96 shadow-xl\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Basic card\"\n    },\n    {\n      \"name\": \"BasicCardWithImage\",\n      \"code\": \"```go\\ntempl BasicCardWithImage() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center py-4\\\"\\u003e\\n\\t\\t@components.Card(\\n\\t\\t\\tcomponents.CardProps{\\n\\t\\t\\t\\tTitle:   \\\"Card with image\\\",\\n\\t\\t\\t\\tContent: \\\"Card with image content\\\",\\n\\t\\t\\t\\tSource:  \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\tAlt:     \\\"avatar image\\\",\\n\\t\\t\\t\\tClass:   \\\"card-bordered bg-base-100 w-96 shadow-xl\\\",\\n\\t\\t\\t},\\n\\t\\t) {\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-sm btn-primary\\\"\\u003eContact\\u003c/button\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Card with image\"\n    }\n  ],\n  \"carousel\": [\n    {\n      \"name\": \"CarouselExample\",\n      \"code\": \"```go\\ntempl CarouselExample() {\\n\\t\\u003cdiv class=\\\"max-h-80 pt-4 max-w-screen-md\\\"\\u003e\\n\\t\\t@components.Carousel(\\n\\t\\t\\tcomponents.CarouselProps{\\n\\t\\t\\t\\t{Source: \\\"/static/images/avatar.jpg\\\", Alt: \\\"avatar image\\\"},\\n\\t\\t\\t\\t{Source: \\\"/static/images/avatar.jpg\\\", Alt: \\\"avatar image\\\"},\\n\\t\\t\\t\\t{Source: \\\"/static/images/avatar.jpg\\\", Alt: \\\"avatar image\\\"},\\n\\t\\t\\t\\t{Source: \\\"/static/images/avatar.jpg\\\", Alt: \\\"avatar image\\\"},\\n\\t\\t\\t\\t{Source: \\\"/static/images/avatar.jpg\\\", Alt: \\\"avatar image\\\"},\\n\\t\\t\\t\\t{Source: \\\"/static/images/avatar.jpg\\\", Alt: \\\"avatar image\\\"},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"chat\": [\n    {\n      \"name\": \"BasicChat\",\n      \"code\": \"```go\\ntempl BasicChat() {\\n\\t\\u003cdiv class=\\\"w-full max-w-screen-sm rounded-box mx-auto border border-base-content/30 p-4\\\"\\u003e\\n\\t\\t@components.Chat(components.ChatProps{\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatarURL: \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\tSender:    \\\"Me\\\",\\n\\t\\t\\t\\tTime:      time.Now().UTC().Add(-4 * time.Minute).Format(\\\"15:04:05\\\"),\\n\\t\\t\\t\\tMessage: `I started learning how to cook more dishes from scratch, \\nand it's been way more satisfying than I expected. Last night, I made homemade pasta!`,\\n\\t\\t\\t\\tFooter:   \\\"✓✓\\\",\\n\\t\\t\\t\\tLocation: \\\"start\\\",\\n\\t\\t\\t\\tClass:    \\\"chat-bubble-primary\\\",\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatarURL: \\\"/static/images/avatar-reverse.jpg\\\",\\n\\t\\t\\t\\tSender:    \\\"Myself\\\",\\n\\t\\t\\t\\tTime:      time.Now().UTC().Add(-2 * time.Minute).Format(\\\"15:04:05\\\"),\\n\\t\\t\\t\\tMessage: `That's awesome! Homemade pasta is no joke—it's a workout, \\ntoo! Did you use a pasta machine, or go for the classic rolling pin method?`,\\n\\t\\t\\t\\tFooter:   \\\"✓✓\\\",\\n\\t\\t\\t\\tLocation: \\\"end\\\",\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatarURL: \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\tSender:    \\\"Me\\\",\\n\\t\\t\\t\\tTime:      time.Now().UTC().Add(-1 * time.Minute).Format(\\\"15:04:05\\\"),\\n\\t\\t\\t\\tMessage: `Went old-school with the rolling pin! Took forever, but it \\nwas worth it. I made a simple marinara sauce to go with it, and honestly, it was better \\nthan what I usually order.`,\\n\\t\\t\\t\\tFooter:   \\\"✓✓\\\",\\n\\t\\t\\t\\tLocation: \\\"start\\\",\\n\\t\\t\\t\\tClass:    \\\"chat-bubble-primary\\\",\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatarURL: \\\"/static/images/avatar-reverse.jpg\\\",\\n\\t\\t\\t\\tSender:    \\\"Myself\\\",\\n\\t\\t\\t\\tTime:      time.Now().UTC().Format(\\\"15:04:05\\\"),\\n\\t\\t\\t\\tMessage: `Love it! Next up, you've got to try ravioli. It's a bit \\nmore work, but filling them with something like ricotta and spinach makes it feel \\nsuper fancy. You'll impress everyone!`,\\n\\t\\t\\t\\tFooter:   \\\"✓✓\\\",\\n\\t\\t\\t\\tLocation: \\\"end\\\",\\n\\t\\t\\t},\\n\\t\\t})\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"checkbox\": [\n    {\n      \"name\": \"DifferentSizeCheckboxes\",\n      \"code\": \"```go\\ntempl DifferentSizeCheckboxes() {\\n\\t\\u003cdiv class=\\\"flex flex-col space-y-4 mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Checkbox(\\n\\t\\t\\tcomponents.CheckboxProps{\\n\\t\\t\\t\\tBefore:  \\\"Remember me\\\",\\n\\t\\t\\t\\tName:    \\\"remember_me\\\",\\n\\t\\t\\t\\tChecked: false,\\n\\t\\t\\t\\tSize:    \\\"xs\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Checkbox(\\n\\t\\t\\tcomponents.CheckboxProps{\\n\\t\\t\\t\\tBefore:  \\\"Remember me\\\",\\n\\t\\t\\t\\tName:    \\\"remember_me\\\",\\n\\t\\t\\t\\tChecked: false,\\n\\t\\t\\t\\tSize:    \\\"sm\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Checkbox(\\n\\t\\t\\tcomponents.CheckboxProps{\\n\\t\\t\\t\\tBefore:  \\\"Remember me\\\",\\n\\t\\t\\t\\tName:    \\\"remember_me\\\",\\n\\t\\t\\t\\tChecked: false,\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Checkbox(\\n\\t\\t\\tcomponents.CheckboxProps{\\n\\t\\t\\t\\tBefore:  \\\"Remember me\\\",\\n\\t\\t\\t\\tName:    \\\"remember_me\\\",\\n\\t\\t\\t\\tChecked: false,\\n\\t\\t\\t\\tSize:    \\\"lg\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Checkbox(\\n\\t\\t\\tcomponents.CheckboxProps{\\n\\t\\t\\t\\tBefore:  \\\"Remember me\\\",\\n\\t\\t\\t\\tName:    \\\"remember_me\\\",\\n\\t\\t\\t\\tChecked: false,\\n\\t\\t\\t\\tSize:    \\\"xl\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Different size checkboxes\"\n    },\n    {\n      \"name\": \"PrimaryCheckbox\",\n      \"code\": \"```go\\ntempl PrimaryCheckbox() {\\n\\t\\u003cdiv class=\\\"mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Checkbox(\\n\\t\\t\\tcomponents.CheckboxProps{\\n\\t\\t\\t\\tAfter:   \\\"Remember me\\\",\\n\\t\\t\\t\\tName:    \\\"remember_me\\\",\\n\\t\\t\\t\\tChecked: true,\\n\\t\\t\\t\\tClass:   \\\"checkbox-primary\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Primary color checkbox with label after\"\n    }\n  ],\n  \"collapse\": [\n    {\n      \"name\": \"CollapseExample\",\n      \"code\": \"```go\\ntempl CollapseExample() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Collapse(\\n\\t\\t\\tcomponents.CollapseProps{\\n\\t\\t\\t\\tTitle:        \\\"Click me to show/hide content\\\",\\n\\t\\t\\t\\tTitleClass:   \\\"text-xl font-medium\\\",\\n\\t\\t\\t\\tClass:        \\\"collapse-plus bg-base-300\\\",\\n\\t\\t\\t\\tContentClass: \\\"bg-base-200\\\",\\n\\t\\t\\t}) {\\n\\t\\t\\t\\u003cdiv class=\\\"pt-4\\\"\\u003e\\n\\t\\t\\t\\t\\u003cp\\u003eCollapse content\\u003c/p\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Basic collapse\"\n    }\n  ],\n  \"combobox\": [\n    {\n      \"name\": \"BasicCombobox\",\n      \"code\": \"```go\\ntempl BasicCombobox() {\\n\\t\\u003cdiv class=\\\"h-96\\\"\\u003e\\n\\t\\t\\u003cform hx-post=\\\"/combobox-submit/example_combo\\\" class=\\\"space-x-4\\\"\\u003e\\n\\t\\t\\t@components.Combobox(components.ComboboxProps{\\n\\t\\t\\t\\tName:  \\\"example_combo\\\",\\n\\t\\t\\t\\tLabel: \\\"Example\\\",\\n\\t\\t\\t\\tURL:   \\\"/combobox/%s/%s\\\",\\n\\t\\t\\t\\tOptions: []string{\\n\\t\\t\\t\\t\\t\\\"Thing 1\\\", \\\"Thing 2\\\", \\\"Thing 3\\\", \\\"Thing 4\\\", \\\"Thing 5\\\", \\\"Thing 6\\\", \\\"Thing 7\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t})\\n\\t\\t\\t\\u003cbutton type=\\\"submit\\\" class=\\\"btn btn-sm btn-primary\\\"\\u003eSubmit\\u003c/button\\u003e\\n\\t\\t\\t\\u003cscript\\u003e\\n\\t\\t\\t\\t// update the form to only include half of the input values\\n\\t\\t\\t\\t// corresponding to the combobox's name since it will contain enabled checkbox values as well\\n\\t\\t\\t\\t((form) =\\u003e {\\n\\t\\t\\t\\t\\tform.addEventListener(\\\"htmx:configRequest\\\", (evt) =\\u003e {\\n\\t\\t\\t\\t\\t\\tlet values = evt.detail.parameters[\\\"example_combo\\\"]\\n\\t\\t\\t\\t\\t\\tif (values !== undefined) {\\n\\t\\t\\t\\t\\t\\t\\tevt.detail.parameters[\\\"example_combo\\\"] = values.slice(0, Math.floor(values.length / 2))\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t})\\n\\t\\t\\t\\t})(document.currentScript.parentElement)\\n\\t\\t\\t\\u003c/script\\u003e\\n\\t\\t\\u003c/form\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"handler\": \"```go\\nfunc PostCombobox(c echo.Context) error {\\n\\tname := c.Param(\\\"name\\\")\\n\\tvalue := c.Param(\\\"value\\\")\\n\\n\\treturn render(c, http.StatusOK, components.ComboBadge(name, value))\\n}\\n\\nfunc PostComboboxSubmit(c echo.Context) error {\\n\\turlValues, err := c.FormParams()\\n\\tif err != nil {\\n\\t\\treturn newErrorToast(http.StatusUnprocessableEntity, \\\"unable to parse form data\\\")\\n\\t}\\n\\n\\tname := c.Param(\\\"name\\\")\\n\\tcomboboxPostData := urlValues[name]\\n\\n\\treturn renderInfoFade(c, http.StatusOK, comboboxPostData)\\n}\\n\\n```\"\n    }\n  ],\n  \"countdown\": [\n    {\n      \"name\": \"CountdownFullExample\",\n      \"code\": \"```go\\ntempl CountdownFullExample() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Countdown(\\n\\t\\t\\tcomponents.CountdownProps{\\n\\t\\t\\t\\tExpires: time.Now().UTC().Add(25*time.Hour + 10*time.Second),\\n\\t\\t\\t\\tDays:    true,\\n\\t\\t\\t\\tHours:   true,\\n\\t\\t\\t\\tSeconds: true,\\n\\t\\t\\t\\tMinutes: true,\\n\\t\\t\\t})\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\"\n    },\n    {\n      \"name\": \"CountdownHoursExample\",\n      \"code\": \"```go\\ntempl CountdownHoursExample() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Countdown(\\n\\t\\t\\tcomponents.CountdownProps{\\n\\t\\t\\t\\tExpires: time.Now().UTC().Add(10*time.Hour + 10*time.Second),\\n\\t\\t\\t\\tHours:   true,\\n\\t\\t\\t\\tSeconds: true,\\n\\t\\t\\t\\tMinutes: true,\\n\\t\\t\\t})\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\"\n    },\n    {\n      \"name\": \"CountdownMinutesExample\",\n      \"code\": \"```go\\ntempl CountdownMinutesExample() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Countdown(\\n\\t\\t\\tcomponents.CountdownProps{\\n\\t\\t\\t\\tExpires: time.Now().UTC().Add(15*time.Minute + 10*time.Second),\\n\\t\\t\\t\\tSeconds: true,\\n\\t\\t\\t\\tMinutes: true,\\n\\t\\t\\t})\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\"\n    },\n    {\n      \"name\": \"CountdownSecondsExample\",\n      \"code\": \"```go\\ntempl CountdownSecondsExample() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Countdown(\\n\\t\\t\\tcomponents.CountdownProps{\\n\\t\\t\\t\\tExpires: time.Now().UTC().Add(20 * time.Second),\\n\\t\\t\\t\\tSeconds: true,\\n\\t\\t\\t})\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"date_picker\": [\n    {\n      \"name\": \"BasicDatePicker\",\n      \"code\": \"```go\\ntempl BasicDatePicker() {\\n\\t{{ now := time.Now().UTC() }}\\n\\t@components.DatePicker(\\n\\t\\tcomponents.DatePickerProps{\\n\\t\\t\\tYear:        now.Year(),\\n\\t\\t\\tMonth:       int(now.Month()),\\n\\t\\t\\tSelected:    now,\\n\\t\\t\\tStartOfWeek: time.Monday,\\n\\t\\t},\\n\\t)\\n}\\n```\",\n      \"handler\": \"```go\\nfunc GetDatePicker(c echo.Context) error {\\n\\tyearStr := c.QueryParam(\\\"year\\\")\\n\\tmonthStr := c.QueryParam(\\\"month\\\")\\n\\n\\tyear, yErr := strconv.Atoi(yearStr)\\n\\tmonth, mErr := strconv.Atoi(monthStr)\\n\\tif month \\u003e 12 {\\n\\t\\tyear += 1\\n\\t\\tmonth = 1\\n\\t}\\n\\tif month \\u003c 1 {\\n\\t\\tyear -= 1\\n\\t\\tmonth = 12\\n\\t}\\n\\n\\tif yErr != nil || mErr != nil {\\n\\t\\treturn newErrorToast(http.StatusUnprocessableEntity, \\\"Invalid year or month\\\")\\n\\t}\\n\\n\\tvar selected time.Time\\n\\tnow := time.Now().UTC()\\n\\tif year == now.Year() \\u0026\\u0026 time.Month(month) == now.Month() {\\n\\t\\tselected = now\\n\\t}\\n\\n\\treturn render(\\n\\t\\tc,\\n\\t\\thttp.StatusOK,\\n\\t\\tcomponents.DatePicker(\\n\\t\\t\\tcomponents.DatePickerProps{\\n\\t\\t\\t\\tYear:        year,\\n\\t\\t\\t\\tMonth:       month,\\n\\t\\t\\t\\tSelected:    selected,\\n\\t\\t\\t\\tStartOfWeek: time.Monday,\\n\\t\\t\\t}),\\n\\t)\\n}\\n\\nfunc PostDatePickerSelectDay(c echo.Context) error {\\n\\tvalue := c.FormValue(\\\"date\\\")\\n\\td, err := time.Parse(\\\"2006-01-02\\\", value)\\n\\tif err != nil {\\n\\t\\treturn newErrorToast(\\n\\t\\t\\thttp.StatusUnprocessableEntity,\\n\\t\\t\\tfmt.Sprintf(\\\"Invalid date '%s'\\\", value),\\n\\t\\t)\\n\\t}\\n\\n\\treturn render(c, http.StatusOK, components.DatePickerInput(d))\\n}\\n\\nfunc GetDatePickerMonthPicker(c echo.Context) error {\\n\\tyearStr := c.QueryParam(\\\"year\\\")\\n\\n\\tyear, yErr := strconv.Atoi(yearStr)\\n\\tif yErr != nil {\\n\\t\\treturn newErrorToast(http.StatusUnprocessableEntity, \\\"Invalid year\\\")\\n\\t}\\n\\n\\tdpp := components.DatePickerProps{\\n\\t\\tYear: year,\\n\\t}\\n\\n\\treturn render(c, http.StatusOK, components.DatePickerMonthPicker(dpp))\\n}\\n\\nfunc GetDatePickerYearPicker(c echo.Context) error {\\n\\tyearStr := c.QueryParam(\\\"year\\\")\\n\\n\\tyear, yErr := strconv.Atoi(yearStr)\\n\\tif yErr != nil {\\n\\t\\treturn newErrorToast(http.StatusUnprocessableEntity, \\\"Invalid year\\\")\\n\\t}\\n\\n\\tdpp := components.DatePickerProps{\\n\\t\\tYear: year,\\n\\t}\\n\\n\\treturn render(c, http.StatusOK, components.DatePickerYearPicker(dpp))\\n}\\n\\n```\"\n    }\n  ],\n  \"diff\": [\n    {\n      \"name\": \"ImageDiff\",\n      \"code\": \"```go\\ntempl ImageDiff() {\\n\\t\\u003cdiv class=\\\"flex mx-auto pt-4 min-h-[240px] sm:min-h-[300px] lg:min-h-[480px]\\\"\\u003e\\n\\t\\t@components.Diff(\\n\\t\\t\\tcomponents.DiffProps{\\n\\t\\t\\t\\tWidth:  16,\\n\\t\\t\\t\\tHeight: 19,\\n\\t\\t\\t\\tImage1: components.DiffImage{\\n\\t\\t\\t\\t\\tSource: \\\"/static/images/diff1.png\\\", Alt: \\\"diff image 1\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tImage2: components.DiffImage{\\n\\t\\t\\t\\t\\tSource: \\\"/static/images/diff2.png\\\", Alt: \\\"diff image 2\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"drawer\": [\n    {\n      \"name\": \"BasicDrawer\",\n      \"code\": \"```go\\ntempl BasicDrawer() {\\n\\t\\u003cdiv class=\\\"w-full h-[400px] flex flex-wrap items-center justify-center overflow-x-hidden\\\"\\u003e\\n\\t\\t@DrawerPreview(DrawerExampleToggle(), DrawerExampleMenu())\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl DrawerPreview(toggle templ.Component, sidebar templ.Component) {\\n\\t\\u003cdiv class=\\\"drawer h-[400px]\\\"\\u003e\\n\\t\\t\\u003cinput id=\\\"my-drawer\\\" type=\\\"checkbox\\\" class=\\\"drawer-toggle\\\"/\\u003e\\n\\t\\t\\u003cdiv class=\\\"flex flex-col items-center justify-center drawer-content\\\"\\u003e\\n\\t\\t\\t{ children... }\\n\\t\\t\\t\\u003clabel for=\\\"my-drawer\\\" class=\\\"btn btn-primary drawer-button\\\"\\u003e\\n\\t\\t\\t\\t@toggle\\n\\t\\t\\t\\u003c/label\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003cdiv class=\\\"drawer-side h-full absolute\\\"\\u003e\\n\\t\\t\\t\\u003clabel for=\\\"my-drawer\\\" aria-label=\\\"close sidebar\\\" class=\\\"drawer-overlay\\\"\\u003e\\u003c/label\\u003e\\n\\t\\t\\t\\u003cul class=\\\"menu bg-base-200 text-base-content min-h-full w-60 md:w-80 p-4\\\"\\u003e\\n\\t\\t\\t\\t@sidebar\\n\\t\\t\\t\\u003c/ul\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl DrawerExampleToggle() {\\n\\t\\u003cspan\\u003eClick me\\u003c/span\\u003e\\n}\\n\\ntempl DrawerExampleMenu() {\\n\\t@components.MenuItem(components.MenuItemProps{Label: \\\"Section 1\\\", Attrs: templ.Attributes{\\\"class\\\": \\\"menu-title\\\"}})\\n\\t@components.MenuItem(components.MenuItemProps{Label: \\\"Section 2\\\", Attrs: templ.Attributes{\\\"class\\\": \\\"menu-title\\\"}}) {\\n\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.1\\\"}) {\\n\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.1.1\\\"})\\n\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.1.2\\\"})\\n\\t\\t}\\n\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.2\\\"}) {\\n\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.2.1\\\"})\\n\\t\\t}\\n\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.3\\\"})\\n\\t}\\n\\t@components.MenuItem(components.MenuItemProps{Label: \\\"Section 3\\\", Attrs: templ.Attributes{\\\"class\\\": \\\"menu-title\\\"}}) {\\n\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"3.1\\\"})\\n\\t}\\n}\\n```\"\n    }\n  ],\n  \"dropdown\": [\n    {\n      \"name\": \"BasicDropdown\",\n      \"code\": \"```go\\ntempl BasicDropdown() {\\n\\t\\u003cdiv class=\\\"h-48\\\"\\u003e\\n\\t\\t@components.Dropdown(\\n\\t\\t\\tcomponents.DropdownProps{\\n\\t\\t\\t\\tLabel: \\\"Dropdown label\\\",\\n\\t\\t\\t\\tItems: []components.DropdownItem{\\n\\t\\t\\t\\t\\t{Label: \\\"Item 1\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Item 2\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Item 3\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tListClass: \\\"bg-base-200 rounded-box z-50 w-52 p-2 shadow-sm\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"fab\": [\n    {\n      \"name\": \"BasicFAB\",\n      \"code\": \"```go\\ntempl BasicFAB() {\\n\\t\\u003cdiv class=\\\"h-68 relative\\\"\\u003e\\n\\t\\t@components.FAB(\\n\\t\\t\\tcomponents.FABProps{\\n\\t\\t\\t\\tClass:       \\\"absolute z-1\\\", // !! preview purpose only\\n\\t\\t\\t\\tToggle:      \\\"F\\\",\\n\\t\\t\\t\\tToggleClass: \\\"btn-lg btn-circle\\\",\\n\\t\\t\\t}) {\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003eA\\u003c/button\\u003e\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003eB\\u003c/button\\u003e\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003eC\\u003c/button\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\"\n    },\n    {\n      \"name\": \"FABWithSVGButtons\",\n      \"code\": \"```go\\ntempl FABWithSVGButtons() {\\n\\t\\u003cdiv class=\\\"h-68 relative\\\"\\u003e\\n\\t\\t@components.FAB(\\n\\t\\t\\tcomponents.FABProps{\\n\\t\\t\\t\\tClass:       \\\"absolute z-1\\\", // !! preview purpose only\\n\\t\\t\\t\\tToggle:      fabSVGToggle(),\\n\\t\\t\\t\\tToggleClass: \\\"btn-lg btn-circle\\\",\\n\\t\\t\\t}) {\\n\\t\\t\\t@fabSVGVoiceButton()\\n\\t\\t\\t@fabSVGImageButton()\\n\\t\\t\\t@fabSVGCameraButton()\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl fabSVGToggle() {\\n\\t\\u003csvg\\n\\t\\taria-label=\\\"New\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\tfill=\\\"none\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\tstroke-width=\\\"2\\\"\\n\\t\\tstroke=\\\"currentColor\\\"\\n\\t\\tclass=\\\"size-6\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\" d=\\\"M12 4.5v15m7.5-7.5h-15\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl fabSVGVoiceButton() {\\n\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003e\\n\\t\\t\\u003csvg\\n\\t\\t\\taria-label=\\\"Camera\\\"\\n\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\tstroke-width=\\\"1.5\\\"\\n\\t\\t\\tstroke=\\\"currentColor\\\"\\n\\t\\t\\tclass=\\\"size-6\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\td=\\\"M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\td=\\\"M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0ZM18.75 10.5h.008v.008h-.008V10.5Z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\u003c/button\\u003e\\n}\\n\\ntempl fabSVGImageButton() {\\n\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003e\\n\\t\\t\\u003csvg\\n\\t\\t\\taria-label=\\\"Gallery\\\"\\n\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\tstroke-width=\\\"1.5\\\"\\n\\t\\t\\tstroke=\\\"currentColor\\\"\\n\\t\\t\\tclass=\\\"size-6\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\td=\\\"m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\u003c/button\\u003e\\n}\\n\\ntempl fabSVGCameraButton() {\\n\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003e\\n\\t\\t\\u003csvg\\n\\t\\t\\taria-label=\\\"Voice\\\"\\n\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\tstroke-width=\\\"1.5\\\"\\n\\t\\t\\tstroke=\\\"currentColor\\\"\\n\\t\\t\\tclass=\\\"size-6\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\tstroke-linecap=\\\"round\\\"\\n\\t\\t\\t\\tstroke-linejoin=\\\"round\\\"\\n\\t\\t\\t\\td=\\\"M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\u003c/button\\u003e\\n}\\n\\n```\",\n      \"title\": \"FAB with SVGs as toggle and content buttons\"\n    },\n    {\n      \"name\": \"FABFlowerExample\",\n      \"code\": \"```go\\ntempl FABFlowerExample() {\\n\\t\\u003cdiv class=\\\"h-68 relative\\\"\\u003e\\n\\t\\t@components.FAB(components.FABProps{\\n\\t\\t\\tClass:       \\\"fab-flower absolute z-1\\\", // !! absolute \\u0026 z-1 preview purpose only\\n\\t\\t\\tToggle:      \\\"F\\\",\\n\\t\\t\\tToggleClass: \\\"btn btn-lg btn-circle\\\",\\n\\t\\t\\tMainAction:  fabFlowerMainAction(),\\n\\t\\t}) {\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003eA\\u003c/button\\u003e\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003eB\\u003c/button\\u003e\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003eC\\u003c/button\\u003e\\n\\t\\t\\t\\u003cbutton class=\\\"btn btn-lg btn-circle\\\"\\u003eD\\u003c/button\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl fabFlowerMainAction() {\\n\\t\\u003cbutton class=\\\"btn btn-lg btn-circle btn-primary\\\"\\u003eM\\u003c/button\\u003e\\n}\\n```\",\n      \"title\": \"FAB flower\"\n    }\n  ],\n  \"features\": [\n    {\n      \"name\": \"FeaturesExample\",\n      \"code\": \"```go\\ntempl FeaturesExample() {\\n\\t@components.Features(\\n\\t\\tcomponents.FeaturesProps{\\n\\t\\t\\tTitle: \\\"Discover our exclusive features\\\",\\n\\t\\t\\tFeatures: []components.FeatureProps{\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tIcon:        CustomizationIcon(),\\n\\t\\t\\t\\t\\tTitle:       \\\"Customization\\\",\\n\\t\\t\\t\\t\\tDescription: \\\"Tailor our product to suit your needs.\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tIcon:        SecurityIcon(),\\n\\t\\t\\t\\t\\tTitle:       \\\"Security\\\",\\n\\t\\t\\t\\t\\tDescription: \\\"Your data is protected by the latest security measures.\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tIcon:        SupportIcon(),\\n\\t\\t\\t\\t\\tTitle:       \\\"Support\\\",\\n\\t\\t\\t\\t\\tDescription: \\\"24/7 customer support for all your inquiries.\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tIcon:        PerformanceIcon(),\\n\\t\\t\\t\\t\\tTitle:       \\\"Performance\\\",\\n\\t\\t\\t\\t\\tDescription: \\\"Experience blazing-fast performance with our product.\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tIcon:  GlobalReachIcon(),\\n\\t\\t\\t\\t\\tTitle: \\\"Global reach\\\",\\n\\t\\t\\t\\t\\tDescription: `Tailor our product to suit your needs. Expand your reach \\nwith our global network.`,\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tIcon:        CommunicationIcon(),\\n\\t\\t\\t\\t\\tTitle:       \\\"Communication\\\",\\n\\t\\t\\t\\t\\tDescription: \\\"Seamless communication for your team.\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t},\\n\\t)\\n}\\n\\ntempl CustomizationIcon() {\\n\\t\\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"currentColor\\\" class=\\\"w-8 mb-6 inline-block\\\" viewBox=\\\"0 0 32 32\\\"\\u003e\\n\\t\\t\\u003cpath d=\\\"M28.068 12h-.128a.934.934 0 0 1-.864-.6.924.924 0 0 1 .2-1.01l.091-.091a2.938 2.938 0 0 0 0-4.147l-1.511-1.51a2.935 2.935 0 0 0-4.146 0l-.091.091A.956.956 0 0 1 20 4.061v-.129A2.935 2.935 0 0 0 17.068 1h-2.136A2.935 2.935 0 0 0 12 3.932v.129a.956.956 0 0 1-1.614.668l-.086-.091a2.935 2.935 0 0 0-4.146 0l-1.516 1.51a2.938 2.938 0 0 0 0 4.147l.091.091a.935.935 0 0 1 .185 1.035.924.924 0 0 1-.854.579h-.128A2.935 2.935 0 0 0 1 14.932v2.136A2.935 2.935 0 0 0 3.932 20h.128a.934.934 0 0 1 .864.6.924.924 0 0 1-.2 1.01l-.091.091a2.938 2.938 0 0 0 0 4.147l1.51 1.509a2.934 2.934 0 0 0 4.147 0l.091-.091a.936.936 0 0 1 1.035-.185.922.922 0 0 1 .579.853v.129A2.935 2.935 0 0 0 14.932 31h2.136A2.935 2.935 0 0 0 20 28.068v-.129a.956.956 0 0 1 1.614-.668l.091.091a2.935 2.935 0 0 0 4.146 0l1.511-1.509a2.938 2.938 0 0 0 0-4.147l-.091-.091a.935.935 0 0 1-.185-1.035.924.924 0 0 1 .854-.58h.128A2.935 2.935 0 0 0 31 17.068v-2.136A2.935 2.935 0 0 0 28.068 12ZM29 17.068a.933.933 0 0 1-.932.932h-.128a2.956 2.956 0 0 0-2.083 5.028l.09.091a.934.934 0 0 1 0 1.319l-1.511 1.509a.932.932 0 0 1-1.318 0l-.09-.091A2.957 2.957 0 0 0 18 27.939v.129a.933.933 0 0 1-.932.932h-2.136a.933.933 0 0 1-.932-.932v-.129a2.951 2.951 0 0 0-5.028-2.082l-.091.091a.934.934 0 0 1-1.318 0l-1.51-1.509a.934.934 0 0 1 0-1.319l.091-.091A2.956 2.956 0 0 0 4.06 18h-.128A.933.933 0 0 1 3 17.068v-2.136A.933.933 0 0 1 3.932 14h.128a2.956 2.956 0 0 0 2.083-5.028l-.09-.091a.933.933 0 0 1 0-1.318l1.51-1.511a.932.932 0 0 1 1.318 0l.09.091A2.957 2.957 0 0 0 14 4.061v-.129A.933.933 0 0 1 14.932 3h2.136a.933.933 0 0 1 .932.932v.129a2.956 2.956 0 0 0 5.028 2.082l.091-.091a.932.932 0 0 1 1.318 0l1.51 1.511a.933.933 0 0 1 0 1.318l-.091.091A2.956 2.956 0 0 0 27.94 14h.128a.933.933 0 0 1 .932.932Z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath d=\\\"M16 9a7 7 0 1 0 7 7 7.008 7.008 0 0 0-7-7Zm0 12a5 5 0 1 1 5-5 5.006 5.006 0 0 1-5 5Z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl SecurityIcon() {\\n\\t\\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"currentColor\\\" class=\\\"w-8 mb-6 inline-block\\\" viewBox=\\\"0 0 682.667 682.667\\\"\\u003e\\n\\t\\t\\u003cdefs\\u003e\\n\\t\\t\\t\\u003cclipPath id=\\\"a\\\" clipPathUnits=\\\"userSpaceOnUse\\\"\\u003e\\n\\t\\t\\t\\t\\u003cpath d=\\\"M0 512h512V0H0Z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003c/clipPath\\u003e\\n\\t\\t\\u003c/defs\\u003e\\n\\t\\t\\u003cg fill=\\\"none\\\" stroke=\\\"currentColor\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\" stroke-miterlimit=\\\"10\\\" stroke-width=\\\"40\\\" clip-path=\\\"url(#a)\\\" transform=\\\"matrix(1.33 0 0 -1.33 0 682.667)\\\"\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M256 492 60 410.623v-98.925C60 183.674 137.469 68.38 256 20c118.53 48.38 196 163.674 196 291.698v98.925z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M178 271.894 233.894 216 334 316.105\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/g\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl SupportIcon() {\\n\\t\\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"currentColor\\\" class=\\\"w-8 mb-6 inline-block\\\" viewBox=\\\"0 0 512.001 512.001\\\"\\u003e\\n\\t\\t\\u003cpath d=\\\"M271.029 0c-33.091 0-61 27.909-61 61s27.909 61 61 61 60-27.909 60-61-26.909-61-60-61zm66.592 122c-16.485 18.279-40.096 30-66.592 30-26.496 0-51.107-11.721-67.592-30-14.392 15.959-23.408 36.866-23.408 60v15c0 8.291 6.709 15 15 15h151c8.291 0 15-6.709 15-15v-15c0-23.134-9.016-44.041-23.408-60zM144.946 460.404 68.505 307.149c-7.381-14.799-25.345-20.834-40.162-13.493l-19.979 9.897c-7.439 3.689-10.466 12.73-6.753 20.156l90 180c3.701 7.423 12.704 10.377 20.083 6.738l19.722-9.771c14.875-7.368 20.938-25.417 13.53-40.272zM499.73 247.7c-12.301-9-29.401-7.2-39.6 3.9l-82 100.8c-5.7 6-16.5 9.6-22.2 9.6h-69.901c-8.401 0-15-6.599-15-15s6.599-15 15-15h60c16.5 0 30-13.5 30-30s-13.5-30-30-30h-78.6c-7.476 0-11.204-4.741-17.1-9.901-23.209-20.885-57.949-30.947-93.119-22.795-19.528 4.526-32.697 12.415-46.053 22.993l-.445-.361-21.696 19.094L174.28 452h171.749c28.2 0 55.201-13.5 72.001-36l87.999-126c9.9-13.201 7.2-32.399-6.299-42.3z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl PerformanceIcon() {\\n\\t\\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"currentColor\\\" class=\\\"w-8 mb-6 inline-block\\\" viewBox=\\\"0 0 24 24\\\"\\u003e\\n\\t\\t\\u003cg fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\"\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M17.03 8.97a.75.75 0 0 1 0 1.06l-4.2 4.2a.75.75 0 0 1-1.154-.114l-1.093-1.639L8.03 15.03a.75.75 0 0 1-1.06-1.06l3.2-3.2a.75.75 0 0 1 1.154.114l1.093 1.639L15.97 8.97a.75.75 0 0 1 1.06 0z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M13.75 9.5a.75.75 0 0 1 .75-.75h2a.75.75 0 0 1 .75.75v2a.75.75 0 0 1-1.5 0v-1.25H14.5a.75.75 0 0 1-.75-.75z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M3.095 3.095C4.429 1.76 6.426 1.25 9 1.25h6c2.574 0 4.57.51 5.905 1.845C22.24 4.429 22.75 6.426 22.75 9v6c0 2.574-.51 4.57-1.845 5.905C19.571 22.24 17.574 22.75 15 22.75H9c-2.574 0-4.57-.51-5.905-1.845C1.76 19.571 1.25 17.574 1.25 15V9c0-2.574.51-4.57 1.845-5.905zm1.06 1.06C3.24 5.071 2.75 6.574 2.75 9v6c0 2.426.49 3.93 1.405 4.845.916.915 2.419 1.405 4.845 1.405h6c2.426 0 3.93-.49 4.845-1.405.915-.916 1.405-2.419 1.405-4.845V9c0-2.426-.49-3.93-1.405-4.845C18.929 3.24 17.426 2.75 15 2.75H9c-2.426 0-3.93.49-4.845 1.405z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/g\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl GlobalReachIcon() {\\n\\t\\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"currentColor\\\" class=\\\"w-8 mb-6 inline-block\\\" viewBox=\\\"0 0 504.69 504.69\\\"\\u003e\\n\\t\\t\\u003cpath d=\\\"M252.343 262.673c-49.32 0-89.447-40.127-89.447-89.447s40.127-89.447 89.447-89.447 89.447 40.127 89.447 89.447-40.121 89.447-89.447 89.447zm0-158.235c-37.926 0-68.787 30.861-68.787 68.787s30.861 68.787 68.787 68.787 68.787-30.861 68.787-68.787-30.855-68.787-68.787-68.787z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath d=\\\"M391.787 405.309c-5.645 0-10.253-4.54-10.325-10.201-.883-70.306-58.819-127.503-129.15-127.503-49.264 0-93.543 27.405-115.561 71.52-8.724 17.473-13.269 36.31-13.517 55.988-.072 5.702-4.757 10.273-10.459 10.201s-10.273-4.757-10.201-10.459c.289-22.814 5.568-44.667 15.691-64.955 25.541-51.164 76.907-82.95 134.047-82.95 81.581 0 148.788 66.349 149.81 147.905.072 5.702-4.494 10.392-10.201 10.459-.046-.005-.087-.005-.134-.005z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath d=\\\"M252.343 463.751c-116.569 0-211.408-94.834-211.408-211.408 0-116.569 94.839-211.408 211.408-211.408 116.574 0 211.408 94.839 211.408 211.408 0 116.574-94.834 211.408-211.408 211.408zm0-402.156c-105.18 0-190.748 85.568-190.748 190.748s85.568 190.748 190.748 190.748 190.748-85.568 190.748-190.748S357.523 61.595 252.343 61.595zM71.827 90.07 14.356 32.599c-4.034-4.034-4.034-10.573 0-14.607 4.029-4.034 10.573-4.034 14.607 0l57.466 57.471c4.034 4.034 3.951 10.49 0 14.607-3.792 3.951-11.039 3.698-14.602 0z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath d=\\\"M14.717 92.254a10.332 10.332 0 0 1-10.299-9.653L.023 15.751a10.317 10.317 0 0 1 2.929-7.908 10.2 10.2 0 0 1 7.851-3.089L77.56 7.796c5.697.258 10.108 5.093 9.85 10.79s-5.041 10.154-10.79 9.85l-55.224-2.521 3.641 55.327c.377 5.692-3.936 10.614-9.628 10.986a7.745 7.745 0 0 1-.692.026zm403.541-2.184c-4.256-3.796-4.034-10.573 0-14.607l58.116-58.116c4.034-4.034 10.573-4.034 14.607 0s4.034 10.573 0 14.607L432.864 90.07c-4.085 3.951-9.338 4.7-14.606 0z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath d=\\\"M489.974 92.254a9.85 9.85 0 0 1-.687-.021c-5.697-.372-10.01-5.294-9.633-10.986l3.641-55.327-55.224 2.515c-5.511.238-10.526-4.147-10.79-9.85-.258-5.702 4.153-10.531 9.85-10.79l66.757-3.042c2.934-.134 5.79.992 7.851 3.089s3.12 4.974 2.929 7.908l-4.401 66.85c-.361 5.465-4.896 9.654-10.293 9.654zM11.711 489.339c-3.791-4.266-4.034-10.573 0-14.607l60.115-60.11c4.029-4.034 10.578-4.034 14.607 0 4.034 4.034 4.034 10.573 0 14.607l-60.115 60.11c-3.827 3.884-11.156 3.884-14.607 0z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath d=\\\"M10.327 499.947a10.33 10.33 0 0 1-7.376-3.104 10.312 10.312 0 0 1-2.929-7.902l4.401-66.85c.372-5.697 5.191-10.036 10.986-9.633 5.692.377 10.005 5.294 9.628 10.986l-3.641 55.332 55.224-2.515c5.645-.191 10.531 4.153 10.79 9.85.258 5.697-4.153 10.526-9.85 10.79l-66.763 3.037c-.155.004-.31.009-.47.009zm465.639-13.01-57.708-57.708c-4.034-4.034-4.034-10.573 0-14.607s10.573-4.034 14.607 0l57.708 57.708c4.034 4.034 3.962 10.5 0 14.607-3.817 3.951-10.062 3.951-14.607 0z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath d=\\\"M494.359 499.947c-.155 0-.315-.005-.47-.01l-66.757-3.042c-5.702-.263-10.108-5.088-9.85-10.79.263-5.702 5.113-9.984 10.79-9.85l55.219 2.515-3.641-55.332c-.372-5.692 3.941-10.609 9.633-10.986 5.625-.398 10.609 3.946 10.986 9.633l4.401 66.85a10.33 10.33 0 0 1-2.929 7.902 10.323 10.323 0 0 1-7.382 3.11z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl CommunicationIcon() {\\n\\t\\u003csvg xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"currentColor\\\" class=\\\"w-8 mb-6 inline-block\\\" viewBox=\\\"0 0 682.667 682.667\\\"\\u003e\\n\\t\\t\\u003cdefs\\u003e\\n\\t\\t\\t\\u003cclipPath id=\\\"a\\\" clipPathUnits=\\\"userSpaceOnUse\\\"\\u003e\\n\\t\\t\\t\\t\\u003cpath d=\\\"M0 512h512V0H0Z\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003c/clipPath\\u003e\\n\\t\\t\\u003c/defs\\u003e\\n\\t\\t\\u003cg fill=\\\"none\\\" stroke=\\\"currentColor\\\" stroke-miterlimit=\\\"10\\\" stroke-width=\\\"30\\\" clip-path=\\\"url(#a)\\\" transform=\\\"matrix(1.33 0 0 -1.33 0 682.667)\\\"\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M226 15v60c0 16.568-13.432 30-30 30H76c-16.568 0-30-13.432-30-30V15Zm-45 165c0-24.853-20.147-45-45-45s-45 20.147-45 45 20.147 45 45 45 45-20.147 45-45ZM466 15v60c0 16.568-13.432 30-30 30H316c-16.568 0-30-13.432-30-30V15Zm-45 165c0-24.853-20.147-45-45-45s-45 20.147-45 45 20.147 45 45 45 45-20.147 45-45Zm-75 167v-50.294L286 347h-60.002L166 296.706V347h-15c-41.421 0-75 33.579-75 75s33.579 75 75 75h210c41.421 0 75-33.579 75-75s-33.579-75-75-75Zm-105 75h30m-90 0h30m90 0h30\\\" data-original=\\\"#000000\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/g\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\"\n    }\n  ],\n  \"file_input\": [\n    {\n      \"name\": \"DifferentSizeFileInputs\",\n      \"code\": \"```go\\ntempl DifferentSizeFileInputs() {\\n\\t@components.FileInput(components.FileInputProps{\\n\\t\\tLabel: \\\"File upload\\\",\\n\\t\\tSize:  \\\"xs\\\",\\n\\t})\\n\\t@components.FileInput(components.FileInputProps{\\n\\t\\tLabel: \\\"File upload\\\",\\n\\t\\tSize:  \\\"sm\\\",\\n\\t})\\n\\t@components.FileInput(components.FileInputProps{\\n\\t\\tLabel: \\\"File upload\\\",\\n\\t})\\n\\t@components.FileInput(components.FileInputProps{\\n\\t\\tLabel: \\\"File upload\\\",\\n\\t\\tSize:  \\\"lg\\\",\\n\\t})\\n\\t@components.FileInput(components.FileInputProps{\\n\\t\\tLabel: \\\"File upload\\\",\\n\\t\\tSize:  \\\"xl\\\",\\n\\t})\\n}\\n```\",\n      \"title\": \"Different size file inputs\"\n    }\n  ],\n  \"footer\": [\n    {\n      \"name\": \"BasicFooterWithLinks\",\n      \"code\": \"```go\\ntempl BasicFooterWithLinks() {\\n\\t@components.Footer(\\n\\t\\tcomponents.FooterProps{\\n\\t\\t\\tIcon:        FooterCompanyInfoIconExample(),\\n\\t\\t\\tName:        \\\"ACME Industries Ltd.\\\",\\n\\t\\t\\tDescription: \\\"Providing reliable tech since 1992\\\",\\n\\t\\t\\tAnchors: []components.AnchorProps{\\n\\t\\t\\t\\t{LeftIcon: XIcon()},\\n\\t\\t\\t\\t{LeftIcon: YoutubeIcon()},\\n\\t\\t\\t\\t{LeftIcon: FacebookIcon()},\\n\\t\\t\\t},\\n\\t\\t},\\n\\t) {\\n\\t\\t@components.FooterNav(\\n\\t\\t\\t\\\"Services\\\",\\n\\t\\t\\t[]components.AnchorProps{\\n\\t\\t\\t\\t{Label: \\\"Branding\\\"},\\n\\t\\t\\t\\t{Label: \\\"Design\\\"},\\n\\t\\t\\t\\t{Label: \\\"Marketing\\\"},\\n\\t\\t\\t\\t{Label: \\\"Advertisement\\\"},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.FooterNav(\\n\\t\\t\\t\\\"Company\\\",\\n\\t\\t\\t[]components.AnchorProps{\\n\\t\\t\\t\\t{Label: \\\"About us\\\"},\\n\\t\\t\\t\\t{Label: \\\"Contact\\\"},\\n\\t\\t\\t\\t{Label: \\\"Jobs\\\"},\\n\\t\\t\\t\\t{Label: \\\"Press kit\\\"},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.FooterNav(\\n\\t\\t\\t\\\"Legal\\\",\\n\\t\\t\\t[]components.AnchorProps{\\n\\t\\t\\t\\t{Label: \\\"Terms of use\\\"},\\n\\t\\t\\t\\t{Label: \\\"Privacy policy\\\"},\\n\\t\\t\\t\\t{Label: \\\"Cookie policy\\\"},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t}\\n}\\n\\ntempl FooterCompanyInfoIconExample() {\\n\\t\\u003csvg\\n\\t\\twidth=\\\"24\\\"\\n\\t\\theight=\\\"24\\\"\\n\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\tfill-rule=\\\"evenodd\\\"\\n\\t\\tclip-rule=\\\"evenodd\\\"\\n\\t\\tclass=\\\"fill-current\\\"\\n\\t\\u003e\\n\\t\\t\\u003cpath\\n\\t\\t\\td=\\\"M22.672 15.226l-2.432.811.841 2.515c.33 1.019-.209 2.127-1.23 2.456-1.15.325-2.148-.321-2.463-1.226l-.84-2.518-5.013 1.677.84 2.517c.391 1.203-.434 2.542-1.831 2.542-.88 0-1.601-.564-1.86-1.314l-.842-2.516-2.431.809c-1.135.328-2.145-.317-2.463-1.229-.329-1.018.211-2.127 1.231-2.456l2.432-.809-1.621-4.823-2.432.808c-1.355.384-2.558-.59-2.558-1.839 0-.817.509-1.582 1.327-1.846l2.433-.809-.842-2.515c-.33-1.02.211-2.129 1.232-2.458 1.02-.329 2.13.209 2.461 1.229l.842 2.515 5.011-1.677-.839-2.517c-.403-1.238.484-2.553 1.843-2.553.819 0 1.585.509 1.85 1.326l.841 2.517 2.431-.81c1.02-.33 2.131.211 2.461 1.229.332 1.018-.21 2.126-1.23 2.456l-2.433.809 1.622 4.823 2.433-.809c1.242-.401 2.557.484 2.557 1.838 0 .819-.51 1.583-1.328 1.847m-8.992-6.428l-5.01 1.675 1.619 4.828 5.011-1.674-1.62-4.829z\\\"\\n\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\"\n    }\n  ],\n  \"hero\": [\n    {\n      \"name\": \"BasicHero\",\n      \"code\": \"```go\\ntempl BasicHero() {\\n\\t\\u003cdiv class=\\\"pt-4\\\"\\u003e\\n\\t\\t@components.Hero(components.HeroProps{\\n\\t\\t\\tSource: \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\tAlt:    \\\"hero avatar\\\",\\n\\t\\t\\tClass:  \\\"bg-base-200 min-h-[600px]\\\",\\n\\t\\t}) {\\n\\t\\t\\t\\u003cdiv class=\\\"prose\\\"\\u003e\\n\\t\\t\\t\\t\\u003ch1\\u003eLorem ipsum!\\u003c/h1\\u003e\\n\\t\\t\\t\\t\\u003cp\\u003e\\n\\t\\t\\t\\t\\tLorem ipsum dolor sit, amet consectetur adipisicing elit.\\n\\t\\t\\t\\t\\tEx quibusdam dicta necessitatibus! Deleniti temporibus iure\\n\\t\\t\\t\\t\\tporro cupiditate dolorum modi voluptate perferendis velit\\n\\t\\t\\t\\t\\ttempora repudiandae expedita, impedit omnis vitae. Laborum,\\n\\t\\t\\t\\t\\tdignissimos?\\n\\t\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\t\\u003cbutton class=\\\"btn btn-primary\\\"\\u003eGet Started\\u003c/button\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\t@components.Hero(components.HeroProps{\\n\\t\\t\\tSource:  \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\tAlt:     \\\"hero avatar\\\",\\n\\t\\t\\tClass:   \\\"bg-base-200 min-h-[600px]\\\",\\n\\t\\t\\tReverse: true,\\n\\t\\t}) {\\n\\t\\t\\t\\u003cdiv class=\\\"prose\\\"\\u003e\\n\\t\\t\\t\\t\\u003ch1\\u003eLorem ipsum!\\u003c/h1\\u003e\\n\\t\\t\\t\\t\\u003cp\\u003e\\n\\t\\t\\t\\t\\tLorem ipsum dolor sit, amet consectetur adipisicing elit.\\n\\t\\t\\t\\t\\tEx quibusdam dicta necessitatibus! Deleniti temporibus iure\\n\\t\\t\\t\\t\\tporro cupiditate dolorum modi voluptate perferendis velit\\n\\t\\t\\t\\t\\ttempora repudiandae expedita, impedit omnis vitae. Laborum,\\n\\t\\t\\t\\t\\tdignissimos?\\n\\t\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\t\\u003cbutton class=\\\"btn btn-primary\\\"\\u003eGet Started\\u003c/button\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"hover_3d_card\": [\n    {\n      \"name\": \"Hover3DCardExample\",\n      \"code\": \"```go\\ntempl Hover3DCardExample() {\\n\\t@components.Hover3DCard() {\\n\\t\\t@components.Card(\\n\\t\\t\\tcomponents.CardProps{\\n\\t\\t\\t\\tTitle:   \\\"Hover 3D Card\\\",\\n\\t\\t\\t\\tContent: \\\"This is a hover 3D card. Move your mouse around the card.\\\",\\n\\t\\t\\t\\tClass:   \\\"h-[200px] card-border\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t}\\n}\\n```\"\n    }\n  ],\n  \"infinite_scroll\": [\n    {\n      \"name\": \"InfiniteScrollTableExample\",\n      \"code\": \"```go\\ntempl InfiniteScrollTableExample() {\\n\\t@components.Table(\\n\\t\\t[]templ.Component{components.PlainText(\\\"Name\\\"), components.PlainText(\\\"Email\\\")},\\n\\t\\tinitialRows(),\\n\\t\\tnil,\\n\\t)\\n\\t\\u003cdiv class=\\\"flex justify-center\\\"\\u003e\\u003cspan id=\\\"spinner\\\" class=\\\"htmx-indicator loading loading-spinner\\\"\\u003e\\u003c/span\\u003e\\u003c/div\\u003e\\n}\\n\\nfunc initialRows() []templ.Component {\\n\\tdata := make([]templ.Component, 10)\\n\\tfor i := 0; i \\u003c 10; i++ {\\n\\t\\tdata[i] = components.InfiniteScrollRow(\\\"John Doe\\\", fmt.Sprintf(\\\"john.doe%d@email.com\\\", i), 0, i == 9)\\n\\t}\\n\\n\\treturn data\\n}\\n```\",\n      \"handler\": \"```go\\nfunc GetInfiniteScrollExample(c echo.Context) error {\\n\\t// generate dummy row data\\n\\tdata := make([][]string, 0, 10)\\n\\tfor i := 0; i \\u003c 10; i++ {\\n\\t\\tdata = append(data, []string{\\\"John Doe\\\", fmt.Sprintf(\\\"john.doe%d@email.com\\\", i)})\\n\\t}\\n\\n\\thasMore := true\\n\\n\\trows := make([]templ.Component, 0, len(data))\\n\\tfor i := range data {\\n\\t\\trows = append(\\n\\t\\t\\trows,\\n\\t\\t\\tcomponents.InfiniteScrollRow(data[i][0], data[i][1], 1, i+1 == 10 \\u0026\\u0026 hasMore),\\n\\t\\t)\\n\\t}\\n\\n\\treturn render(c, http.StatusOK, components.InfiniteScrollTable(rows))\\n}\\n\\nfunc GetInfiniteScrollExampleRows(c echo.Context) error {\\n\\t// short delay for loading indicator\\n\\ttime.Sleep(500 * time.Millisecond)\\n\\n\\tpageStr := c.QueryParam(\\\"page\\\")\\n\\tpage, err := strconv.Atoi(pageStr)\\n\\tif err != nil {\\n\\t\\treturn newErrorToast(\\n\\t\\t\\thttp.StatusUnprocessableEntity,\\n\\t\\t\\tfmt.Sprintf(\\\"invalid page '%s'\\\", pageStr),\\n\\t\\t)\\n\\t}\\n\\n\\t// generate dummy date for the page\\n\\tdata := make([][]string, 0, 10)\\n\\tfor i := (page - 1) * 10; i \\u003c (page-1)*10+10; i++ {\\n\\t\\tdata = append(data, []string{\\\"John Doe\\\", fmt.Sprintf(\\\"john.doe%d@email.com\\\", i)})\\n\\t}\\n\\n\\thasMore := len(data) == 10 \\u0026\\u0026 page \\u003c 10\\n\\n\\trows := make([]templ.Component, 0, len(data))\\n\\tfor i := range data {\\n\\t\\trows = append(\\n\\t\\t\\trows,\\n\\t\\t\\tcomponents.InfiniteScrollRow(data[i][0], data[i][1], page, i+1 == 10 \\u0026\\u0026 hasMore),\\n\\t\\t)\\n\\t}\\n\\n\\treturn render(c, http.StatusOK, components.InfiniteScrollRows(rows))\\n}\\n\\n```\"\n    }\n  ],\n  \"input\": [\n    {\n      \"name\": \"DifferentSizeInputs\",\n      \"code\": \"```go\\ntempl DifferentSizeInputs() {\\n\\t@components.Input(components.InputProps{\\n\\t\\tLabel:       \\\"Name\\\",\\n\\t\\tPlaceholder: \\\"Your name...\\\",\\n\\t\\tSize:        \\\"xs\\\",\\n\\t})\\n\\t@components.Input(components.InputProps{\\n\\t\\tLabel:       \\\"Name\\\",\\n\\t\\tPlaceholder: \\\"Your name...\\\",\\n\\t\\tSize:        \\\"sm\\\",\\n\\t})\\n\\t@components.Input(components.InputProps{\\n\\t\\tLabel:       \\\"Name\\\",\\n\\t\\tPlaceholder: \\\"Your name...\\\",\\n\\t})\\n\\t@components.Input(components.InputProps{\\n\\t\\tLabel:       \\\"Name\\\",\\n\\t\\tPlaceholder: \\\"Your name...\\\",\\n\\t\\tSize:        \\\"lg\\\",\\n\\t})\\n\\t@components.Input(components.InputProps{\\n\\t\\tLabel:       \\\"Name\\\",\\n\\t\\tPlaceholder: \\\"Your name...\\\",\\n\\t\\tSize:        \\\"xl\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"Different size inputs\"\n    },\n    {\n      \"name\": \"IntegerInput\",\n      \"code\": \"```go\\ntempl IntegerInput() {\\n\\t@components.Input(components.InputProps{\\n\\t\\tName:        \\\"my_number\\\",\\n\\t\\tType:        \\\"number\\\",\\n\\t\\tPlaceholder: \\\"Give a number...\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"Integer input\"\n    },\n    {\n      \"name\": \"DecimalInput\",\n      \"code\": \"```go\\ntempl DecimalInput() {\\n\\t@components.Input(components.InputProps{\\n\\t\\tName:        \\\"my_number\\\",\\n\\t\\tType:        \\\"number\\\",\\n\\t\\tPlaceholder: \\\"Give a decimal number...\\\",\\n\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\\"min\\\":  \\\"0.00\\\",\\n\\t\\t\\t\\\"max\\\":  \\\"2.00\\\",\\n\\t\\t\\t\\\"step\\\": \\\"0.25\\\",\\n\\t\\t},\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"Decimal input\"\n    },\n    {\n      \"name\": \"PasswordFieldWithValidator\",\n      \"code\": \"```go\\ntempl PasswordFieldWithValidator() {\\n\\t@components.Input(components.InputProps{\\n\\t\\tName:          \\\"password\\\",\\n\\t\\tType:          \\\"password\\\",\\n\\t\\tPlaceholder:   \\\"Password\\\",\\n\\t\\tRequired:      true,\\n\\t\\tPattern:       `(?=.*(\\\\W|_))(?=.*\\\\d)(?=.*[a-z])(?=.*[A-Z]).{8,255}`,\\n\\t\\tValidatorHint: \\\"Must be at least 8 characters long, including a digit, lower- and uppercase letter, and a special character\\\",\\n\\t\\tIcon:          keyIcon(),\\n\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\\"minlength\\\": \\\"8\\\",\\n\\t\\t\\t\\\"maxlength\\\": \\\"255\\\",\\n\\t\\t},\\n\\t})\\n}\\n\\ntempl keyIcon() {\\n\\t\\u003csvg class=\\\"fill-current/75 h-5 w-5\\\" viewBox=\\\"0 0 32 32\\\" id=\\\"icon\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003cpath d=\\\"M21,2a8.9977,8.9977,0,0,0-8.6119,11.6118L2,24v6H8L18.3881,19.6118A9,9,0,1,0,21,2Zm0,16a7.0125,7.0125,0,0,1-2.0322-.3022L17.821,17.35l-.8472.8472-3.1811,3.1812L12.4141,20,11,21.4141l1.3787,1.3786-1.5859,1.586L9.4141,23,8,24.4141l1.3787,1.3786L7.1716,28H4V24.8284l9.8023-9.8023.8472-.8474-.3473-1.1467A7,7,0,1,1,21,18Z\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003ccircle cx=\\\"22\\\" cy=\\\"10\\\" r=\\\"2\\\"\\u003e\\u003c/circle\\u003e\\n\\t\\t\\u003crect class=\\\"fill-none\\\" id=\\\"_Transparent_Rectangle_\\\"\\u003e\\u003c/rect\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\n```\",\n      \"title\": \"Password field with validator\"\n    },\n    {\n      \"name\": \"EmailFieldWithValidator\",\n      \"code\": \"```go\\ntempl EmailFieldWithValidator() {\\n\\t@components.Input(components.InputProps{\\n\\t\\tName:          \\\"email\\\",\\n\\t\\tType:          \\\"email\\\",\\n\\t\\tPlaceholder:   \\\"Email\\\",\\n\\t\\tRequired:      true,\\n\\t\\tPattern:       `^[^\\\\s@]+@[^\\\\s@]+\\\\.[^\\\\s@]+$`,\\n\\t\\tValidatorHint: \\\"Please enter a valid email address\\\",\\n\\t\\tIcon:          emailIcon(),\\n\\t})\\n}\\n\\ntempl emailIcon() {\\n\\t\\u003csvg class=\\\"h-5 w-5\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current/75\\\" d=\\\"M4 7.00005L10.2 11.65C11.2667 12.45 12.7333 12.45 13.8 11.65L20 7\\\" stroke-width=\\\"1\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003crect class=\\\"stroke-current/75\\\" x=\\\"3\\\" y=\\\"5\\\" width=\\\"18\\\" height=\\\"14\\\" rx=\\\"2\\\" stroke-width=\\\"1\\\" stroke-linecap=\\\"round\\\"\\u003e\\u003c/rect\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\n```\",\n      \"title\": \"Email field with validtor\"\n    },\n    {\n      \"name\": \"SignUpFormExample\",\n      \"code\": \"```go\\ntempl SignUpFormExample() {\\n\\t\\u003cdiv class=\\\"w-full max-w-xs mx-auto pt-12 pb-4\\\"\\u003e\\n\\t\\t\\u003ch2 class=\\\"text-xl text-center mb-8\\\"\\u003eSign Up\\u003c/h2\\u003e\\n\\t\\t@OAuthButtons()\\n\\t\\t\\u003cdiv class=\\\"divider !my-6\\\"\\u003eOR\\u003c/div\\u003e\\n\\t\\t@SignUpForm(\\n\\t\\t\\t\\\"\\\", \\\"\\\",\\n\\t\\t\\t\\\"\\\", \\\"\\\",\\n\\t\\t\\t\\\"\\\", \\\"\\\",\\n\\t\\t\\t\\\"\\\", \\\"\\\",\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl SignUpForm(\\n\\tfirstName, firstNameError,\\n\\tlastName, lastNameError,\\n\\temail, emailError,\\n\\tpassword, passwordError string,\\n) {\\n\\t\\u003cdiv class=\\\"w-full max-w-xs mx-auto\\\"\\u003e\\n\\t\\t\\u003cdiv\\n\\t\\t\\tclass=\\\"form space-y-1\\\"\\n\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\u003e\\n\\t\\t\\t@components.Input(\\n\\t\\t\\t\\tcomponents.InputProps{\\n\\t\\t\\t\\t\\tLabel:       \\\"First name\\\",\\n\\t\\t\\t\\t\\tName:        \\\"first_name\\\",\\n\\t\\t\\t\\t\\tPlaceholder: \\\"Your first name...\\\",\\n\\t\\t\\t\\t\\tValue:       firstName,\\n\\t\\t\\t\\t\\tError:       firstNameError,\\n\\t\\t\\t\\t\\tRequired:    true,\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\\"hx-post\\\": \\\"/validate/string/first_name?v=notempty\\\",\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t)\\n\\t\\t\\t@components.Input(\\n\\t\\t\\t\\tcomponents.InputProps{\\n\\t\\t\\t\\t\\tLabel:       \\\"Last name\\\",\\n\\t\\t\\t\\t\\tName:        \\\"last_name\\\",\\n\\t\\t\\t\\t\\tPlaceholder: \\\"Your last name...\\\",\\n\\t\\t\\t\\t\\tValue:       lastName,\\n\\t\\t\\t\\t\\tError:       lastNameError,\\n\\t\\t\\t\\t\\tRequired:    true,\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\\"hx-post\\\": \\\"/validate/string/last_name?v=notempty\\\",\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t)\\n\\t\\t\\t@components.Input(\\n\\t\\t\\t\\tcomponents.InputProps{\\n\\t\\t\\t\\t\\tLabel:       \\\"Email\\\",\\n\\t\\t\\t\\t\\tName:        \\\"email\\\",\\n\\t\\t\\t\\t\\tType:        \\\"email\\\",\\n\\t\\t\\t\\t\\tPlaceholder: \\\"Your email...\\\",\\n\\t\\t\\t\\t\\tValue:       email,\\n\\t\\t\\t\\t\\tError:       emailError,\\n\\t\\t\\t\\t\\tRequired:    true,\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\\"hx-post\\\": \\\"/validate/string/email?v=email\\\",\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t)\\n\\t\\t\\t@components.Input(\\n\\t\\t\\t\\tcomponents.InputProps{\\n\\t\\t\\t\\t\\tLabel:         \\\"Password\\\",\\n\\t\\t\\t\\t\\tName:          \\\"password\\\",\\n\\t\\t\\t\\t\\tType:          \\\"password\\\",\\n\\t\\t\\t\\t\\tPlaceholder:   \\\"Your new password...\\\",\\n\\t\\t\\t\\t\\tRequired:      true,\\n\\t\\t\\t\\t\\tMinLength:     \\\"8\\\",\\n\\t\\t\\t\\t\\tMaxLength:     \\\"255\\\",\\n\\t\\t\\t\\t\\tPattern:       `(?=.*(\\\\W|_))(?=.*\\\\d)(?=.*[a-z])(?=.*[A-Z]).{8,255}`,\\n\\t\\t\\t\\t\\tValidatorHint: \\\"Must be at least 8 characters long, including a digit, lower- and uppercase letter, and a special character\\\",\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\\"hx-post\\\": \\\"/validate/string/password?v=hasupper\\u0026v=haslower\\u0026v=hasdigit\\\",\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t)\\n\\t\\t\\t\\u003cdiv class=\\\"pt-4\\\"\\u003e\\n\\t\\t\\t\\t\\u003cbutton type=\\\"submit\\\" class=\\\"w-full btn btn-primary\\\"\\u003e\\n\\t\\t\\t\\t\\tSign up\\n\\t\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl OAuthButtons() {\\n\\t\\u003cdiv class=\\\"w-full max-w-xs flex flex-col space-y-4 items-center justify-center\\\"\\u003e\\n\\t\\t@GoogleOAuthLink(\\\"\\\")\\n\\t\\t@GithubOAuthLink(\\\"\\\")\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl GoogleOAuthLink(href string) {\\n\\t\\u003ca\\n\\t\\thref={ templ.SafeURL(href) }\\n\\t\\tclass=\\\"w-full max-w-sm py-3 flex justify-center gap-2 bg-gray-50 dark:bg-gray-900 hover:bg-gray-100 dark:hover:bg-black text-slate-950 dark:text-slate-50 rounded-box shadow-md transition-colors duration-300\\\"\\n\\t\\u003e\\n\\t\\t\\u003csvg class=\\\"w-6 h-6\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 32 32\\\" fill=\\\"none\\\"\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M30.0014 16.3109C30.0014 15.1598 29.9061 14.3198 29.6998 13.4487H16.2871V18.6442H24.1601C24.0014 19.9354 23.1442 21.8798 21.2394 23.1864L21.2127 23.3604L25.4536 26.58L25.7474 26.6087C28.4458 24.1665 30.0014 20.5731 30.0014 16.3109Z\\\" fill=\\\"#4285F4\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M16.2863 29.9998C20.1434 29.9998 23.3814 28.7553 25.7466 26.6086L21.2386 23.1863C20.0323 24.0108 18.4132 24.5863 16.2863 24.5863C12.5086 24.5863 9.30225 22.1441 8.15929 18.7686L7.99176 18.7825L3.58208 22.127L3.52441 22.2841C5.87359 26.8574 10.699 29.9998 16.2863 29.9998Z\\\" fill=\\\"#34A853\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M8.15964 18.769C7.85806 17.8979 7.68352 16.9645 7.68352 16.0001C7.68352 15.0356 7.85806 14.1023 8.14377 13.2312L8.13578 13.0456L3.67083 9.64746L3.52475 9.71556C2.55654 11.6134 2.00098 13.7445 2.00098 16.0001C2.00098 18.2556 2.55654 20.3867 3.52475 22.2845L8.15964 18.769Z\\\" fill=\\\"#FBBC05\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\t\\u003cpath d=\\\"M16.2864 7.4133C18.9689 7.4133 20.7784 8.54885 21.8102 9.4978L25.8419 5.64C23.3658 3.38445 20.1435 2 16.2864 2C10.699 2 5.8736 5.1422 3.52441 9.71549L8.14345 13.2311C9.30229 9.85555 12.5086 7.4133 16.2864 7.4133Z\\\" fill=\\\"#EB4335\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\u003cspan\\u003eSign in with Google\\u003c/span\\u003e\\n\\t\\u003c/a\\u003e\\n}\\n\\ntempl GithubOAuthLink(href string) {\\n\\t\\u003ca\\n\\t\\thref={ templ.SafeURL(href) }\\n\\t\\tclass=\\\"py-3 px-4 max-w-md flex justify-center items-center bg-gray-600 hover:bg-gray-700 focus:ring-gray-500 focus:ring-offset-gray-200 text-white w-full transition-colors duration-300 text-center text-base font-semibold shadow-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 rounded-box\\\"\\n\\t\\u003e\\n\\t\\t\\u003csvg class=\\\"w-6 h-6 mr-2\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" fill=\\\"currentColor\\\" class=\\\"mr-2\\\" viewBox=\\\"0 0 1792 1792\\\"\\u003e\\n\\t\\t\\t\\u003cpath\\n\\t\\t\\t\\td=\\\"M896 128q209 0 385.5 103t279.5 279.5 103 385.5q0 251-146.5 451.5t-378.5 277.5q-27 5-40-7t-13-30q0-3 .5-76.5t.5-134.5q0-97-52-142 57-6 102.5-18t94-39 81-66.5 53-105 20.5-150.5q0-119-79-206 37-91-8-204-28-9-81 11t-92 44l-38 24q-93-26-192-26t-192 26q-16-11-42.5-27t-83.5-38.5-85-13.5q-45 113-8 204-79 87-79 206 0 85 20.5 150t52.5 105 80.5 67 94 39 102.5 18q-39 36-49 103-21 10-45 15t-57 5-65.5-21.5-55.5-62.5q-19-32-48.5-52t-49.5-24l-20-3q-21 0-29 4.5t-5 11.5 9 14 13 12l7 5q22 10 43.5 38t31.5 51l10 23q13 38 44 61.5t67 30 69.5 7 55.5-3.5l23-4q0 38 .5 88.5t.5 54.5q0 18-13 30t-40 7q-232-77-378.5-277.5t-146.5-451.5q0-209 103-385.5t279.5-279.5 385.5-103zm-477 1103q3-7-7-12-10-3-13 2-3 7 7 12 9 6 13-2zm31 34q7-5-2-16-10-9-16-3-7 5 2 16 10 10 16 3zm30 45q9-7 0-19-8-13-17-6-9 5 0 18t17 7zm42 42q8-8-4-19-12-12-20-3-9 8 4 19 12 12 20 3zm57 25q3-11-13-16-15-4-19 7t13 15q15 6 19-6zm63 5q0-13-17-11-16 0-16 11 0 13 17 11 16 0 16-11zm58-10q-2-11-18-9-16 3-14 15t18 8 14-14z\\\"\\n\\t\\t\\t\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003c/svg\\u003e\\n\\t\\t\\u003cspan\\u003eSign in with GitHub\\u003c/span\\u003e\\n\\t\\u003c/a\\u003e\\n}\\n```\",\n      \"title\": \"Sign up form with inline validation\"\n    }\n  ],\n  \"lazy_load\": [\n    {\n      \"name\": \"LazyLoadExample\",\n      \"code\": \"```go\\ntempl LazyLoadExample() {\\n\\t@components.LazyLoad(\\\"/lazy-load\\\")\\n}\\n\\ntempl LazyLoadResult() {\\n\\t\\u003cdiv\\n\\t\\tclass={\\n\\t\\t\\t\\\"bg-warning text-warning-content rounded-box\\\",\\n\\t\\t\\t\\\"w-28 h-28 flex justify-center items-center text-center\\\",\\n\\t\\t}\\n\\t\\u003e\\n\\t\\tLAZY\\n\\t\\t\\u003cbr/\\u003e\\n\\t\\tLOAD\\n\\t\\t\\u003cbr/\\u003e\\n\\t\\tCOMPLETE\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"handler\": \"```go\\nfunc GetLazyLoadExample(c echo.Context) error {\\n\\ttime.Sleep(2 * time.Second)\\n\\n\\treturn render(c, http.StatusOK, examples.LazyLoadResult())\\n}\\n\\n```\"\n    }\n  ],\n  \"menu\": [\n    {\n      \"name\": \"MenuExample\",\n      \"code\": \"```go\\ntempl MenuExample() {\\n\\t\\u003cdiv class=\\\"w-full mx-auto max-w-xs pt-4\\\"\\u003e\\n\\t\\t@components.Menu(components.MenuProps{Title: \\\"Basic menu\\\", Class: \\\"w-52\\\"}) {\\n\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"Section 1\\\", Attrs: templ.Attributes{\\\"class\\\": \\\"menu-title\\\"}})\\n\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"Section 2\\\", Attrs: templ.Attributes{\\\"class\\\": \\\"menu-title\\\"}}) {\\n\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.1\\\"}) {\\n\\t\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.1.1\\\"})\\n\\t\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.1.2\\\"})\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.2\\\"}) {\\n\\t\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.2.1\\\"})\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.3\\\"})\\n\\t\\t\\t}\\n\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"Section 3\\\", Attrs: templ.Attributes{\\\"class\\\": \\\"menu-title\\\"}}) {\\n\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"3.1\\\"})\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Basic menu\"\n    },\n    {\n      \"name\": \"MenuWithSubmenusExample\",\n      \"code\": \"```go\\ntempl MenuWithSubmenusExample() {\\n\\t\\u003cdiv class=\\\"w-full mx-auto max-w-xs pt-4 min-h-72\\\"\\u003e\\n\\t\\t@components.Menu(components.MenuProps{Class: \\\"w-52\\\"}) {\\n\\t\\t\\t@components.MenuItem(\\n\\t\\t\\t\\tcomponents.MenuItemProps{\\n\\t\\t\\t\\t\\tLabel: \\\"Section 1\\\",\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\\"class\\\": \\\"menu-title\\\"},\\n\\t\\t\\t\\t})\\n\\t\\t\\t@components.Submenu(\\n\\t\\t\\t\\tcomponents.SubmenuProps{\\n\\t\\t\\t\\t\\tTitle: \\\"Section 2\\\",\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\\"open\\\": \\\"\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t) {\\n\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.1\\\"})\\n\\t\\t\\t\\t@components.MenuItem(components.MenuItemProps{Label: \\\"2.2\\\"})\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Menu with a submenu\"\n    },\n    {\n      \"name\": \"DashboardMenuExample\",\n      \"code\": \"```go\\ntempl DashboardMenuExample() {\\n\\t@components.Menu(\\n\\t\\tcomponents.MenuProps{Class: \\\"w-64 bg-base-200 rounded-box\\\"}) {\\n\\t\\t@components.MenuItem(\\n\\t\\t\\tcomponents.MenuItemProps{\\n\\t\\t\\t\\tLabel: \\\"Dashboard\\\",\\n\\t\\t\\t\\tIcon:  HomeIcon(),\\n\\t\\t\\t\\tAttrs: templ.Attributes{\\\"href\\\": \\\"#dashboard\\\"},\\n\\t\\t\\t})\\n\\t\\t@components.MenuItem(\\n\\t\\t\\tcomponents.MenuItemProps{\\n\\t\\t\\t\\tLabel: \\\"Users\\\",\\n\\t\\t\\t\\tIcon:  UsersIcon(),\\n\\t\\t\\t\\tAttrs: templ.Attributes{\\\"href\\\": \\\"#users\\\"},\\n\\t\\t\\t})\\n\\t\\t@components.Submenu(components.SubmenuProps{Title: \\\"Content\\\", Icon: ContentIcon()}) {\\n\\t\\t\\t@components.MenuItem(\\n\\t\\t\\t\\tcomponents.MenuItemProps{\\n\\t\\t\\t\\t\\tLabel: \\\"Posts\\\",\\n\\t\\t\\t\\t\\tIcon:  PostsIcon(),\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\\"href\\\": \\\"#posts\\\"},\\n\\t\\t\\t\\t})\\n\\t\\t\\t@components.MenuItem(\\n\\t\\t\\t\\tcomponents.MenuItemProps{\\n\\t\\t\\t\\t\\tLabel: \\\"Images\\\",\\n\\t\\t\\t\\t\\tIcon:  ImagesIcon(),\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\\"href\\\": \\\"#images\\\"},\\n\\t\\t\\t\\t})\\n\\t\\t\\t@components.MenuItem(\\n\\t\\t\\t\\tcomponents.MenuItemProps{\\n\\t\\t\\t\\t\\tLabel: \\\"Videos\\\",\\n\\t\\t\\t\\t\\tIcon:  VideosIcon(),\\n\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\\"href\\\": \\\"#videos\\\"},\\n\\t\\t\\t\\t})\\n\\t\\t}\\n\\t}\\n}\\n\\ntempl HomeIcon() {\\n\\t\\u003csvg class=\\\"h-5 w-5 opacity-75\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M2 12.2039C2 9.91549 2 8.77128 2.5192 7.82274C3.0384 6.87421 3.98695 6.28551 5.88403 5.10813L7.88403 3.86687C9.88939 2.62229 10.8921 2 12 2C13.1079 2 14.1106 2.62229 16.116 3.86687L18.116 5.10812C20.0131 6.28551 20.9616 6.87421 21.4808 7.82274C22 8.77128 22 9.91549 22 12.2039V13.725C22 17.6258 22 19.5763 20.8284 20.7881C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.7881C2 19.5763 2 17.6258 2 13.725V12.2039Z\\\" stroke-width=\\\"1.5\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M15 18H9\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl UsersIcon() {\\n\\t\\u003csvg class=\\\"h-5 w-5 opacity-75\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M16 7C16 9.20914 14.2091 11 12 11C9.79086 11 8 9.20914 8 7C8 4.79086 9.79086 3 12 3C14.2091 3 16 4.79086 16 7Z\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M12 14C8.13401 14 5 17.134 5 21H19C19 17.134 15.866 14 12 14Z\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl ContentIcon() {\\n\\t\\u003csvg class=\\\"h-5 w-5 opacity-75\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" opacity=\\\"0.5\\\" d=\\\"M18 10L13 10\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M2 6.94975C2 6.06722 2 5.62595 2.06935 5.25839C2.37464 3.64031 3.64031 2.37464 5.25839 2.06935C5.62595 2 6.06722 2 6.94975 2C7.33642 2 7.52976 2 7.71557 2.01738C8.51665 2.09229 9.27652 2.40704 9.89594 2.92051C10.0396 3.03961 10.1763 3.17633 10.4497 3.44975L11 4C11.8158 4.81578 12.2237 5.22367 12.7121 5.49543C12.9804 5.64471 13.2651 5.7626 13.5604 5.84678C14.0979 6 14.6747 6 15.8284 6H16.2021C18.8345 6 20.1506 6 21.0062 6.76946C21.0849 6.84024 21.1598 6.91514 21.2305 6.99383C22 7.84935 22 9.16554 22 11.7979V14C22 17.7712 22 19.6569 20.8284 20.8284C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14V6.94975Z\\\" stroke-width=\\\"1.5\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl PostsIcon() {\\n\\t\\u003csvg class=\\\"h-5 w-5 opacity-75\\\" viewBox=\\\"0 0 24 24\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M1 6v12h9V6zm8 11H2V7h7zm-8 3h22v1H1zM1 3h22v1H1zm11 4h11v1H12zm0 3h11v1H12zm0 3h11v1H12zm0 3h11v1H12z\\\"\\u003e\\u003c/path\\u003e\\u003cpath fill=\\\"none\\\" d=\\\"M0 0h24v24H0z\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl ImagesIcon() {\\n\\t\\u003csvg class=\\\"h-5 w-5 opacity-75\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003crect width=\\\"24\\\" height=\\\"24\\\" class=\\\"fill-base-100\\\"\\u003e\\u003c/rect\\u003e\\n\\t\\t\\u003cpath class=\\\"stroke-current\\\" d=\\\"M21 16V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V18M21 16V4C21 3.44772 20.5523 3 20 3H4C3.44772 3 3 3.44772 3 4V18M21 16L15.4829 12.3219C15.1843 12.1228 14.8019 12.099 14.4809 12.2595L3 18\\\" stroke-linejoin=\\\"round\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003ccircle class=\\\"stroke-current\\\" cx=\\\"8\\\" cy=\\\"9\\\" r=\\\"2\\\" stroke-linejoin=\\\"round\\\"\\u003e\\u003c/circle\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n\\ntempl VideosIcon() {\\n\\t\\u003csvg class=\\\"h-5 w-5 opacity-75\\\" viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"\\u003e\\n\\t\\t\\u003cpath class=\\\"fill-current\\\" fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" d=\\\"M9.98966 10.91C10.4482 10.609 11.0657 10.5541 11.6048 10.8884L14.9764 12.9785C15.5136 13.3116 15.75 13.8874 15.75 14.4102C15.75 14.933 15.5136 15.5088 14.9764 15.8418L11.6048 17.932C11.0657 18.2662 10.4482 18.2114 9.98966 17.9103C9.539 17.6144 9.25 17.0934 9.25 16.5003V12.32C9.25 11.727 9.539 11.2059 9.98966 10.91ZM10.8129 12.1639C10.7945 12.176 10.75 12.2203 10.75 12.32V16.5003C10.75 16.6 10.7945 16.6443 10.8129 16.6564L10.8142 16.6572L14.186 14.5669C14.2072 14.5538 14.25 14.5085 14.25 14.4102C14.25 14.3118 14.2072 14.2665 14.186 14.2534L10.8145 12.1633L10.8129 12.1639Z\\\"\\u003e\\u003c/path\\u003e\\n\\t\\t\\u003cpath class=\\\"fill-current\\\" fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" d=\\\"M8.69935 1.25001C8.4795 1.24995 8.31094 1.2499 8.16359 1.26571C6.80943 1.41104 5.77295 2.52304 5.71005 3.87007C4.51917 4.22559 3.67058 5.3275 3.65528 6.5913C3.05445 6.77164 2.53621 7.05606 2.11196 7.51432C1.45997 8.21857 1.25792 9.08649 1.25023 10.1003C1.24283 11.075 1.41651 12.3067 1.63219 13.8363L2.07118 16.9499C2.23979 18.146 2.37676 19.1176 2.58989 19.879C2.81286 20.6756 3.14152 21.331 3.75003 21.8349C4.35372 22.3347 5.06993 22.5502 5.91647 22.6518C6.73501 22.75 7.76474 22.75 9.04682 22.75H14.9531C16.2352 22.75 17.265 22.75 18.0835 22.6518C18.9301 22.5502 19.6463 22.3347 20.25 21.8349C20.8585 21.331 21.1871 20.6756 21.4101 19.879C21.6232 19.1176 21.7602 18.146 21.9288 16.9499L22.3678 13.8363C22.5835 12.3067 22.7572 11.075 22.7498 10.1003C22.7421 9.08649 22.54 8.21857 21.888 7.51432C21.4637 7.05595 20.9453 6.77151 20.3443 6.59118C20.3289 5.3275 19.4805 4.22571 18.2897 3.87013C18.2268 2.52307 17.1903 1.41104 15.8362 1.26571C15.6888 1.2499 15.5203 1.24995 15.3004 1.25001H8.69935ZM18.8105 6.32781C18.6734 5.72018 18.1306 5.25001 17.4617 5.25001H6.53787C5.86896 5.25001 5.32618 5.72019 5.18902 6.32785C6.11481 6.24999 7.24973 6.25 8.61594 6.25001H15.384C16.75 6.25 17.8848 6.24999 18.8105 6.32781ZM16.7677 3.75001C16.6611 3.22633 16.2263 2.8162 15.6761 2.75715C15.6198 2.75111 15.5396 2.75001 15.2588 2.75001H8.74099C8.46013 2.75001 8.37993 2.75111 8.32365 2.75715C7.77344 2.8162 7.33862 3.22633 7.2321 3.75001H16.7677ZM3.21267 8.53336C3.51557 8.20618 3.97106 7.98917 4.85612 7.87145C5.75726 7.75159 6.96357 7.75001 8.67239 7.75001H15.3276C17.0364 7.75001 18.2427 7.75159 19.1439 7.87145C20.0289 7.98917 20.4844 8.20618 20.7873 8.53336C21.0832 8.85293 21.2436 9.28782 21.2498 10.1117C21.2563 10.9618 21.1002 12.0828 20.8738 13.6883L20.4509 16.6883C20.2731 17.9491 20.1486 18.821 19.9656 19.4747C19.7894 20.1042 19.582 20.4405 19.2934 20.6795C18.9999 20.9225 18.6058 21.0784 17.9048 21.1625C17.1861 21.2488 16.2465 21.25 14.9046 21.25H9.09536C7.75347 21.25 6.81393 21.2488 6.09519 21.1625C5.39417 21.0784 5.00014 20.9225 4.70664 20.6795C4.41795 20.4405 4.21058 20.1042 4.03437 19.4747C3.8514 18.821 3.7269 17.9491 3.54913 16.6883L3.12616 13.6883C2.89981 12.0828 2.74373 10.9618 2.75018 10.1117C2.75644 9.28782 2.91681 8.85293 3.21267 8.53336Z\\\"\\u003e\\u003c/path\\u003e\\n\\t\\u003c/svg\\u003e\\n}\\n```\",\n      \"title\": \"Menu with icons and a submenu\"\n    }\n  ],\n  \"modal\": [\n    {\n      \"name\": \"BasicModal\",\n      \"code\": \"```go\\ntempl BasicModal() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center py-8\\\"\\u003e\\n\\t\\t@components.Modal(components.ModalProps{ID: \\\"my_modal\\\", Label: \\\"Click me\\\"}) {\\n\\t\\t\\t\\u003ch3 class=\\\"text-3xl\\\"\\u003eModal title\\u003c/h3\\u003e\\n\\t\\t\\t\\u003cp\\u003eModal content goes here\\u003c/p\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Basic modal\"\n    },\n    {\n      \"name\": \"MultipleModals\",\n      \"code\": \"```go\\ntempl MultipleModals() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center py-8\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"grid grid-cols-3 gap-4\\\"\\u003e\\n\\t\\t\\tfor i := range 3 {\\n\\t\\t\\t\\t@components.Modal(components.ModalProps{ID: fmt.Sprintf(\\\"my_modal_%d\\\", i), Label: \\\"Click me\\\"}) {\\n\\t\\t\\t\\t\\t\\u003ch3 class=\\\"text-3xl\\\"\\u003eModal title { fmt.Sprintf(\\\"%d\\\", i) }\\u003c/h3\\u003e\\n\\t\\t\\t\\t\\t\\u003cp\\u003eModal content { fmt.Sprintf(\\\"%d\\\", i) }\\u003c/p\\u003e\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Multiple modals\"\n    },\n    {\n      \"name\": \"ModalWithAction\",\n      \"code\": \"```go\\ntempl ModalWithAction() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center py-8\\\"\\u003e\\n\\t\\t@components.Modal(components.ModalProps{ID: \\\"my_modal_actions\\\", Label: \\\"Click me\\\"}) {\\n\\t\\t\\t\\u003ch3 class=\\\"text-3xl\\\"\\u003eModal title\\u003c/h3\\u003e\\n\\t\\t\\t\\u003cp\\u003eModal content goes here\\u003c/p\\u003e\\n\\t\\t\\t\\u003cdiv class=\\\"modal-action\\\"\\u003e\\n\\t\\t\\t\\t\\u003cbutton class=\\\"btn\\\" onclick=\\\"my_modal_actions.close()\\\"\\u003eClose\\u003c/button\\u003e\\n\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Modal with action button\"\n    },\n    {\n      \"name\": \"ModalConfirmDelete\",\n      \"code\": \"```go\\ntempl ModalConfirmDelete() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center\\\"\\u003e\\n\\t\\t\\u003cdiv class=\\\"grid grid-cols-3 gap-4\\\"\\u003e\\n\\t\\t\\tfor i := range 6 {\\n\\t\\t\\t\\t\\u003cdiv name=\\\"modal-confirm-example\\\"\\u003e\\n\\t\\t\\t\\t\\t@components.Modal(\\n\\t\\t\\t\\t\\t\\tcomponents.ModalProps{\\n\\t\\t\\t\\t\\t\\t\\tID:    fmt.Sprintf(\\\"modal_confirm_%d\\\", i),\\n\\t\\t\\t\\t\\t\\t\\tLabel: modalConfirmDeleteButton(i, templ.Attributes{\\\"onclick\\\": fmt.Sprintf(\\\"modal_confirm_%d.showModal()\\\", i)}),\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t) {\\n\\t\\t\\t\\t\\t\\t\\u003cdiv class=\\\"flex flex-col gap-8\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cdiv class=\\\"grid grid-cols-9 gap-6\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003cdiv class=\\\"col-span-2 flex justify-center items-center\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\u003csvg\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tclass=\\\"col-span-1 h-10 w-10\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tviewBox=\\\"0 0 24 24\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tfill=\\\"none\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\txmlns=\\\"http://www.w3.org/2000/svg\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\u003e\\u003cpath class=\\\"fill-error\\\" fill-rule=\\\"evenodd\\\" clip-rule=\\\"evenodd\\\" d=\\\"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm-1.5-5.009c0-.867.659-1.491 1.491-1.491.85 0 1.509.624 1.509 1.491 0 .867-.659 1.509-1.509 1.509-.832 0-1.491-.642-1.491-1.509zM11.172 6a.5.5 0 0 0-.499.522l.306 7a.5.5 0 0 0 .5.478h1.043a.5.5 0 0 0 .5-.478l.305-7a.5.5 0 0 0-.5-.522h-1.655z\\\"\\u003e\\u003c/path\\u003e\\u003c/svg\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003cdiv class=\\\"flex justify-center items-center col-span-7\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\u003cp\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tAre you sure you want to delete { fmt.Sprintf(\\\"%d\\\", i) }?\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\u003c/p\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cdiv class=\\\"flex justify-between items-center\\\"\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003cbutton\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tid=\\\"modal-confirm-example-delete-button\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tclass=\\\"btn btn-error\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\thx-delete={ fmt.Sprintf(\\\"/modal-confirm?value=%d\\\", i) }\\n\\t\\t\\t\\t\\t\\t\\t\\t\\thx-target=\\\"closest div[name=modal-confirm-example]\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\thx-swap=\\\"outerHTML\\\"\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tDelete\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003cbutton class=\\\"btn\\\" { templ.Attributes{\\\"onclick\\\": fmt.Sprintf(\\\"modal_confirm_%d.close()\\\", i)}... }\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tCancel\\n\\t\\t\\t\\t\\t\\t\\t\\t\\u003c/button\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003cscript\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\t((modal) =\\u003e {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\tdocument.addEventListener(\\\"htmx:afterRequest\\\", (evt) =\\u003e {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tif (evt.detail.elt.id === \\\"modal-confirm-example-delete-button\\\" \\u0026\\u0026 evt.detail.successful) {\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\tmodal.close()\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t\\t\\t\\t\\t})\\n\\t\\t\\t\\t\\t\\t\\t\\t})(document.currentScript.closest(\\\"dialog.modal\\\"))\\n\\t\\t\\t\\t\\t\\t\\t\\u003c/script\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003c/div\\u003e\\n\\t\\t\\t}\\n\\t\\t\\u003c/div\\u003e\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl modalConfirmDeleteButton(i int, attrs templ.Attributes) {\\n\\t\\u003cbutton { attrs... } class=\\\"btn\\\"\\u003e\\n\\t\\tClick to delete { fmt.Sprintf(\\\"%d\\\", i) }\\n\\t\\u003c/button\\u003e\\n}\\n```\",\n      \"handler\": \"```go\\n// endpoint to log deleted 'element' and return an empty string\\n// to replace the element, i.e. remove it from the DOM\\nfunc DeleteModalExample(c echo.Context) error {\\n\\tvalue := c.QueryParam(\\\"value\\\")\\n\\tlog.Println(\\\"deleting modal\\\", value)\\n\\treturn c.String(http.StatusOK, \\\"\\\")\\n}\\n\\n```\",\n      \"title\": \"Modal to confirm delete action\"\n    }\n  ],\n  \"pagination\": [\n    {\n      \"name\": \"BasicPaginationExample\",\n      \"code\": \"```go\\ntempl BasicPaginationExample() {\\n\\t@BasicPagination(\\n\\t\\t\\\"example-pagination\\\",\\n\\t\\tcomponents.PaginationProps{\\n\\t\\t\\tURL:      \\\"/pagination-pages\\\",\\n\\t\\t\\tPage:     1,\\n\\t\\t\\tLow:      1,\\n\\t\\t\\tHigh:     7,\\n\\t\\t\\tMaxPages: 20,\\n\\t\\t},\\n\\t\\t[][]string{\\n\\t\\t\\t{\\\"Key0\\\", \\\"Value0\\\"},\\n\\t\\t\\t{\\\"Key1\\\", \\\"Value1\\\"},\\n\\t\\t\\t{\\\"Key2\\\", \\\"Value2\\\"},\\n\\t\\t\\t{\\\"Key3\\\", \\\"Value3\\\"},\\n\\t\\t\\t{\\\"Key4\\\", \\\"Value4\\\"},\\n\\t\\t\\t{\\\"Key5\\\", \\\"Value5\\\"},\\n\\t\\t\\t{\\\"Key6\\\", \\\"Value6\\\"},\\n\\t\\t\\t{\\\"Key7\\\", \\\"Value7\\\"},\\n\\t\\t\\t{\\\"Key8\\\", \\\"Value8\\\"},\\n\\t\\t\\t{\\\"Key9\\\", \\\"Value9\\\"},\\n\\t\\t},\\n\\t)\\n}\\n\\ntempl BasicPagination(id string, p components.PaginationProps, data [][]string) {\\n\\t@components.Pagination(\\\"example-pagination\\\", p) {\\n\\t\\t\\u003cdiv class=\\\"overflow-x-auto\\\"\\u003e\\n\\t\\t\\t\\u003ctable class=\\\"table\\\"\\u003e\\n\\t\\t\\t\\t\\u003cthead\\u003e\\n\\t\\t\\t\\t\\t\\u003ctr\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003cth\\u003eKey\\u003c/th\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003cth\\u003eValue\\u003c/th\\u003e\\n\\t\\t\\t\\t\\t\\u003c/tr\\u003e\\n\\t\\t\\t\\t\\u003c/thead\\u003e\\n\\t\\t\\t\\t\\u003ctbody\\u003e\\n\\t\\t\\t\\t\\tfor _, d := range data {\\n\\t\\t\\t\\t\\t\\t\\u003ctr\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003ctd\\u003e{ d[0] }\\u003c/td\\u003e\\n\\t\\t\\t\\t\\t\\t\\t\\u003ctd\\u003e{ d[1] }\\u003c/td\\u003e\\n\\t\\t\\t\\t\\t\\t\\u003c/tr\\u003e\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\u003c/tbody\\u003e\\n\\t\\t\\t\\u003c/table\\u003e\\n\\t\\t\\u003c/div\\u003e\\n\\t}\\n}\\n```\",\n      \"handler\": \"```go\\nconst (\\n\\tItemsPerPage = 10\\n\\tPagesPerSide = 3\\n)\\n\\nfunc GetPaginationExamplePage(c echo.Context) error {\\n\\tpageStr := c.QueryParam(\\\"page\\\")\\n\\tpage, err := strconv.Atoi(pageStr)\\n\\tif err != nil {\\n\\t\\treturn newErrorToast(\\n\\t\\t\\thttp.StatusUnprocessableEntity,\\n\\t\\t\\tfmt.Sprintf(\\\"invalid page '%s'\\\", pageStr),\\n\\t\\t)\\n\\t}\\n\\n\\t// generate dummy data for the page\\n\\tdata := make([][]string, 0, 200)\\n\\tfor i := range 200 {\\n\\t\\tdata = append(data, []string{fmt.Sprintf(\\\"Key%d\\\", i), fmt.Sprintf(\\\"Value%d\\\", i)})\\n\\t}\\n\\tout := data[(page-1)*ItemsPerPage : (page-1)*ItemsPerPage+ItemsPerPage]\\n\\n\\tmaxPages := int(math.Ceil(200 / ItemsPerPage))\\n\\tlow, high := getPaginationLowAndHigh(page, maxPages, PagesPerSide)\\n\\n\\tcom := examples.BasicPagination(\\n\\t\\t\\\"pagination-example-1\\\",\\n\\t\\tcomponents.PaginationProps{\\n\\t\\t\\tURL:      c.Request().URL.Path,\\n\\t\\t\\tPage:     page,\\n\\t\\t\\tLow:      low,\\n\\t\\t\\tHigh:     high,\\n\\t\\t\\tMaxPages: maxPages,\\n\\t\\t},\\n\\t\\tout)\\n\\n\\treturn render(c, http.StatusOK, com)\\n}\\n\\nfunc getPaginationLowAndHigh(page, maxPages, pagePerSide int) (int, int) {\\n\\tlow := max(0, page-pagePerSide-1)\\n\\thigh := min(maxPages-1, page+pagePerSide-1)\\n\\n\\t// if there are less than 'pagePerSide' pages to the left\\n\\t// of the current page, we add more pages to the high end of the\\n\\t// pagination element by adding to 'high'\\n\\tadd := pagePerSide - page\\n\\tif add \\u003e= 0 {\\n\\t\\thigh += add + 1\\n\\t}\\n\\n\\t// if there are less than 'pagePerSide' pages to the right\\n\\t// of the current page, we add more pages to the low end of the\\n\\t// pagination element, by subtracting from 'low'\\n\\tdistanceFromMaxPages := maxPages - page\\n\\tif distanceFromMaxPages \\u003c pagePerSide {\\n\\t\\tlow -= (pagePerSide - distanceFromMaxPages)\\n\\t}\\n\\treturn low, high\\n}\\n\\n```\"\n    }\n  ],\n  \"pricing\": [\n    {\n      \"name\": \"PricingExample\",\n      \"code\": \"```go\\ntempl PricingExample() {\\n\\t@components.Pricing(\\n\\t\\tcomponents.PricingProps{\\n\\t\\t\\tChecked: true,\\n\\t\\t\\tPrices: []components.PriceProps{\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tTitle:            \\\"Free\\\",\\n\\t\\t\\t\\t\\tDescription:      \\\"My free plan\\\",\\n\\t\\t\\t\\t\\tPriceMonthly:     \\\"$ 0\\\",\\n\\t\\t\\t\\t\\tPerMonthly:       \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPriceAnnually:    \\\"$ 0\\\",\\n\\t\\t\\t\\t\\tPerAnnually:      \\\"/ month\\\",\\n\\t\\t\\t\\t\\tIncludedFeatures: []string{\\\"Feature 1\\\", \\\"Feature 2\\\", \\\"Feature 3\\\"},\\n\\t\\t\\t\\t\\tExcludedFeatures: []string{\\\"Feature 4\\\", \\\"Feature 5\\\"},\\n\\t\\t\\t\\t\\tCallToAction: components.PriceButtonProps{\\n\\t\\t\\t\\t\\t\\tLabel: \\\"Start free\\\",\\n\\t\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\t\\\"class\\\": \\\"btn btn-outline mt-8\\\",\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tTitle:            \\\"Starter\\\",\\n\\t\\t\\t\\t\\tDescription:      \\\"Starter plan\\\",\\n\\t\\t\\t\\t\\tPriceMonthly:     \\\"$ 12\\\",\\n\\t\\t\\t\\t\\tPerMonthly:       \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPriceAnnually:    \\\"$ 10\\\",\\n\\t\\t\\t\\t\\tPerAnnually:      \\\"/ month\\\",\\n\\t\\t\\t\\t\\tIncludedFeatures: []string{\\\"Feature 1\\\", \\\"Feature 2\\\", \\\"Feature 3\\\"},\\n\\t\\t\\t\\t\\tExcludedFeatures: []string{\\\"Feature 4\\\", \\\"Feature 5\\\"},\\n\\t\\t\\t\\t\\tCallToAction: components.PriceButtonProps{\\n\\t\\t\\t\\t\\t\\tLabel: \\\"Get started\\\",\\n\\t\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\t\\\"class\\\": \\\"btn btn-primary mt-8\\\",\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tTitle:            \\\"Professional\\\",\\n\\t\\t\\t\\t\\tDescription:      \\\"Professional plan\\\",\\n\\t\\t\\t\\t\\tPriceMonthly:     \\\"$ 20\\\",\\n\\t\\t\\t\\t\\tPerMonthly:       \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPriceAnnually:    \\\"$ 16\\\",\\n\\t\\t\\t\\t\\tPerAnnually:      \\\"/ month\\\",\\n\\t\\t\\t\\t\\tIncludedFeatures: []string{\\\"Feature 1\\\", \\\"Feature 2\\\", \\\"Feature 3\\\"},\\n\\t\\t\\t\\t\\tExcludedFeatures: []string{\\\"Feature 4\\\", \\\"Feature 5\\\"},\\n\\t\\t\\t\\t\\tCallToAction: components.PriceButtonProps{\\n\\t\\t\\t\\t\\t\\tLabel: \\\"Get started\\\",\\n\\t\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\t\\\"class\\\": \\\"btn btn-primary mt-8\\\",\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t},\\n\\t)\\n}\\n\\n```\",\n      \"title\": \"Basic pricing section\"\n    },\n    {\n      \"name\": \"PricingWithPromotionExample\",\n      \"code\": \"```go\\ntempl PricingWithPromotionExample() {\\n\\t@components.Pricing(\\n\\t\\tcomponents.PricingProps{\\n\\t\\t\\tChecked: true,\\n\\t\\t\\tPrices: []components.PriceProps{\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tTitle:            \\\"Free\\\",\\n\\t\\t\\t\\t\\tDescription:      \\\"My free plan\\\",\\n\\t\\t\\t\\t\\tPriceMonthly:     \\\"$ 0\\\",\\n\\t\\t\\t\\t\\tPerMonthly:       \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPriceAnnually:    \\\"$ 0\\\",\\n\\t\\t\\t\\t\\tPerAnnually:      \\\"/ month\\\",\\n\\t\\t\\t\\t\\tIncludedFeatures: []string{\\\"Feature 1\\\", \\\"Feature 2\\\", \\\"Feature 3\\\"},\\n\\t\\t\\t\\t\\tExcludedFeatures: []string{\\\"Feature 4\\\", \\\"Feature 5\\\"},\\n\\t\\t\\t\\t\\tCallToAction: components.PriceButtonProps{\\n\\t\\t\\t\\t\\t\\tLabel: \\\"Start free\\\",\\n\\t\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\t\\\"class\\\": \\\"btn btn-outline mt-8\\\",\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tTitle:            \\\"Starter\\\",\\n\\t\\t\\t\\t\\tDescription:      \\\"Starter plan\\\",\\n\\t\\t\\t\\t\\tPriceMonthly:     \\\"$ 12\\\",\\n\\t\\t\\t\\t\\tPerMonthly:       \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPriceAnnually:    \\\"$ 10\\\",\\n\\t\\t\\t\\t\\tPerAnnually:      \\\"/ month\\\",\\n\\t\\t\\t\\t\\tIncludedFeatures: []string{\\\"Feature 1\\\", \\\"Feature 2\\\", \\\"Feature 3\\\"},\\n\\t\\t\\t\\t\\tExcludedFeatures: []string{\\\"Feature 4\\\", \\\"Feature 5\\\"},\\n\\t\\t\\t\\t\\tCallToAction: components.PriceButtonProps{\\n\\t\\t\\t\\t\\t\\tLabel: \\\"Get started\\\",\\n\\t\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\t\\\"class\\\": \\\"btn btn-primary mt-8\\\",\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tTitle:            \\\"Professional\\\",\\n\\t\\t\\t\\t\\tDescription:      \\\"Professional plan\\\",\\n\\t\\t\\t\\t\\tPriceMonthly:     \\\"$ 20\\\",\\n\\t\\t\\t\\t\\tPerMonthly:       \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPriceAnnually:    \\\"$ 16\\\",\\n\\t\\t\\t\\t\\tPerAnnually:      \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPromotion:        \\\"Popular\\\",\\n\\t\\t\\t\\t\\tIncludedFeatures: []string{\\\"Feature 1\\\", \\\"Feature 2\\\", \\\"Feature 3\\\"},\\n\\t\\t\\t\\t\\tExcludedFeatures: []string{\\\"Feature 4\\\", \\\"Feature 5\\\"},\\n\\t\\t\\t\\t\\tCallToAction: components.PriceButtonProps{\\n\\t\\t\\t\\t\\t\\tLabel: \\\"Get started\\\",\\n\\t\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\t\\\"class\\\": \\\"btn btn-primary mt-8\\\",\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tTitle:            \\\"Ultimate\\\",\\n\\t\\t\\t\\t\\tDescription:      \\\"Ultimate plan\\\",\\n\\t\\t\\t\\t\\tPriceMonthly:     \\\"$ 30\\\",\\n\\t\\t\\t\\t\\tPerMonthly:       \\\"/ month\\\",\\n\\t\\t\\t\\t\\tPriceAnnually:    \\\"$ 25\\\",\\n\\t\\t\\t\\t\\tPerAnnually:      \\\"/ month\\\",\\n\\t\\t\\t\\t\\tIncludedFeatures: []string{\\\"Feature 1\\\", \\\"Feature 2\\\", \\\"Feature 3\\\", \\\"Feature 4\\\", \\\"Feature 5\\\"},\\n\\t\\t\\t\\t\\tCallToAction: components.PriceButtonProps{\\n\\t\\t\\t\\t\\t\\tLabel: \\\"Get started\\\",\\n\\t\\t\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\t\\t\\\"class\\\": \\\"btn btn-primary mt-8\\\",\\n\\t\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t\\t},\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t},\\n\\t)\\n}\\n```\",\n      \"title\": \"Pricing section with promotion\"\n    }\n  ],\n  \"radio\": [\n    {\n      \"name\": \"DefaultRadio\",\n      \"code\": \"```go\\ntempl DefaultRadio() {\\n\\t\\u003cdiv class=\\\"max-w-xs mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Radio(\\n\\t\\t\\tcomponents.RadioProps{\\n\\t\\t\\t\\tName: \\\"my-radio-group1\\\",\\n\\t\\t\\t\\tValues: map[string]string{\\n\\t\\t\\t\\t\\t\\\"Apples\\\":  \\\"apples\\\",\\n\\t\\t\\t\\t\\t\\\"Oranges\\\": \\\"oranges\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"xs\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t\\u003cdiv class=\\\"divider\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t@components.Radio(\\n\\t\\t\\tcomponents.RadioProps{\\n\\t\\t\\t\\tName: \\\"my-radio-group1\\\",\\n\\t\\t\\t\\tValues: map[string]string{\\n\\t\\t\\t\\t\\t\\\"Apples\\\":  \\\"apples\\\",\\n\\t\\t\\t\\t\\t\\\"Oranges\\\": \\\"oranges\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"sm\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t\\u003cdiv class=\\\"divider\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t@components.Radio(\\n\\t\\t\\tcomponents.RadioProps{\\n\\t\\t\\t\\tName: \\\"my-radio-group1\\\",\\n\\t\\t\\t\\tValues: map[string]string{\\n\\t\\t\\t\\t\\t\\\"Apples\\\":  \\\"apples\\\",\\n\\t\\t\\t\\t\\t\\\"Oranges\\\": \\\"oranges\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t\\u003cdiv class=\\\"divider\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t@components.Radio(\\n\\t\\t\\tcomponents.RadioProps{\\n\\t\\t\\t\\tName: \\\"my-radio-group1\\\",\\n\\t\\t\\t\\tValues: map[string]string{\\n\\t\\t\\t\\t\\t\\\"Apples\\\":  \\\"apples\\\",\\n\\t\\t\\t\\t\\t\\\"Oranges\\\": \\\"oranges\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"lg\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t\\u003cdiv class=\\\"divider\\\"\\u003e\\u003c/div\\u003e\\n\\t\\t@components.Radio(\\n\\t\\t\\tcomponents.RadioProps{\\n\\t\\t\\t\\tName: \\\"my-radio-group1\\\",\\n\\t\\t\\t\\tValues: map[string]string{\\n\\t\\t\\t\\t\\t\\\"Apples\\\":  \\\"apples\\\",\\n\\t\\t\\t\\t\\t\\\"Oranges\\\": \\\"oranges\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"xl\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Different size radio groups\"\n    },\n    {\n      \"name\": \"PrimaryRadio\",\n      \"code\": \"```go\\ntempl PrimaryRadio() {\\n\\t\\u003cdiv class=\\\"max-w-xs mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Radio(\\n\\t\\t\\tcomponents.RadioProps{\\n\\t\\t\\t\\tName: \\\"my-radio-group2\\\",\\n\\t\\t\\t\\tValues: map[string]string{\\n\\t\\t\\t\\t\\t\\\"Apples\\\":  \\\"apples\\\",\\n\\t\\t\\t\\t\\t\\\"Oranges\\\": \\\"oranges\\\",\\n\\t\\t\\t\\t\\t\\\"And something truly special here to see how this works with a longer key\\\": \\\"blaaaaa\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tClass: \\\"radio-primary\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Primary radio group\"\n    }\n  ],\n  \"range\": [\n    {\n      \"name\": \"BasicRange\",\n      \"code\": \"```go\\ntempl BasicRange() {\\n\\t\\u003cdiv class=\\\"max-w-sm mx-auto pt-4 space-y-2\\\"\\u003e\\n\\t\\t@components.Range(\\n\\t\\t\\tcomponents.RangeProps{\\n\\t\\t\\t\\tName:  \\\"my-range\\\",\\n\\t\\t\\t\\tValue: 25,\\n\\t\\t\\t\\tMin:   0,\\n\\t\\t\\t\\tMax:   100,\\n\\t\\t\\t\\tStep:  5,\\n\\t\\t\\t\\tSize:  \\\"xs\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Range(\\n\\t\\t\\tcomponents.RangeProps{\\n\\t\\t\\t\\tName:  \\\"my-range\\\",\\n\\t\\t\\t\\tValue: 25,\\n\\t\\t\\t\\tMin:   0,\\n\\t\\t\\t\\tMax:   100,\\n\\t\\t\\t\\tStep:  5,\\n\\t\\t\\t\\tSize:  \\\"sm\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Range(\\n\\t\\t\\tcomponents.RangeProps{\\n\\t\\t\\t\\tName:  \\\"my-range\\\",\\n\\t\\t\\t\\tValue: 25,\\n\\t\\t\\t\\tMin:   0,\\n\\t\\t\\t\\tMax:   100,\\n\\t\\t\\t\\tStep:  5,\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Range(\\n\\t\\t\\tcomponents.RangeProps{\\n\\t\\t\\t\\tName:  \\\"my-range\\\",\\n\\t\\t\\t\\tValue: 25,\\n\\t\\t\\t\\tMin:   0,\\n\\t\\t\\t\\tMax:   100,\\n\\t\\t\\t\\tStep:  5,\\n\\t\\t\\t\\tSize:  \\\"lg\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Range(\\n\\t\\t\\tcomponents.RangeProps{\\n\\t\\t\\t\\tName:  \\\"my-range\\\",\\n\\t\\t\\t\\tValue: 25,\\n\\t\\t\\t\\tMin:   0,\\n\\t\\t\\t\\tMax:   100,\\n\\t\\t\\t\\tStep:  5,\\n\\t\\t\\t\\tSize:  \\\"xl\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Range component using alpine.js\"\n    },\n    {\n      \"name\": \"DatastarRange\",\n      \"code\": \"```go\\ntempl DatastarRange() {\\n\\t\\u003cdiv class=\\\"max-w-sm mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.DatastarRange(\\n\\t\\t\\tcomponents.RangeProps{\\n\\t\\t\\t\\tName:  \\\"my-range\\\",\\n\\t\\t\\t\\tValue: 25,\\n\\t\\t\\t\\tMin:   0,\\n\\t\\t\\t\\tMax:   100,\\n\\t\\t\\t\\tStep:  5,\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Range component using datastar.js\"\n    }\n  ],\n  \"rating\": [\n    {\n      \"name\": \"RatingFromOneToFive\",\n      \"code\": \"```go\\ntempl RatingFromOneToFive() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Rating(\\n\\t\\t\\tcomponents.RatingProps{\\n\\t\\t\\t\\tName: \\\"my-rating\\\",\\n\\t\\t\\t\\tMin:  1,\\n\\t\\t\\t\\tMax:  5,\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Rating from 1 to 5\"\n    },\n    {\n      \"name\": \"RatingFromZeroToFive\",\n      \"code\": \"```go\\ntempl RatingFromZeroToFive() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Rating(\\n\\t\\t\\tcomponents.RatingProps{\\n\\t\\t\\t\\tName: \\\"my-rating2\\\",\\n\\t\\t\\t\\tMin:  0,\\n\\t\\t\\t\\tMax:  5,\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Rating from 0 to 5\"\n    }\n  ],\n  \"select\": [\n    {\n      \"name\": \"DifferentSizeSelects\",\n      \"code\": \"```go\\ntempl DifferentSizeSelects() {\\n\\t\\u003cdiv class=\\\"max-w-xs mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Select(\\n\\t\\t\\tcomponents.SelectProps{\\n\\t\\t\\t\\tLabel: \\\"Make a choice\\\",\\n\\t\\t\\t\\tName:  \\\"my-select\\\",\\n\\t\\t\\t\\tOptions: []components.SelectOption{\\n\\t\\t\\t\\t\\t{Label: \\\"Which one?\\\", Selected: true, Disabled: true},\\n\\t\\t\\t\\t\\t{Label: \\\"Apples\\\", Value: \\\"apples\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Oranges\\\", Value: \\\"oranges\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"xs\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Select(\\n\\t\\t\\tcomponents.SelectProps{\\n\\t\\t\\t\\tLabel: \\\"Make a choice\\\",\\n\\t\\t\\t\\tName:  \\\"my-select\\\",\\n\\t\\t\\t\\tOptions: []components.SelectOption{\\n\\t\\t\\t\\t\\t{Label: \\\"Which one?\\\", Selected: true, Disabled: true},\\n\\t\\t\\t\\t\\t{Label: \\\"Apples\\\", Value: \\\"apples\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Oranges\\\", Value: \\\"oranges\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"sm\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Select(\\n\\t\\t\\tcomponents.SelectProps{\\n\\t\\t\\t\\tLabel: \\\"Make a choice\\\",\\n\\t\\t\\t\\tName:  \\\"my-select\\\",\\n\\t\\t\\t\\tOptions: []components.SelectOption{\\n\\t\\t\\t\\t\\t{Label: \\\"Which one?\\\", Selected: true, Disabled: true},\\n\\t\\t\\t\\t\\t{Label: \\\"Apples\\\", Value: \\\"apples\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Oranges\\\", Value: \\\"oranges\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Select(\\n\\t\\t\\tcomponents.SelectProps{\\n\\t\\t\\t\\tLabel: \\\"Make a choice\\\",\\n\\t\\t\\t\\tName:  \\\"my-select\\\",\\n\\t\\t\\t\\tOptions: []components.SelectOption{\\n\\t\\t\\t\\t\\t{Label: \\\"Which one?\\\", Selected: true, Disabled: true},\\n\\t\\t\\t\\t\\t{Label: \\\"Apples\\\", Value: \\\"apples\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Oranges\\\", Value: \\\"oranges\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"lg\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Select(\\n\\t\\t\\tcomponents.SelectProps{\\n\\t\\t\\t\\tLabel: \\\"Make a choice\\\",\\n\\t\\t\\t\\tName:  \\\"my-select\\\",\\n\\t\\t\\t\\tOptions: []components.SelectOption{\\n\\t\\t\\t\\t\\t{Label: \\\"Which one?\\\", Selected: true, Disabled: true},\\n\\t\\t\\t\\t\\t{Label: \\\"Apples\\\", Value: \\\"apples\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Oranges\\\", Value: \\\"oranges\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tSize: \\\"xl\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Different size selects\"\n    },\n    {\n      \"name\": \"CascadingSelect\",\n      \"code\": \"```go\\ntempl CascadingSelect() {\\n\\t\\u003cdiv class=\\\"max-w-xs mx-auto py-8\\\"\\u003e\\n\\t\\t@components.Select(\\n\\t\\t\\tcomponents.SelectProps{\\n\\t\\t\\t\\tLabel: \\\"Make\\\",\\n\\t\\t\\t\\tName:  \\\"make\\\",\\n\\t\\t\\t\\tOptions: []components.SelectOption{\\n\\t\\t\\t\\t\\t{Label: \\\"Audi\\\", Value: \\\"audi\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"BMW\\\", Value: \\\"bmw\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"Toyota\\\", Value: \\\"toyota\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\\"hx-get\\\":    \\\"/models\\\",\\n\\t\\t\\t\\t\\t\\\"hx-target\\\": \\\"#models\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Select(\\n\\t\\t\\tcomponents.SelectProps{\\n\\t\\t\\t\\tLabel: \\\"Model\\\",\\n\\t\\t\\t\\tName:  \\\"model\\\",\\n\\t\\t\\t\\tOptions: []components.SelectOption{\\n\\t\\t\\t\\t\\t{Label: \\\"A1\\\", Value: \\\"a1\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"A4\\\", Value: \\\"a4\\\"},\\n\\t\\t\\t\\t\\t{Label: \\\"A6\\\", Value: \\\"a6\\\"},\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\tAttrs: templ.Attributes{\\n\\t\\t\\t\\t\\t\\\"id\\\": \\\"models\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"handler\": \"```go\\nvar modelOptions = map[string][]components.SelectOption{\\n\\t\\\"audi\\\": {\\n\\t\\t{Label: \\\"A1\\\", Value: \\\"a1\\\"},\\n\\t\\t{Label: \\\"A4\\\", Value: \\\"a4\\\"},\\n\\t\\t{Label: \\\"A6\\\", Value: \\\"a6\\\"},\\n\\t},\\n\\t\\\"bmw\\\": {\\n\\t\\t{Label: \\\"316i\\\", Value: \\\"316i\\\"},\\n\\t\\t{Label: \\\"320d\\\", Value: \\\"320d\\\"},\\n\\t},\\n\\t\\\"toyota\\\": {\\n\\t\\t{Label: \\\"Corolla\\\", Value: \\\"corolla\\\"},\\n\\t\\t{Label: \\\"Yaris\\\", Value: \\\"yaris\\\"},\\n\\t\\t{Label: \\\"RAV4\\\", Value: \\\"rav4\\\"},\\n\\t},\\n}\\n\\nfunc GetCascadingSelectExample(c echo.Context) error {\\n\\tmake := c.FormValue(\\\"make\\\")\\n\\n\\treturn render(c, http.StatusOK, components.SelectOptions(modelOptions[make]))\\n}\\n\\n```\",\n      \"title\": \"Cascading select\"\n    }\n  ],\n  \"skeleton\": [\n    {\n      \"name\": \"SkeletonExample\",\n      \"code\": \"```go\\ntempl SkeletonExample() {\\n\\t\\u003cdiv class=\\\"max-w-xs mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Skeleton()\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"stats\": [\n    {\n      \"name\": \"BasicStats\",\n      \"code\": \"```go\\ntempl BasicStats() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Stats() {\\n\\t\\t\\t@components.Stat(components.StatProps{\\n\\t\\t\\t\\tTitle:       \\\"Downloads\\\",\\n\\t\\t\\t\\tValue:       \\\"31k\\\",\\n\\t\\t\\t\\tDescription: \\\"Jan 1st - Feb 1st\\\",\\n\\t\\t\\t})\\n\\t\\t\\t@components.Stat(components.StatProps{\\n\\t\\t\\t\\tTitle:       \\\"New Users\\\",\\n\\t\\t\\t\\tValue:       \\\"4,200\\\",\\n\\t\\t\\t\\tDescription: \\\"↗︎ 400 (22%)\\\",\\n\\t\\t\\t})\\n\\t\\t\\t@components.Stat(components.StatProps{\\n\\t\\t\\t\\tTitle:       \\\"New Registers\\\",\\n\\t\\t\\t\\tValue:       \\\"1,200\\\",\\n\\t\\t\\t\\tDescription: \\\"↘︎ 90 (14%)\\\",\\n\\t\\t\\t})\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"status\": [\n    {\n      \"name\": \"StatusNotFound\",\n      \"code\": \"```go\\ntempl StatusNotFound() {\\n\\t@components.Status(components.StatusProps{\\n\\t\\tCode:              404,\\n\\t\\tTitle:             \\\"Not Found\\\",\\n\\t\\tDescription:       \\\"Looks like there's nothing here...\\\",\\n\\t\\tReturnButtonLabel: \\\"Go back\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"404 Not Found status\"\n    },\n    {\n      \"name\": \"StatusForbidden\",\n      \"code\": \"```go\\ntempl StatusForbidden() {\\n\\t@components.Status(components.StatusProps{\\n\\t\\tCode:              403,\\n\\t\\tTitle:             \\\"Forbidden\\\",\\n\\t\\tDescription:       \\\"Invalid permissions to view this page.\\\",\\n\\t\\tReturnButtonLabel: \\\"Go back\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"403 Forbidden status\"\n    },\n    {\n      \"name\": \"StatusUnauthorized\",\n      \"code\": \"```go\\ntempl StatusUnauthorized() {\\n\\t@components.Status(components.StatusProps{\\n\\t\\tCode:              401,\\n\\t\\tTitle:             \\\"Unauthorized\\\",\\n\\t\\tDescription:       \\\"This page is only available to authenticated users.\\\",\\n\\t\\tReturnButtonLabel: \\\"Go back\\\",\\n\\t})\\n}\\n\\n```\",\n      \"title\": \"401 Unauthorized status\"\n    },\n    {\n      \"name\": \"StatusInternalServerError\",\n      \"code\": \"```go\\ntempl StatusInternalServerError() {\\n\\t@components.Status(components.StatusProps{\\n\\t\\tCode:              500,\\n\\t\\tTitle:             \\\"Internal Server Error\\\",\\n\\t\\tDescription:       \\\"Something went terribly wrong...\\\",\\n\\t\\tReturnButtonLabel: \\\"Go back\\\",\\n\\t})\\n}\\n```\",\n      \"title\": \"500 Internal Server Error status\"\n    }\n  ],\n  \"steps\": [\n    {\n      \"name\": \"BasicSteps\",\n      \"code\": \"```go\\ntempl BasicSteps() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Steps() {\\n\\t\\t\\t@components.Step(components.StepProps{Label: \\\"Register\\\", Done: true})\\n\\t\\t\\t@components.Step(components.StepProps{Label: \\\"Choose plan\\\", Done: true})\\n\\t\\t\\t@components.Step(components.StepProps{Label: \\\"Purchase\\\"})\\n\\t\\t\\t@components.Step(components.StepProps{Label: \\\"Receive product\\\"})\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"swap\": [\n    {\n      \"name\": \"BasicSwap\",\n      \"code\": \"```go\\ntempl BasicSwap() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center h-20\\\"\\u003e\\n\\t\\t@components.Swap(\\n\\t\\t\\tcomponents.SwapProps{\\n\\t\\t\\t\\tOn:    SwapExampleOn(),\\n\\t\\t\\t\\tOff:   SwapExampleOff(),\\n\\t\\t\\t\\tClass: \\\"swap-flip\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\ntempl SwapExampleOn() {\\n\\t\\u003cspan class=\\\"font-bold text-success\\\"\\u003eON\\u003c/span\\u003e\\n}\\n\\ntempl SwapExampleOff() {\\n\\t\\u003cspan class=\\\"font-bold text-base-content/70\\\"\\u003eOFF\\u003c/span\\u003e\\n}\\n```\"\n    }\n  ],\n  \"table\": [\n    {\n      \"name\": \"BasicTable\",\n      \"code\": \"```go\\ntempl BasicTable() {\\n\\t@components.Table(\\n\\t\\t[]templ.Component{\\n\\t\\t\\tcomponents.Checkbox(\\n\\t\\t\\t\\tcomponents.CheckboxProps{\\n\\t\\t\\t\\t\\tName: \\\"all\\\",\\n\\t\\t\\t\\t},\\n\\t\\t\\t),\\n\\t\\t\\tcomponents.PlainText(\\\"Name\\\"),\\n\\t\\t\\tcomponents.PlainText(\\\"Email\\\"),\\n\\t\\t},\\n\\t\\t[]templ.Component{\\n\\t\\t\\tTableExampleRow(\\\"John Doe\\\", \\\"john.doe@example.com\\\"),\\n\\t\\t\\tTableExampleRow(\\\"Jane Doe\\\", \\\"Jane.doe@example.com\\\"),\\n\\t\\t\\tTableExampleRow(\\\"Jim Smith\\\", \\\"jim.smith@example.com\\\"),\\n\\t\\t\\tTableExampleRow(\\\"Julie Smith\\\", \\\"julie.smith@example.com\\\"),\\n\\t\\t},\\n\\t\\tnil,\\n\\t)\\n}\\n\\ntempl TableExampleRow(name, email string) {\\n\\t\\u003ctr\\u003e\\n\\t\\t\\u003ctd\\u003e\\n\\t\\t\\t@components.Checkbox(components.CheckboxProps{Name: email})\\n\\t\\t\\u003c/td\\u003e\\n\\t\\t\\u003ctd\\u003e\\n\\t\\t\\t@components.PlainText(name)\\n\\t\\t\\u003c/td\\u003e\\n\\t\\t\\u003ctd\\u003e\\n\\t\\t\\t@components.PlainText(email)\\n\\t\\t\\u003c/td\\u003e\\n\\t\\u003c/tr\\u003e\\n}\\n```\"\n    }\n  ],\n  \"tabs\": [\n    {\n      \"name\": \"BasicTabs\",\n      \"code\": \"```go\\ntempl BasicTabs() {\\n\\t@components.Tabs(\\n\\t\\tcomponents.TabsProps{\\n\\t\\t\\tName:         \\\"basic-tabs\\\",\\n\\t\\t\\tClass:        \\\"tabs-border\\\",\\n\\t\\t\\tContentClass: \\\"bg-base-100 py-8\\\",\\n\\t\\t\\tTabs: []components.TabProps{\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tLabel:   \\\"Home\\\",\\n\\t\\t\\t\\t\\tContent: homeTabContent(),\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tLabel:   \\\"Info\\\",\\n\\t\\t\\t\\t\\tContent: infoTabContent(),\\n\\t\\t\\t\\t},\\n\\t\\t\\t\\t{\\n\\t\\t\\t\\t\\tLabel:   \\\"Stats\\\",\\n\\t\\t\\t\\t\\tContent: statsTabContent(),\\n\\t\\t\\t\\t},\\n\\t\\t\\t},\\n\\t\\t})\\n}\\n\\ntempl homeTabContent() {\\n\\t\\u003cp\\u003eThis is the home tab\\u003c/p\\u003e\\n}\\n\\ntempl infoTabContent() {\\n\\t\\u003cp\\u003eThis is the info tab\\u003c/p\\u003e\\n}\\n\\ntempl statsTabContent() {\\n\\t\\u003cp\\u003eThis is the stats tab\\u003c/p\\u003e\\n}\\n```\"\n    }\n  ],\n  \"testimonial\": [\n    {\n      \"name\": \"TestimonialGridExample\",\n      \"code\": \"```go\\ntempl TestimonialGridExample() {\\n\\t@components.TestimonialGrid(\\n\\t\\t\\\"Read what our customers think\\\",\\n\\t\\tcomponents.TestimonialProps{\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 5,\\n\\t\\t\\t\\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \\nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \\nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \\nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas odio minus \\nnecessitatibus perspiciatis, aliquid repellat iste.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(\\n\\t\\t\\t\\t\\tcomponents.AvatarProps{\\n\\t\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\"},\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 4,\\n\\t\\t\\t\\tContent: `maiores quia dicta magni ex labore? Lorem ipsum dolor \\nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \\nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas odio minus \\nnecessitatibus perspiciatis, aliquid repellat iste.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 3,\\n\\t\\t\\t\\tContent: `Iure impedit, placeat sed provident enim fuga possimus \\nducimus est iusto inventore earum aliquid officia minus, maiores quia dicta magni \\nex labore? Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero maxime \\nquos laboriosam natus illum similique id nam, rerum, sunt veritatis dolorum \\naccusamus voluptas odio minus necessitatibus perspiciatis, aliquid repellat iste.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 5,\\n\\t\\t\\t\\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \\nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \\nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \\nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas odio minus \\nnecessitatibus perspiciatis, aliquid repellat iste.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:    \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating:  5,\\n\\t\\t\\t\\tContent: \\\"Lorem ipsum dolor sit amet consectetur adipisicing elit.\\\",\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 1,\\n\\t\\t\\t\\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \\nearum aliquid officia minus.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 2,\\n\\t\\t\\t\\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \\nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \\nsit amet consectetur adipisicing elit.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 5,\\n\\t\\t\\t\\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore\\nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \\nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \\nsimilique id nam, rerum, sunt veritatis.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 4,\\n\\t\\t\\t\\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \\nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \\nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \\nsimilique id nam, rerum.`,\\n\\t\\t\\t},\\n\\t\\t\\t{\\n\\t\\t\\t\\tAvatar: components.Avatar(components.AvatarProps{\\n\\t\\t\\t\\t\\tContainerClass: \\\"rounded h-20\\\",\\n\\t\\t\\t\\t\\tSource:         \\\"/static/images/avatar.jpg\\\",\\n\\t\\t\\t\\t}),\\n\\t\\t\\t\\tName:   \\\"Jane Doe\\\",\\n\\t\\t\\t\\tRating: 4,\\n\\t\\t\\t\\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \\nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \\nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \\nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \\nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas.`,\\n\\t\\t\\t},\\n\\t\\t},\\n\\t)\\n}\\n```\"\n    }\n  ],\n  \"text_rotate\": [\n    {\n      \"name\": \"TextRotateExample\",\n      \"code\": \"```go\\ntempl TextRotateExample() {\\n\\t@components.TextRotate(\\n\\t\\tcomponents.TextRotateProps{\\n\\t\\t\\tClass: \\\"text-5xl font-bold\\\",\\n\\t\\t\\tItems: []components.TextRotateItem{\\n\\t\\t\\t\\t{Text: \\\"ONE\\\", Class: \\\"text-primary\\\"},\\n\\t\\t\\t\\t{Text: \\\"TWO\\\", Class: \\\"text-accent\\\"},\\n\\t\\t\\t\\t{Text: \\\"THREE\\\", Class: \\\"text-secondary\\\"},\\n\\t\\t\\t},\\n\\t\\t},\\n\\t)\\n}\\n```\"\n    }\n  ],\n  \"textarea\": [\n    {\n      \"name\": \"BasicTextarea\",\n      \"code\": \"```go\\ntempl BasicTextarea() {\\n\\t\\u003cdiv class=\\\"pt-4\\\"\\u003e\\n\\t\\t@components.Textarea(\\n\\t\\t\\tcomponents.TextareaProps{\\n\\t\\t\\t\\tLabel: \\\"Description\\\",\\n\\t\\t\\t\\tName:  \\\"description\\\",\\n\\t\\t\\t\\tClass: \\\"textarea-bordered resize-none\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Basic textarea\"\n    },\n    {\n      \"name\": \"DifferentSizeTextareas\",\n      \"code\": \"```go\\ntempl DifferentSizeTextareas() {\\n\\t\\u003cdiv class=\\\"pt-4\\\"\\u003e\\n\\t\\t@components.Textarea(\\n\\t\\t\\tcomponents.TextareaProps{\\n\\t\\t\\t\\tLabel: \\\"Description\\\",\\n\\t\\t\\t\\tClass: \\\"textarea-bordered resize-none\\\",\\n\\t\\t\\t\\tValue: \\\"Extra small\\\",\\n\\t\\t\\t\\tSize:  \\\"xs\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Textarea(\\n\\t\\t\\tcomponents.TextareaProps{\\n\\t\\t\\t\\tLabel: \\\"Description\\\",\\n\\t\\t\\t\\tClass: \\\"textarea-bordered resize-none\\\",\\n\\t\\t\\t\\tValue: \\\"Small\\\",\\n\\t\\t\\t\\tSize:  \\\"sm\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Textarea(\\n\\t\\t\\tcomponents.TextareaProps{\\n\\t\\t\\t\\tLabel: \\\"Description\\\",\\n\\t\\t\\t\\tClass: \\\"textarea-bordered resize-none\\\",\\n\\t\\t\\t\\tValue: \\\"Medium\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Textarea(\\n\\t\\t\\tcomponents.TextareaProps{\\n\\t\\t\\t\\tLabel: \\\"Description\\\",\\n\\t\\t\\t\\tClass: \\\"textarea-bordered resize-none\\\",\\n\\t\\t\\t\\tValue: \\\"Large\\\",\\n\\t\\t\\t\\tSize:  \\\"lg\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Textarea(\\n\\t\\t\\tcomponents.TextareaProps{\\n\\t\\t\\t\\tLabel: \\\"Description\\\",\\n\\t\\t\\t\\tClass: \\\"textarea-bordered resize-none\\\",\\n\\t\\t\\t\\tValue: \\\"Extra Large\\\",\\n\\t\\t\\t\\tSize:  \\\"xl\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Different sizes\"\n    },\n    {\n      \"name\": \"BasicTextareaWithError\",\n      \"code\": \"```go\\ntempl BasicTextareaWithError() {\\n\\t\\u003cdiv class=\\\"pt-4\\\"\\u003e\\n\\t\\t@components.Textarea(\\n\\t\\t\\tcomponents.TextareaProps{\\n\\t\\t\\t\\tLabel: \\\"Description\\\",\\n\\t\\t\\t\\tName:  \\\"description\\\",\\n\\t\\t\\t\\tErr:   \\\"Description cannot be empty\\\",\\n\\t\\t\\t\\tClass: \\\"textarea-bordered resize-none\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Textarea with error\"\n    }\n  ],\n  \"time_slot_picker\": [\n    {\n      \"name\": \"BasicTimeSlotPicker\",\n      \"code\": \"```go\\ntempl BasicTimeSlotPicker() {\\n\\t\\u003cdiv hx-get={ \\\"/timeslotpicker?date=\\\" + time.Now().UTC().Format(\\\"2006-01-02\\\") } hx-trigger=\\\"intersect\\\" hx-swap=\\\"outerHTML\\\"\\u003e\\u003c/div\\u003e\\n}\\n```\",\n      \"handler\": \"```go\\nfunc GetTimeSlotPicker(c echo.Context) error {\\n\\tdateStr := c.QueryParam(\\\"date\\\")\\n\\tdate, err := time.Parse(\\\"2006-01-02\\\", dateStr)\\n\\tif err != nil {\\n\\t\\treturn newErrorToast(http.StatusUnprocessableEntity, \\\"Invalid date\\\")\\n\\t}\\n\\n\\tprops := components.TimeSlotPickerProps{\\n\\t\\tID:          \\\"time-slot-picker-example\\\",\\n\\t\\tCurrentDate: date,\\n\\t\\tPickerURL:   \\\"/timeslotpicker\\\",\\n\\t\\tReserveURL:  \\\"/timeslotpicker/reserve\\\",\\n\\t\\tTimeSlots:   getTimeSlots(date),\\n\\t}\\n\\treturn render(c, http.StatusOK, components.TimeSlotPicker(props))\\n}\\n\\nfunc getTimeSlots(date time.Time) []components.TimeSlot {\\n\\tslots := make([]components.TimeSlot, 32)\\n\\n\\tfor i := range 32 {\\n\\t\\tslots[i] = components.TimeSlot{\\n\\t\\t\\tStart: date.Add(time.Duration(10+i*2) * time.Hour),\\n\\t\\t\\tEnd:   date.Add(time.Duration(11+i*2) * time.Hour),\\n\\t\\t}\\n\\t}\\n\\n\\treturn slots\\n}\\n\\nfunc PostTimeSlotPickerReserve(c echo.Context) error {\\n\\tstartStr := c.QueryParam(\\\"start\\\")\\n\\tstart, err := time.Parse(\\\"2006-01-02-15-04\\\", startStr)\\n\\tif err != nil {\\n\\t\\treturn newErrorToast(http.StatusUnprocessableEntity, \\\"Invalid start date\\\")\\n\\t}\\n\\tendStr := c.QueryParam(\\\"end\\\")\\n\\tend, err := time.Parse(\\\"2006-01-02-15-04\\\", endStr)\\n\\tif err != nil {\\n\\t\\treturn newErrorToast(http.StatusUnprocessableEntity, \\\"Invalid end date\\\")\\n\\t}\\n\\n\\treturn renderInfoFade(\\n\\t\\tc,\\n\\t\\thttp.StatusOK,\\n\\t\\t[]string{\\n\\t\\t\\tfmt.Sprintf(\\n\\t\\t\\t\\t\\\"Time slot on %s, %s - %s reserved!\\\",\\n\\t\\t\\t\\tstart.Format(\\\"Mon Jan 02\\\"),\\n\\t\\t\\t\\tstart.Format(\\\"15:04\\\"),\\n\\t\\t\\t\\tend.Format(\\\"15:04\\\"),\\n\\t\\t\\t),\\n\\t\\t},\\n\\t)\\n}\\n\\n```\",\n      \"title\": \"Basic time slot picker\"\n    }\n  ],\n  \"timeline\": [\n    {\n      \"name\": \"BasicTimeline\",\n      \"code\": \"```go\\ntempl BasicTimeline() {\\n\\t\\u003cdiv class=\\\"flex justify-center items-center pt-4\\\"\\u003e\\n\\t\\t@components.Timeline(\\n\\t\\t\\tcomponents.TimelineProps{\\n\\t\\t\\t\\t{Start: \\\"1984\\\", Middle: components.TimelineCheckbox(true), End: \\\"First Macintosh computer\\\"},\\n\\t\\t\\t\\t{Start: \\\"1998\\\", Middle: components.TimelineCheckbox(true), End: \\\"iMac\\\"},\\n\\t\\t\\t\\t{Start: \\\"2001\\\", Middle: components.TimelineCheckbox(false), End: \\\"iPod\\\"},\\n\\t\\t\\t\\t{Start: \\\"2007\\\", Middle: components.TimelineCheckbox(false), End: \\\"iPhone\\\"},\\n\\t\\t\\t\\t{Start: \\\"2015\\\", Middle: components.TimelineCheckbox(false), End: \\\"Apple Watch\\\"},\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\"\n    }\n  ],\n  \"toast\": [\n    {\n      \"name\": \"InfoToast\",\n      \"code\": \"```go\\ntempl InfoToast() {\\n\\t\\u003cdiv class=\\\"relative min-h-60\\\"\\u003e\\n\\t\\t@components.Toast(\\n\\t\\t\\tcomponents.ToastProps{\\n\\t\\t\\t\\tName:       \\\"info-toast\\\",\\n\\t\\t\\t\\tToastClass: \\\"absolute toast-end toast-top\\\",\\n\\t\\t\\t\\tAlertClass: \\\"alert-info\\\",\\n\\t\\t\\t},\\n\\t\\t) {\\n\\t\\t\\t\\u003cspan\\u003eInfo toast\\u003c/span\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Info-type toast\"\n    },\n    {\n      \"name\": \"WarningToast\",\n      \"code\": \"```go\\ntempl WarningToast() {\\n\\t\\u003cdiv class=\\\"relative min-h-60\\\"\\u003e\\n\\t\\t@components.Toast(\\n\\t\\t\\tcomponents.ToastProps{\\n\\t\\t\\t\\tName:       \\\"warning-toast\\\",\\n\\t\\t\\t\\tToastClass: \\\"absolute toast-end toast-bottom\\\",\\n\\t\\t\\t\\tAlertClass: \\\"alert-warning\\\",\\n\\t\\t\\t},\\n\\t\\t) {\\n\\t\\t\\t\\u003cspan\\u003eWarning toast\\u003c/span\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Warning-type toast\"\n    },\n    {\n      \"name\": \"ErrorToast\",\n      \"code\": \"```go\\ntempl ErrorToast() {\\n\\t\\u003cdiv class=\\\"relative min-h-60\\\"\\u003e\\n\\t\\t@components.Toast(\\n\\t\\t\\tcomponents.ToastProps{\\n\\t\\t\\t\\tName:       \\\"error-toast\\\",\\n\\t\\t\\t\\tToastClass: \\\"absolute toast-center toast-top\\\",\\n\\t\\t\\t\\tAlertClass: \\\"alert-error\\\",\\n\\t\\t\\t},\\n\\t\\t) {\\n\\t\\t\\t\\u003cspan\\u003eError toast\\u003c/span\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Error-type toast\"\n    },\n    {\n      \"name\": \"InfoToastConfirm\",\n      \"code\": \"```go\\ntempl InfoToastConfirm() {\\n\\t\\u003cdiv class=\\\"relative min-h-60\\\"\\u003e\\n\\t\\t@components.Toast(components.ToastProps{\\n\\t\\t\\tName:       \\\"error-toast\\\",\\n\\t\\t\\tToastClass: \\\"absolute toast-end toast-top\\\",\\n\\t\\t\\tAlertClass: \\\"alert-info\\\",\\n\\t\\t},\\n\\t\\t) {\\n\\t\\t\\t\\u003cspan\\u003eInfo toast\\u003c/span\\u003e\\n\\t\\t\\t\\u003cbutton id=\\\"toast-remover-btn\\\" class=\\\"btn btn-info\\\"\\u003eOK\\u003c/button\\u003e\\n\\t\\t\\t\\u003cscript\\u003e\\n                ((toast) =\\u003e {\\n                    document.getElementById(\\\"toast-remover-btn\\\").addEventListener(\\\"click\\\", () =\\u003e {\\n                        toast.remove()\\n                    })\\n                })(document.currentScript.closest(\\\"div.toast\\\"))\\n            \\u003c/script\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Info-type toast with button to remove it\"\n    }\n  ],\n  \"toggle\": [\n    {\n      \"name\": \"DifferentSizeToggles\",\n      \"code\": \"```go\\ntempl DifferentSizeToggles() {\\n\\t\\u003cdiv class=\\\"max-w-52 mx-auto pt-4 space-y-2\\\"\\u003e\\n\\t\\t@components.Toggle(\\n\\t\\t\\tcomponents.ToggleProps{\\n\\t\\t\\t\\tBefore: \\\"Check me out\\\",\\n\\t\\t\\t\\tName:   \\\"checkbox1\\\",\\n\\t\\t\\t\\tSize:   \\\"xs\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Toggle(\\n\\t\\t\\tcomponents.ToggleProps{\\n\\t\\t\\t\\tBefore: \\\"Check me out\\\",\\n\\t\\t\\t\\tName:   \\\"checkbox1\\\",\\n\\t\\t\\t\\tSize:   \\\"sm\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Toggle(\\n\\t\\t\\tcomponents.ToggleProps{\\n\\t\\t\\t\\tBefore: \\\"Check me out\\\",\\n\\t\\t\\t\\tName:   \\\"checkbox1\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Toggle(\\n\\t\\t\\tcomponents.ToggleProps{\\n\\t\\t\\t\\tBefore: \\\"Check me out\\\",\\n\\t\\t\\t\\tName:   \\\"checkbox1\\\",\\n\\t\\t\\t\\tSize:   \\\"lg\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\t@components.Toggle(\\n\\t\\t\\tcomponents.ToggleProps{\\n\\t\\t\\t\\tBefore: \\\"Check me out\\\",\\n\\t\\t\\t\\tName:   \\\"checkbox1\\\",\\n\\t\\t\\t\\tSize:   \\\"xl\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Different size toggles\"\n    },\n    {\n      \"name\": \"PrimaryToggle\",\n      \"code\": \"```go\\ntempl PrimaryToggle() {\\n\\t\\u003cdiv class=\\\"max-w-52 mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Toggle(\\n\\t\\t\\tcomponents.ToggleProps{\\n\\t\\t\\t\\tAfter:   \\\"Check me out\\\",\\n\\t\\t\\t\\tName:    \\\"checkbox2\\\",\\n\\t\\t\\t\\tChecked: true,\\n\\t\\t\\t\\tClass:   \\\"toggle-primary\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Primary toggle with label after\"\n    },\n    {\n      \"name\": \"PrimaryToggleWithHighlight\",\n      \"code\": \"```go\\ntempl PrimaryToggleWithHighlight() {\\n\\t\\u003cdiv class=\\\"max-w-xs mx-auto pt-4\\\"\\u003e\\n\\t\\t@components.Toggle(\\n\\t\\t\\tcomponents.ToggleProps{\\n\\t\\t\\t\\tBefore:    \\\"Paid monthly\\\",\\n\\t\\t\\t\\tAfter:     \\\"Paid annually\\\",\\n\\t\\t\\t\\tName:      \\\"checkbox3\\\",\\n\\t\\t\\t\\tHighlight: true,\\n\\t\\t\\t\\tClass:     \\\"toggle-primary\\\",\\n\\t\\t\\t},\\n\\t\\t)\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Primary toggle with highlight\"\n    }\n  ],\n  \"tooltip\": [\n    {\n      \"name\": \"BasicTooltip\",\n      \"code\": \"```go\\ntempl BasicTooltip() {\\n\\t\\u003cdiv class=\\\"min-h-60 flex justify-center items-center\\\"\\u003e\\n\\t\\t@components.Tooltip(components.TooltipProps{Tip: \\\"Hello\\\"}) {\\n\\t\\t\\t\\u003cbutton class=\\\"btn\\\"\\u003eHover me\\u003c/button\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n\\n```\",\n      \"title\": \"Basic tooltip at the top\"\n    },\n    {\n      \"name\": \"BasicTooltipError\",\n      \"code\": \"```go\\ntempl BasicTooltipError() {\\n\\t\\u003cdiv class=\\\"min-h-60 flex justify-center items-center\\\"\\u003e\\n\\t\\t@components.Tooltip(\\n\\t\\t\\tcomponents.TooltipProps{\\n\\t\\t\\t\\tTip:   \\\"Hello\\\",\\n\\t\\t\\t\\tClass: \\\"tooltip-bottom tooltip-error\\\",\\n\\t\\t\\t},\\n\\t\\t) {\\n\\t\\t\\t\\u003cbutton class=\\\"btn\\\"\\u003eHover me\\u003c/button\\u003e\\n\\t\\t}\\n\\t\\u003c/div\\u003e\\n}\\n```\",\n      \"title\": \"Error-type tooltip on the bottom\"\n    }\n  ]\n}"
  },
  {
    "path": "internal/assets/generated/components.go",
    "content": "package generated\n\nimport (\n\t\"github.com/a-h/templ\"\n\t\"github.com/haatos/goshipit/internal/views/examples\"\n)\n\nvar ExampleComponents = map[string]templ.Component{\n\t\"AccordionWithCheckbox\":       examples.AccordionWithCheckbox(),\n\t\"AccordionWithRadio\":          examples.AccordionWithRadio(),\n\t\"ActiveSearchExampleTable\":    examples.ActiveSearchExampleTable(),\n\t\"AlertInfoExample\":            examples.AlertInfoExample(),\n\t\"AlertSuccessExample\":         examples.AlertSuccessExample(),\n\t\"AlertWarningExample\":         examples.AlertWarningExample(),\n\t\"AlertErrorExample\":           examples.AlertErrorExample(),\n\t\"BasicAnchor\":                 examples.BasicAnchor(),\n\t\"PrimaryAnchor\":               examples.PrimaryAnchor(),\n\t\"AnchorWithIcon\":              examples.AnchorWithIcon(),\n\t\"SocialAnchors\":               examples.SocialAnchors(),\n\t\"MultipleAvatarSizes\":         examples.MultipleAvatarSizes(),\n\t\"GroupOfAvatars\":              examples.GroupOfAvatars(),\n\t\"OnlineAndOffline\":            examples.OnlineAndOffline(),\n\t\"BannerExample\":               examples.BannerExample(),\n\t\"BreadcrumbsExample\":          examples.BreadcrumbsExample(),\n\t\"BasicCard\":                   examples.BasicCard(),\n\t\"BasicCardWithImage\":          examples.BasicCardWithImage(),\n\t\"CarouselExample\":             examples.CarouselExample(),\n\t\"BasicChat\":                   examples.BasicChat(),\n\t\"DifferentSizeCheckboxes\":     examples.DifferentSizeCheckboxes(),\n\t\"PrimaryCheckbox\":             examples.PrimaryCheckbox(),\n\t\"CollapseExample\":             examples.CollapseExample(),\n\t\"BasicCombobox\":               examples.BasicCombobox(),\n\t\"CountdownFullExample\":        examples.CountdownFullExample(),\n\t\"CountdownHoursExample\":       examples.CountdownHoursExample(),\n\t\"CountdownMinutesExample\":     examples.CountdownMinutesExample(),\n\t\"CountdownSecondsExample\":     examples.CountdownSecondsExample(),\n\t\"BasicDatePicker\":             examples.BasicDatePicker(),\n\t\"ImageDiff\":                   examples.ImageDiff(),\n\t\"BasicDrawer\":                 examples.BasicDrawer(),\n\t\"BasicDropdown\":               examples.BasicDropdown(),\n\t\"BasicFAB\":                    examples.BasicFAB(),\n\t\"FABWithSVGButtons\":           examples.FABWithSVGButtons(),\n\t\"FABFlowerExample\":            examples.FABFlowerExample(),\n\t\"FeaturesExample\":             examples.FeaturesExample(),\n\t\"DifferentSizeFileInputs\":     examples.DifferentSizeFileInputs(),\n\t\"BasicFooterWithLinks\":        examples.BasicFooterWithLinks(),\n\t\"BasicHero\":                   examples.BasicHero(),\n\t\"Hover3DCardExample\":          examples.Hover3DCardExample(),\n\t\"InfiniteScrollTableExample\":  examples.InfiniteScrollTableExample(),\n\t\"DifferentSizeInputs\":         examples.DifferentSizeInputs(),\n\t\"IntegerInput\":                examples.IntegerInput(),\n\t\"DecimalInput\":                examples.DecimalInput(),\n\t\"PasswordFieldWithValidator\":  examples.PasswordFieldWithValidator(),\n\t\"EmailFieldWithValidator\":     examples.EmailFieldWithValidator(),\n\t\"SignUpFormExample\":           examples.SignUpFormExample(),\n\t\"LazyLoadExample\":             examples.LazyLoadExample(),\n\t\"MenuExample\":                 examples.MenuExample(),\n\t\"MenuWithSubmenusExample\":     examples.MenuWithSubmenusExample(),\n\t\"DashboardMenuExample\":        examples.DashboardMenuExample(),\n\t\"BasicModal\":                  examples.BasicModal(),\n\t\"MultipleModals\":              examples.MultipleModals(),\n\t\"ModalWithAction\":             examples.ModalWithAction(),\n\t\"ModalConfirmDelete\":          examples.ModalConfirmDelete(),\n\t\"BasicPaginationExample\":      examples.BasicPaginationExample(),\n\t\"PricingExample\":              examples.PricingExample(),\n\t\"PricingWithPromotionExample\": examples.PricingWithPromotionExample(),\n\t\"DefaultRadio\":                examples.DefaultRadio(),\n\t\"PrimaryRadio\":                examples.PrimaryRadio(),\n\t\"BasicRange\":                  examples.BasicRange(),\n\t\"DatastarRange\":               examples.DatastarRange(),\n\t\"RatingFromOneToFive\":         examples.RatingFromOneToFive(),\n\t\"RatingFromZeroToFive\":        examples.RatingFromZeroToFive(),\n\t\"DifferentSizeSelects\":        examples.DifferentSizeSelects(),\n\t\"CascadingSelect\":             examples.CascadingSelect(),\n\t\"SkeletonExample\":             examples.SkeletonExample(),\n\t\"BasicStats\":                  examples.BasicStats(),\n\t\"StatusNotFound\":              examples.StatusNotFound(),\n\t\"StatusForbidden\":             examples.StatusForbidden(),\n\t\"StatusUnauthorized\":          examples.StatusUnauthorized(),\n\t\"StatusInternalServerError\":   examples.StatusInternalServerError(),\n\t\"BasicSteps\":                  examples.BasicSteps(),\n\t\"BasicSwap\":                   examples.BasicSwap(),\n\t\"BasicTable\":                  examples.BasicTable(),\n\t\"BasicTabs\":                   examples.BasicTabs(),\n\t\"TestimonialGridExample\":      examples.TestimonialGridExample(),\n\t\"TextRotateExample\":           examples.TextRotateExample(),\n\t\"BasicTextarea\":               examples.BasicTextarea(),\n\t\"DifferentSizeTextareas\":      examples.DifferentSizeTextareas(),\n\t\"BasicTextareaWithError\":      examples.BasicTextareaWithError(),\n\t\"BasicTimeSlotPicker\":         examples.BasicTimeSlotPicker(),\n\t\"BasicTimeline\":               examples.BasicTimeline(),\n\t\"InfoToast\":                   examples.InfoToast(),\n\t\"WarningToast\":                examples.WarningToast(),\n\t\"ErrorToast\":                  examples.ErrorToast(),\n\t\"InfoToastConfirm\":            examples.InfoToastConfirm(),\n\t\"DifferentSizeToggles\":        examples.DifferentSizeToggles(),\n\t\"PrimaryToggle\":               examples.PrimaryToggle(),\n\t\"PrimaryToggleWithHighlight\":  examples.PrimaryToggleWithHighlight(),\n\t\"BasicTooltip\":                examples.BasicTooltip(),\n\t\"BasicTooltipError\":           examples.BasicTooltipError(),\n}\n"
  },
  {
    "path": "internal/assets/public/static/css/chroma.css",
    "content": ".bg {\n  color: #b0c4de;\n  background-color: #282c34;\n}\n\n.chroma {\n  color: #b0c4de;\n  background-color: #111318;\n}\n\n.chroma .lntd {\n  vertical-align: top;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\n.chroma .lntable {\n  border-spacing: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\n.chroma .hl {\n  background-color: #3d4148;\n}\n\n.chroma .lnt {\n  white-space: pre;\n  user-select: none;\n  margin-right: 0.4em;\n  padding: 0 0.4em 0 0.4em;\n  color: #58626f;\n}\n\n.chroma .ln {\n  white-space: pre;\n  user-select: none;\n  margin-right: 0.4em;\n  padding: 0 0.4em 0 0.4em;\n  color: #58626f;\n}\n\n.chroma .line {\n  display: flex;\n}\n\n.chroma .k {\n  color: #76a9f9;\n}\n\n.chroma .kc {\n  color: #e5c07b;\n}\n\n.chroma .kd {\n  color: #76a9f9;\n}\n\n.chroma .kn {\n  color: #76a9f9;\n}\n\n.chroma .kp {\n  color: #76a9f9;\n}\n\n.chroma .kr {\n  color: #76a9f9;\n}\n\n.chroma .kt {\n  color: #e5c07b;\n}\n\n.chroma .n {\n  color: #aa89ea;\n}\n\n.chroma .na {\n  color: #cebc3a;\n}\n\n.chroma .nb {\n  color: #e5c07b;\n}\n\n.chroma .bp {\n  color: #aa89ea;\n}\n\n.chroma .nc {\n  color: #ca72ff;\n}\n\n.chroma .no {\n  color: #aa89ea;\n  font-weight: bold;\n}\n\n.chroma .nd {\n  color: #e5c07b;\n}\n\n.chroma .ni {\n  color: #bda26f;\n}\n\n.chroma .ne {\n  color: #fd7474;\n  font-weight: bold;\n}\n\n.chroma .nf {\n  color: #00b1f7;\n}\n\n.chroma .fm {\n  color: #aa89ea;\n}\n\n.chroma .nl {\n  color: #f5a40d;\n}\n\n.chroma .nn {\n  color: #ca72ff;\n}\n\n.chroma .nx {\n  color: #aa89ea;\n}\n\n.chroma .py {\n  color: #cebc3a;\n}\n\n.chroma .nt {\n  color: #76a9f9;\n}\n\n.chroma .nv {\n  color: #dcaeea;\n}\n\n.chroma .vc {\n  color: #dcaeea;\n}\n\n.chroma .vg {\n  color: #dcaeea;\n  font-weight: bold;\n}\n\n.chroma .vi {\n  color: #e06c75;\n}\n\n.chroma .vm {\n  color: #dcaeea;\n}\n\n.chroma .l {\n  color: #98c379;\n}\n\n.chroma .ld {\n  color: #98c379;\n}\n\n.chroma .s {\n  color: #98c379;\n}\n\n.chroma .sa {\n  color: #98c379;\n}\n\n.chroma .sb {\n  color: #98c379;\n}\n\n.chroma .sc {\n  color: #98c379;\n}\n\n.chroma .dl {\n  color: #98c379;\n}\n\n.chroma .sd {\n  color: #7e97c3;\n}\n\n.chroma .s2 {\n  color: #63c381;\n}\n\n.chroma .se {\n  color: #d26464;\n  font-weight: bold;\n}\n\n.chroma .sh {\n  color: #98c379;\n}\n\n.chroma .si {\n  color: #98c379;\n}\n\n.chroma .sx {\n  color: #70b33f;\n}\n\n.chroma .sr {\n  color: #56b6c2;\n}\n\n.chroma .s1 {\n  color: #98c379;\n}\n\n.chroma .ss {\n  color: #56b6c2;\n}\n\n.chroma .m {\n  color: #d19a66;\n}\n\n.chroma .mb {\n  color: #d19a66;\n}\n\n.chroma .mf {\n  color: #d19a66;\n}\n\n.chroma .mh {\n  color: #d19a66;\n}\n\n.chroma .mi {\n  color: #d19a66;\n}\n\n.chroma .il {\n  color: #d19a66;\n}\n\n.chroma .mo {\n  color: #d19a66;\n}\n\n.chroma .o {\n  color: #54b1c7;\n}\n\n.chroma .ow {\n  color: #b756ff;\n  font-weight: bold;\n}\n\n.chroma .p {\n  color: #abb2bf;\n}\n\n.chroma .c {\n  color: #8a93a5;\n  font-style: italic;\n}\n\n.chroma .ch {\n  color: #8a93a5;\n  font-weight: bold;\n  font-style: italic;\n}\n\n.chroma .cm {\n  color: #8a93a5;\n  font-style: italic;\n}\n\n.chroma .c1 {\n  color: #8a93a5;\n  font-style: italic;\n}\n\n.chroma .cs {\n  color: #8a93a5;\n  font-style: italic;\n}\n\n.chroma .cp {\n  color: #8a93a5;\n  font-style: italic;\n}\n\n.chroma .cpf {\n  color: #8a93a5;\n  font-style: italic;\n}\n\n.chroma .ge {\n  font-style: italic;\n}\n\n.chroma .gh {\n  color: #a2cbff;\n  font-weight: bold;\n}\n\n.chroma .gi {\n  color: #a6e22e;\n}\n\n.chroma .go {\n  color: #a6e22e;\n}\n\n.chroma .gp {\n  color: #a6e22e;\n}\n\n.chroma .gs {\n  font-weight: bold;\n}\n\n.chroma .gu {\n  color: #a2cbff;\n}\n\n.chroma .gt {\n  color: #a2cbff;\n}\n\n.chroma .gl {\n  text-decoration: underline;\n}\n\n.chroma {\n  padding: 5px;\n  border-radius: 16px;\n  max-width: 1024px;\n  overflow-x: auto;\n  font-size: 14px;\n}\n\n.chroma code {\n  font-family: \"JetBrains Mono\", monospace !important;\n  font-weight: 500 !important;\n  font-style: normal !important;\n}\n\n@media screen and (min-width: 768px) {\n  .chroma {\n    padding: 10px;\n  }\n}\n"
  },
  {
    "path": "internal/assets/public/static/css/custom.css",
    "content": ".font-saira-black {\n  font-family: \"Saira\", sans-serif;\n  font-weight: 900;\n  font-style: normal;\n}\n\nbody,\nhtml {\n  margin: 0;\n  padding: 0;\n  width: 100%;\n  font-family: \"Montserrat\", sans-serif;\n}\n\n.htmx-indicator {\n  opacity: 0;\n  transition: opacity 500ms ease-in;\n}\n\n.htmx-request .htmx-indicator {\n  opacity: 1;\n}\n\n.htmx-request.htmx-indicator {\n  opacity: 1;\n}\n\narticle > p > img {\n  margin: auto;\n}\n\npre:not([class=\"chroma\"]) {\n  background-color: #111318;\n  padding: 0px;\n}\n\npre[class=\"chroma\"] {\n  position: relative;\n  overflow: auto;\n\n  margin: 5px 0;\n  padding: 1.75rem 0 1.75rem 1rem;\n  border-radius: 10px;\n}\n\npre[class=\"chroma\"] button {\n  position: absolute;\n  top: 5px;\n  right: 5px;\n}\n\npre[class=\"chroma\"] button:hover {\n  cursor: pointer;\n}\n"
  },
  {
    "path": "internal/assets/public/static/js/alpine.js",
    "content": "(() => {\n    var rt = !1, nt = !1, U = [], it = -1; function qt(e) { Cn(e) } function Cn(e) { U.includes(e) || U.push(e), Tn() } function Ee(e) { let t = U.indexOf(e); t !== -1 && t > it && U.splice(t, 1) } function Tn() { !nt && !rt && (rt = !0, queueMicrotask(Rn)) } function Rn() { rt = !1, nt = !0; for (let e = 0; e < U.length; e++)U[e](), it = e; U.length = 0, it = -1, nt = !1 } var R, D, L, st, ot = !0; function Ut(e) { ot = !1, e(), ot = !0 } function Wt(e) { R = e.reactive, L = e.release, D = t => e.effect(t, { scheduler: r => { ot ? qt(r) : r() } }), st = e.raw } function at(e) { D = e } function Gt(e) { let t = () => { }; return [n => { let i = D(n); return e._x_effects || (e._x_effects = new Set, e._x_runEffects = () => { e._x_effects.forEach(o => o()) }), e._x_effects.add(i), t = () => { i !== void 0 && (e._x_effects.delete(i), L(i)) }, i }, () => { t() }] } function ve(e, t) { let r = !0, n, i = D(() => { let o = e(); JSON.stringify(o), r ? n = o : queueMicrotask(() => { t(o, n), n = o }), r = !1 }); return () => L(i) } var Jt = [], Yt = [], Xt = []; function Zt(e) { Xt.push(e) } function ee(e, t) { typeof t == \"function\" ? (e._x_cleanups || (e._x_cleanups = []), e._x_cleanups.push(t)) : (t = e, Yt.push(t)) } function Ae(e) { Jt.push(e) } function Oe(e, t, r) { e._x_attributeCleanups || (e._x_attributeCleanups = {}), e._x_attributeCleanups[t] || (e._x_attributeCleanups[t] = []), e._x_attributeCleanups[t].push(r) } function ct(e, t) { e._x_attributeCleanups && Object.entries(e._x_attributeCleanups).forEach(([r, n]) => { (t === void 0 || t.includes(r)) && (n.forEach(i => i()), delete e._x_attributeCleanups[r]) }) } function Qt(e) { if (e._x_cleanups) for (; e._x_cleanups.length;)e._x_cleanups.pop()() } var lt = new MutationObserver(pt), ut = !1; function le() { lt.observe(document, { subtree: !0, childList: !0, attributes: !0, attributeOldValue: !0 }), ut = !0 } function ft() { Mn(), lt.disconnect(), ut = !1 } var ce = []; function Mn() { let e = lt.takeRecords(); ce.push(() => e.length > 0 && pt(e)); let t = ce.length; queueMicrotask(() => { if (ce.length === t) for (; ce.length > 0;)ce.shift()() }) } function _(e) { if (!ut) return e(); ft(); let t = e(); return le(), t } var dt = !1, Se = []; function er() { dt = !0 } function tr() { dt = !1, pt(Se), Se = [] } function pt(e) { if (dt) { Se = Se.concat(e); return } let t = new Set, r = new Set, n = new Map, i = new Map; for (let o = 0; o < e.length; o++)if (!e[o].target._x_ignoreMutationObserver && (e[o].type === \"childList\" && (e[o].addedNodes.forEach(s => s.nodeType === 1 && t.add(s)), e[o].removedNodes.forEach(s => s.nodeType === 1 && r.add(s))), e[o].type === \"attributes\")) { let s = e[o].target, a = e[o].attributeName, c = e[o].oldValue, l = () => { n.has(s) || n.set(s, []), n.get(s).push({ name: a, value: s.getAttribute(a) }) }, u = () => { i.has(s) || i.set(s, []), i.get(s).push(a) }; s.hasAttribute(a) && c === null ? l() : s.hasAttribute(a) ? (u(), l()) : u() } i.forEach((o, s) => { ct(s, o) }), n.forEach((o, s) => { Jt.forEach(a => a(s, o)) }); for (let o of r) t.has(o) || Yt.forEach(s => s(o)); t.forEach(o => { o._x_ignoreSelf = !0, o._x_ignore = !0 }); for (let o of t) r.has(o) || o.isConnected && (delete o._x_ignoreSelf, delete o._x_ignore, Xt.forEach(s => s(o)), o._x_ignore = !0, o._x_ignoreSelf = !0); t.forEach(o => { delete o._x_ignoreSelf, delete o._x_ignore }), t = null, r = null, n = null, i = null } function Ce(e) { return F(j(e)) } function P(e, t, r) { return e._x_dataStack = [t, ...j(r || e)], () => { e._x_dataStack = e._x_dataStack.filter(n => n !== t) } } function j(e) { return e._x_dataStack ? e._x_dataStack : typeof ShadowRoot == \"function\" && e instanceof ShadowRoot ? j(e.host) : e.parentNode ? j(e.parentNode) : [] } function F(e) { return new Proxy({ objects: e }, Nn) } var Nn = { ownKeys({ objects: e }) { return Array.from(new Set(e.flatMap(t => Object.keys(t)))) }, has({ objects: e }, t) { return t == Symbol.unscopables ? !1 : e.some(r => Object.prototype.hasOwnProperty.call(r, t) || Reflect.has(r, t)) }, get({ objects: e }, t, r) { return t == \"toJSON\" ? Dn : Reflect.get(e.find(n => Reflect.has(n, t)) || {}, t, r) }, set({ objects: e }, t, r, n) { let i = e.find(s => Object.prototype.hasOwnProperty.call(s, t)) || e[e.length - 1], o = Object.getOwnPropertyDescriptor(i, t); return o?.set && o?.get ? o.set.call(n, r) || !0 : Reflect.set(i, t, r) } }; function Dn() { return Reflect.ownKeys(this).reduce((t, r) => (t[r] = Reflect.get(this, r), t), {}) } function Te(e) { let t = n => typeof n == \"object\" && !Array.isArray(n) && n !== null, r = (n, i = \"\") => { Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o, { value: s, enumerable: a }]) => { if (a === !1 || s === void 0 || typeof s == \"object\" && s !== null && s.__v_skip) return; let c = i === \"\" ? o : `${i}.${o}`; typeof s == \"object\" && s !== null && s._x_interceptor ? n[o] = s.initialize(e, c, o) : t(s) && s !== n && !(s instanceof Element) && r(s, c) }) }; return r(e) } function Re(e, t = () => { }) { let r = { initialValue: void 0, _x_interceptor: !0, initialize(n, i, o) { return e(this.initialValue, () => Pn(n, i), s => mt(n, i, s), i, o) } }; return t(r), n => { if (typeof n == \"object\" && n !== null && n._x_interceptor) { let i = r.initialize.bind(r); r.initialize = (o, s, a) => { let c = n.initialize(o, s, a); return r.initialValue = c, i(o, s, a) } } else r.initialValue = n; return r } } function Pn(e, t) { return t.split(\".\").reduce((r, n) => r[n], e) } function mt(e, t, r) { if (typeof t == \"string\" && (t = t.split(\".\")), t.length === 1) e[t[0]] = r; else { if (t.length === 0) throw error; return e[t[0]] || (e[t[0]] = {}), mt(e[t[0]], t.slice(1), r) } } var rr = {}; function y(e, t) { rr[e] = t } function ue(e, t) { return Object.entries(rr).forEach(([r, n]) => { let i = null; function o() { if (i) return i; { let [s, a] = _t(t); return i = { interceptor: Re, ...s }, ee(t, a), i } } Object.defineProperty(e, `$${r}`, { get() { return n(t, o()) }, enumerable: !1 }) }), e } function nr(e, t, r, ...n) { try { return r(...n) } catch (i) { te(i, e, t) } } function te(e, t, r = void 0) {\n        e = Object.assign(e ?? { message: \"No error message given.\" }, { el: t, expression: r }), console.warn(`Alpine Expression Error: ${e.message}\n\n${r ? 'Expression: \"' + r + `\"\n\n`: \"\"}`, t), setTimeout(() => { throw e }, 0)\n    } var Me = !0; function De(e) { let t = Me; Me = !1; let r = e(); return Me = t, r } function M(e, t, r = {}) { let n; return x(e, t)(i => n = i, r), n } function x(...e) { return ir(...e) } var ir = gt; function or(e) { ir = e } function gt(e, t) { let r = {}; ue(r, e); let n = [r, ...j(e)], i = typeof t == \"function\" ? In(n, t) : Ln(n, t, e); return nr.bind(null, e, t, i) } function In(e, t) { return (r = () => { }, { scope: n = {}, params: i = [] } = {}) => { let o = t.apply(F([n, ...e]), i); Ne(r, o) } } var ht = {}; function kn(e, t) { if (ht[e]) return ht[e]; let r = Object.getPrototypeOf(async function () { }).constructor, n = /^[\\n\\s]*if.*\\(.*\\)/.test(e.trim()) || /^(let|const)\\s/.test(e.trim()) ? `(async()=>{ ${e} })()` : e, o = (() => { try { let s = new r([\"__self\", \"scope\"], `with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`); return Object.defineProperty(s, \"name\", { value: `[Alpine] ${e}` }), s } catch (s) { return te(s, t, e), Promise.resolve() } })(); return ht[e] = o, o } function Ln(e, t, r) { let n = kn(t, r); return (i = () => { }, { scope: o = {}, params: s = [] } = {}) => { n.result = void 0, n.finished = !1; let a = F([o, ...e]); if (typeof n == \"function\") { let c = n(n, a).catch(l => te(l, r, t)); n.finished ? (Ne(i, n.result, a, s, r), n.result = void 0) : c.then(l => { Ne(i, l, a, s, r) }).catch(l => te(l, r, t)).finally(() => n.result = void 0) } } } function Ne(e, t, r, n, i) { if (Me && typeof t == \"function\") { let o = t.apply(r, n); o instanceof Promise ? o.then(s => Ne(e, s, r, n)).catch(s => te(s, i, t)) : e(o) } else typeof t == \"object\" && t instanceof Promise ? t.then(o => e(o)) : e(t) } var bt = \"x-\"; function C(e = \"\") { return bt + e } function sr(e) { bt = e } var Pe = {}; function d(e, t) { return Pe[e] = t, { before(r) { if (!Pe[r]) { console.warn(String.raw`Cannot find directive \\`${r}\\`. \\`${e}\\` will use the default order of execution`); return } let n = W.indexOf(r); W.splice(n >= 0 ? n : W.indexOf(\"DEFAULT\"), 0, e) } } } function ar(e) { return Object.keys(Pe).includes(e) } function de(e, t, r) { if (t = Array.from(t), e._x_virtualDirectives) { let o = Object.entries(e._x_virtualDirectives).map(([a, c]) => ({ name: a, value: c })), s = wt(o); o = o.map(a => s.find(c => c.name === a.name) ? { name: `x-bind:${a.name}`, value: `\"${a.value}\"` } : a), t = t.concat(o) } let n = {}; return t.map(ur((o, s) => n[o] = s)).filter(dr).map(jn(n, r)).sort(Fn).map(o => $n(e, o)) } function wt(e) { return Array.from(e).map(ur()).filter(t => !dr(t)) } var xt = !1, fe = new Map, cr = Symbol(); function lr(e) { xt = !0; let t = Symbol(); cr = t, fe.set(t, []); let r = () => { for (; fe.get(t).length;)fe.get(t).shift()(); fe.delete(t) }, n = () => { xt = !1, r() }; e(r), n() } function _t(e) { let t = [], r = a => t.push(a), [n, i] = Gt(e); return t.push(i), [{ Alpine: B, effect: n, cleanup: r, evaluateLater: x.bind(x, e), evaluate: M.bind(M, e) }, () => t.forEach(a => a())] } function $n(e, t) { let r = () => { }, n = Pe[t.type] || r, [i, o] = _t(e); Oe(e, t.original, o); let s = () => { e._x_ignore || e._x_ignoreSelf || (n.inline && n.inline(e, t, i), n = n.bind(n, e, t, i), xt ? fe.get(cr).push(n) : n()) }; return s.runCleanups = o, s } var Ie = (e, t) => ({ name: r, value: n }) => (r.startsWith(e) && (r = r.replace(e, t)), { name: r, value: n }), ke = e => e; function ur(e = () => { }) { return ({ name: t, value: r }) => { let { name: n, value: i } = fr.reduce((o, s) => s(o), { name: t, value: r }); return n !== t && e(n, t), { name: n, value: i } } } var fr = []; function re(e) { fr.push(e) } function dr({ name: e }) { return pr().test(e) } var pr = () => new RegExp(`^${bt}([^:^.]+)\\\\b`); function jn(e, t) { return ({ name: r, value: n }) => { let i = r.match(pr()), o = r.match(/:([a-zA-Z0-9\\-_:]+)/), s = r.match(/\\.[^.\\]]+(?=[^\\]]*$)/g) || [], a = t || e[r] || r; return { type: i ? i[1] : null, value: o ? o[1] : null, modifiers: s.map(c => c.replace(\".\", \"\")), expression: n, original: a } } } var yt = \"DEFAULT\", W = [\"ignore\", \"ref\", \"data\", \"id\", \"anchor\", \"bind\", \"init\", \"for\", \"model\", \"modelable\", \"transition\", \"show\", \"if\", yt, \"teleport\"]; function Fn(e, t) { let r = W.indexOf(e.type) === -1 ? yt : e.type, n = W.indexOf(t.type) === -1 ? yt : t.type; return W.indexOf(r) - W.indexOf(n) } function G(e, t, r = {}) { e.dispatchEvent(new CustomEvent(t, { detail: r, bubbles: !0, composed: !0, cancelable: !0 })) } function T(e, t) { if (typeof ShadowRoot == \"function\" && e instanceof ShadowRoot) { Array.from(e.children).forEach(i => T(i, t)); return } let r = !1; if (t(e, () => r = !0), r) return; let n = e.firstElementChild; for (; n;)T(n, t, !1), n = n.nextElementSibling } function E(e, ...t) { console.warn(`Alpine Warning: ${e}`, ...t) } var mr = !1; function _r() { mr && E(\"Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems.\"), mr = !0, document.body || E(\"Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?\"), G(document, \"alpine:init\"), G(document, \"alpine:initializing\"), le(), Zt(t => S(t, T)), ee(t => vt(t)), Ae((t, r) => { de(t, r).forEach(n => n()) }); let e = t => !J(t.parentElement, !0); Array.from(document.querySelectorAll(xr().join(\",\"))).filter(e).forEach(t => { S(t) }), G(document, \"alpine:initialized\"), setTimeout(() => { Bn() }) } var Et = [], hr = []; function gr() { return Et.map(e => e()) } function xr() { return Et.concat(hr).map(e => e()) } function Le(e) { Et.push(e) } function $e(e) { hr.push(e) } function J(e, t = !1) { return z(e, r => { if ((t ? xr() : gr()).some(i => r.matches(i))) return !0 }) } function z(e, t) { if (e) { if (t(e)) return e; if (e._x_teleportBack && (e = e._x_teleportBack), !!e.parentElement) return z(e.parentElement, t) } } function yr(e) { return gr().some(t => e.matches(t)) } var br = []; function wr(e) { br.push(e) } function S(e, t = T, r = () => { }) { lr(() => { t(e, (n, i) => { r(n, i), br.forEach(o => o(n, i)), de(n, n.attributes).forEach(o => o()), n._x_ignore && i() }) }) } function vt(e, t = T) { t(e, r => { ct(r), Qt(r) }) } function Bn() { [[\"ui\", \"dialog\", [\"[x-dialog], [x-popover]\"]], [\"anchor\", \"anchor\", [\"[x-anchor]\"]], [\"sort\", \"sort\", [\"[x-sort]\"]]].forEach(([t, r, n]) => { ar(r) || n.some(i => { if (document.querySelector(i)) return E(`found \"${i}\", but missing ${t} plugin`), !0 }) }) } var St = [], At = !1; function ne(e = () => { }) { return queueMicrotask(() => { At || setTimeout(() => { je() }) }), new Promise(t => { St.push(() => { e(), t() }) }) } function je() { for (At = !1; St.length;)St.shift()() } function Er() { At = !0 } function pe(e, t) { return Array.isArray(t) ? vr(e, t.join(\" \")) : typeof t == \"object\" && t !== null ? zn(e, t) : typeof t == \"function\" ? pe(e, t()) : vr(e, t) } function vr(e, t) { let r = o => o.split(\" \").filter(Boolean), n = o => o.split(\" \").filter(s => !e.classList.contains(s)).filter(Boolean), i = o => (e.classList.add(...o), () => { e.classList.remove(...o) }); return t = t === !0 ? t = \"\" : t || \"\", i(n(t)) } function zn(e, t) { let r = a => a.split(\" \").filter(Boolean), n = Object.entries(t).flatMap(([a, c]) => c ? r(a) : !1).filter(Boolean), i = Object.entries(t).flatMap(([a, c]) => c ? !1 : r(a)).filter(Boolean), o = [], s = []; return i.forEach(a => { e.classList.contains(a) && (e.classList.remove(a), s.push(a)) }), n.forEach(a => { e.classList.contains(a) || (e.classList.add(a), o.push(a)) }), () => { s.forEach(a => e.classList.add(a)), o.forEach(a => e.classList.remove(a)) } } function Y(e, t) { return typeof t == \"object\" && t !== null ? Kn(e, t) : Hn(e, t) } function Kn(e, t) { let r = {}; return Object.entries(t).forEach(([n, i]) => { r[n] = e.style[n], n.startsWith(\"--\") || (n = Vn(n)), e.style.setProperty(n, i) }), setTimeout(() => { e.style.length === 0 && e.removeAttribute(\"style\") }), () => { Y(e, r) } } function Hn(e, t) { let r = e.getAttribute(\"style\", t); return e.setAttribute(\"style\", t), () => { e.setAttribute(\"style\", r || \"\") } } function Vn(e) { return e.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase() } function me(e, t = () => { }) { let r = !1; return function () { r ? t.apply(this, arguments) : (r = !0, e.apply(this, arguments)) } } d(\"transition\", (e, { value: t, modifiers: r, expression: n }, { evaluate: i }) => { typeof n == \"function\" && (n = i(n)), n !== !1 && (!n || typeof n == \"boolean\" ? Un(e, r, t) : qn(e, n, t)) }); function qn(e, t, r) { Sr(e, pe, \"\"), { enter: i => { e._x_transition.enter.during = i }, \"enter-start\": i => { e._x_transition.enter.start = i }, \"enter-end\": i => { e._x_transition.enter.end = i }, leave: i => { e._x_transition.leave.during = i }, \"leave-start\": i => { e._x_transition.leave.start = i }, \"leave-end\": i => { e._x_transition.leave.end = i } }[r](t) } function Un(e, t, r) { Sr(e, Y); let n = !t.includes(\"in\") && !t.includes(\"out\") && !r, i = n || t.includes(\"in\") || [\"enter\"].includes(r), o = n || t.includes(\"out\") || [\"leave\"].includes(r); t.includes(\"in\") && !n && (t = t.filter((g, b) => b < t.indexOf(\"out\"))), t.includes(\"out\") && !n && (t = t.filter((g, b) => b > t.indexOf(\"out\"))); let s = !t.includes(\"opacity\") && !t.includes(\"scale\"), a = s || t.includes(\"opacity\"), c = s || t.includes(\"scale\"), l = a ? 0 : 1, u = c ? _e(t, \"scale\", 95) / 100 : 1, p = _e(t, \"delay\", 0) / 1e3, m = _e(t, \"origin\", \"center\"), w = \"opacity, transform\", $ = _e(t, \"duration\", 150) / 1e3, we = _e(t, \"duration\", 75) / 1e3, f = \"cubic-bezier(0.4, 0.0, 0.2, 1)\"; i && (e._x_transition.enter.during = { transformOrigin: m, transitionDelay: `${p}s`, transitionProperty: w, transitionDuration: `${$}s`, transitionTimingFunction: f }, e._x_transition.enter.start = { opacity: l, transform: `scale(${u})` }, e._x_transition.enter.end = { opacity: 1, transform: \"scale(1)\" }), o && (e._x_transition.leave.during = { transformOrigin: m, transitionDelay: `${p}s`, transitionProperty: w, transitionDuration: `${we}s`, transitionTimingFunction: f }, e._x_transition.leave.start = { opacity: 1, transform: \"scale(1)\" }, e._x_transition.leave.end = { opacity: l, transform: `scale(${u})` }) } function Sr(e, t, r = {}) { e._x_transition || (e._x_transition = { enter: { during: r, start: r, end: r }, leave: { during: r, start: r, end: r }, in(n = () => { }, i = () => { }) { Fe(e, t, { during: this.enter.during, start: this.enter.start, end: this.enter.end }, n, i) }, out(n = () => { }, i = () => { }) { Fe(e, t, { during: this.leave.during, start: this.leave.start, end: this.leave.end }, n, i) } }) } window.Element.prototype._x_toggleAndCascadeWithTransitions = function (e, t, r, n) { let i = document.visibilityState === \"visible\" ? requestAnimationFrame : setTimeout, o = () => i(r); if (t) { e._x_transition && (e._x_transition.enter || e._x_transition.leave) ? e._x_transition.enter && (Object.entries(e._x_transition.enter.during).length || Object.entries(e._x_transition.enter.start).length || Object.entries(e._x_transition.enter.end).length) ? e._x_transition.in(r) : o() : e._x_transition ? e._x_transition.in(r) : o(); return } e._x_hidePromise = e._x_transition ? new Promise((s, a) => { e._x_transition.out(() => { }, () => s(n)), e._x_transitioning && e._x_transitioning.beforeCancel(() => a({ isFromCancelledTransition: !0 })) }) : Promise.resolve(n), queueMicrotask(() => { let s = Ar(e); s ? (s._x_hideChildren || (s._x_hideChildren = []), s._x_hideChildren.push(e)) : i(() => { let a = c => { let l = Promise.all([c._x_hidePromise, ...(c._x_hideChildren || []).map(a)]).then(([u]) => u?.()); return delete c._x_hidePromise, delete c._x_hideChildren, l }; a(e).catch(c => { if (!c.isFromCancelledTransition) throw c }) }) }) }; function Ar(e) { let t = e.parentNode; if (t) return t._x_hidePromise ? t : Ar(t) } function Fe(e, t, { during: r, start: n, end: i } = {}, o = () => { }, s = () => { }) { if (e._x_transitioning && e._x_transitioning.cancel(), Object.keys(r).length === 0 && Object.keys(n).length === 0 && Object.keys(i).length === 0) { o(), s(); return } let a, c, l; Wn(e, { start() { a = t(e, n) }, during() { c = t(e, r) }, before: o, end() { a(), l = t(e, i) }, after: s, cleanup() { c(), l() } }) } function Wn(e, t) { let r, n, i, o = me(() => { _(() => { r = !0, n || t.before(), i || (t.end(), je()), t.after(), e.isConnected && t.cleanup(), delete e._x_transitioning }) }); e._x_transitioning = { beforeCancels: [], beforeCancel(s) { this.beforeCancels.push(s) }, cancel: me(function () { for (; this.beforeCancels.length;)this.beforeCancels.shift()(); o() }), finish: o }, _(() => { t.start(), t.during() }), Er(), requestAnimationFrame(() => { if (r) return; let s = Number(getComputedStyle(e).transitionDuration.replace(/,.*/, \"\").replace(\"s\", \"\")) * 1e3, a = Number(getComputedStyle(e).transitionDelay.replace(/,.*/, \"\").replace(\"s\", \"\")) * 1e3; s === 0 && (s = Number(getComputedStyle(e).animationDuration.replace(\"s\", \"\")) * 1e3), _(() => { t.before() }), n = !0, requestAnimationFrame(() => { r || (_(() => { t.end() }), je(), setTimeout(e._x_transitioning.finish, s + a), i = !0) }) }) } function _e(e, t, r) { if (e.indexOf(t) === -1) return r; let n = e[e.indexOf(t) + 1]; if (!n || t === \"scale\" && isNaN(n)) return r; if (t === \"duration\" || t === \"delay\") { let i = n.match(/([0-9]+)ms/); if (i) return i[1] } return t === \"origin\" && [\"top\", \"right\", \"left\", \"center\", \"bottom\"].includes(e[e.indexOf(t) + 2]) ? [n, e[e.indexOf(t) + 2]].join(\" \") : n } var I = !1; function A(e, t = () => { }) { return (...r) => I ? t(...r) : e(...r) } function Or(e) { return (...t) => I && e(...t) } var Cr = []; function K(e) { Cr.push(e) } function Tr(e, t) { Cr.forEach(r => r(e, t)), I = !0, Mr(() => { S(t, (r, n) => { n(r, () => { }) }) }), I = !1 } var Be = !1; function Rr(e, t) { t._x_dataStack || (t._x_dataStack = e._x_dataStack), I = !0, Be = !0, Mr(() => { Gn(t) }), I = !1, Be = !1 } function Gn(e) { let t = !1; S(e, (n, i) => { T(n, (o, s) => { if (t && yr(o)) return s(); t = !0, i(o, s) }) }) } function Mr(e) { let t = D; at((r, n) => { let i = t(r); return L(i), () => { } }), e(), at(t) } function he(e, t, r, n = []) { switch (e._x_bindings || (e._x_bindings = R({})), e._x_bindings[t] = r, t = n.includes(\"camel\") ? ri(t) : t, t) { case \"value\": Jn(e, r); break; case \"style\": Xn(e, r); break; case \"class\": Yn(e, r); break; case \"selected\": case \"checked\": Zn(e, t, r); break; default: Dr(e, t, r); break } } function Jn(e, t) { if (e.type === \"radio\") e.attributes.value === void 0 && (e.value = t), window.fromModel && (typeof t == \"boolean\" ? e.checked = ge(e.value) === t : e.checked = Nr(e.value, t)); else if (e.type === \"checkbox\") Number.isInteger(t) ? e.value = t : !Array.isArray(t) && typeof t != \"boolean\" && ![null, void 0].includes(t) ? e.value = String(t) : Array.isArray(t) ? e.checked = t.some(r => Nr(r, e.value)) : e.checked = !!t; else if (e.tagName === \"SELECT\") ti(e, t); else { if (e.value === t) return; e.value = t === void 0 ? \"\" : t } } function Yn(e, t) { e._x_undoAddedClasses && e._x_undoAddedClasses(), e._x_undoAddedClasses = pe(e, t) } function Xn(e, t) { e._x_undoAddedStyles && e._x_undoAddedStyles(), e._x_undoAddedStyles = Y(e, t) } function Zn(e, t, r) { Dr(e, t, r), ei(e, t, r) } function Dr(e, t, r) { [null, void 0, !1].includes(r) && ni(t) ? e.removeAttribute(t) : (Pr(t) && (r = t), Qn(e, t, r)) } function Qn(e, t, r) { e.getAttribute(t) != r && e.setAttribute(t, r) } function ei(e, t, r) { e[t] !== r && (e[t] = r) } function ti(e, t) { let r = [].concat(t).map(n => n + \"\"); Array.from(e.options).forEach(n => { n.selected = r.includes(n.value) }) } function ri(e) { return e.toLowerCase().replace(/-(\\w)/g, (t, r) => r.toUpperCase()) } function Nr(e, t) { return e == t } function ge(e) { return [1, \"1\", \"true\", \"on\", \"yes\", !0].includes(e) ? !0 : [0, \"0\", \"false\", \"off\", \"no\", !1].includes(e) ? !1 : e ? Boolean(e) : null } function Pr(e) { return [\"disabled\", \"checked\", \"required\", \"readonly\", \"open\", \"selected\", \"autofocus\", \"itemscope\", \"multiple\", \"novalidate\", \"allowfullscreen\", \"allowpaymentrequest\", \"formnovalidate\", \"autoplay\", \"controls\", \"loop\", \"muted\", \"playsinline\", \"default\", \"ismap\", \"reversed\", \"async\", \"defer\", \"nomodule\"].includes(e) } function ni(e) { return ![\"aria-pressed\", \"aria-checked\", \"aria-expanded\", \"aria-selected\"].includes(e) } function Ir(e, t, r) { return e._x_bindings && e._x_bindings[t] !== void 0 ? e._x_bindings[t] : Lr(e, t, r) } function kr(e, t, r, n = !0) { if (e._x_bindings && e._x_bindings[t] !== void 0) return e._x_bindings[t]; if (e._x_inlineBindings && e._x_inlineBindings[t] !== void 0) { let i = e._x_inlineBindings[t]; return i.extract = n, De(() => M(e, i.expression)) } return Lr(e, t, r) } function Lr(e, t, r) { let n = e.getAttribute(t); return n === null ? typeof r == \"function\" ? r() : r : n === \"\" ? !0 : Pr(t) ? !![t, \"true\"].includes(n) : n } function ze(e, t) { var r; return function () { var n = this, i = arguments, o = function () { r = null, e.apply(n, i) }; clearTimeout(r), r = setTimeout(o, t) } } function Ke(e, t) { let r; return function () { let n = this, i = arguments; r || (e.apply(n, i), r = !0, setTimeout(() => r = !1, t)) } } function He({ get: e, set: t }, { get: r, set: n }) { let i = !0, o, s, a = D(() => { let c = e(), l = r(); if (i) n(Ot(c)), i = !1; else { let u = JSON.stringify(c), p = JSON.stringify(l); u !== o ? n(Ot(c)) : u !== p && t(Ot(l)) } o = JSON.stringify(e()), s = JSON.stringify(r()) }); return () => { L(a) } } function Ot(e) { return typeof e == \"object\" ? JSON.parse(JSON.stringify(e)) : e } function $r(e) { (Array.isArray(e) ? e : [e]).forEach(r => r(B)) } var X = {}, jr = !1; function Fr(e, t) { if (jr || (X = R(X), jr = !0), t === void 0) return X[e]; X[e] = t, typeof t == \"object\" && t !== null && t.hasOwnProperty(\"init\") && typeof t.init == \"function\" && X[e].init(), Te(X[e]) } function Br() { return X } var zr = {}; function Kr(e, t) { let r = typeof t != \"function\" ? () => t : t; return e instanceof Element ? Ct(e, r()) : (zr[e] = r, () => { }) } function Hr(e) { return Object.entries(zr).forEach(([t, r]) => { Object.defineProperty(e, t, { get() { return (...n) => r(...n) } }) }), e } function Ct(e, t, r) { let n = []; for (; n.length;)n.pop()(); let i = Object.entries(t).map(([s, a]) => ({ name: s, value: a })), o = wt(i); return i = i.map(s => o.find(a => a.name === s.name) ? { name: `x-bind:${s.name}`, value: `\"${s.value}\"` } : s), de(e, i, r).map(s => { n.push(s.runCleanups), s() }), () => { for (; n.length;)n.pop()() } } var Vr = {}; function qr(e, t) { Vr[e] = t } function Ur(e, t) { return Object.entries(Vr).forEach(([r, n]) => { Object.defineProperty(e, r, { get() { return (...i) => n.bind(t)(...i) }, enumerable: !1 }) }), e } var ii = { get reactive() { return R }, get release() { return L }, get effect() { return D }, get raw() { return st }, version: \"3.14.1\", flushAndStopDeferringMutations: tr, dontAutoEvaluateFunctions: De, disableEffectScheduling: Ut, startObservingMutations: le, stopObservingMutations: ft, setReactivityEngine: Wt, onAttributeRemoved: Oe, onAttributesAdded: Ae, closestDataStack: j, skipDuringClone: A, onlyDuringClone: Or, addRootSelector: Le, addInitSelector: $e, interceptClone: K, addScopeToNode: P, deferMutations: er, mapAttributes: re, evaluateLater: x, interceptInit: wr, setEvaluator: or, mergeProxies: F, extractProp: kr, findClosest: z, onElRemoved: ee, closestRoot: J, destroyTree: vt, interceptor: Re, transition: Fe, setStyles: Y, mutateDom: _, directive: d, entangle: He, throttle: Ke, debounce: ze, evaluate: M, initTree: S, nextTick: ne, prefixed: C, prefix: sr, plugin: $r, magic: y, store: Fr, start: _r, clone: Rr, cloneNode: Tr, bound: Ir, $data: Ce, watch: ve, walk: T, data: qr, bind: Kr }, B = ii; function Tt(e, t) { let r = Object.create(null), n = e.split(\",\"); for (let i = 0; i < n.length; i++)r[n[i]] = !0; return t ? i => !!r[i.toLowerCase()] : i => !!r[i] } var oi = \"itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly\"; var Ms = Tt(oi + \",async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected\"); var Wr = Object.freeze({}), Ns = Object.freeze([]); var si = Object.prototype.hasOwnProperty, xe = (e, t) => si.call(e, t), H = Array.isArray, ie = e => Gr(e) === \"[object Map]\"; var ai = e => typeof e == \"string\", Ve = e => typeof e == \"symbol\", ye = e => e !== null && typeof e == \"object\"; var ci = Object.prototype.toString, Gr = e => ci.call(e), Rt = e => Gr(e).slice(8, -1); var qe = e => ai(e) && e !== \"NaN\" && e[0] !== \"-\" && \"\" + parseInt(e, 10) === e; var Ue = e => { let t = Object.create(null); return r => t[r] || (t[r] = e(r)) }, li = /-(\\w)/g, Ds = Ue(e => e.replace(li, (t, r) => r ? r.toUpperCase() : \"\")), ui = /\\B([A-Z])/g, Ps = Ue(e => e.replace(ui, \"-$1\").toLowerCase()), Mt = Ue(e => e.charAt(0).toUpperCase() + e.slice(1)), Is = Ue(e => e ? `on${Mt(e)}` : \"\"), Nt = (e, t) => e !== t && (e === e || t === t); var Dt = new WeakMap, be = [], k, Z = Symbol(\"iterate\"), Pt = Symbol(\"Map key iterate\"); function fi(e) { return e && e._isEffect === !0 } function en(e, t = Wr) { fi(e) && (e = e.raw); let r = pi(e, t); return t.lazy || r(), r } function tn(e) { e.active && (rn(e), e.options.onStop && e.options.onStop(), e.active = !1) } var di = 0; function pi(e, t) { let r = function () { if (!r.active) return e(); if (!be.includes(r)) { rn(r); try { return _i(), be.push(r), k = r, e() } finally { be.pop(), nn(), k = be[be.length - 1] } } }; return r.id = di++, r.allowRecurse = !!t.allowRecurse, r._isEffect = !0, r.active = !0, r.raw = e, r.deps = [], r.options = t, r } function rn(e) { let { deps: t } = e; if (t.length) { for (let r = 0; r < t.length; r++)t[r].delete(e); t.length = 0 } } var oe = !0, kt = []; function mi() { kt.push(oe), oe = !1 } function _i() { kt.push(oe), oe = !0 } function nn() { let e = kt.pop(); oe = e === void 0 ? !0 : e } function N(e, t, r) { if (!oe || k === void 0) return; let n = Dt.get(e); n || Dt.set(e, n = new Map); let i = n.get(r); i || n.set(r, i = new Set), i.has(k) || (i.add(k), k.deps.push(i), k.options.onTrack && k.options.onTrack({ effect: k, target: e, type: t, key: r })) } function q(e, t, r, n, i, o) { let s = Dt.get(e); if (!s) return; let a = new Set, c = u => { u && u.forEach(p => { (p !== k || p.allowRecurse) && a.add(p) }) }; if (t === \"clear\") s.forEach(c); else if (r === \"length\" && H(e)) s.forEach((u, p) => { (p === \"length\" || p >= n) && c(u) }); else switch (r !== void 0 && c(s.get(r)), t) { case \"add\": H(e) ? qe(r) && c(s.get(\"length\")) : (c(s.get(Z)), ie(e) && c(s.get(Pt))); break; case \"delete\": H(e) || (c(s.get(Z)), ie(e) && c(s.get(Pt))); break; case \"set\": ie(e) && c(s.get(Z)); break }let l = u => { u.options.onTrigger && u.options.onTrigger({ effect: u, target: e, key: r, type: t, newValue: n, oldValue: i, oldTarget: o }), u.options.scheduler ? u.options.scheduler(u) : u() }; a.forEach(l) } var hi = Tt(\"__proto__,__v_isRef,__isVue\"), on = new Set(Object.getOwnPropertyNames(Symbol).map(e => Symbol[e]).filter(Ve)), gi = sn(); var xi = sn(!0); var Jr = yi(); function yi() { let e = {}; return [\"includes\", \"indexOf\", \"lastIndexOf\"].forEach(t => { e[t] = function (...r) { let n = h(this); for (let o = 0, s = this.length; o < s; o++)N(n, \"get\", o + \"\"); let i = n[t](...r); return i === -1 || i === !1 ? n[t](...r.map(h)) : i } }), [\"push\", \"pop\", \"shift\", \"unshift\", \"splice\"].forEach(t => { e[t] = function (...r) { mi(); let n = h(this)[t].apply(this, r); return nn(), n } }), e } function sn(e = !1, t = !1) { return function (n, i, o) { if (i === \"__v_isReactive\") return !e; if (i === \"__v_isReadonly\") return e; if (i === \"__v_raw\" && o === (e ? t ? ki : un : t ? Ii : ln).get(n)) return n; let s = H(n); if (!e && s && xe(Jr, i)) return Reflect.get(Jr, i, o); let a = Reflect.get(n, i, o); return (Ve(i) ? on.has(i) : hi(i)) || (e || N(n, \"get\", i), t) ? a : It(a) ? !s || !qe(i) ? a.value : a : ye(a) ? e ? fn(a) : Qe(a) : a } } var bi = wi(); function wi(e = !1) { return function (r, n, i, o) { let s = r[n]; if (!e && (i = h(i), s = h(s), !H(r) && It(s) && !It(i))) return s.value = i, !0; let a = H(r) && qe(n) ? Number(n) < r.length : xe(r, n), c = Reflect.set(r, n, i, o); return r === h(o) && (a ? Nt(i, s) && q(r, \"set\", n, i, s) : q(r, \"add\", n, i)), c } } function Ei(e, t) { let r = xe(e, t), n = e[t], i = Reflect.deleteProperty(e, t); return i && r && q(e, \"delete\", t, void 0, n), i } function vi(e, t) { let r = Reflect.has(e, t); return (!Ve(t) || !on.has(t)) && N(e, \"has\", t), r } function Si(e) { return N(e, \"iterate\", H(e) ? \"length\" : Z), Reflect.ownKeys(e) } var Ai = { get: gi, set: bi, deleteProperty: Ei, has: vi, ownKeys: Si }, Oi = { get: xi, set(e, t) { return console.warn(`Set operation on key \"${String(t)}\" failed: target is readonly.`, e), !0 }, deleteProperty(e, t) { return console.warn(`Delete operation on key \"${String(t)}\" failed: target is readonly.`, e), !0 } }; var Lt = e => ye(e) ? Qe(e) : e, $t = e => ye(e) ? fn(e) : e, jt = e => e, Ze = e => Reflect.getPrototypeOf(e); function We(e, t, r = !1, n = !1) { e = e.__v_raw; let i = h(e), o = h(t); t !== o && !r && N(i, \"get\", t), !r && N(i, \"get\", o); let { has: s } = Ze(i), a = n ? jt : r ? $t : Lt; if (s.call(i, t)) return a(e.get(t)); if (s.call(i, o)) return a(e.get(o)); e !== i && e.get(t) } function Ge(e, t = !1) { let r = this.__v_raw, n = h(r), i = h(e); return e !== i && !t && N(n, \"has\", e), !t && N(n, \"has\", i), e === i ? r.has(e) : r.has(e) || r.has(i) } function Je(e, t = !1) { return e = e.__v_raw, !t && N(h(e), \"iterate\", Z), Reflect.get(e, \"size\", e) } function Yr(e) { e = h(e); let t = h(this); return Ze(t).has.call(t, e) || (t.add(e), q(t, \"add\", e, e)), this } function Xr(e, t) { t = h(t); let r = h(this), { has: n, get: i } = Ze(r), o = n.call(r, e); o ? cn(r, n, e) : (e = h(e), o = n.call(r, e)); let s = i.call(r, e); return r.set(e, t), o ? Nt(t, s) && q(r, \"set\", e, t, s) : q(r, \"add\", e, t), this } function Zr(e) { let t = h(this), { has: r, get: n } = Ze(t), i = r.call(t, e); i ? cn(t, r, e) : (e = h(e), i = r.call(t, e)); let o = n ? n.call(t, e) : void 0, s = t.delete(e); return i && q(t, \"delete\", e, void 0, o), s } function Qr() { let e = h(this), t = e.size !== 0, r = ie(e) ? new Map(e) : new Set(e), n = e.clear(); return t && q(e, \"clear\", void 0, void 0, r), n } function Ye(e, t) { return function (n, i) { let o = this, s = o.__v_raw, a = h(s), c = t ? jt : e ? $t : Lt; return !e && N(a, \"iterate\", Z), s.forEach((l, u) => n.call(i, c(l), c(u), o)) } } function Xe(e, t, r) { return function (...n) { let i = this.__v_raw, o = h(i), s = ie(o), a = e === \"entries\" || e === Symbol.iterator && s, c = e === \"keys\" && s, l = i[e](...n), u = r ? jt : t ? $t : Lt; return !t && N(o, \"iterate\", c ? Pt : Z), { next() { let { value: p, done: m } = l.next(); return m ? { value: p, done: m } : { value: a ? [u(p[0]), u(p[1])] : u(p), done: m } }, [Symbol.iterator]() { return this } } } } function V(e) { return function (...t) { { let r = t[0] ? `on key \"${t[0]}\" ` : \"\"; console.warn(`${Mt(e)} operation ${r}failed: target is readonly.`, h(this)) } return e === \"delete\" ? !1 : this } } function Ci() { let e = { get(o) { return We(this, o) }, get size() { return Je(this) }, has: Ge, add: Yr, set: Xr, delete: Zr, clear: Qr, forEach: Ye(!1, !1) }, t = { get(o) { return We(this, o, !1, !0) }, get size() { return Je(this) }, has: Ge, add: Yr, set: Xr, delete: Zr, clear: Qr, forEach: Ye(!1, !0) }, r = { get(o) { return We(this, o, !0) }, get size() { return Je(this, !0) }, has(o) { return Ge.call(this, o, !0) }, add: V(\"add\"), set: V(\"set\"), delete: V(\"delete\"), clear: V(\"clear\"), forEach: Ye(!0, !1) }, n = { get(o) { return We(this, o, !0, !0) }, get size() { return Je(this, !0) }, has(o) { return Ge.call(this, o, !0) }, add: V(\"add\"), set: V(\"set\"), delete: V(\"delete\"), clear: V(\"clear\"), forEach: Ye(!0, !0) }; return [\"keys\", \"values\", \"entries\", Symbol.iterator].forEach(o => { e[o] = Xe(o, !1, !1), r[o] = Xe(o, !0, !1), t[o] = Xe(o, !1, !0), n[o] = Xe(o, !0, !0) }), [e, r, t, n] } var [Ti, Ri, Mi, Ni] = Ci(); function an(e, t) { let r = t ? e ? Ni : Mi : e ? Ri : Ti; return (n, i, o) => i === \"__v_isReactive\" ? !e : i === \"__v_isReadonly\" ? e : i === \"__v_raw\" ? n : Reflect.get(xe(r, i) && i in n ? r : n, i, o) } var Di = { get: an(!1, !1) }; var Pi = { get: an(!0, !1) }; function cn(e, t, r) { let n = h(r); if (n !== r && t.call(e, n)) { let i = Rt(e); console.warn(`Reactive ${i} contains both the raw and reactive versions of the same object${i === \"Map\" ? \" as keys\" : \"\"}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`) } } var ln = new WeakMap, Ii = new WeakMap, un = new WeakMap, ki = new WeakMap; function Li(e) { switch (e) { case \"Object\": case \"Array\": return 1; case \"Map\": case \"Set\": case \"WeakMap\": case \"WeakSet\": return 2; default: return 0 } } function $i(e) { return e.__v_skip || !Object.isExtensible(e) ? 0 : Li(Rt(e)) } function Qe(e) { return e && e.__v_isReadonly ? e : dn(e, !1, Ai, Di, ln) } function fn(e) { return dn(e, !0, Oi, Pi, un) } function dn(e, t, r, n, i) { if (!ye(e)) return console.warn(`value cannot be made reactive: ${String(e)}`), e; if (e.__v_raw && !(t && e.__v_isReactive)) return e; let o = i.get(e); if (o) return o; let s = $i(e); if (s === 0) return e; let a = new Proxy(e, s === 2 ? n : r); return i.set(e, a), a } function h(e) { return e && h(e.__v_raw) || e } function It(e) { return Boolean(e && e.__v_isRef === !0) } y(\"nextTick\", () => ne); y(\"dispatch\", e => G.bind(G, e)); y(\"watch\", (e, { evaluateLater: t, cleanup: r }) => (n, i) => { let o = t(n), a = ve(() => { let c; return o(l => c = l), c }, i); r(a) }); y(\"store\", Br); y(\"data\", e => Ce(e)); y(\"root\", e => J(e)); y(\"refs\", e => (e._x_refs_proxy || (e._x_refs_proxy = F(ji(e))), e._x_refs_proxy)); function ji(e) { let t = []; return z(e, r => { r._x_refs && t.push(r._x_refs) }), t } var Ft = {}; function Bt(e) { return Ft[e] || (Ft[e] = 0), ++Ft[e] } function pn(e, t) { return z(e, r => { if (r._x_ids && r._x_ids[t]) return !0 }) } function mn(e, t) { e._x_ids || (e._x_ids = {}), e._x_ids[t] || (e._x_ids[t] = Bt(t)) } y(\"id\", (e, { cleanup: t }) => (r, n = null) => { let i = `${r}${n ? `-${n}` : \"\"}`; return Fi(e, i, t, () => { let o = pn(e, r), s = o ? o._x_ids[r] : Bt(r); return n ? `${r}-${s}-${n}` : `${r}-${s}` }) }); K((e, t) => { e._x_id && (t._x_id = e._x_id) }); function Fi(e, t, r, n) { if (e._x_id || (e._x_id = {}), e._x_id[t]) return e._x_id[t]; let i = n(); return e._x_id[t] = i, r(() => { delete e._x_id[t] }), i } y(\"el\", e => e); _n(\"Focus\", \"focus\", \"focus\"); _n(\"Persist\", \"persist\", \"persist\"); function _n(e, t, r) { y(t, n => E(`You can't use [$${t}] without first installing the \"${e}\" plugin here: https://alpinejs.dev/plugins/${r}`, n)) } d(\"modelable\", (e, { expression: t }, { effect: r, evaluateLater: n, cleanup: i }) => { let o = n(t), s = () => { let u; return o(p => u = p), u }, a = n(`${t} = __placeholder`), c = u => a(() => { }, { scope: { __placeholder: u } }), l = s(); c(l), queueMicrotask(() => { if (!e._x_model) return; e._x_removeModelListeners.default(); let u = e._x_model.get, p = e._x_model.set, m = He({ get() { return u() }, set(w) { p(w) } }, { get() { return s() }, set(w) { c(w) } }); i(m) }) }); d(\"teleport\", (e, { modifiers: t, expression: r }, { cleanup: n }) => { e.tagName.toLowerCase() !== \"template\" && E(\"x-teleport can only be used on a <template> tag\", e); let i = hn(r), o = e.content.cloneNode(!0).firstElementChild; e._x_teleport = o, o._x_teleportBack = e, e.setAttribute(\"data-teleport-template\", !0), o.setAttribute(\"data-teleport-target\", !0), e._x_forwardEvents && e._x_forwardEvents.forEach(a => { o.addEventListener(a, c => { c.stopPropagation(), e.dispatchEvent(new c.constructor(c.type, c)) }) }), P(o, {}, e); let s = (a, c, l) => { l.includes(\"prepend\") ? c.parentNode.insertBefore(a, c) : l.includes(\"append\") ? c.parentNode.insertBefore(a, c.nextSibling) : c.appendChild(a) }; _(() => { s(o, i, t), A(() => { S(o), o._x_ignore = !0 })() }), e._x_teleportPutBack = () => { let a = hn(r); _(() => { s(e._x_teleport, a, t) }) }, n(() => o.remove()) }); var Bi = document.createElement(\"div\"); function hn(e) { let t = A(() => document.querySelector(e), () => Bi)(); return t || E(`Cannot find x-teleport element for selector: \"${e}\"`), t } var gn = () => { }; gn.inline = (e, { modifiers: t }, { cleanup: r }) => { t.includes(\"self\") ? e._x_ignoreSelf = !0 : e._x_ignore = !0, r(() => { t.includes(\"self\") ? delete e._x_ignoreSelf : delete e._x_ignore }) }; d(\"ignore\", gn); d(\"effect\", A((e, { expression: t }, { effect: r }) => { r(x(e, t)) })); function se(e, t, r, n) { let i = e, o = c => n(c), s = {}, a = (c, l) => u => l(c, u); if (r.includes(\"dot\") && (t = zi(t)), r.includes(\"camel\") && (t = Ki(t)), r.includes(\"passive\") && (s.passive = !0), r.includes(\"capture\") && (s.capture = !0), r.includes(\"window\") && (i = window), r.includes(\"document\") && (i = document), r.includes(\"debounce\")) { let c = r[r.indexOf(\"debounce\") + 1] || \"invalid-wait\", l = et(c.split(\"ms\")[0]) ? Number(c.split(\"ms\")[0]) : 250; o = ze(o, l) } if (r.includes(\"throttle\")) { let c = r[r.indexOf(\"throttle\") + 1] || \"invalid-wait\", l = et(c.split(\"ms\")[0]) ? Number(c.split(\"ms\")[0]) : 250; o = Ke(o, l) } return r.includes(\"prevent\") && (o = a(o, (c, l) => { l.preventDefault(), c(l) })), r.includes(\"stop\") && (o = a(o, (c, l) => { l.stopPropagation(), c(l) })), r.includes(\"once\") && (o = a(o, (c, l) => { c(l), i.removeEventListener(t, o, s) })), (r.includes(\"away\") || r.includes(\"outside\")) && (i = document, o = a(o, (c, l) => { e.contains(l.target) || l.target.isConnected !== !1 && (e.offsetWidth < 1 && e.offsetHeight < 1 || e._x_isShown !== !1 && c(l)) })), r.includes(\"self\") && (o = a(o, (c, l) => { l.target === e && c(l) })), (Vi(t) || yn(t)) && (o = a(o, (c, l) => { qi(l, r) || c(l) })), i.addEventListener(t, o, s), () => { i.removeEventListener(t, o, s) } } function zi(e) { return e.replace(/-/g, \".\") } function Ki(e) { return e.toLowerCase().replace(/-(\\w)/g, (t, r) => r.toUpperCase()) } function et(e) { return !Array.isArray(e) && !isNaN(e) } function Hi(e) { return [\" \", \"_\"].includes(e) ? e : e.replace(/([a-z])([A-Z])/g, \"$1-$2\").replace(/[_\\s]/, \"-\").toLowerCase() } function Vi(e) { return [\"keydown\", \"keyup\"].includes(e) } function yn(e) { return [\"contextmenu\", \"click\", \"mouse\"].some(t => e.includes(t)) } function qi(e, t) { let r = t.filter(o => ![\"window\", \"document\", \"prevent\", \"stop\", \"once\", \"capture\", \"self\", \"away\", \"outside\", \"passive\"].includes(o)); if (r.includes(\"debounce\")) { let o = r.indexOf(\"debounce\"); r.splice(o, et((r[o + 1] || \"invalid-wait\").split(\"ms\")[0]) ? 2 : 1) } if (r.includes(\"throttle\")) { let o = r.indexOf(\"throttle\"); r.splice(o, et((r[o + 1] || \"invalid-wait\").split(\"ms\")[0]) ? 2 : 1) } if (r.length === 0 || r.length === 1 && xn(e.key).includes(r[0])) return !1; let i = [\"ctrl\", \"shift\", \"alt\", \"meta\", \"cmd\", \"super\"].filter(o => r.includes(o)); return r = r.filter(o => !i.includes(o)), !(i.length > 0 && i.filter(s => ((s === \"cmd\" || s === \"super\") && (s = \"meta\"), e[`${s}Key`])).length === i.length && (yn(e.type) || xn(e.key).includes(r[0]))) } function xn(e) { if (!e) return []; e = Hi(e); let t = { ctrl: \"control\", slash: \"/\", space: \" \", spacebar: \" \", cmd: \"meta\", esc: \"escape\", up: \"arrow-up\", down: \"arrow-down\", left: \"arrow-left\", right: \"arrow-right\", period: \".\", comma: \",\", equal: \"=\", minus: \"-\", underscore: \"_\" }; return t[e] = e, Object.keys(t).map(r => { if (t[r] === e) return r }).filter(r => r) } d(\"model\", (e, { modifiers: t, expression: r }, { effect: n, cleanup: i }) => { let o = e; t.includes(\"parent\") && (o = e.parentNode); let s = x(o, r), a; typeof r == \"string\" ? a = x(o, `${r} = __placeholder`) : typeof r == \"function\" && typeof r() == \"string\" ? a = x(o, `${r()} = __placeholder`) : a = () => { }; let c = () => { let m; return s(w => m = w), bn(m) ? m.get() : m }, l = m => { let w; s($ => w = $), bn(w) ? w.set(m) : a(() => { }, { scope: { __placeholder: m } }) }; typeof r == \"string\" && e.type === \"radio\" && _(() => { e.hasAttribute(\"name\") || e.setAttribute(\"name\", r) }); var u = e.tagName.toLowerCase() === \"select\" || [\"checkbox\", \"radio\"].includes(e.type) || t.includes(\"lazy\") ? \"change\" : \"input\"; let p = I ? () => { } : se(e, u, t, m => { l(zt(e, t, m, c())) }); if (t.includes(\"fill\") && ([void 0, null, \"\"].includes(c()) || e.type === \"checkbox\" && Array.isArray(c()) || e.tagName.toLowerCase() === \"select\" && e.multiple) && l(zt(e, t, { target: e }, c())), e._x_removeModelListeners || (e._x_removeModelListeners = {}), e._x_removeModelListeners.default = p, i(() => e._x_removeModelListeners.default()), e.form) { let m = se(e.form, \"reset\", [], w => { ne(() => e._x_model && e._x_model.set(zt(e, t, { target: e }, c()))) }); i(() => m()) } e._x_model = { get() { return c() }, set(m) { l(m) } }, e._x_forceModelUpdate = m => { m === void 0 && typeof r == \"string\" && r.match(/\\./) && (m = \"\"), window.fromModel = !0, _(() => he(e, \"value\", m)), delete window.fromModel }, n(() => { let m = c(); t.includes(\"unintrusive\") && document.activeElement.isSameNode(e) || e._x_forceModelUpdate(m) }) }); function zt(e, t, r, n) { return _(() => { if (r instanceof CustomEvent && r.detail !== void 0) return r.detail !== null && r.detail !== void 0 ? r.detail : r.target.value; if (e.type === \"checkbox\") if (Array.isArray(n)) { let i = null; return t.includes(\"number\") ? i = Kt(r.target.value) : t.includes(\"boolean\") ? i = ge(r.target.value) : i = r.target.value, r.target.checked ? n.includes(i) ? n : n.concat([i]) : n.filter(o => !Ui(o, i)) } else return r.target.checked; else { if (e.tagName.toLowerCase() === \"select\" && e.multiple) return t.includes(\"number\") ? Array.from(r.target.selectedOptions).map(i => { let o = i.value || i.text; return Kt(o) }) : t.includes(\"boolean\") ? Array.from(r.target.selectedOptions).map(i => { let o = i.value || i.text; return ge(o) }) : Array.from(r.target.selectedOptions).map(i => i.value || i.text); { let i; return e.type === \"radio\" ? r.target.checked ? i = r.target.value : i = n : i = r.target.value, t.includes(\"number\") ? Kt(i) : t.includes(\"boolean\") ? ge(i) : t.includes(\"trim\") ? i.trim() : i } } }) } function Kt(e) { let t = e ? parseFloat(e) : null; return Wi(t) ? t : e } function Ui(e, t) { return e == t } function Wi(e) { return !Array.isArray(e) && !isNaN(e) } function bn(e) { return e !== null && typeof e == \"object\" && typeof e.get == \"function\" && typeof e.set == \"function\" } d(\"cloak\", e => queueMicrotask(() => _(() => e.removeAttribute(C(\"cloak\"))))); $e(() => `[${C(\"init\")}]`); d(\"init\", A((e, { expression: t }, { evaluate: r }) => typeof t == \"string\" ? !!t.trim() && r(t, {}, !1) : r(t, {}, !1))); d(\"text\", (e, { expression: t }, { effect: r, evaluateLater: n }) => { let i = n(t); r(() => { i(o => { _(() => { e.textContent = o }) }) }) }); d(\"html\", (e, { expression: t }, { effect: r, evaluateLater: n }) => { let i = n(t); r(() => { i(o => { _(() => { e.innerHTML = o, e._x_ignoreSelf = !0, S(e), delete e._x_ignoreSelf }) }) }) }); re(Ie(\":\", ke(C(\"bind:\")))); var wn = (e, { value: t, modifiers: r, expression: n, original: i }, { effect: o, cleanup: s }) => { if (!t) { let c = {}; Hr(c), x(e, n)(u => { Ct(e, u, i) }, { scope: c }); return } if (t === \"key\") return Gi(e, n); if (e._x_inlineBindings && e._x_inlineBindings[t] && e._x_inlineBindings[t].extract) return; let a = x(e, n); o(() => a(c => { c === void 0 && typeof n == \"string\" && n.match(/\\./) && (c = \"\"), _(() => he(e, t, c, r)) })), s(() => { e._x_undoAddedClasses && e._x_undoAddedClasses(), e._x_undoAddedStyles && e._x_undoAddedStyles() }) }; wn.inline = (e, { value: t, modifiers: r, expression: n }) => { t && (e._x_inlineBindings || (e._x_inlineBindings = {}), e._x_inlineBindings[t] = { expression: n, extract: !1 }) }; d(\"bind\", wn); function Gi(e, t) { e._x_keyExpression = t } Le(() => `[${C(\"data\")}]`); d(\"data\", (e, { expression: t }, { cleanup: r }) => { if (Ji(e)) return; t = t === \"\" ? \"{}\" : t; let n = {}; ue(n, e); let i = {}; Ur(i, n); let o = M(e, t, { scope: i }); (o === void 0 || o === !0) && (o = {}), ue(o, e); let s = R(o); Te(s); let a = P(e, s); s.init && M(e, s.init), r(() => { s.destroy && M(e, s.destroy), a() }) }); K((e, t) => { e._x_dataStack && (t._x_dataStack = e._x_dataStack, t.setAttribute(\"data-has-alpine-state\", !0)) }); function Ji(e) { return I ? Be ? !0 : e.hasAttribute(\"data-has-alpine-state\") : !1 } d(\"show\", (e, { modifiers: t, expression: r }, { effect: n }) => { let i = x(e, r); e._x_doHide || (e._x_doHide = () => { _(() => { e.style.setProperty(\"display\", \"none\", t.includes(\"important\") ? \"important\" : void 0) }) }), e._x_doShow || (e._x_doShow = () => { _(() => { e.style.length === 1 && e.style.display === \"none\" ? e.removeAttribute(\"style\") : e.style.removeProperty(\"display\") }) }); let o = () => { e._x_doHide(), e._x_isShown = !1 }, s = () => { e._x_doShow(), e._x_isShown = !0 }, a = () => setTimeout(s), c = me(p => p ? s() : o(), p => { typeof e._x_toggleAndCascadeWithTransitions == \"function\" ? e._x_toggleAndCascadeWithTransitions(e, p, s, o) : p ? a() : o() }), l, u = !0; n(() => i(p => { !u && p === l || (t.includes(\"immediate\") && (p ? a() : o()), c(p), l = p, u = !1) })) }); d(\"for\", (e, { expression: t }, { effect: r, cleanup: n }) => { let i = Xi(t), o = x(e, i.items), s = x(e, e._x_keyExpression || \"index\"); e._x_prevKeys = [], e._x_lookup = {}, r(() => Yi(e, i, o, s)), n(() => { Object.values(e._x_lookup).forEach(a => a.remove()), delete e._x_prevKeys, delete e._x_lookup }) }); function Yi(e, t, r, n) { let i = s => typeof s == \"object\" && !Array.isArray(s), o = e; r(s => { Zi(s) && s >= 0 && (s = Array.from(Array(s).keys(), f => f + 1)), s === void 0 && (s = []); let a = e._x_lookup, c = e._x_prevKeys, l = [], u = []; if (i(s)) s = Object.entries(s).map(([f, g]) => { let b = En(t, g, f, s); n(v => { u.includes(v) && E(\"Duplicate key on x-for\", e), u.push(v) }, { scope: { index: f, ...b } }), l.push(b) }); else for (let f = 0; f < s.length; f++) { let g = En(t, s[f], f, s); n(b => { u.includes(b) && E(\"Duplicate key on x-for\", e), u.push(b) }, { scope: { index: f, ...g } }), l.push(g) } let p = [], m = [], w = [], $ = []; for (let f = 0; f < c.length; f++) { let g = c[f]; u.indexOf(g) === -1 && w.push(g) } c = c.filter(f => !w.includes(f)); let we = \"template\"; for (let f = 0; f < u.length; f++) { let g = u[f], b = c.indexOf(g); if (b === -1) c.splice(f, 0, g), p.push([we, f]); else if (b !== f) { let v = c.splice(f, 1)[0], O = c.splice(b - 1, 1)[0]; c.splice(f, 0, O), c.splice(b, 0, v), m.push([v, O]) } else $.push(g); we = g } for (let f = 0; f < w.length; f++) { let g = w[f]; a[g]._x_effects && a[g]._x_effects.forEach(Ee), a[g].remove(), a[g] = null, delete a[g] } for (let f = 0; f < m.length; f++) { let [g, b] = m[f], v = a[g], O = a[b], Q = document.createElement(\"div\"); _(() => { O || E('x-for \":key\" is undefined or invalid', o, b, a), O.after(Q), v.after(O), O._x_currentIfEl && O.after(O._x_currentIfEl), Q.before(v), v._x_currentIfEl && v.after(v._x_currentIfEl), Q.remove() }), O._x_refreshXForScope(l[u.indexOf(b)]) } for (let f = 0; f < p.length; f++) { let [g, b] = p[f], v = g === \"template\" ? o : a[g]; v._x_currentIfEl && (v = v._x_currentIfEl); let O = l[b], Q = u[b], ae = document.importNode(o.content, !0).firstElementChild, Vt = R(O); P(ae, Vt, o), ae._x_refreshXForScope = Sn => { Object.entries(Sn).forEach(([An, On]) => { Vt[An] = On }) }, _(() => { v.after(ae), A(() => S(ae))() }), typeof Q == \"object\" && E(\"x-for key cannot be an object, it must be a string or an integer\", o), a[Q] = ae } for (let f = 0; f < $.length; f++)a[$[f]]._x_refreshXForScope(l[u.indexOf($[f])]); o._x_prevKeys = u }) } function Xi(e) { let t = /,([^,\\}\\]]*)(?:,([^,\\}\\]]*))?$/, r = /^\\s*\\(|\\)\\s*$/g, n = /([\\s\\S]*?)\\s+(?:in|of)\\s+([\\s\\S]*)/, i = e.match(n); if (!i) return; let o = {}; o.items = i[2].trim(); let s = i[1].replace(r, \"\").trim(), a = s.match(t); return a ? (o.item = s.replace(t, \"\").trim(), o.index = a[1].trim(), a[2] && (o.collection = a[2].trim())) : o.item = s, o } function En(e, t, r, n) { let i = {}; return /^\\[.*\\]$/.test(e.item) && Array.isArray(t) ? e.item.replace(\"[\", \"\").replace(\"]\", \"\").split(\",\").map(s => s.trim()).forEach((s, a) => { i[s] = t[a] }) : /^\\{.*\\}$/.test(e.item) && !Array.isArray(t) && typeof t == \"object\" ? e.item.replace(\"{\", \"\").replace(\"}\", \"\").split(\",\").map(s => s.trim()).forEach(s => { i[s] = t[s] }) : i[e.item] = t, e.index && (i[e.index] = r), e.collection && (i[e.collection] = n), i } function Zi(e) { return !Array.isArray(e) && !isNaN(e) } function vn() { } vn.inline = (e, { expression: t }, { cleanup: r }) => { let n = J(e); n._x_refs || (n._x_refs = {}), n._x_refs[t] = e, r(() => delete n._x_refs[t]) }; d(\"ref\", vn); d(\"if\", (e, { expression: t }, { effect: r, cleanup: n }) => { e.tagName.toLowerCase() !== \"template\" && E(\"x-if can only be used on a <template> tag\", e); let i = x(e, t), o = () => { if (e._x_currentIfEl) return e._x_currentIfEl; let a = e.content.cloneNode(!0).firstElementChild; return P(a, {}, e), _(() => { e.after(a), A(() => S(a))() }), e._x_currentIfEl = a, e._x_undoIf = () => { T(a, c => { c._x_effects && c._x_effects.forEach(Ee) }), a.remove(), delete e._x_currentIfEl }, a }, s = () => { e._x_undoIf && (e._x_undoIf(), delete e._x_undoIf) }; r(() => i(a => { a ? o() : s() })), n(() => e._x_undoIf && e._x_undoIf()) }); d(\"id\", (e, { expression: t }, { evaluate: r }) => { r(t).forEach(i => mn(e, i)) }); K((e, t) => { e._x_ids && (t._x_ids = e._x_ids) }); re(Ie(\"@\", ke(C(\"on:\")))); d(\"on\", A((e, { value: t, modifiers: r, expression: n }, { cleanup: i }) => { let o = n ? x(e, n) : () => { }; e.tagName.toLowerCase() === \"template\" && (e._x_forwardEvents || (e._x_forwardEvents = []), e._x_forwardEvents.includes(t) || e._x_forwardEvents.push(t)); let s = se(e, t, r, a => { o(() => { }, { scope: { $event: a }, params: [a] }) }); i(() => s()) })); tt(\"Collapse\", \"collapse\", \"collapse\"); tt(\"Intersect\", \"intersect\", \"intersect\"); tt(\"Focus\", \"trap\", \"focus\"); tt(\"Mask\", \"mask\", \"mask\"); function tt(e, t, r) { d(t, n => E(`You can't use [x-${t}] without first installing the \"${e}\" plugin here: https://alpinejs.dev/plugins/${r}`, n)) } B.setEvaluator(gt); B.setReactivityEngine({ reactive: Qe, effect: en, release: tn, raw: h }); var Ht = B; window.Alpine = Ht; queueMicrotask(() => { Ht.start() });\n})();\n"
  },
  {
    "path": "internal/assets/public/static/js/datastar.js",
    "content": "// Datastar v1.0.0-beta.2\nvar je=/🖕JS_DS🚀/.source,pe=je.slice(0,5),ke=je.slice(4),L=\"datastar\";var Be=\"Datastar-Request\",Ge=\"1.0.0-beta.1\",me=300;var Ke=\"type module\",ge=!1,Je=!1,ze=!0,O={Morph:\"morph\",Inner:\"inner\",Outer:\"outer\",Prepend:\"prepend\",Append:\"append\",Before:\"before\",After:\"after\",UpsertAttributes:\"upsertAttributes\"},Xe=O.Morph,I={MergeFragments:\"datastar-merge-fragments\",MergeSignals:\"datastar-merge-signals\",RemoveFragments:\"datastar-remove-fragments\",RemoveSignals:\"datastar-remove-signals\",ExecuteScript:\"datastar-execute-script\"};var p=(r=>(r[r.Attribute=1]=\"Attribute\",r[r.Watcher=2]=\"Watcher\",r[r.Action=3]=\"Action\",r))(p||{});var xn=\"computed\",Ye={type:1,name:xn,keyReq:1,valReq:1,onLoad:({key:t,signals:e,genRX:n})=>{let r=n();e.setComputed(t,r)}};var $=t=>t.trim()===\"true\",U=t=>t.replace(/[A-Z]+(?![a-z])|[A-Z]/g,(e,n)=>(n?\"-\":\"\")+e.toLowerCase()),Ze=t=>t.replace(/(?:^\\w|[A-Z]|\\b\\w)/g,(e,n)=>n===0?e.toLowerCase():e.toUpperCase()).replace(/\\s+/g,\"\"),he=t=>new Function(`return Object.assign({}, ${t})`)(),j=t=>t.startsWith(\"$\")?t.slice(1):t;var Qe={type:1,name:\"signals\",removeOnLoad:!0,onLoad:t=>{let{key:e,value:n,genRX:r,signals:i,mods:s}=t,o=s.has(\"ifmissing\");if(e!==\"\"&&!o){let a=n===\"\"?n:r()();i.setValue(e,a)}else{let a=he(t.value);t.value=JSON.stringify(a);let u=r()();i.merge(u,o)}}};var et={type:1,name:\"star\",keyReq:2,valReq:2,onLoad:()=>{alert(\"YOU ARE PROBABLY OVERCOMPLICATING IT\")}};var ie=class{#e=0;#t;constructor(e=L){this.#t=e}with(e){if(typeof e==\"string\")for(let n of e.split(\"\"))this.with(n.charCodeAt(0));else this.#e=(this.#e<<5)-this.#e+e;return this}reset(){return this.#e=0,this}get value(){return this.#t+Math.abs(this.#e).toString(36)}};function tt(t){if(t.id)return t.id;let e=new ie,n=t;for(;n.parentNode;){if(n.id){e.with(n.id);break}if(n===n.ownerDocument.documentElement)e.with(n.tagName);else{for(let r=1,i=t;i.previousElementSibling;i=i.previousElementSibling,r++)e.with(r);n=n.parentNode}n=n.parentNode}return e.value}function nt(t,e){let n=new MutationObserver(r=>{for(let i of r)for(let s of i.removedNodes)if(s===t){n.disconnect(),e();return}});n.observe(t.parentNode,{childList:!0})}var Pn=`${window.location.origin}/errors`;function De(t,e,n={}){let r=new Error;e=e[0].toUpperCase()+e.slice(1),r.name=`${L} ${t} error`;let i=U(e).replaceAll(\"-\",\"_\"),s=new URLSearchParams({metadata:JSON.stringify(n)}).toString(),o=JSON.stringify(n,null,2);return r.message=`${e}\nMore info: ${Pn}/${t}/${i}?${s}\nContext: ${o}`,r}function P(t,e,n={}){return De(\"internal\",e,Object.assign({from:t},n))}function V(t,e,n={}){let r={plugin:{name:e.plugin.name,type:p[e.plugin.type]}};return De(\"init\",t,Object.assign(r,n))}function h(t,e,n={}){let r={plugin:{name:e.plugin.name,type:p[e.plugin.type]},element:{id:e.el.id,tag:e.el.tagName},expression:{rawKey:e.rawKey,key:e.key,value:e.value,validSignals:e.signals.paths(),fnContent:e.fnContent}};return De(\"runtime\",t,Object.assign(r,n))}var G=\"preact-signals\",Nn=Symbol.for(\"preact-signals\"),F=1,X=2,se=4,Z=8,ye=16,Y=32;function Oe(){ve++}function Ve(){if(ve>1){ve--;return}let t,e=!1;for(;oe!==void 0;){let n=oe;for(oe=void 0,Le++;n!==void 0;){let r=n._nextBatchedEffect;if(n._nextBatchedEffect=void 0,n._flags&=~X,!(n._flags&Z)&&it(n))try{n._callback()}catch(i){e||(t=i,e=!0)}n=r}}if(Le=0,ve--,e)throw P(G,\"BatchError, error\",{error:t})}var v;var oe,ve=0,Le=0,be=0;function rt(t){if(v===void 0)return;let e=t._node;if(e===void 0||e._target!==v)return e={_version:0,_source:t,_prevSource:v._sources,_nextSource:void 0,_target:v,_prevTarget:void 0,_nextTarget:void 0,_rollbackNode:e},v._sources!==void 0&&(v._sources._nextSource=e),v._sources=e,t._node=e,v._flags&Y&&t._subscribe(e),e;if(e._version===-1)return e._version=0,e._nextSource!==void 0&&(e._nextSource._prevSource=e._prevSource,e._prevSource!==void 0&&(e._prevSource._nextSource=e._nextSource),e._prevSource=v._sources,e._nextSource=void 0,v._sources._nextSource=e,v._sources=e),e}function R(t){this._value=t,this._version=0,this._node=void 0,this._targets=void 0}R.prototype.brand=Nn;R.prototype._refresh=()=>!0;R.prototype._subscribe=function(t){this._targets!==t&&t._prevTarget===void 0&&(t._nextTarget=this._targets,this._targets!==void 0&&(this._targets._prevTarget=t),this._targets=t)};R.prototype._unsubscribe=function(t){if(this._targets!==void 0){let e=t._prevTarget,n=t._nextTarget;e!==void 0&&(e._nextTarget=n,t._prevTarget=void 0),n!==void 0&&(n._prevTarget=e,t._nextTarget=void 0),t===this._targets&&(this._targets=n)}};R.prototype.subscribe=function(t){return Se(()=>{let e=this.value,n=v;v=void 0;try{t(e)}finally{v=n}})};R.prototype.valueOf=function(){return this.value};R.prototype.toString=function(){return`${this.value}`};R.prototype.toJSON=function(){return this.value};R.prototype.peek=function(){let t=v;v=void 0;try{return this.value}finally{v=t}};Object.defineProperty(R.prototype,\"value\",{get(){let t=rt(this);return t!==void 0&&(t._version=this._version),this._value},set(t){if(t!==this._value){if(Le>100)throw P(G,\"SignalCycleDetected\");this._value=t,this._version++,be++,Oe();try{for(let e=this._targets;e!==void 0;e=e._nextTarget)e._target._notify()}finally{Ve()}}}});function it(t){for(let e=t._sources;e!==void 0;e=e._nextSource)if(e._source._version!==e._version||!e._source._refresh()||e._source._version!==e._version)return!0;return!1}function ot(t){for(let e=t._sources;e!==void 0;e=e._nextSource){let n=e._source._node;if(n!==void 0&&(e._rollbackNode=n),e._source._node=e,e._version=-1,e._nextSource===void 0){t._sources=e;break}}}function st(t){let e=t._sources,n;for(;e!==void 0;){let r=e._prevSource;e._version===-1?(e._source._unsubscribe(e),r!==void 0&&(r._nextSource=e._nextSource),e._nextSource!==void 0&&(e._nextSource._prevSource=r)):n=e,e._source._node=e._rollbackNode,e._rollbackNode!==void 0&&(e._rollbackNode=void 0),e=r}t._sources=n}function K(t){R.call(this,void 0),this._fn=t,this._sources=void 0,this._globalVersion=be-1,this._flags=se}K.prototype=new R;K.prototype._refresh=function(){if(this._flags&=~X,this._flags&F)return!1;if((this._flags&(se|Y))===Y||(this._flags&=~se,this._globalVersion===be))return!0;if(this._globalVersion=be,this._flags|=F,this._version>0&&!it(this))return this._flags&=~F,!0;let t=v;try{ot(this),v=this;let e=this._fn();(this._flags&ye||this._value!==e||this._version===0)&&(this._value=e,this._flags&=~ye,this._version++)}catch(e){this._value=e,this._flags|=ye,this._version++}return v=t,st(this),this._flags&=~F,!0};K.prototype._subscribe=function(t){if(this._targets===void 0){this._flags|=se|Y;for(let e=this._sources;e!==void 0;e=e._nextSource)e._source._subscribe(e)}R.prototype._subscribe.call(this,t)};K.prototype._unsubscribe=function(t){if(this._targets!==void 0&&(R.prototype._unsubscribe.call(this,t),this._targets===void 0)){this._flags&=~Y;for(let e=this._sources;e!==void 0;e=e._nextSource)e._source._unsubscribe(e)}};K.prototype._notify=function(){if(!(this._flags&X)){this._flags|=se|X;for(let t=this._targets;t!==void 0;t=t._nextTarget)t._target._notify()}};Object.defineProperty(K.prototype,\"value\",{get(){if(this._flags&F)throw P(G,\"SignalCycleDetected\");let t=rt(this);if(this._refresh(),t!==void 0&&(t._version=this._version),this._flags&ye)throw P(G,\"GetComputedError\",{value:this._value});return this._value}});function at(t){return new K(t)}function lt(t){let e=t._cleanup;if(t._cleanup=void 0,typeof e==\"function\"){Oe();let n=v;v=void 0;try{e()}catch(r){throw t._flags&=~F,t._flags|=Z,Fe(t),P(G,\"CleanupEffectError\",{error:r})}finally{v=n,Ve()}}}function Fe(t){for(let e=t._sources;e!==void 0;e=e._nextSource)e._source._unsubscribe(e);t._fn=void 0,t._sources=void 0,lt(t)}function Mn(t){if(v!==this)throw P(G,\"EndEffectError\");st(this),v=t,this._flags&=~F,this._flags&Z&&Fe(this),Ve()}function ae(t){this._fn=t,this._cleanup=void 0,this._sources=void 0,this._nextBatchedEffect=void 0,this._flags=Y}ae.prototype._callback=function(){let t=this._start();try{if(this._flags&Z||this._fn===void 0)return;let e=this._fn();typeof e==\"function\"&&(this._cleanup=e)}finally{t()}};ae.prototype._start=function(){if(this._flags&F)throw P(G,\"SignalCycleDetected\");this._flags|=F,this._flags&=~Z,lt(this),ot(this),Oe();let t=v;return v=this,Mn.bind(this,t)};ae.prototype._notify=function(){this._flags&X||(this._flags|=X,this._nextBatchedEffect=oe,oe=this)};ae.prototype._dispose=function(){this._flags|=Z,this._flags&F||Fe(this)};function Se(t){let e=new ae(t);try{e._callback()}catch(n){throw e._dispose(),n}return e._dispose.bind(e)}var ut=\"namespacedSignals\";function ct(t,e=!1){let n={};for(let r in t)if(Object.hasOwn(t,r)){if(e&&r.startsWith(\"_\"))continue;let i=t[r];i instanceof R?n[r]=i.value:n[r]=ct(i)}return n}function ft(t,e,n=!1){for(let r in e)if(Object.hasOwn(e,r)){if(r.match(/\\_\\_+/))throw P(ut,\"InvalidSignalKey\",{key:r});let i=e[r];if(i instanceof Object&&!Array.isArray(i))t[r]||(t[r]={}),ft(t[r],i,n);else{if(Object.hasOwn(t,r)){if(n)continue;let o=t[r];if(o instanceof R){o.value=i;continue}}t[r]=new R(i)}}}function dt(t,e){for(let n in t)if(Object.hasOwn(t,n)){let r=t[n];r instanceof R?e(n,r):dt(r,(i,s)=>{e(`${n}.${i}`,s)})}}function Cn(t,...e){let n={};for(let r of e){let i=r.split(\".\"),s=t,o=n;for(let l=0;l<i.length-1;l++){let u=i[l];if(!s[u])return{};o[u]||(o[u]={}),s=s[u],o=o[u]}let a=i[i.length-1];o[a]=s[a]}return n}var Ee=class{#e={};exists(e){return!!this.signal(e)}signal(e){let n=e.split(\".\"),r=this.#e;for(let o=0;o<n.length-1;o++){let a=n[o];if(!r[a])return null;r=r[a]}let i=n[n.length-1],s=r[i];if(!s)throw P(ut,\"SignalNotFound\",{path:e});return s}setSignal(e,n){let r=e.split(\".\"),i=this.#e;for(let o=0;o<r.length-1;o++){let a=r[o];i[a]||(i[a]={}),i=i[a]}let s=r[r.length-1];i[s]=n}setComputed(e,n){let r=at(()=>n());this.setSignal(e,r)}value(e){return this.signal(e)?.value}setValue(e,n){let r=this.upsertIfMissing(e,n);r.value=n}upsertIfMissing(e,n){let r=e.split(\".\"),i=this.#e;for(let l=0;l<r.length-1;l++){let u=r[l];i[u]||(i[u]={}),i=i[u]}let s=r[r.length-1],o=i[s];if(o instanceof R)return o;let a=new R(n);return i[s]=a,a}remove(...e){for(let n of e){let r=n.split(\".\"),i=this.#e;for(let o=0;o<r.length-1;o++){let a=r[o];if(!i[a])return;i=i[a]}let s=r[r.length-1];delete i[s]}}merge(e,n=!1){ft(this.#e,e,n)}subset(...e){return Cn(this.values(),...e)}walk(e){dt(this.#e,e)}paths(){let e=new Array;return this.walk(n=>e.push(n)),e}values(e=!1){return ct(this.#e,e)}JSON(e=!0,n=!1){let r=this.values(n);return e?JSON.stringify(r,null,2):JSON.stringify(r)}toString(){return this.JSON()}};var Te=class{#e=new Ee;#t=[];#r={};#s=[];#n=new Map;get signals(){return this.#e}get version(){return Ge}load(...e){for(let n of e){let r=this,i={get signals(){return r.#e},effect:o=>Se(o),actions:this.#r,apply:this.apply.bind(this),cleanup:this.#i.bind(this),plugin:n},s;switch(n.type){case 2:{let o=n;this.#s.push(o),s=o.onGlobalInit;break}case 3:{this.#r[n.name]=n;break}case 1:{let o=n;this.#t.push(o),s=o.onGlobalInit;break}default:throw V(\"InvalidPluginType\",i)}s&&s(i)}this.#t.sort((n,r)=>{let i=r.name.length-n.name.length;return i!==0?i:n.name.localeCompare(r.name)})}apply(e){this.#o(e,n=>{this.#i(n);for(let r of Object.keys(n.dataset)){let i=this.#t.find(f=>r.startsWith(f.name));if(!i)continue;n.id.length||(n.id=tt(n));let[s,...o]=r.slice(i.name.length).split(/\\_\\_+/),a=s.length>0;if(a){let f=s.slice(1);s=s.startsWith(\"-\")?f:s[0].toLowerCase()+f}let l=`${n.dataset[r]}`||\"\",u=l.length>0,c=this,d={get signals(){return c.#e},effect:f=>Se(f),apply:this.apply.bind(this),cleanup:this.#i.bind(this),actions:this.#r,genRX:()=>this.#a(d,...i.argNames||[]),plugin:i,el:n,rawKey:r,key:s,value:l,mods:new Map},y=i.keyReq||0;if(a){if(y===2)throw h(`${i.name}KeyNotAllowed`,d)}else if(y===1)throw h(`${i.name}KeyRequired`,d);let S=i.valReq||0;if(u){if(S===2)throw h(`${i.name}ValueNotAllowed`,d)}else if(S===1)throw h(`${i.name}ValueRequired`,d);if(y===3||S===3){if(a&&u)throw h(`${i.name}KeyAndValueProvided`,d);if(!a&&!u)throw h(`${i.name}KeyOrValueRequired`,d)}for(let f of o){let[E,...w]=f.split(\".\");d.mods.set(Ze(E),new Set(w.map(C=>C.toLowerCase())))}let m=i.onLoad(d);m&&(this.#n.has(n)||this.#n.set(n,{id:n.id,fns:[]}),this.#n.get(n)?.fns.push(m)),i?.removeOnLoad&&delete n.dataset[r]}})}#a(e,...n){let r=e.value.split(/;|\\n/).map(f=>f.trim()).filter(f=>f!==\"\"),i=r.length-1;r[i].startsWith(\"return\")||(r[i]=`return (${r[i]});`);let o=r.join(`;\n`).trim(),a=new Map,l=new RegExp(`(?:${pe})(.*?)(?:${ke})`,\"gm\");for(let f of o.matchAll(l)){let E=f[1],w=new ie(\"dsEscaped\").with(E).value;a.set(w,E),o=o.replace(pe+E+ke,w)}let u=/@(\\w*)\\(/gm,c=o.matchAll(u),d=new Set;for(let f of c)d.add(f[1]);let y=new RegExp(`@(${Object.keys(this.#r).join(\"|\")})\\\\(`,\"gm\");o=o.replaceAll(y,\"ctx.actions.$1.fn(ctx,\");let S=e.signals.paths();if(S.length){let f=new RegExp(`\\\\$(${S.join(\"|\")})(\\\\W|$)`,\"gm\");o=o.replaceAll(f,\"ctx.signals.signal('$1').value$2\")}for(let[f,E]of a)o=o.replace(f,E);let m=`return (()=> {\n${o}\n})()`;e.fnContent=m;try{let f=new Function(\"ctx\",...n,m);return(...E)=>{try{return f(e,...E)}catch(w){throw h(\"ExecuteExpression\",e,{error:w.message})}}}catch(f){throw h(\"GenerateExpression\",e,{error:f.message})}}#o(e,n){if(!e||!(e instanceof HTMLElement||e instanceof SVGElement))return null;let r=e.dataset;if(\"starIgnore\"in r)return null;\"starIgnore__self\"in r||n(e);let i=e.firstElementChild;for(;i;)this.#o(i,n),i=i.nextElementSibling}#i(e){let n=this.#n.get(e);if(n){for(let r of n.fns)r();this.#n.delete(e)}}};var pt=new Te;pt.load(et,Qe,Ye);var Ae=pt;async function In(t,e){let n=t.getReader(),r;for(;!(r=await n.read()).done;)e(r.value)}function kn(t){let e,n,r,i=!1;return function(o){e===void 0?(e=o,n=0,r=-1):e=Ln(e,o);let a=e.length,l=0;for(;n<a;){i&&(e[n]===10&&(l=++n),i=!1);let u=-1;for(;n<a&&u===-1;++n)switch(e[n]){case 58:r===-1&&(r=n-l);break;case 13:i=!0;case 10:u=n;break}if(u===-1)break;t(e.subarray(l,u),r),l=n,r=-1}l===a?e=void 0:l!==0&&(e=e.subarray(l),n-=l)}}function Dn(t,e,n){let r=mt(),i=new TextDecoder;return function(o,a){if(o.length===0)n?.(r),r=mt();else if(a>0){let l=i.decode(o.subarray(0,a)),u=a+(o[a+1]===32?2:1),c=i.decode(o.subarray(u));switch(l){case\"data\":r.data=r.data?`${r.data}\n${c}`:c;break;case\"event\":r.event=c;break;case\"id\":t(r.id=c);break;case\"retry\":{let d=Number.parseInt(c,10);Number.isNaN(d)||e(r.retry=d);break}}}}}function Ln(t,e){let n=new Uint8Array(t.length+e.length);return n.set(t),n.set(e,t.length),n}function mt(){return{data:\"\",event:\"\",id:\"\",retry:void 0}}var On=\"text/event-stream\",gt=\"last-event-id\";function ht(t,e,{signal:n,headers:r,onopen:i,onmessage:s,onclose:o,onerror:a,openWhenHidden:l,fetch:u,retryInterval:c=1e3,retryScaler:d=2,retryMaxWaitMs:y=3e4,retryMaxCount:S=10,...m}){return new Promise((f,E)=>{let w=0,C={...r};C.accept||(C.accept=On);let A;function T(){A.abort(),document.hidden||D()}l||document.addEventListener(\"visibilitychange\",T);let b=0;function x(){document.removeEventListener(\"visibilitychange\",T),window.clearTimeout(b),A.abort()}n?.addEventListener(\"abort\",()=>{x(),f()});let N=u??window.fetch,g=i??function(){};async function D(){A=new AbortController;try{let M=await N(e,{...m,headers:C,signal:A.signal});await g(M),await In(M.body,kn(Dn(_=>{_?C[gt]=_:delete C[gt]},_=>{c=_},s))),o?.(),x(),f()}catch(M){if(!A.signal.aborted)try{let _=a?.(M)??c;window.clearTimeout(b),b=window.setTimeout(D,_),c*=d,c=Math.min(c,y),w++,w>=S?(x(),E(h(\"SseMaxRetries\",t,{retryMaxCount:S}))):console.error(`Datastar failed to reach ${m.method}: ${e.toString()} retry in ${_}ms`)}catch(_){x(),E(_)}}}D()})}var Q=`${L}-sse`,He=`${L}-settling`,J=`${L}-swapping`,_e=\"started\",we=\"finished\",yt=\"error\";function H(t,e){document.addEventListener(Q,n=>{if(n.detail.type!==t)return;let{argsRaw:r}=n.detail;e(r)})}function Re(t,e){document.dispatchEvent(new CustomEvent(Q,{detail:{type:t,argsRaw:e}}))}var vt=t=>`${t}`.includes(\"text/event-stream\"),q=async(t,e,n,r)=>{let{el:{id:i},el:s,signals:o}=t,{headers:a,contentType:l,includeLocal:u,selector:c,openWhenHidden:d,retryInterval:y,retryScaler:S,retryMaxWaitMs:m,retryMaxCount:f,abort:E}=Object.assign({headers:{},contentType:\"json\",includeLocal:!1,selector:null,openWhenHidden:!1,retryInterval:1e3,retryScaler:2,retryMaxWaitMs:3e4,retryMaxCount:10,abort:void 0},r),w=e.toLowerCase(),C=()=>{};try{if(Re(_e,{elId:i}),!n?.length)throw h(\"SseNoUrlProvided\",t,{action:w});let A={};A[Be]=!0,l===\"json\"&&(A[\"Content-Type\"]=\"application/json\");let T=Object.assign({},A,a),b={method:e,headers:T,openWhenHidden:d,retryInterval:y,retryScaler:S,retryMaxWaitMs:m,retryMaxCount:f,signal:E,onopen:async g=>{if(g.status>=400){let D=g.status.toString();Re(yt,{status:D})}},onmessage:g=>{if(!g.event.startsWith(L))return;let D=g.event,M={},_=g.data.split(`\n`);for(let re of _){let fe=re.indexOf(\" \"),Ue=re.slice(0,fe),de=M[Ue];de||(de=[],M[Ue]=de);let Rn=re.slice(fe+1).trim();de.push(Rn)}let W={};for(let[re,fe]of Object.entries(M))W[re]=fe.join(`\n`);Re(D,W)},onerror:g=>{if(vt(g))throw h(\"InvalidContentType\",t,{url:n});g&&console.error(g.message)}},x=new URL(n,window.location.origin),N=new URLSearchParams(x.search);if(l===\"json\"){let g=o.JSON(!1,!u);e===\"GET\"?N.set(L,g):b.body=g}else if(l===\"form\"){let g=c?document.querySelector(c):s.closest(\"form\");if(g===null)throw c?h(\"SseFormNotFound\",t,{action:w,selector:c}):h(\"SseClosestFormNotFound\",t,{action:w});if(s!==g){let M=_=>_.preventDefault();g.addEventListener(\"submit\",M),C=()=>g.removeEventListener(\"submit\",M)}if(!g.checkValidity()){g.reportValidity(),C();return}let D=new FormData(g);if(e===\"GET\"){let M=new URLSearchParams(D);for(let[_,W]of M)N.set(_,W)}else b.body=D}else throw h(\"SseInvalidContentType\",t,{action:w,contentType:l});x.search=N.toString();try{await ht(t,x.toString(),b)}catch(g){if(!vt(g))throw h(\"SseFetchFailed\",t,{method:e,url:n,error:g})}}finally{Re(we,{elId:i}),C()}};var bt={type:3,name:\"delete\",fn:async(t,e,n)=>q(t,\"DELETE\",e,{...n})};var St={type:3,name:\"get\",fn:async(t,e,n)=>q(t,\"GET\",e,{...n})};var Et={type:3,name:\"patch\",fn:async(t,e,n)=>q(t,\"PATCH\",e,{...n})};var Tt={type:3,name:\"post\",fn:async(t,e,n)=>q(t,\"POST\",e,{...n})};var At={type:3,name:\"put\",fn:async(t,e,n)=>q(t,\"PUT\",e,{...n})};var _t={type:1,name:\"indicator\",keyReq:3,valReq:3,onLoad:({value:t,signals:e,el:n,key:r})=>{let i=r||j(t),s=e.upsertIfMissing(i,!1),o=a=>{let{type:l,argsRaw:{elId:u}}=a.detail;if(u===n.id)switch(l){case _e:s.value=!0;break;case we:s.value=!1;break}};return document.addEventListener(Q,o),()=>{document.removeEventListener(Q,o)}}};var wt={type:2,name:I.ExecuteScript,onGlobalInit:async t=>{H(I.ExecuteScript,({autoRemove:e=`${ze}`,attributes:n=Ke,script:r})=>{let i=$(e);if(!r?.length)throw V(\"NoScriptProvided\",t);let s=document.createElement(\"script\");for(let o of n.split(`\n`)){let a=o.indexOf(\" \"),l=a?o.slice(0,a):o,u=a?o.slice(a):\"\";s.setAttribute(l.trim(),u.trim())}s.text=r,document.head.appendChild(s),i&&s.remove()})}};var le=document,ee=!!le.startViewTransition;var te=\"idiomorph\",Pe=new WeakSet;function Nt(t,e,n={}){t instanceof Document&&(t=t.documentElement);let r;typeof e==\"string\"?r=Wn(e):r=e;let i=$n(r),s=Fn(t,i,n);return Mt(t,i,s)}function Mt(t,e,n){if(n.head.block){let r=t.querySelector(\"head\"),i=e.querySelector(\"head\");if(r&&i){let s=It(i,r,n);Promise.all(s).then(()=>{Mt(t,e,Object.assign(n,{head:{block:!1,ignore:!0}}))});return}}if(n.morphStyle===\"innerHTML\")return Ct(e,t,n),t.children;if(n.morphStyle===\"outerHTML\"||n.morphStyle==null){let r=jn(e,t,n);if(!r)throw P(te,\"NoBestMatchFound\",{old:t,new:e});let i=r?.previousSibling,s=r?.nextSibling,o=Ne(t,r,n);return r?Un(i,o,s):[]}throw P(te,\"InvalidMorphStyle\",{style:n.morphStyle})}function Ne(t,e,n){if(!(n.ignoreActive&&t===document.activeElement))if(e==null){if(n.callbacks.beforeNodeRemoved(t)===!1)return;t.remove(),n.callbacks.afterNodeRemoved(t);return}else{if(Me(t,e))return n.callbacks.beforeNodeMorphed(t,e)===!1?void 0:(t instanceof HTMLHeadElement&&n.head.ignore||(e instanceof HTMLHeadElement&&t instanceof HTMLHeadElement&&n.head.style!==O.Morph?It(e,t,n):(Vn(e,t),Ct(e,t,n))),n.callbacks.afterNodeMorphed(t,e),t);if(n.callbacks.beforeNodeRemoved(t)===!1||n.callbacks.beforeNodeAdded(e)===!1)return;if(!t.parentElement)throw P(te,\"NoParentElementFound\",{oldNode:t});return t.parentElement.replaceChild(e,t),n.callbacks.afterNodeAdded(e),n.callbacks.afterNodeRemoved(t),e}}function Ct(t,e,n){let r=t.firstChild,i=e.firstChild,s;for(;r;){if(s=r,r=s.nextSibling,i==null){if(n.callbacks.beforeNodeAdded(s)===!1)return;e.appendChild(s),n.callbacks.afterNodeAdded(s),z(n,s);continue}if(kt(s,i,n)){Ne(i,s,n),i=i.nextSibling,z(n,s);continue}let o=Hn(t,e,s,i,n);if(o){i=Rt(i,o,n),Ne(o,s,n),z(n,s);continue}let a=qn(t,s,i,n);if(a){i=Rt(i,a,n),Ne(a,s,n),z(n,s);continue}if(n.callbacks.beforeNodeAdded(s)===!1)return;e.insertBefore(s,i),n.callbacks.afterNodeAdded(s),z(n,s)}for(;i!==null;){let o=i;i=i.nextSibling,Dt(o,n)}}function Vn(t,e){let n=t.nodeType;if(n===1){for(let r of t.attributes)e.getAttribute(r.name)!==r.value&&e.setAttribute(r.name,r.value);for(let r of e.attributes)t.hasAttribute(r.name)||e.removeAttribute(r.name)}if((n===Node.COMMENT_NODE||n===Node.TEXT_NODE)&&e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),t instanceof HTMLInputElement&&e instanceof HTMLInputElement&&t.type!==\"file\")e.value=t.value||\"\",xe(t,e,\"value\"),xe(t,e,\"checked\"),xe(t,e,\"disabled\");else if(t instanceof HTMLOptionElement)xe(t,e,\"selected\");else if(t instanceof HTMLTextAreaElement&&e instanceof HTMLTextAreaElement){let r=t.value,i=e.value;r!==i&&(e.value=r),e.firstChild&&e.firstChild.nodeValue!==r&&(e.firstChild.nodeValue=r)}}function xe(t,e,n){let r=t.getAttribute(n),i=e.getAttribute(n);r!==i&&(r?e.setAttribute(n,r):e.removeAttribute(n))}function It(t,e,n){let r=[],i=[],s=[],o=[],a=n.head.style,l=new Map;for(let c of t.children)l.set(c.outerHTML,c);for(let c of e.children){let d=l.has(c.outerHTML),y=n.head.shouldReAppend(c),S=n.head.shouldPreserve(c);d||S?y?i.push(c):(l.delete(c.outerHTML),s.push(c)):a===O.Append?y&&(i.push(c),o.push(c)):n.head.shouldRemove(c)!==!1&&i.push(c)}o.push(...l.values());let u=[];for(let c of o){let d=document.createRange().createContextualFragment(c.outerHTML).firstChild;if(!d)throw P(te,\"NewElementCouldNotBeCreated\",{newNode:c});if(n.callbacks.beforeNodeAdded(d)){if(d.hasAttribute(\"href\")||d.hasAttribute(\"src\")){let y,S=new Promise(m=>{y=m});d.addEventListener(\"load\",()=>{y(void 0)}),u.push(S)}e.appendChild(d),n.callbacks.afterNodeAdded(d),r.push(d)}}for(let c of i)n.callbacks.beforeNodeRemoved(c)!==!1&&(e.removeChild(c),n.callbacks.afterNodeRemoved(c));return n.head.afterHeadMorphed(e,{added:r,kept:s,removed:i}),u}function B(){}function Fn(t,e,n){return{target:t,newContent:e,config:n,morphStyle:n.morphStyle,ignoreActive:n.ignoreActive,idMap:Jn(t,e),deadIds:new Set,callbacks:Object.assign({beforeNodeAdded:B,afterNodeAdded:B,beforeNodeMorphed:B,afterNodeMorphed:B,beforeNodeRemoved:B,afterNodeRemoved:B},n.callbacks),head:Object.assign({style:\"merge\",shouldPreserve:r=>r.getAttribute(\"im-preserve\")===\"true\",shouldReAppend:r=>r.getAttribute(\"im-re-append\")===\"true\",shouldRemove:B,afterHeadMorphed:B},n.head)}}function kt(t,e,n){return!t||!e?!1:t.nodeType===e.nodeType&&t.tagName===e.tagName?t?.id?.length&&t.id===e.id?!0:ue(n,t,e)>0:!1}function Me(t,e){return!t||!e?!1:t.nodeType===e.nodeType&&t.tagName===e.tagName}function Rt(t,e,n){for(;t!==e;){let r=t;if(t=t?.nextSibling,!r)throw P(te,\"NoTemporaryNodeFound\",{startInclusive:t,endExclusive:e});Dt(r,n)}return z(n,e),e.nextSibling}function Hn(t,e,n,r,i){let s=ue(i,n,e),o=null;if(s>0){o=r;let a=0;for(;o!=null;){if(kt(n,o,i))return o;if(a+=ue(i,o,t),a>s)return null;o=o.nextSibling}}return o}function qn(t,e,n,r){let i=n,s=e.nextSibling,o=0;for(;i&&s;){if(ue(r,i,t)>0)return null;if(Me(e,i))return i;if(Me(s,i)&&(o++,s=s.nextSibling,o>=2))return null;i=i.nextSibling}return i}var xt=new DOMParser;function Wn(t){let e=t.replace(/<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim,\"\");if(e.match(/<\\/html>/)||e.match(/<\\/head>/)||e.match(/<\\/body>/)){let i=xt.parseFromString(t,\"text/html\");if(e.match(/<\\/html>/))return Pe.add(i),i;let s=i.firstChild;return s?(Pe.add(s),s):null}let r=xt.parseFromString(`<body><template>${t}</template></body>`,\"text/html\").body.querySelector(\"template\")?.content;if(!r)throw P(te,\"NoContentFound\",{newContent:t});return Pe.add(r),r}function $n(t){if(t==null)return document.createElement(\"div\");if(Pe.has(t))return t;if(t instanceof Node){let n=document.createElement(\"div\");return n.append(t),n}let e=document.createElement(\"div\");for(let n of[...t])e.append(n);return e}function Un(t,e,n){let r=[],i=[];for(;t;)r.push(t),t=t.previousSibling;for(;r.length>0;){let s=r.pop();i.push(s),e?.parentElement?.insertBefore(s,e)}for(i.push(e);n;)r.push(n),i.push(n),n=n.nextSibling;for(;r.length;)e?.parentElement?.insertBefore(r.pop(),e.nextSibling);return i}function jn(t,e,n){let r=t.firstChild,i=r,s=0;for(;r;){let o=Bn(r,e,n);o>s&&(i=r,s=o),r=r.nextSibling}return i}function Bn(t,e,n){return Me(t,e)?.5+ue(n,t,e):0}function Dt(t,e){z(e,t),e.callbacks.beforeNodeRemoved(t)!==!1&&(t.remove(),e.callbacks.afterNodeRemoved(t))}function Gn(t,e){return!t.deadIds.has(e)}function Kn(t,e,n){return t.idMap.get(n)?.has(e)||!1}function z(t,e){let n=t.idMap.get(e);if(n)for(let r of n)t.deadIds.add(r)}function ue(t,e,n){let r=t.idMap.get(e);if(!r)return 0;let i=0;for(let s of r)Gn(t,s)&&Kn(t,s,n)&&++i;return i}function Pt(t,e){let n=t.parentElement,r=t.querySelectorAll(\"[id]\");for(let i of r){let s=i;for(;s!==n&&s;){let o=e.get(s);o==null&&(o=new Set,e.set(s,o)),o.add(i.id),s=s.parentElement}}}function Jn(t,e){let n=new Map;return Pt(t,n),Pt(e,n),n}var Ot={type:2,name:I.MergeFragments,onGlobalInit:async t=>{let e=document.createElement(\"template\");H(I.MergeFragments,({fragments:n=\"<div></div>\",selector:r=\"\",mergeMode:i=Xe,settleDuration:s=`${me}`,useViewTransition:o=`${ge}`})=>{let a=Number.parseInt(s),l=$(o);e.innerHTML=n.trim();let u=[...e.content.children];for(let c of u){if(!(c instanceof Element))throw V(\"NoFragmentsFound\",t);let d=r||`#${c.getAttribute(\"id\")}`,y=[...document.querySelectorAll(d)||[]];if(!y.length)throw V(\"NoTargetsFound\",t,{selectorOrID:d});ee&&l?le.startViewTransition(()=>Lt(t,i,a,c,y)):Lt(t,i,a,c,y)}})}};function Lt(t,e,n,r,i){for(let s of i){s.classList.add(J);let o=s.outerHTML,a=s;switch(e){case O.Morph:{let c=Nt(a,r,{callbacks:{beforeNodeRemoved:(d,y)=>(t.cleanup(d),!0)}});if(!c?.length)throw V(\"MorphFailed\",t);a=c[0];break}case O.Inner:a.innerHTML=r.innerHTML;break;case O.Outer:a.replaceWith(r);break;case O.Prepend:a.prepend(r);break;case O.Append:a.append(r);break;case O.Before:a.before(r);break;case O.After:a.after(r);break;case O.UpsertAttributes:for(let c of r.getAttributeNames()){let d=r.getAttribute(c);a.setAttribute(c,d)}break;default:throw V(\"InvalidMergeMode\",t,{mergeMode:e})}t.cleanup(a);let l=a.classList;l.add(J),t.apply(document.body),setTimeout(()=>{s.classList.remove(J),l.remove(J)},n);let u=a.outerHTML;o!==u&&(l.add(He),setTimeout(()=>{l.remove(He)},n))}}var Vt={type:2,name:I.MergeSignals,onGlobalInit:async t=>{H(I.MergeSignals,({signals:e=\"{}\",onlyIfMissing:n=`${Je}`})=>{let{signals:r}=t,i=$(n);r.merge(he(e),i),t.apply(document.body)})}};var Ft={type:2,name:I.RemoveFragments,onGlobalInit:async t=>{H(I.RemoveFragments,({selector:e,settleDuration:n=`${me}`,useViewTransition:r=`${ge}`})=>{if(!e.length)throw V(\"NoSelectorProvided\",t);let i=Number.parseInt(n),s=$(r),o=document.querySelectorAll(e),a=()=>{for(let l of o)l.classList.add(J);setTimeout(()=>{for(let l of o)l.remove()},i)};ee&&s?le.startViewTransition(()=>a()):a()})}};var Ht={type:2,name:I.RemoveSignals,onGlobalInit:async t=>{H(I.RemoveSignals,({paths:e=\"\"})=>{let n=e.split(`\n`).map(r=>r.trim());if(!n?.length)throw V(\"NoPathsProvided\",t);t.signals.remove(...n),t.apply(document.body)})}};var qt={type:3,name:\"clipboard\",fn:(t,e)=>{if(!navigator.clipboard)throw h(\"ClipboardNotAvailable\",t);navigator.clipboard.writeText(e)}};var Wt={type:1,name:\"customValidity\",keyReq:2,valReq:1,onLoad:t=>{let{el:e,genRX:n,effect:r}=t;if(!(e instanceof HTMLInputElement))throw h(\"CustomValidityInvalidElement\",t);let i=n();return r(()=>{let s=i();if(typeof s!=\"string\")throw h(\"CustomValidityInvalidExpression\",t,{result:s});e.setCustomValidity(s)})}};var $t=\"once\",Ut=\"half\",jt=\"full\",Bt={type:1,name:\"intersects\",keyReq:2,mods:new Set([$t,Ut,jt]),onLoad:({el:t,rawKey:e,mods:n,genRX:r})=>{let i={threshold:0};n.has(jt)?i.threshold=1:n.has(Ut)&&(i.threshold=.5);let s=r(),o=new IntersectionObserver(a=>{for(let l of a)l.isIntersecting&&(s(),n.has($t)&&(o.disconnect(),delete t.dataset[e]))},i);return o.observe(t),()=>o.disconnect()}};var Gt=\"session\",Kt={type:1,name:\"persist\",mods:new Set([Gt]),onLoad:({key:t,value:e,signals:n,effect:r,mods:i})=>{t===\"\"&&(t=L);let s=i.has(Gt)?sessionStorage:localStorage,o=e.split(/\\s+/).filter(u=>u!==\"\");o=o.map(u=>j(u));let a=()=>{let u=s.getItem(t)||\"{}\",c=JSON.parse(u);n.merge(c)},l=()=>{let u;o.length?u=n.subset(...o):u=n.values(),s.setItem(t,JSON.stringify(u))};return a(),r(()=>{l()})}};var Jt={type:1,name:\"replaceUrl\",keyReq:2,valReq:1,onLoad:({effect:t,genRX:e})=>{let n=e();return t(()=>{let r=n(),i=window.location.href,s=new URL(r,i).toString();window.history.replaceState({},\"\",s)})}};var Ce=\"smooth\",qe=\"instant\",We=\"auto\",zt=\"hstart\",Xt=\"hcenter\",Yt=\"hend\",Zt=\"hnearest\",Qt=\"vstart\",en=\"vcenter\",tn=\"vend\",nn=\"vnearest\",zn=\"focus\",Ie=\"center\",rn=\"start\",on=\"end\",sn=\"nearest\",an={type:1,name:\"scrollIntoView\",keyReq:2,valReq:2,mods:new Set([Ce,qe,We,zt,Xt,Yt,Zt,Qt,en,tn,nn,zn]),onLoad:t=>{let{el:e,mods:n,rawKey:r}=t;e.tabIndex||e.setAttribute(\"tabindex\",\"0\");let i={behavior:Ce,block:Ie,inline:Ie};if(n.has(Ce)&&(i.behavior=Ce),n.has(qe)&&(i.behavior=qe),n.has(We)&&(i.behavior=We),n.has(zt)&&(i.inline=rn),n.has(Xt)&&(i.inline=Ie),n.has(Yt)&&(i.inline=on),n.has(Zt)&&(i.inline=sn),n.has(Qt)&&(i.block=rn),n.has(en)&&(i.block=Ie),n.has(tn)&&(i.block=on),n.has(nn)&&(i.block=sn),!(e instanceof HTMLElement||e instanceof SVGElement))throw h(\"ScrollIntoViewInvalidElement\",t);return e.tabIndex||e.setAttribute(\"tabindex\",\"0\"),e.scrollIntoView(i),n.has(\"focus\")&&e.focus(),delete e.dataset[r],()=>{}}};var ln=\"none\",un=\"display\",cn={type:1,name:\"show\",keyReq:2,valReq:1,onLoad:({el:{style:t},genRX:e,effect:n})=>{let r=e();return n(async()=>{r()?t.display===ln&&t.removeProperty(un):t.setProperty(un,ln)})}};var fn=\"view-transition\",dn={type:1,name:\"viewTransition\",keyReq:2,valReq:1,onGlobalInit(){let t=!1;for(let e of document.head.childNodes)e instanceof HTMLMetaElement&&e.name===fn&&(t=!0);if(!t){let e=document.createElement(\"meta\");e.name=fn,e.content=\"same-origin\",document.head.appendChild(e)}},onLoad:({effect:t,el:e,genRX:n})=>{if(!ee){console.error(\"Browser does not support view transitions\");return}let r=n();return t(()=>{let i=r();if(!i?.length)return;let s=e.style;s.viewTransitionName=i})}};var pn={type:1,name:\"attr\",valReq:1,onLoad:({el:t,genRX:e,key:n,effect:r})=>{let i=e();return n===\"\"?r(async()=>{let s=i();for(let[o,a]of Object.entries(s))t.setAttribute(o,a)}):(n=U(n),r(async()=>{let s=!1;try{s=i()}catch{}let o;typeof s==\"string\"?o=s:o=JSON.stringify(s),!o||o===\"false\"||o===\"null\"||o===\"undefined\"?t.removeAttribute(n):t.setAttribute(n,o)}))}};var Xn=/^data:(?<mime>[^;]+);base64,(?<contents>.*)$/,mn=[\"change\",\"input\",\"keydown\"],gn={type:1,name:\"bind\",keyReq:3,valReq:3,onLoad:t=>{let{el:e,value:n,key:r,signals:i,effect:s}=t,o=r||j(n),a=()=>{},l=()=>{},u=e.tagName.toLowerCase(),c=\"\",d=u.includes(\"input\"),y=e.getAttribute(\"type\"),S=u.includes(\"checkbox\")||d&&y===\"checkbox\";S&&(c=!1),d&&y===\"number\"&&(c=0);let f=u.includes(\"select\"),E=u.includes(\"radio\")||d&&y===\"radio\",w=d&&y===\"file\";E&&(e.getAttribute(\"name\")?.length||e.setAttribute(\"name\",o)),i.upsertIfMissing(o,c),a=()=>{let A=\"value\"in e,T=i.value(o),b=`${T}`;if(S||E){let x=e;S?x.checked=!!T||T===\"true\":E&&(x.checked=b===x.value)}else if(!w)if(f){let x=e;if(x.multiple)for(let N of x.options){if(N?.disabled)return;Array.isArray(T)||typeof T==\"string\"?N.selected=T.includes(N.value):typeof T==\"number\"?N.selected=T===Number(N.value):N.selected=T}else x.value=b}else A?e.value=b:e.setAttribute(\"value\",b)},l=async()=>{if(w){let b=[...e?.files||[]],x=[],N=[],g=[];await Promise.all(b.map(D=>new Promise(M=>{let _=new FileReader;_.onload=()=>{if(typeof _.result!=\"string\")throw h(\"InvalidFileResultType\",t,{resultType:typeof _.result});let W=_.result.match(Xn);if(!W?.groups)throw h(\"InvalidDataUri\",t,{result:_.result});x.push(W.groups.contents),N.push(W.groups.mime),g.push(D.name)},_.onloadend=()=>M(void 0),_.readAsDataURL(D)}))),i.setValue(o,x),i.setValue(`${o}Mimes`,N),i.setValue(`${o}Names`,g);return}let A=i.value(o),T=e||e;if(typeof A==\"number\"){let b=Number(T.value||T.getAttribute(\"value\"));i.setValue(o,b)}else if(typeof A==\"string\"){let b=T.value||T.getAttribute(\"value\")||\"\";i.setValue(o,b)}else if(typeof A==\"boolean\")if(S){let b=T.checked||T.getAttribute(\"checked\")===\"true\";i.setValue(o,b)}else{let b=!!(T.value||T.getAttribute(\"value\"));i.setValue(o,b)}else if(!(typeof A>\"u\"))if(Array.isArray(A))if(f){let N=[...e.selectedOptions].filter(g=>g.selected).map(g=>g.value);i.setValue(o,N)}else{let b=JSON.stringify(T.value.split(\",\"));i.setValue(o,b)}else throw h(\"BindUnsupportedSignalType\",t,{signalType:typeof A})};for(let A of mn)e.addEventListener(A,l);let C=s(()=>a());return()=>{C();for(let A of mn)e.removeEventListener(A,l)}}};var hn={type:1,name:\"class\",valReq:1,onLoad:({key:t,el:e,genRX:n,effect:r})=>{let i=e.classList,s=n();return r(()=>{if(t===\"\"){let o=s();for(let[a,l]of Object.entries(o)){let u=a.split(/\\s+/);l?i.add(...u):i.remove(...u)}}else{let o=s(),a=U(t);o?i.add(a):i.remove(a)}})}};function ce(t){if(!t||t.size<=0)return 0;for(let e of t){if(e.endsWith(\"ms\"))return Number(e.replace(\"ms\",\"\"));if(e.endsWith(\"s\"))return Number(e.replace(\"s\",\"\"))*1e3;try{return Number.parseFloat(e)}catch{}}return 0}function ne(t,e,n=!1){return t?t.has(e.toLowerCase()):n}function yn(t,e,n=!1){return function(...i){n?t(...i):setTimeout(()=>{t(...i)},e)}}function vn(t,e,n=!1,r=!0){let i=-1,s=()=>i&&clearTimeout(i);return function(...a){s(),n&&!i&&t(...a),i=setTimeout(()=>{r&&t(...a),s()},e)}}function bn(t,e,n=!0,r=!1){let i=!1;return function(...o){i||(n&&t(...o),i=!0,setTimeout(()=>{i=!1,r&&t(...o)},e))}}var $e=new Map,Yn=\"evt\",Sn={type:1,name:\"on\",keyReq:1,valReq:1,argNames:[Yn],onLoad:({el:t,key:e,genRX:n,mods:r,signals:i,effect:s})=>{let o=n(),a=t;r.has(\"window\")&&(a=window);let l=m=>{m&&((r.has(\"prevent\")||e===\"submit\")&&m.preventDefault(),r.has(\"stop\")&&m.stopPropagation()),o(m)},u=r.get(\"delay\");if(u){let m=ce(u),f=ne(u,\"leading\",!1);l=yn(l,m,f)}let c=r.get(\"debounce\");if(c){let m=ce(c),f=ne(c,\"leading\",!1),E=!ne(c,\"notrail\",!1);l=vn(l,m,f,E)}let d=r.get(\"throttle\");if(d){let m=ce(d),f=!ne(d,\"noleading\",!1),E=ne(d,\"trail\",!1);l=bn(l,m,f,E)}let y={capture:!0,passive:!1,once:!1};r.has(\"capture\")||(y.capture=!1),r.has(\"passive\")&&(y.passive=!0),r.has(\"once\")&&(y.once=!0);let S=U(e).toLowerCase();switch(S){case\"load\":return l(),delete t.dataset.onLoad,()=>{};case\"interval\":{let m=1e3;u&&(m=ce(u),l());let f=setInterval(l,m);return()=>{clearInterval(f)}}case\"raf\":{let m,f=()=>{l(),m=requestAnimationFrame(f)};return m=requestAnimationFrame(f),()=>{m&&cancelAnimationFrame(m)}}case\"signals-change\":return nt(t,()=>{$e.delete(t.id)}),s(()=>{let m=r.has(\"remote\"),f=i.JSON(!1,m);($e.get(t.id)||\"\")!==f&&($e.set(t.id,f),l())});default:{if(r.has(\"outside\")){a=document;let f=l;l=w=>{let C=w?.target;t.contains(C)||f(w)}}return a.addEventListener(S,l,y),()=>{a.removeEventListener(S,l)}}}}};var En={type:1,name:\"ref\",keyReq:3,valReq:3,onLoad:({el:t,key:e,value:n,signals:r})=>{let i=e||j(n);return r.setValue(i,t),()=>r.setValue(i,null)}};var Tn={type:1,name:\"text\",keyReq:2,valReq:1,onLoad:t=>{let{el:e,genRX:n,effect:r}=t,i=n();return e instanceof HTMLElement||h(\"TextInvalidElement\",t),r(()=>{let s=i(t);e.textContent=`${s}`})}};var{round:Zn,max:Qn,min:er}=Math,An={type:3,name:\"fit\",fn:(t,e,n,r,i,s,o=!1,a=!1)=>{let l=(e-n)/(r-n)*(s-i)+i;return a&&(l=Zn(l)),o&&(l=Qn(i,er(s,l))),l}};var _n={type:3,name:\"setAll\",fn:({signals:t},e,n)=>{t.walk((r,i)=>{r.startsWith(e)&&(i.value=n)})}};var wn={type:3,name:\"toggleAll\",fn:({signals:t},e)=>{t.walk((n,r)=>{n.startsWith(e)&&(r.value=!r.value)})}};Ae.load(pn,gn,hn,Sn,En,cn,Tn,_t,St,Tt,At,Et,bt,Ot,Vt,Ft,Ht,wt,qt,Wt,Bt,Kt,Jt,an,dn,An,_n,wn);Ae.apply(document.body);var bs=Ae;export{bs as Datastar};\n//# sourceMappingURL=datastar.js.map\n"
  },
  {
    "path": "internal/components.go",
    "content": "package internal\n\nimport (\n\t\"encoding/json\"\n\t\"log\"\n\n\t\"github.com/haatos/goshipit/internal/assets\"\n\t\"github.com/haatos/goshipit/internal/model\"\n)\n\nvar ComponentCodeMap model.ComponentCodeMap\nvar ComponentExampleCodeMap model.ComponentExampleCodeMap\n\nfunc init() {\n\tgetComponentCodeMap()\n\tgetComponentExampleCodeMap()\n}\n\nfunc getComponentCodeMap() {\n\tb, err := assets.GeneratedFS.ReadFile(\"generated/component_code_map.json\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tif err := json.Unmarshal(b, &ComponentCodeMap); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor k := range ComponentCodeMap {\n\t\tfor i := range ComponentCodeMap[k] {\n\t\t\tComponentCodeMap[k][i].Label = SnakeCaseToCapitalized(ComponentCodeMap[k][i].Name)\n\t\t}\n\t}\n}\n\nfunc getComponentExampleCodeMap() {\n\tb, err := assets.GeneratedFS.ReadFile(\"generated/component_example_code_map.json\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tif err := json.Unmarshal(b, &ComponentExampleCodeMap); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor k := range ComponentExampleCodeMap {\n\t\tfor i := range ComponentExampleCodeMap[k] {\n\t\t\tComponentExampleCodeMap[k][i].Label = SnakeCaseToCapitalized(\n\t\t\t\tComponentExampleCodeMap[k][i].Name,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc SnakeCaseToCapitalized(s string) string {\n\tb := []byte(s)\n\tfor i := range b {\n\t\tif i == 0 || (i > 0 && b[i-1] == ' ') {\n\t\t\tif (b[i] >= 'a' && b[i] <= 'z') || (b[i] >= 'A' && b[i] <= 'Z') {\n\t\t\t\tb[i] = b[i] - ('a' - 'A')\n\t\t\t}\n\t\t}\n\t\tif b[i] == '_' {\n\t\t\tb[i] = ' '\n\t\t}\n\t}\n\treturn string(b)\n}\n"
  },
  {
    "path": "internal/echo.go",
    "content": "package internal\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/labstack/echo/v4/middleware\"\n\t\"golang.org/x/time/rate\"\n)\n\nfunc GracefulShutdown(e *echo.Echo, port string) {\n\tctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)\n\tdefer stop()\n\n\tgo func() {\n\t\tif err := e.Start(port); err != nil && err != http.ErrServerClosed {\n\t\t\te.Logger.Fatal(\"shutting down the server\")\n\t\t}\n\t}()\n\n\t<-ctx.Done()\n\tctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\n\tdefer cancel()\n\tif err := e.Shutdown(ctx); err != nil {\n\t\te.Logger.Fatal(err)\n\t}\n}\n\nfunc GetRateLimiterConfig() middleware.RateLimiterConfig {\n\treturn middleware.RateLimiterConfig{\n\t\tSkipper: middleware.DefaultSkipper,\n\t\tStore: middleware.NewRateLimiterMemoryStoreWithConfig(\n\t\t\tmiddleware.RateLimiterMemoryStoreConfig{Rate: rate.Limit(10), Burst: 30, ExpiresIn: 3 * time.Minute},\n\t\t),\n\t\tIdentifierExtractor: func(ctx echo.Context) (string, error) {\n\t\t\tid := ctx.RealIP()\n\t\t\treturn id, nil\n\t\t},\n\t\tErrorHandler: func(context echo.Context, err error) error {\n\t\t\treturn context.JSON(http.StatusForbidden, nil)\n\t\t},\n\t\tDenyHandler: func(context echo.Context, identifier string, err error) error {\n\t\t\treturn context.JSON(http.StatusTooManyRequests, nil)\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "internal/handler/components.go",
    "content": "package handler\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"math\"\n\t\"net/http\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/haatos/goshipit/internal\"\n\t\"github.com/haatos/goshipit/internal/assets/generated\"\n\t\"github.com/haatos/goshipit/internal/markdown\"\n\t\"github.com/haatos/goshipit/internal/model\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n\t\"github.com/haatos/goshipit/internal/views/examples\"\n\t\"github.com/haatos/goshipit/internal/views/pages\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nfunc GetComponentAnchors(c echo.Context) error {\n\tkeys := make([]string, 0, len(internal.ComponentCodeMap))\n\tfor k := range internal.ComponentCodeMap {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\n\treturn render(c, http.StatusOK, pages.ComponentAnchors(keys, internal.ComponentCodeMap))\n}\n\nfunc GetComponentPage(c echo.Context) error {\n\tcategory := c.Param(\"category\")\n\tname := c.Param(\"name\")\n\n\tvar componentCode model.ComponentCode\n\tfor i := range internal.ComponentCodeMap[category] {\n\t\tif internal.ComponentCodeMap[category][i].Name == name {\n\t\t\tcomponentCode = internal.ComponentCodeMap[category][i]\n\t\t}\n\t}\n\n\texampleCodes := internal.ComponentExampleCodeMap[name]\n\tcoms := make([]templ.Component, 0, len(exampleCodes))\n\tfor i, exampleCode := range exampleCodes {\n\t\ttabs := []components.TabProps{\n\t\t\t{\n\t\t\t\tLabel:   \"Preview\",\n\t\t\t\tContent: generated.ExampleComponents[exampleCode.Name],\n\t\t\t},\n\t\t\t{\n\t\t\t\tLabel:   \"Templ\",\n\t\t\t\tContent: templ.Raw(markdown.GetHTMLFromMarkdown([]byte(exampleCode.Code))),\n\t\t\t},\n\t\t}\n\t\tif exampleCode.Handler != \"\" {\n\t\t\ttabs = append(\n\t\t\t\ttabs,\n\t\t\t\tcomponents.TabProps{\n\t\t\t\t\tLabel:   \"Handler\",\n\t\t\t\t\tContent: templ.Raw(markdown.GetHTMLFromMarkdown([]byte(exampleCode.Handler))),\n\t\t\t\t})\n\t\t}\n\t\tcoms = append(\n\t\t\tcoms,\n\t\t\tpages.ComponentExampleTabs(\n\t\t\t\texampleCode.Title,\n\t\t\t\texampleCode.Description,\n\t\t\t\tpages.ComponentTabs(fmt.Sprintf(\"%s-%d-tab\", exampleCode.Name, i), tabs),\n\t\t\t),\n\t\t)\n\t}\n\n\tif isHXRequest(c) {\n\t\treturn render(c, http.StatusOK, pages.ComponentMain(componentCode, coms))\n\t}\n\treturn render(c, http.StatusOK, pages.ComponentPage(componentCode, coms))\n}\n\nfunc GetComponentSearch(c echo.Context) error {\n\tsearch := c.FormValue(\"search\")\n\tsearch = strings.ToLower(search)\n\tsearch = strings.TrimSpace(search)\n\tif search == \"\" {\n\t\treturn nil\n\t}\n\n\tresults := []pages.ComponentSearchItem{}\n\tfor category := range internal.ComponentCodeMap {\n\t\tfor i := range internal.ComponentCodeMap[category] {\n\t\t\tif strings.Contains(\n\t\t\t\tstrings.ToLower(\n\t\t\t\t\tinternal.SnakeCaseToCapitalized(internal.ComponentCodeMap[category][i].Name),\n\t\t\t\t),\n\t\t\t\tsearch,\n\t\t\t) {\n\t\t\t\tresults = append(results, pages.ComponentSearchItem{\n\t\t\t\t\tCategory: category,\n\t\t\t\t\tName:     internal.ComponentCodeMap[category][i].Name,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\treturn render(c, http.StatusOK, pages.ComponentSearchListItems(results))\n}\n\n// ActiveSearchExampleTable\nfunc GetActiveSearchExample(c echo.Context) error {\n\ttime.Sleep(500 * time.Millisecond)\n\n\tsearch := strings.ToLower(strings.TrimSpace(c.FormValue(\"active-search-example\")))\n\n\tout := make([]templ.Component, 0, len(examples.ActiveSearchTableData))\n\n\tfor _, rowData := range examples.ActiveSearchTableData {\n\t\tif search == \"\" || (strings.Contains(strings.ToLower(rowData.FirstName), search) ||\n\t\t\tstrings.Contains(strings.ToLower(rowData.LastName), search) ||\n\t\t\tstrings.Contains(strings.ToLower(rowData.Email), search)) {\n\t\t\tout = append(out, examples.ActiveSearchTableRow(\n\t\t\t\trowData.FirstName, rowData.LastName, rowData.Email))\n\t\t}\n\t}\n\n\treturn render(c, http.StatusOK, examples.ActiveSearchTableRows(out))\n}\n\n// ActiveSearchExampleTable\n\n// InfiniteScrollTableExample\nfunc GetInfiniteScrollExample(c echo.Context) error {\n\t// generate dummy row data\n\tdata := make([][]string, 0, 10)\n\tfor i := 0; i < 10; i++ {\n\t\tdata = append(data, []string{\"John Doe\", fmt.Sprintf(\"john.doe%d@email.com\", i)})\n\t}\n\n\thasMore := true\n\n\trows := make([]templ.Component, 0, len(data))\n\tfor i := range data {\n\t\trows = append(\n\t\t\trows,\n\t\t\tcomponents.InfiniteScrollRow(data[i][0], data[i][1], 1, i+1 == 10 && hasMore),\n\t\t)\n\t}\n\n\treturn render(c, http.StatusOK, components.InfiniteScrollTable(rows))\n}\n\nfunc GetInfiniteScrollExampleRows(c echo.Context) error {\n\t// short delay for loading indicator\n\ttime.Sleep(500 * time.Millisecond)\n\n\tpageStr := c.QueryParam(\"page\")\n\tpage, err := strconv.Atoi(pageStr)\n\tif err != nil {\n\t\treturn newErrorToast(\n\t\t\thttp.StatusUnprocessableEntity,\n\t\t\tfmt.Sprintf(\"invalid page '%s'\", pageStr),\n\t\t)\n\t}\n\n\t// generate dummy date for the page\n\tdata := make([][]string, 0, 10)\n\tfor i := (page - 1) * 10; i < (page-1)*10+10; i++ {\n\t\tdata = append(data, []string{\"John Doe\", fmt.Sprintf(\"john.doe%d@email.com\", i)})\n\t}\n\n\thasMore := len(data) == 10 && page < 10\n\n\trows := make([]templ.Component, 0, len(data))\n\tfor i := range data {\n\t\trows = append(\n\t\t\trows,\n\t\t\tcomponents.InfiniteScrollRow(data[i][0], data[i][1], page, i+1 == 10 && hasMore),\n\t\t)\n\t}\n\n\treturn render(c, http.StatusOK, components.InfiniteScrollRows(rows))\n}\n\n// InfiniteScrollTableExample\n\n// LazyLoadExample\nfunc GetLazyLoadExample(c echo.Context) error {\n\ttime.Sleep(2 * time.Second)\n\n\treturn render(c, http.StatusOK, examples.LazyLoadResult())\n}\n\n// LazyLoadExample\n\n// CascadingSelect\nvar modelOptions = map[string][]components.SelectOption{\n\t\"audi\": {\n\t\t{Label: \"A1\", Value: \"a1\"},\n\t\t{Label: \"A4\", Value: \"a4\"},\n\t\t{Label: \"A6\", Value: \"a6\"},\n\t},\n\t\"bmw\": {\n\t\t{Label: \"316i\", Value: \"316i\"},\n\t\t{Label: \"320d\", Value: \"320d\"},\n\t},\n\t\"toyota\": {\n\t\t{Label: \"Corolla\", Value: \"corolla\"},\n\t\t{Label: \"Yaris\", Value: \"yaris\"},\n\t\t{Label: \"RAV4\", Value: \"rav4\"},\n\t},\n}\n\nfunc GetCascadingSelectExample(c echo.Context) error {\n\tmake := c.FormValue(\"make\")\n\n\treturn render(c, http.StatusOK, components.SelectOptions(modelOptions[make]))\n}\n\n// CascadingSelect\n\n// BasicPaginationExample\nconst (\n\tItemsPerPage = 10\n\tPagesPerSide = 3\n)\n\nfunc GetPaginationExamplePage(c echo.Context) error {\n\tpageStr := c.QueryParam(\"page\")\n\tpage, err := strconv.Atoi(pageStr)\n\tif err != nil {\n\t\treturn newErrorToast(\n\t\t\thttp.StatusUnprocessableEntity,\n\t\t\tfmt.Sprintf(\"invalid page '%s'\", pageStr),\n\t\t)\n\t}\n\n\t// generate dummy data for the page\n\tdata := make([][]string, 0, 200)\n\tfor i := range 200 {\n\t\tdata = append(data, []string{fmt.Sprintf(\"Key%d\", i), fmt.Sprintf(\"Value%d\", i)})\n\t}\n\tout := data[(page-1)*ItemsPerPage : (page-1)*ItemsPerPage+ItemsPerPage]\n\n\tmaxPages := int(math.Ceil(200 / ItemsPerPage))\n\tlow, high := getPaginationLowAndHigh(page, maxPages, PagesPerSide)\n\n\tcom := examples.BasicPagination(\n\t\t\"pagination-example-1\",\n\t\tcomponents.PaginationProps{\n\t\t\tURL:      c.Request().URL.Path,\n\t\t\tPage:     page,\n\t\t\tLow:      low,\n\t\t\tHigh:     high,\n\t\t\tMaxPages: maxPages,\n\t\t},\n\t\tout)\n\n\treturn render(c, http.StatusOK, com)\n}\n\nfunc getPaginationLowAndHigh(page, maxPages, pagePerSide int) (int, int) {\n\tlow := max(0, page-pagePerSide-1)\n\thigh := min(maxPages-1, page+pagePerSide-1)\n\n\t// if there are less than 'pagePerSide' pages to the left\n\t// of the current page, we add more pages to the high end of the\n\t// pagination element by adding to 'high'\n\tadd := pagePerSide - page\n\tif add >= 0 {\n\t\thigh += add + 1\n\t}\n\n\t// if there are less than 'pagePerSide' pages to the right\n\t// of the current page, we add more pages to the low end of the\n\t// pagination element, by subtracting from 'low'\n\tdistanceFromMaxPages := maxPages - page\n\tif distanceFromMaxPages < pagePerSide {\n\t\tlow -= (pagePerSide - distanceFromMaxPages)\n\t}\n\treturn low, high\n}\n\n// BasicPaginationExample\n\n// BasicCombobox\nfunc PostCombobox(c echo.Context) error {\n\tname := c.Param(\"name\")\n\tvalue := c.Param(\"value\")\n\n\treturn render(c, http.StatusOK, components.ComboBadge(name, value))\n}\n\nfunc PostComboboxSubmit(c echo.Context) error {\n\turlValues, err := c.FormParams()\n\tif err != nil {\n\t\treturn newErrorToast(http.StatusUnprocessableEntity, \"unable to parse form data\")\n\t}\n\n\tname := c.Param(\"name\")\n\tcomboboxPostData := urlValues[name]\n\n\treturn renderInfoFade(c, http.StatusOK, comboboxPostData)\n}\n\n// BasicCombobox\n\n// ModalConfirmDelete\n// endpoint to log deleted 'element' and return an empty string\n// to replace the element, i.e. remove it from the DOM\nfunc DeleteModalExample(c echo.Context) error {\n\tvalue := c.QueryParam(\"value\")\n\tlog.Println(\"deleting modal\", value)\n\treturn c.String(http.StatusOK, \"\")\n}\n\n// ModalConfirmDelete\n\n// BasicDatePicker\nfunc GetDatePicker(c echo.Context) error {\n\tyearStr := c.QueryParam(\"year\")\n\tmonthStr := c.QueryParam(\"month\")\n\n\tyear, yErr := strconv.Atoi(yearStr)\n\tmonth, mErr := strconv.Atoi(monthStr)\n\tif month > 12 {\n\t\tyear += 1\n\t\tmonth = 1\n\t}\n\tif month < 1 {\n\t\tyear -= 1\n\t\tmonth = 12\n\t}\n\n\tif yErr != nil || mErr != nil {\n\t\treturn newErrorToast(http.StatusUnprocessableEntity, \"Invalid year or month\")\n\t}\n\n\tvar selected time.Time\n\tnow := time.Now().UTC()\n\tif year == now.Year() && time.Month(month) == now.Month() {\n\t\tselected = now\n\t}\n\n\treturn render(\n\t\tc,\n\t\thttp.StatusOK,\n\t\tcomponents.DatePicker(\n\t\t\tcomponents.DatePickerProps{\n\t\t\t\tYear:        year,\n\t\t\t\tMonth:       month,\n\t\t\t\tSelected:    selected,\n\t\t\t\tStartOfWeek: time.Monday,\n\t\t\t}),\n\t)\n}\n\nfunc PostDatePickerSelectDay(c echo.Context) error {\n\tvalue := c.FormValue(\"date\")\n\td, err := time.Parse(\"2006-01-02\", value)\n\tif err != nil {\n\t\treturn newErrorToast(\n\t\t\thttp.StatusUnprocessableEntity,\n\t\t\tfmt.Sprintf(\"Invalid date '%s'\", value),\n\t\t)\n\t}\n\n\treturn render(c, http.StatusOK, components.DatePickerInput(d))\n}\n\nfunc GetDatePickerMonthPicker(c echo.Context) error {\n\tyearStr := c.QueryParam(\"year\")\n\n\tyear, yErr := strconv.Atoi(yearStr)\n\tif yErr != nil {\n\t\treturn newErrorToast(http.StatusUnprocessableEntity, \"Invalid year\")\n\t}\n\n\tdpp := components.DatePickerProps{\n\t\tYear: year,\n\t}\n\n\treturn render(c, http.StatusOK, components.DatePickerMonthPicker(dpp))\n}\n\nfunc GetDatePickerYearPicker(c echo.Context) error {\n\tyearStr := c.QueryParam(\"year\")\n\n\tyear, yErr := strconv.Atoi(yearStr)\n\tif yErr != nil {\n\t\treturn newErrorToast(http.StatusUnprocessableEntity, \"Invalid year\")\n\t}\n\n\tdpp := components.DatePickerProps{\n\t\tYear: year,\n\t}\n\n\treturn render(c, http.StatusOK, components.DatePickerYearPicker(dpp))\n}\n\n// BasicDatePicker\n\n// BasicTimeSlotPicker\nfunc GetTimeSlotPicker(c echo.Context) error {\n\tdateStr := c.QueryParam(\"date\")\n\tdate, err := time.Parse(\"2006-01-02\", dateStr)\n\tif err != nil {\n\t\treturn newErrorToast(http.StatusUnprocessableEntity, \"Invalid date\")\n\t}\n\n\tprops := components.TimeSlotPickerProps{\n\t\tID:          \"time-slot-picker-example\",\n\t\tCurrentDate: date,\n\t\tPickerURL:   \"/timeslotpicker\",\n\t\tReserveURL:  \"/timeslotpicker/reserve\",\n\t\tTimeSlots:   getTimeSlots(date),\n\t}\n\treturn render(c, http.StatusOK, components.TimeSlotPicker(props))\n}\n\nfunc getTimeSlots(date time.Time) []components.TimeSlot {\n\tslots := make([]components.TimeSlot, 32)\n\n\tfor i := range 32 {\n\t\tslots[i] = components.TimeSlot{\n\t\t\tStart: date.Add(time.Duration(10+i*2) * time.Hour),\n\t\t\tEnd:   date.Add(time.Duration(11+i*2) * time.Hour),\n\t\t}\n\t}\n\n\treturn slots\n}\n\nfunc PostTimeSlotPickerReserve(c echo.Context) error {\n\tstartStr := c.QueryParam(\"start\")\n\tstart, err := time.Parse(\"2006-01-02-15-04\", startStr)\n\tif err != nil {\n\t\treturn newErrorToast(http.StatusUnprocessableEntity, \"Invalid start date\")\n\t}\n\tendStr := c.QueryParam(\"end\")\n\tend, err := time.Parse(\"2006-01-02-15-04\", endStr)\n\tif err != nil {\n\t\treturn newErrorToast(http.StatusUnprocessableEntity, \"Invalid end date\")\n\t}\n\n\treturn renderInfoFade(\n\t\tc,\n\t\thttp.StatusOK,\n\t\t[]string{\n\t\t\tfmt.Sprintf(\n\t\t\t\t\"Time slot on %s, %s - %s reserved!\",\n\t\t\t\tstart.Format(\"Mon Jan 02\"),\n\t\t\t\tstart.Format(\"15:04\"),\n\t\t\t\tend.Format(\"15:04\"),\n\t\t\t),\n\t\t},\n\t)\n}\n\n// BasicTimeSlotPicker\n"
  },
  {
    "path": "internal/handler/error.go",
    "content": "package handler\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/haatos/goshipit/internal/views/pages\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nfunc ErrorHandler(err error, c echo.Context) {\n\tc.Logger().Errorf(\"Handler error: %+v\\n\", err)\n\tswitch e := err.(type) {\n\tcase ErrorToast:\n\t\trenderErrorConfirm(c, e.Status, e.Messages)\n\tcase *echo.HTTPError:\n\t\tswitch e.Code {\n\t\tcase http.StatusNotFound:\n\t\t\trender(c, e.Code, pages.NotFound())\n\t\tcase http.StatusInternalServerError:\n\t\t\trender(c, e.Code, pages.InternalServerError())\n\t\tcase http.StatusForbidden:\n\t\t\trender(c, e.Code, pages.Forbidden(\"Invalid permissions to view this page.\"))\n\t\t}\n\t}\n}\n\ntype ErrorToast struct {\n\tStatus   int\n\tMessages []string\n}\n\nfunc (te ErrorToast) Error() string {\n\treturn strings.Join(te.Messages, \", \")\n}\n\nfunc newErrorToast(status int, messages ...string) ErrorToast {\n\treturn ErrorToast{\n\t\tStatus:   status,\n\t\tMessages: messages,\n\t}\n}\n\nfunc NotFound(c echo.Context) error {\n\treturn render(c, http.StatusNotFound, pages.NotFound())\n}\n"
  },
  {
    "path": "internal/handler/htmx.go",
    "content": "package handler\n\nimport \"github.com/labstack/echo/v4\"\n\nfunc hxRetarget(c echo.Context, target string) {\n\tc.Response().Writer.Header().Set(\"HX-Retarget\", target)\n}\n\nfunc hxReswap(c echo.Context, swap string) {\n\tc.Response().Writer.Header().Set(\"HX-Reswap\", swap)\n}\n\nfunc isHXRequest(c echo.Context) bool {\n\treturn c.Request().Header.Get(\"hx-request\") != \"\"\n}\n"
  },
  {
    "path": "internal/handler/input_validation.go",
    "content": "package handler\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/haatos/goshipit/internal/views/components\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nvar emailRegexp = regexp.MustCompile(`^[^@]+@[^@]+\\.[^@]+$`)\n\nvar StringValidations = map[string]func(data string) string{\n\t\"notempty\": func(data string) string {\n\t\tdata = strings.TrimSpace(data)\n\t\tif data == \"\" {\n\t\t\treturn \"must not be empty\"\n\t\t}\n\t\treturn \"\"\n\t},\n\t\"email\": func(data string) string {\n\t\tdata = strings.TrimSpace(data)\n\t\tif !emailRegexp.Match([]byte(data)) {\n\t\t\treturn \"must be valid\"\n\t\t}\n\t\treturn \"\"\n\t},\n\t\"hasupper\": func(data string) string {\n\t\tfor _, r := range data {\n\t\t\tif unicode.IsUpper(r) {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t\treturn \"must contain a uppercase letter\"\n\t},\n\t\"haslower\": func(data string) string {\n\t\tfor _, r := range data {\n\t\t\tif unicode.IsLower(r) {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t\treturn \"must contain a lowercase letter\"\n\t},\n\t\"hasdigit\": func(data string) string {\n\t\tfor _, r := range data {\n\t\t\tif unicode.IsNumber(r) {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t\treturn \"must contain a number\"\n\t},\n\t\"hasspecial\": func(data string) string {\n\t\tchars := `§!\"@#£¤$%&/{([=?+\\'*<>,;.:-_])}`\n\t\tif strings.ContainsAny(data, chars) {\n\t\t\treturn \"\"\n\t\t}\n\t\treturn fmt.Sprintf(\"must contain one of %s\", chars)\n\t},\n}\n\nfunc PostValidateString(c echo.Context) error {\n\tname := c.Param(\"name\")\n\tvalue := c.FormValue(name)\n\tvalidations := c.QueryParams()[\"v\"]\n\n\terrors := make([]string, 0, len(validations))\n\tfor _, validation := range validations {\n\t\tif res := StringValidations[validation](value); res != \"\" {\n\t\t\terrors = append(errors, res)\n\t\t}\n\t}\n\n\te := strings.Join(errors, \", \")\n\n\tif e != \"\" {\n\t\treturn render(c, http.StatusUnprocessableEntity, components.PlainText(e))\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/handler/pages.go",
    "content": "package handler\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/haatos/goshipit/internal\"\n\t\"github.com/haatos/goshipit/internal/assets\"\n\t\"github.com/haatos/goshipit/internal/markdown\"\n\t\"github.com/haatos/goshipit/internal/views/pages\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nvar gettingStartedHTML string\nvar typesHTML string\nvar cliHTML string\n\nconst (\n\tcontentTypesMarkdownPath   = \"content/types.md\"\n\tgettingStartedMarkdownPath = \"content/getting_started.md\"\n\tcliMarkdownPath            = \"content/cli.md\"\n)\n\nfunc getGettingStartedHTML() {\n\tif gettingStartedHTML != \"\" {\n\t\treturn\n\t}\n\n\tpageContent, err := assets.ContentFS.ReadFile(gettingStartedMarkdownPath)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tgettingStartedHTML = markdown.GetHTMLFromMarkdown(pageContent)\n}\n\nfunc getTypesHTML() {\n\tif typesHTML != \"\" {\n\t\treturn\n\t}\n\n\tpageContent, err := assets.ContentFS.ReadFile(contentTypesMarkdownPath)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\ttypesHTML = markdown.GetHTMLFromMarkdown(pageContent)\n}\n\nfunc getCLIHTML() {\n\tif cliHTML != \"\" {\n\t\treturn\n\t}\n\n\tpageContent, err := assets.ContentFS.ReadFile(cliMarkdownPath)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tcliHTML = markdown.GetHTMLFromMarkdown(pageContent)\n}\n\nfunc GetIndexPage(c echo.Context) error {\n\tif isHXRequest(c) {\n\t\treturn render(c, http.StatusOK, pages.IndexPageContent())\n\t}\n\treturn render(c, http.StatusOK, pages.IndexPage())\n}\n\nfunc GetAboutPage(c echo.Context) error {\n\tif isHXRequest(c) {\n\t\treturn render(c, http.StatusOK, pages.AboutPageMain())\n\t}\n\treturn render(c, http.StatusOK, pages.AboutPage())\n}\n\nfunc GetGettingStartedPage(c echo.Context) error {\n\tgetGettingStartedHTML()\n\n\tif isHXRequest(c) {\n\t\treturn render(c, http.StatusOK, pages.GettingStartedPageMain(gettingStartedHTML))\n\t}\n\treturn render(c, http.StatusOK, pages.GettingStartedPage(gettingStartedHTML))\n}\n\nfunc GetTypesPage(c echo.Context) error {\n\tgetTypesHTML()\n\n\tif isHXRequest(c) {\n\t\treturn render(c, http.StatusOK, pages.TypesPageMain(typesHTML))\n\t}\n\treturn render(c, http.StatusOK, pages.TypesPage(typesHTML))\n}\n\nfunc GetCLIPage(c echo.Context) error {\n\tgetCLIHTML()\n\n\tif isHXRequest(c) {\n\t\treturn render(c, http.StatusOK, pages.CLIPageMain(cliHTML))\n\t}\n\treturn render(c, http.StatusOK, pages.CLIPage(cliHTML))\n}\n\nfunc GetPrivacyPolicyPage(c echo.Context) error {\n\tif isHXRequest(c) {\n\t\treturn render(\n\t\t\tc, http.StatusOK,\n\t\t\tpages.PrivacyMain(internal.Settings.Domain, internal.Settings.ContactEmail))\n\t}\n\treturn render(\n\t\tc, http.StatusOK,\n\t\tpages.PrivacyPage(internal.Settings.Domain, internal.Settings.ContactEmail))\n}\n\nfunc GetTermsOfServicePage(c echo.Context) error {\n\tif isHXRequest(c) {\n\t\treturn render(\n\t\t\tc, http.StatusOK,\n\t\t\tpages.TermsOfServiceMain(internal.Settings.Domain, internal.Settings.ContactEmail))\n\t}\n\treturn render(\n\t\tc, http.StatusOK,\n\t\tpages.TermsOfService(internal.Settings.Domain, internal.Settings.ContactEmail))\n}\n"
  },
  {
    "path": "internal/handler/render.go",
    "content": "package handler\n\nimport (\n\t\"context\"\n\n\t\"github.com/a-h/templ\"\n\t\"github.com/haatos/goshipit/internal/views/custom\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/labstack/gommon/log\"\n)\n\nfunc render(c echo.Context, status int, com templ.Component) error {\n\tbuf := templ.GetBuffer()\n\tdefer templ.ReleaseBuffer(buf)\n\n\tif err := com.Render(c.Request().Context(), buf); err != nil {\n\t\treturn err\n\t}\n\n\treturn c.HTML(status, buf.String())\n}\n\nfunc renderErrorConfirm(c echo.Context, status int, errs []string) error {\n\thxRetarget(c, \"body\")\n\thxReswap(c, \"beforeend\")\n\treturn render(c, status, custom.ToastErrorConfirm(errs...))\n}\n\nfunc renderInfoFade(c echo.Context, status int, messages []string) error {\n\thxRetarget(c, \"body\")\n\thxReswap(c, \"beforeend\")\n\treturn render(c, status, custom.HXToastInfoFade(messages...))\n}\n\nfunc getHTMLFromComponent(com templ.Component) string {\n\tbuf := templ.GetBuffer()\n\tdefer templ.ReleaseBuffer(buf)\n\n\tif err := com.Render(context.Background(), buf); err != nil {\n\t\tlog.Error(err)\n\t}\n\n\treturn buf.String()\n}\n"
  },
  {
    "path": "internal/markdown/markdown.go",
    "content": "package markdown\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"log\"\n\t\"strings\"\n\n\t\"github.com/PuerkitoBio/goquery\"\n\tchromaHTML \"github.com/alecthomas/chroma/formatters/html\"\n\t\"github.com/alecthomas/chroma/lexers\"\n\t\"github.com/alecthomas/chroma/styles\"\n\t\"github.com/russross/blackfriday\"\n)\n\nfunc GetHTMLFromMarkdown(markdown []byte) string {\n\thtmlBytes := blackfriday.MarkdownCommon(markdown)\n\treplaced, err := replaceCodeParts(htmlBytes)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\treturn replaced\n}\n\nfunc replaceCodeParts(mdFile []byte) (string, error) {\n\tbyteReader := bytes.NewReader(mdFile)\n\tdoc, err := goquery.NewDocumentFromReader(byteReader)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tvar hlErr error\n\tdoc.Find(\"code[class*=\\\"language-\\\"]\").Each(func(i int, s *goquery.Selection) {\n\t\tif hlErr != nil {\n\t\t\treturn\n\t\t}\n\t\tclass, _ := s.Attr(\"class\")\n\t\tlang := strings.TrimPrefix(class, \"language-\")\n\t\toldCode := s.Text()\n\t\tlexer := lexers.Get(lang)\n\t\tformatter := chromaHTML.New(chromaHTML.WithClasses(true))\n\t\titerator, err := lexer.Tokenise(nil, string(oldCode))\n\t\tif err != nil {\n\t\t\thlErr = err\n\t\t\treturn\n\t\t}\n\t\tb := bytes.Buffer{}\n\t\tbuf := bufio.NewWriter(&b)\n\t\tif err := formatter.Format(buf, styles.GitHub, iterator); err != nil {\n\t\t\thlErr = err\n\t\t\treturn\n\t\t}\n\t\tif err := buf.Flush(); err != nil {\n\t\t\thlErr = err\n\t\t\treturn\n\t\t}\n\t\ts.SetHtml(b.String())\n\t})\n\tif hlErr != nil {\n\t\treturn \"\", hlErr\n\t}\n\tnew, err := doc.Html()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn new, nil\n}\n\nfunc CodeSliceToMarkdown(s []string) string {\n\tif s == nil {\n\t\treturn \"\"\n\t}\n\tn := make([]string, len(s)+2)\n\tn[0] = \"```go\"\n\tn[len(s)+2-1] = \"```\"\n\tcopy(n[1:len(s)+1], s)\n\treturn strings.Join(n, \"\\n\")\n}\n"
  },
  {
    "path": "internal/markdown.go",
    "content": "package internal\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"log\"\n\t\"strings\"\n\n\t\"github.com/PuerkitoBio/goquery\"\n\tchromaHTML \"github.com/alecthomas/chroma/formatters/html\"\n\t\"github.com/alecthomas/chroma/lexers\"\n\t\"github.com/alecthomas/chroma/styles\"\n\t\"github.com/russross/blackfriday\"\n)\n\nfunc GetHTMLFromMarkdown(markdown []byte) string {\n\thtmlBytes := blackfriday.MarkdownCommon(markdown)\n\treplaced, err := replaceCodeParts(htmlBytes)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\treturn replaced\n}\n\nfunc replaceCodeParts(mdFile []byte) (string, error) {\n\tbyteReader := bytes.NewReader(mdFile)\n\tdoc, err := goquery.NewDocumentFromReader(byteReader)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tvar hlErr error\n\tdoc.Find(\"code[class*=\\\"language-\\\"]\").Each(func(i int, s *goquery.Selection) {\n\t\tif hlErr != nil {\n\t\t\treturn\n\t\t}\n\t\tclass, _ := s.Attr(\"class\")\n\t\tlang := strings.TrimPrefix(class, \"language-\")\n\t\toldCode := s.Text()\n\t\tlexer := lexers.Get(lang)\n\t\tformatter := chromaHTML.New(chromaHTML.WithClasses(true))\n\t\titerator, err := lexer.Tokenise(nil, string(oldCode))\n\t\tif err != nil {\n\t\t\thlErr = err\n\t\t\treturn\n\t\t}\n\t\tb := bytes.Buffer{}\n\t\tbuf := bufio.NewWriter(&b)\n\t\tif err := formatter.Format(buf, styles.GitHub, iterator); err != nil {\n\t\t\thlErr = err\n\t\t\treturn\n\t\t}\n\t\tif err := buf.Flush(); err != nil {\n\t\t\thlErr = err\n\t\t\treturn\n\t\t}\n\t\ts.SetHtml(b.String())\n\t})\n\tif hlErr != nil {\n\t\treturn \"\", hlErr\n\t}\n\tnew, err := doc.Html()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn new, nil\n}\n"
  },
  {
    "path": "internal/model/generation.go",
    "content": "package model\n\ntype ComponentCode struct {\n\tName        string `json:\"name\"`\n\tCode        string `json:\"code,omitempty\"`\n\tHandler     string `json:\"handler,omitempty\"`\n\tTitle       string `json:\"title,omitempty\"`\n\tDescription string `json:\"description,omitempty\"`\n\tDaisyUIURL  string `json:\"daisy_ui_url,omitempty\"`\n\n\tLabel string `json:\"-\"`\n}\n\ntype ComponentCodeMap map[string][]ComponentCode\n\ntype ComponentExampleCodeMap map[string][]ComponentCode\n"
  },
  {
    "path": "internal/settings.go",
    "content": "package internal\n\nimport (\n\t\"bufio\"\n\t\"log\"\n\t\"log/slog\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nvar Settings *AppSettings\n\nfunc NewSettings() *AppSettings {\n\tsettings := AppSettings{\n\t\tTitle:        \"goship.it\",\n\t\tContactEmail: os.Getenv(\"CONTACT_EMAIL\"),\n\t\tDomain:       getEnvOrDefault(\"DOMAIN\", \"localhost\"),\n\t\tPort:         getEnvOrDefault(\"PORT\", \":8080\"),\n\t}\n\tif !strings.HasPrefix(settings.Port, \":\") {\n\t\tsettings.Port = \":\" + settings.Port\n\t}\n\treturn &settings\n}\n\nfunc getEnvOrDefault(key, defaultValue string) string {\n\tvalue, ok := os.LookupEnv(key)\n\tif !ok {\n\t\treturn defaultValue\n\t}\n\treturn value\n}\n\ntype AppSettings struct {\n\tTitle        string\n\tContactEmail string\n\tDomain       string\n\tPort         string\n}\n\nfunc ReadDotenv() {\n\tpath := \"./.env\"\n\tre := regexp.MustCompile(`^[^0-9][A-Z0-9_]+=.+$`)\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\tlog.Fatal(\"err opening dotenv: \", err)\n\t}\n\tdefer f.Close()\n\n\tscanner := bufio.NewScanner(f)\n\tfor scanner.Scan() {\n\t\tline := scanner.Bytes()\n\t\tif len(line) > 0 && line[0] != '#' && re.Match(line) {\n\t\t\tsplit := strings.Split(string(line), \"=\")\n\t\t\tname := strings.TrimSpace(split[0])\n\t\t\tvalue := strings.TrimSpace(split[1])\n\t\t\tvalue = strings.Trim(value, `\"`)\n\t\t\tos.Setenv(name, value)\n\t\t} else {\n\t\t\tslog.Debug(\"not including invalid or empty line\", \"line\", string(line))\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/views/components/accordion.templ",
    "content": "// data_display\n// https://daisyui.com/components/accordion\npackage components\n\ntype AccordionRowProps struct {\n\tLabel string\n\tType  string\n\tName  string\n}\n\ntempl AccordionRow(props AccordionRowProps) {\n\t<div class=\"collapse collapse-arrow bg-base-300 join-item\">\n\t\t<input\n\t\t\tif props.Type == \"\" {\n\t\t\t\ttype=\"checkbox\"\n\t\t\t} else {\n\t\t\t\ttype={ props.Type }\n\t\t\t}\n\t\t\tname={ props.Name }\n\t\t/>\n\t\t<div class=\"collapse-title text-xl font-medium\">{ props.Label }</div>\n\t\t<div class=\"collapse-content bg-base-200\">\n\t\t\t{ children... }\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/active_search.templ",
    "content": "// data_display\npackage components\n\nimport \"fmt\"\n\ntype ActiveSearchInputProps struct {\n\tID         string\n\tURL        string\n\tTarget     string\n\tInputProps InputProps\n}\n\ntempl ActiveSearchInput(props ActiveSearchInputProps) {\n\t<div class=\"w-full flex space-x-2 items-center\">\n\t\t<div class=\"flex items-center gap-2 w-full max-w-xs\">\n\t\t\t<form\n\t\t\t\tid={ props.ID }\n\t\t\t\thx-get={ props.URL }\n\t\t\t\thx-target={ props.Target }\n\t\t\t\thx-swap=\"innerHTML\"\n\t\t\t\thx-trigger={ fmt.Sprintf(\"keyup from:input[name=%s] delay:500ms, search\", props.InputProps.Name) }\n\t\t\t\thx-indicator={ fmt.Sprintf(\"#%s\", props.ID) }\n\t\t\t\tclass=\"w-full relative\"\n\t\t\t>\n\t\t\t\t@Input(props.InputProps)\n\t\t\t\t<div class=\"absolute -right-8 top-2\">\n\t\t\t\t\t<span id={ props.ID } class=\"htmx-indicator loading loading-sm loading-spinner\"></span>\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/alert.templ",
    "content": "// feedback\n// https://daisyui.com/components/alert\npackage components\n\ntempl Alert(class string) {\n\t<div role=\"alert\" class={ \"alert\", class }>\n\t\t{ children... }\n\t</div>\n}\n\ntempl AlertInfo(message string) {\n\t@Alert(\"alert-info\") {\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tclass=\"stroke-info-content h-6 w-6 shrink-0\"\n\t\t>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\tstroke-width=\"2\"\n\t\t\t\td=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n\t\t\t></path>\n\t\t</svg>\n\t\t<span>{ message }</span>\n\t\t{ children... }\n\t}\n}\n\ntempl AlertSuccess(message string) {\n\t@Alert(\"alert-success\") {\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tclass=\"stroke-success-content h-6 w-6 shrink-0\"\n\t\t>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\tstroke-width=\"2\"\n\t\t\t\td=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n\t\t\t></path>\n\t\t</svg>\n\t\t<span>{ message }</span>\n\t\t{ children... }\n\t}\n}\n\ntempl AlertWarning(message string) {\n\t@Alert(\"alert-warning\") {\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tclass=\"stroke-warning-content h-6 w-6 shrink-0\"\n\t\t>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\tstroke-width=\"2\"\n\t\t\t\td=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n\t\t\t></path>\n\t\t</svg>\n\t\t<span>{ message }</span>\n\t\t{ children... }\n\t}\n}\n\ntempl AlertError(message string) {\n\t@Alert(\"alert-error\") {\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tclass=\"stroke-error-content h-6 w-6 shrink-0\"\n\t\t>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\tstroke-width=\"2\"\n\t\t\t\td=\"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z\"\n\t\t\t></path>\n\t\t</svg>\n\t\t<span>{ message }</span>\n\t\t{ children... }\n\t}\n}\n"
  },
  {
    "path": "internal/views/components/anchor.templ",
    "content": "// navigation\npackage components\n\ntype AnchorProps struct {\n\tHref      string\n\tLabel     string\n\tLeftIcon  templ.Component\n\tRightIcon templ.Component\n\tAttrs     templ.Attributes\n\tClass     string\n}\n\ntempl Anchor(props AnchorProps) {\n\t<a\n\t\tif props.Href != \"\" {\n\t\t\thref={ templ.SafeURL(props.Href) }\n\t\t}\n\t\tclass={ \"group items-center cursor-pointer\", props.Class }\n\t\t{ props.Attrs... }\n\t>\n\t\tif props.LeftIcon != nil {\n\t\t\t@props.LeftIcon\n\t\t}\n\t\t{ props.Label }\n\t\tif props.RightIcon != nil {\n\t\t\t@props.RightIcon\n\t\t}\n\t</a>\n}\n"
  },
  {
    "path": "internal/views/components/avatar.templ",
    "content": "// data_display\n// https://daisyui.com/components/avatar\npackage components\n\ntype AvatarProps struct {\n\tAvatarClass      string\n\tContainerClass   string\n\tSource           string\n\tPlaceholder      string\n\tPlaceholderClass string\n}\n\ntempl Avatar(props AvatarProps) {\n\t<div class={ \"avatar\", props.AvatarClass }>\n\t\t<div class={ props.ContainerClass }>\n\t\t\t<img src={ props.Source }/>\n\t\t\tif props.Placeholder != \"\" {\n\t\t\t\t<span class={ props.PlaceholderClass }>{ props.Placeholder }</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n}\n\ntempl AvatarGroup(class string) {\n\t<div class={ \"avatar-group rtl:space-x-reverse\", class }>\n\t\t{ children... }\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/banner.templ",
    "content": "// layout\npackage components\n\ntype BannerProps struct {\n\tTitle       templ.Component\n\tDescription string\n}\n\ntempl Banner(props BannerProps) {\n\t<section>\n\t\t<div class=\"mx-auto max-w-screen-xl px-4 py-32 lg:flex lg:items-center\">\n\t\t\t<div class=\"mx-auto max-w-xl text-center\">\n\t\t\t\t@props.Title\n\t\t\t\t<p class=\"mt-4 sm:text-xl/relaxed\">\n\t\t\t\t\t{ props.Description }\n\t\t\t\t</p>\n\t\t\t\t<div class=\"mt-8 flex flex-wrap justify-center gap-4\">\n\t\t\t\t\t// call to action\n\t\t\t\t\t{ children... }\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n}\n"
  },
  {
    "path": "internal/views/components/breadcrumbs.templ",
    "content": "// navigation\n// https://daisyui.com/components/breadcrumbs\npackage components\n\ntype BreadcrumbsProps []BreadcrumbsProp\n\ntype BreadcrumbsProp struct {\n\tLabel string\n\tAttrs templ.Attributes\n}\n\ntempl Breadcrumbs(props BreadcrumbsProps) {\n\t<div class=\"breadcrumbs text-sm\">\n\t\t<ul>\n\t\t\tfor i, prop := range props {\n\t\t\t\t<li class=\"select-none\">\n\t\t\t\t\tif i < len(props) - 1 {\n\t\t\t\t\t\t<a { prop.Attrs... }>{ prop.Label }</a>\n\t\t\t\t\t} else {\n\t\t\t\t\t\t{ prop.Label }\n\t\t\t\t\t}\n\t\t\t\t</li>\n\t\t\t}\n\t\t</ul>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/card.templ",
    "content": "// data_display\n// https://daisyui.com/components/card\npackage components\n\ntype CardProps struct {\n\tTitle   string\n\tContent string\n\tSource  string\n\tAlt     string\n\tClass   string\n}\n\ntempl Card(props CardProps) {\n\t<div class={ \"card\", props.Class }>\n\t\tif props.Source != \"\" {\n\t\t\t<figure>\n\t\t\t\t<img src={ props.Source } alt={ props.Alt }/>\n\t\t\t</figure>\n\t\t}\n\t\t<div class=\"card-body\">\n\t\t\t<h2 class=\"card-title\">{ props.Title }</h2>\n\t\t\t<p>{ props.Content }</p>\n\t\t\t<div class=\"card-actions justify-end\">\n\t\t\t\t{ children... }\n\t\t\t</div>\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/carousel.templ",
    "content": "// data_display\n// https://daisyui.com/components/carousel\npackage components\n\ntype CarouselProps []CarouselProp\n\ntype CarouselProp struct {\n\tSource string\n\tAlt    string\n}\n\ntempl Carousel(props CarouselProps) {\n\t<div class=\"carousel carousel-center rounded-box\">\n\t\tfor _, prop := range props {\n\t\t\t<div class=\"carousel-item [&:not(:last-child)]:border-r border-r-base-300\">\n\t\t\t\t<img class=\"max-w-xs\" src={ prop.Source } alt={ prop.Alt }/>\n\t\t\t</div>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/chat.templ",
    "content": "// data_display\n// https://daisyui.com/components/chat\npackage components\n\ntype ChatProps []ChatMessageProps\n\ntype ChatMessageProps struct {\n\tAvatarURL string\n\tSender    string\n\tTime      string\n\tMessage   string\n\tFooter    string\n\tLocation  string\n\tClass     string\n}\n\ntempl Chat(props ChatProps) {\n\tfor _, prop := range props {\n\t\t@ChatMessage(prop)\n\t}\n}\n\ntempl ChatMessage(props ChatMessageProps) {\n\t<div\n\t\tclass={\n\t\t\t\"chat\",\n\t\t\ttempl.KV(\"chat-start\", props.Location == \"start\"),\n\t\t\ttempl.KV(\"chat-end\", props.Location == \"end\"),\n\t\t}\n\t>\n\t\tif props.AvatarURL != \"\" {\n\t\t\t@Avatar(AvatarProps{ContainerClass: \"chat-image w-10 rounded-full\", Source: props.AvatarURL})\n\t\t}\n\t\t<div class=\"chat-header\">\n\t\t\t{ props.Sender }\n\t\t\t<time class=\"text-xs opacity-50\">{ props.Time }</time>\n\t\t</div>\n\t\t<div class={ \"chat-bubble\", props.Class }>\n\t\t\t{ props.Message }\n\t\t</div>\n\t\t<div class=\"chat-footer\">\n\t\t\t{ props.Footer }\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/checkbox.templ",
    "content": "// data_input\n// https://daisyui.com/components/checkbox\npackage components\n\ntype CheckboxProps struct {\n\tID      string\n\tBefore  string\n\tAfter   string\n\tName    string\n\tChecked bool\n\tClass   string\n\tAttrs   templ.Attributes\n\tSize    string\n}\n\ntempl Checkbox(props CheckboxProps) {\n\t<label class=\"label justify-center cursor-pointer\">\n\t\tif props.Before != \"\" {\n\t\t\t<span\n\t\t\t\tclass={\n\t\t\t\t\ttempl.KV(\"text-xs\", props.Size == \"xs\"),\n\t\t\t\t\ttempl.KV(\"text-sm\", props.Size == \"sm\"),\n\t\t\t\t\ttempl.KV(\"text-lg\", props.Size == \"lg\"),\n\t\t\t\t\ttempl.KV(\"text-xl\", props.Size == \"xl\"),\n\t\t\t\t\t\"mr-2\",\n\t\t\t\t}\n\t\t\t>\n\t\t\t\t{ props.Before }\n\t\t\t</span>\n\t\t}\n\t\t<input\n\t\t\t{ props.Attrs... }\n\t\t\tif props.ID != \"\" {\n\t\t\t\tid={ props.ID }\n\t\t\t}\n\t\t\ttype=\"checkbox\"\n\t\t\tname={ props.Name }\n\t\t\tif props.Checked {\n\t\t\t\tchecked=\"checked\"\n\t\t\t}\n\t\t\tclass={\n\t\t\t\t\"checkbox\", props.Class,\n\t\t\t\ttempl.KV(\"checkbox-xs\", props.Size == \"xs\"),\n\t\t\t\ttempl.KV(\"checkbox-sm\", props.Size == \"sm\"),\n\t\t\t\ttempl.KV(\"checkbox-lg\", props.Size == \"lg\"),\n\t\t\t\ttempl.KV(\"checkbox-xl\", props.Size == \"xl\"),\n\t\t\t}\n\t\t/>\n\t\tif props.After != \"\" {\n\t\t\t<span class=\"ml-2\">\n\t\t\t\t{ props.After }\n\t\t\t</span>\n\t\t}\n\t</label>\n}\n"
  },
  {
    "path": "internal/views/components/collapse.templ",
    "content": "// data_display\n// https://daisyui.com/components/collapse\npackage components\n\ntype CollapseProps struct {\n\tClass        string\n\tTitle        string\n\tTitleClass   string\n\tContentClass string\n}\n\ntempl Collapse(props CollapseProps) {\n\t<div\n\t\ttabindex=\"0\"\n\t\tclass={ \"collapse\", props.Class }\n\t>\n\t\t<input type=\"checkbox\"/>\n\t\t<div class={ \"collapse-title\", props.TitleClass }>\n\t\t\t{ props.Title }\n\t\t</div>\n\t\t<div class={ \"collapse-content\", props.ContentClass }>\n\t\t\t{ children... }\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/combobox.templ",
    "content": "// data_input\npackage components\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n)\n\ntype ComboboxProps struct {\n\tLabel    string\n\tName     string\n\tURL      string\n\tOptions  []string\n\tSelected []string\n}\n\ntempl Combobox(props ComboboxProps) {\n\t<details class=\"dropdown w-full max-w-md min-h-8\">\n\t\t<summary\n\t\t\tclass={\n\t\t\t\t\"cursor-pointer flex space-x-2 w-full rounded-box\",\n\t\t\t\t\"border border-base-content py-1 px-2\",\n\t\t\t}\n\t\t>\n\t\t\t<span class=\"text-sm text-nowrap\">{ props.Label }</span>\n\t\t\t<div class=\"w-full flex items-center space-x-1\">\n\t\t\t\t<div\n\t\t\t\t\tid={ fmt.Sprintf(\"%s_selections\", props.Name) }\n\t\t\t\t\tclass=\"w-full grid-flow-col-dense\"\n\t\t\t\t>\n\t\t\t\t\tfor _, s := range props.Selected {\n\t\t\t\t\t\t@ComboBadge(props.Name, s)\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</summary>\n\t\t<ul class=\"menu dropdown-content bg-base-200 rounded-box z-50 p-2 shadow-sm\">\n\t\t\tfor _, opt := range props.Options {\n\t\t\t\t<li>\n\t\t\t\t\t<label class=\"label cursor-pointer space-x-2\">\n\t\t\t\t\t\t<span class=\"label-text\">\n\t\t\t\t\t\t\t{ opt }\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\thx-post={ fmt.Sprintf(props.URL, props.Name, url.PathEscape(opt)) }\n\t\t\t\t\t\t\thx-target={ fmt.Sprintf(\"#%s_selections\", props.Name) }\n\t\t\t\t\t\t\thx-swap=\"beforeend\"\n\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\tname={ props.Name }\n\t\t\t\t\t\t\tclass={ \"checkbox\" }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</label>\n\t\t\t\t</li>\n\t\t\t}\n\t\t</ul>\n\t\t<script data-checkbox-name={ props.Name } type=\"text/javascript\">\n\t\t\tvar name = document.currentScript.getAttribute(\"data-checkbox-name\");\n\t\t\t((name) => {\n\t\t\t\tdocument.addEventListener(\"htmx:configRequest\", (evt) => {\n\t\t\t\t\tif (evt.target.getAttribute(\"name\") === name && !evt.target.checked) {\n\t\t\t\t\t\t// prevent htmx request when checkbox is unchecked\n\t\t\t\t\t\tevt.preventDefault()\n\n\t\t\t\t\t\t// remove from selected elements\n\t\t\t\t\t\tlet label = evt.target.closest(\"label\")\n\t\t\t\t\t\tif (label !== null && label !== undefined) {\n\t\t\t\t\t\t\tlet span = label.querySelector(\"span.label-text\")\n\t\t\t\t\t\t\tlet value = span.innerText\n\t\t\t\t\t\t\tlet input = document.querySelector(`input[value=\"${value}\"]`)\n\t\t\t\t\t\t\tif (input.getAttribute(\"name\") === name) {\n\t\t\t\t\t\t\t\tinput.closest(\"div\").remove()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})(name);\n\t\t</script>\n\t</details>\n}\n\ntempl ComboBadge(name, value string) {\n\t<div class=\"ml-2 badge badge-neutral p-1 text-nowrap select-none\">\n\t\t<input type=\"hidden\" name={ name } value={ value }/>\n\t\t<span>{ value }</span>\n\t\t<button\n\t\t\tonclick=\"uncheckAndRemoveBadge(event)\"\n\t\t\tclass=\"ml-1 btn btn-xs btn-circle btn-ghost\"\n\t\t>\n\t\t\t@crossIcon()\n\t\t</button>\n\t\t<script>\n\t\t\tfunction uncheckAndRemoveBadge(evt) {\n\t\t\t\tvar div = evt.target.parentElement\n\t\t\t\twhile (div.nodeName !== \"DIV\") {\n\t\t\t\t\tdiv = div.parentElement\n\t\t\t\t}\n\t\t\t\tlet input = div.querySelector(\"input[type=hidden]\")\n\t\t\t\tlet name = input.getAttribute(\"name\")\n\t\t\t\tlet labelText = input.value\n\n\t\t\t\tlet details = div.closest(\"details\")\n\t\t\t\tlet ul = details.querySelector(\"ul\")\n\t\t\t\tlet checkboxes = ul.querySelectorAll(`input[name=\"${name}\"]`)\n\t\t\t\tcheckboxes.forEach((cb) => {\n\t\t\t\t\tif (cb.checked) {\n\t\t\t\t\t\tlet label = cb.parentElement\n\t\t\t\t\t\tlabel.querySelectorAll(\"span.label-text\").forEach((el) => {\n\t\t\t\t\t\t\tif (el.innerHTML === labelText) {\n\t\t\t\t\t\t\t\tcb.checked = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tdiv.remove()\n\t\t\t}\n\t\t</script>\n\t</div>\n}\n\ntempl crossIcon() {\n\t<svg\n\t\tclass=\"h-3 w-3\"\n\t\tviewBox=\"0 0 25 25\"\n\t\tversion=\"1.1\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\t\txmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\"\n\t>\n\t\t<g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n\t\t\t<g class=\"fill-base-content\" id=\"Icon-Set-Filled\" sketch:type=\"MSLayerGroup\" transform=\"translate(-469.000000, -1041.000000)\">\n\t\t\t\t<path d=\"M487.148,1053.48 L492.813,1047.82 C494.376,1046.26 494.376,1043.72 492.813,1042.16 C491.248,1040.59 488.712,1040.59 487.148,1042.16 L481.484,1047.82 L475.82,1042.16 C474.257,1040.59 471.721,1040.59 470.156,1042.16 C468.593,1043.72 468.593,1046.26 470.156,1047.82 L475.82,1053.48 L470.156,1059.15 C468.593,1060.71 468.593,1063.25 470.156,1064.81 C471.721,1066.38 474.257,1066.38 475.82,1064.81 L481.484,1059.15 L487.148,1064.81 C488.712,1066.38 491.248,1066.38 492.813,1064.81 C494.376,1063.25 494.376,1060.71 492.813,1059.15 L487.148,1053.48\" sketch:type=\"MSShapeGroup\"></path>\n\t\t\t</g>\n\t\t</g>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/components/countdown.templ",
    "content": "// data_display\npackage components\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntype CountdownProps struct {\n\tExpires time.Time\n\tDays    bool\n\tHours   bool\n\tMinutes bool\n\tSeconds bool\n}\n\ntempl Countdown(props CountdownProps) {\n\t{{ spanID := time.Now().UnixNano() }}\n\t<div class=\"grid auto-cols-max grid-flow-col gap-5 text-center\">\n\t\t<div\n\t\t\tclass={\n\t\t\t\t\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\",\n\t\t\t\ttempl.KV(\"hidden\", !props.Days),\n\t\t\t}\n\t\t>\n\t\t\t<span class=\"countdown font-mono text-5xl\">\n\t\t\t\t<span id={ fmt.Sprintf(\"span-days-%d\", spanID) } style=\"--value:15;\" aria-live=\"polite\" aria-label=\"15\">15</span>\n\t\t\t</span>\n\t\t\tdays\n\t\t</div>\n\t\t<div\n\t\t\tclass={\n\t\t\t\t\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\",\n\t\t\t\ttempl.KV(\"hidden\", !props.Hours),\n\t\t\t}\n\t\t>\n\t\t\t<span class=\"countdown font-mono text-5xl\">\n\t\t\t\t<span id={ fmt.Sprintf(\"span-hours-%d\", spanID) } style=\"--value:10;\" aria-live=\"polite\" aria-label=\"10\">10</span>\n\t\t\t</span>\n\t\t\thours\n\t\t</div>\n\t\t<div\n\t\t\tclass={\n\t\t\t\t\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\",\n\t\t\t\ttempl.KV(\"hidden\", !props.Minutes),\n\t\t\t}\n\t\t>\n\t\t\t<span class=\"countdown font-mono text-5xl\">\n\t\t\t\t<span id={ fmt.Sprintf(\"span-minutes-%d\", spanID) } style=\"--value:24;\" aria-live=\"polite\" aria-label=\"24\">24</span>\n\t\t\t</span>\n\t\t\tmin\n\t\t</div>\n\t\t<div\n\t\t\tclass={\n\t\t\t\t\"bg-neutral rounded-box text-neutral-content flex flex-col p-2\",\n\t\t\t\ttempl.KV(\"hidden\", !props.Seconds),\n\t\t\t}\n\t\t>\n\t\t\t<span class=\"countdown font-mono text-5xl\">\n\t\t\t\t<span id={ fmt.Sprintf(\"span-seconds-%d\", spanID) } style=\"--value:59;\" aria-live=\"polite\" aria-label=\"59\">59</span>\n\t\t\t</span>\n\t\t\tsec\n\t\t</div>\n\t\t<script data-expires={ props.Expires.Format(\"2006-01-02T15:04:05Z\") } data-id={ spanID }>\n            var intervalId = null;\n\n            function updateTimes(expires, days, hours, minutes, seconds) {\n                let expiresDate = Date.parse(expires);\n                let now = new Date()\n                let diffMs = Math.abs(expiresDate - now.getTime());\n                let totalSeconds = diffMs / 1000;\n\n                if (now.getTime() >= expiresDate) {\n                    clearInterval(intervalId);\n                    return\n                }\n\n                const daysRemaining = Math.floor(diffMs / (1000 * 60 * 60 * 24))\n                diffMs -= daysRemaining * (1000 * 60 * 60 *24)\n                days.setAttribute(\"style\", `--value:${daysRemaining};`)\n\n                const hoursRemaining = Math.floor(diffMs / (1000 * 60 * 60));\n                diffMs -= hoursRemaining * (1000 * 60 * 60)\n                hours.setAttribute(\"style\", `--value:${hoursRemaining};`)\n\n                const minutesRemaining = Math.floor(diffMs / (1000 * 60));\n                diffMs -= minutesRemaining * (1000 * 60);\n                minutes.setAttribute(\"style\", `--value:${minutesRemaining};`)\n\n                const secondsRemaining = Math.floor(diffMs / 1000);\n                seconds.setAttribute(\"style\", `--value:${secondsRemaining};`)\n            }\n\n            function startUpdatingTimes(expires, days, hours, minutes, seconds) {\n                updateTimes(expires, days, hours, minutes, seconds);\n                intervalId = setInterval(() => updateTimes(expires, days, hours, minutes, seconds), 1000);\n            }\n\n            ((expires) => {\n                let days = document.getElementById(`span-days-${document.currentScript.getAttribute(\"data-id\")}`);\n                let hours = document.getElementById(`span-hours-${document.currentScript.getAttribute(\"data-id\")}`);\n                let minutes = document.getElementById(`span-minutes-${document.currentScript.getAttribute(\"data-id\")}`);\n                let seconds = document.getElementById(`span-seconds-${document.currentScript.getAttribute(\"data-id\")}`);\n                startUpdatingTimes(expires, days, hours, minutes, seconds);\n            })(document.currentScript.getAttribute(\"data-expires\"))\n        </script>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/date_picker.templ",
    "content": "// data_input\npackage components \n\nimport \"fmt\"\nimport \"time\"\n\ntype DatePickerProps struct {\n\tYear        int\n\tMonth       int\n\tSelected    time.Time\n\tStartOfWeek time.Weekday\n}\n\nfunc (props DatePickerProps) Days() []time.Time {\n\tdays := make([]time.Time, 0, 31)\n\tnow := time.Now().UTC()\n\tstart := time.Date(props.Year, time.Month(props.Month), 1, 0, 0, 0, 0, now.Location())\n\tend := start.AddDate(0, 1, -1)\n\tfor end.Weekday() != props.StartOfWeek {\n\t\tend = end.AddDate(0, 0, 1)\n\t}\n\tend = end.AddDate(0, 0, -1)\n\n\tfor start.Weekday() != props.StartOfWeek {\n\t\tstart = start.AddDate(0, 0, -1)\n\t}\n\tfor !start.After(end) {\n\t\tdays = append(days, start)\n\t\tstart = start.AddDate(0, 0, 1)\n\t}\n\treturn days\n}\n\nfunc (props DatePickerProps) Months() []time.Time {\n\tmonths := make([]time.Time, 12)\n\tfor i := 1; i <= 12; i++ {\n\t\tdt := time.Date(props.Year, time.Month(i), 1, 0, 0, 0, 0, time.Now().Location())\n\t\tmonths[i-1] = dt\n\t}\n\treturn months\n}\n\ntempl DatePicker(props DatePickerProps) {\n\t{{ utcNow := time.Now().UTC() }}\n\t{{ days := props.Days() }}\n\t<div\n\t\tname=\"datepicker-div\"\n\t\tclass=\"flex flex-col space-y-1 w-[300px] h-[405px]\"\n\t>\n\t\t<div class=\"flex space-x-1\">\n\t\t\t<button\n\t\t\t\thx-get={ fmt.Sprintf(\"/datepicker?year=%d&month=%d\", props.Year, props.Month-1) }\n\t\t\t\thx-target=\"div[name=datepicker-div]\"\n\t\t\t\thx-swap=\"outerHTML\"\n\t\t\t\tclass=\"btn btn-square btn-sm\"\n\t\t\t>\n\t\t\t\t<svg class=\"h-3 w-3\" viewBox=\"-5.5 0 26 26\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n\t\t\t\t\t<g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n\t\t\t\t\t\t<g class=\"fill-base-content\" id=\"Icon-Set-Filled\" sketch:type=\"MSLayerGroup\" transform=\"translate(-423.000000, -1196.000000)\">\n\t\t\t\t\t\t\t<path d=\"M428.115,1209 L437.371,1200.6 C438.202,1199.77 438.202,1198.43 437.371,1197.6 C436.541,1196.76 435.194,1196.76 434.363,1197.6 L423.596,1207.36 C423.146,1207.81 422.948,1208.41 422.985,1209 C422.948,1209.59 423.146,1210.19 423.596,1210.64 L434.363,1220.4 C435.194,1221.24 436.541,1221.24 437.371,1220.4 C438.202,1219.57 438.202,1218.23 437.371,1217.4 L428.115,1209\" id=\"chevron-left\" sketch:type=\"MSShapeGroup\"></path>\n\t\t\t\t\t\t</g>\n\t\t\t\t\t</g>\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t<details class=\"dropdown w-full max-w-[300px]\">\n\t\t\t\t<summary class=\"btn btn-sm w-full\">{ fmt.Sprintf(\"%d\", props.Year) }</summary>\n\t\t\t\t<div\n\t\t\t\t\tclass={\n\t\t\t\t\t\t\"menu dropdown-content grid grid-cols-3 gap-1\",\n\t\t\t\t\t\t\"w-full max-w-[300px] p-1 bg-base-300 rounded-b-box\",\n\t\t\t\t\t}\n\t\t\t\t\thx-get={ fmt.Sprintf(\"/datepicker/yearpicker?year=%d\", props.Year) }\n\t\t\t\t\thx-trigger=\"datePickerDropdownClosed from:body\"\n\t\t\t\t>\n\t\t\t\t\t@DatePickerYearPicker(props)\n\t\t\t\t</div>\n\t\t\t\t<script>\n                    ((details)=>{\n                        details.querySelector(\"summary\").addEventListener(\"click\", (evt) => {\n                            if (details.hasAttribute(\"open\")) {\n                                    let event = new Event(\"datePickerDropdownClosed\");\n                                    document.querySelector(\"body\").dispatchEvent(event);\n                                }\n                        })\n                    })(document.currentScript.parentElement)\n                </script>\n\t\t\t</details>\n\t\t\t<button\n\t\t\t\thx-get={ fmt.Sprintf(\"/datepicker?year=%d&month=%d\", props.Year, props.Month+1) }\n\t\t\t\thx-target=\"div[name=datepicker-div]\"\n\t\t\t\thx-swap=\"outerHTML\"\n\t\t\t\tclass=\"btn btn-square btn-sm\"\n\t\t\t>\n\t\t\t\t<svg class=\"h-3 w-3\" viewBox=\"-5.5 0 26 26\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n\t\t\t\t\t<g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n\t\t\t\t\t\t<g class=\"fill-base-content\" id=\"Icon-Set-Filled\" sketch:type=\"MSLayerGroup\" transform=\"translate(-474.000000, -1196.000000)\">\n\t\t\t\t\t\t\t<path d=\"M488.404,1207.36 L477.637,1197.6 C476.806,1196.76 475.459,1196.76 474.629,1197.6 C473.798,1198.43 473.798,1199.77 474.629,1200.6 L483.885,1209 L474.629,1217.4 C473.798,1218.23 473.798,1219.57 474.629,1220.4 C475.459,1221.24 476.806,1221.24 477.637,1220.4 L488.404,1210.64 C488.854,1210.19 489.052,1209.59 489.015,1209 C489.052,1208.41 488.854,1207.81 488.404,1207.36\" id=\"chevron-right\" sketch:type=\"MSShapeGroup\"></path>\n\t\t\t\t\t\t</g>\n\t\t\t\t\t</g>\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t</div>\n\t\t<div class=\"grid grid-cols-7 gap-1 text-sm text-base-content/75\">\n\t\t\tif props.StartOfWeek == time.Sunday {\n\t\t\t\t<span class=\"text-center\">Su</span>\n\t\t\t}\n\t\t\t<span class=\"text-center\">Mo</span>\n\t\t\t<span class=\"text-center\">Tu</span>\n\t\t\t<span class=\"text-center\">We</span>\n\t\t\t<span class=\"text-center\">Th</span>\n\t\t\t<span class=\"text-center\">Fr</span>\n\t\t\t<span class=\"text-center\">Sa</span>\n\t\t\tif props.StartOfWeek == time.Monday {\n\t\t\t\t<span class=\"text-center\">Su</span>\n\t\t\t}\n\t\t</div>\n\t\t<div\n\t\t\tclass=\"grid grid-cols-7 gap-1\"\n\t\t>\n\t\t\t@DatePickerInput(props.Selected)\n\t\t\tfor _, d := range days {\n\t\t\t\t<button\n\t\t\t\t\tname=\"datepicker-day-btn\"\n\t\t\t\t\tclass={\n\t\t\t\t\t\t\"btn btn-square border shadow-md shadow-base-300 h-10 w-10 p-3\",\n\t\t\t\t\t\ttempl.KV(\"text-primary\", d.Year() == utcNow.Year() && d.Month() == utcNow.Month() && utcNow.Day() == d.Day()),\n\t\t\t\t\t\ttempl.KV(\"btn-ghost\", d.Month() == time.Month(props.Month)),\n\t\t\t\t\t\ttempl.KV(\"btn-neutral\", d.Month() != time.Month(props.Month)),\n\t\t\t\t\t\ttempl.KV(\"border-primary bg-base-300\", !props.Selected.IsZero() && d.Day() == props.Selected.Day()),\n\t\t\t\t\t}\n\t\t\t\t\thx-post={ \"/datepicker/select?date=\" + d.Format(\"2006-01-02\") }\n\t\t\t\t\thx-target=\"#datepicker-input\"\n\t\t\t\t\thx-swap=\"outerHTML\"\n\t\t\t\t\tif d.Month() != time.Month(props.Month) {\n\t\t\t\t\t\tdisabled\n\t\t\t\t\t}\n\t\t\t\t>\n\t\t\t\t\tif d.Day() == 1 {\n\t\t\t\t\t\t{ d.Format(\"Jan \") }\n\t\t\t\t\t}\n\t\t\t\t\t{ d.Format(\"2\") }\n\t\t\t\t</button>\n\t\t\t}\n\t\t\t<script>\n                function addDayButtonEventHandler() {\n                    document.querySelectorAll(\"button[name=datepicker-day-btn]\").forEach((btn) => {\n                        btn.addEventListener(\"click\", () => {\n                            document.querySelectorAll(\"button[name=datepicker-day-btn]\").forEach((el) => {\n                                el.classList.remove(\"border-primary\", \"bg-base-300\")\n                            })\n                            btn.classList.add(\"border-primary\", \"bg-base-300\")\n                        })\n                    })\n                }\n                document.addEventListener(\"htmx:afterSettle\", () => {\n                    addDayButtonEventHandler();\n                })\n                document.addEventListener(\"DOMContentLoaded\", () => {\n                    addDayButtonEventHandler();\n                })\n            </script>\n\t\t</div>\n\t</div>\n}\n\ntempl DatePickerInput(d time.Time) {\n\t<input id=\"datepicker-input\" type=\"hidden\" name=\"date\" value={ d.Format(\"2006-01-02\") }/>\n}\n\ntempl DatePickerYearPicker(props DatePickerProps) {\n\t{{ utcNow := time.Now().UTC() }}\n\tfor i := range 12 {\n\t\t<button\n\t\t\tclass=\"btn btn-sm border\"\n\t\t\thx-get={ fmt.Sprintf(\"/datepicker/monthpicker?year=%d\", props.Year-(12-i)) }\n\t\t\thx-target=\"closest div\"\n\t\t>\n\t\t\t{ fmt.Sprintf(\"%d\", props.Year-(12-i)) }\n\t\t</button>\n\t}\n\t<button\n\t\tclass=\"btn btn-sm border col-span-3\"\n\t\thx-get={ fmt.Sprintf(\"/datepicker/monthpicker?year=%d\", utcNow.Year()) }\n\t\thx-target=\"closest div\"\n\t>\n\t\t{ fmt.Sprintf(\"%d\", utcNow.Year()) }\n\t</button>\n}\n\ntempl DatePickerMonthPicker(props DatePickerProps) {\n\t{{ months := props.Months() }}\n\tfor _, m := range months {\n\t\t<button\n\t\t\tclass={\n\t\t\t\t\"btn btn-sm border\",\n\t\t\t\ttempl.KV(\"border-primary\", m.Month() == time.Month(props.Month)),\n\t\t\t}\n\t\t\thx-get={ fmt.Sprintf(\"/datepicker?year=%d&month=%d\", props.Year, m.Month()) }\n\t\t\thx-target=\"div[name=datepicker-div]\"\n\t\t\thx-swap=\"outerHTML\"\n\t\t>\n\t\t\t{ m.Format(\"Jan\") }\n\t\t</button>\n\t}\n}\n"
  },
  {
    "path": "internal/views/components/diff.templ",
    "content": "// data_display\n// https://daisyui.com/components/diff\npackage components\n\nimport \"fmt\"\n\ntype DiffProps struct {\n\tWidth  int\n\tHeight int\n\tImage1 DiffImage\n\tImage2 DiffImage\n}\n\ntype DiffImage struct {\n\tSource string\n\tAlt    string\n}\n\ntempl Diff(props DiffProps) {\n\t<div class={ \"diff\", fmt.Sprintf(\"aspect-[%d/%d]\", props.Width, props.Height) }>\n\t\t<div class=\"diff-item-1\">\n\t\t\t<img alt={ props.Image1.Alt } src={ props.Image1.Source }/>\n\t\t</div>\n\t\t<div class=\"diff-item-2\">\n\t\t\t<img alt={ props.Image2.Alt } src={ props.Image2.Source }/>\n\t\t</div>\n\t\t<div class=\"diff-resizer\"></div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/drawer.templ",
    "content": "// layout\n// https://daisyui.com/components/drawer\npackage components\n\ntempl Drawer(toggle templ.Component, sidebar templ.Component) {\n\t<div class=\"drawer\">\n\t\t<input id=\"my-drawer\" type=\"checkbox\" class=\"drawer-toggle\"/>\n\t\t<div class=\"drawer-content\">\n\t\t\t<label for=\"my-drawer\" class=\"btn btn-primary drawer-button\">\n\t\t\t\t@toggle\n\t\t\t</label>\n\t\t\t{ children... }\n\t\t</div>\n\t\t<div class=\"drawer-side\">\n\t\t\t<label for=\"my-drawer\" aria-label=\"close sidebar\" class=\"drawer-overlay\"></label>\n\t\t\t<ul class=\"menu bg-base-200 text-base-content min-h-full w-80 p-4\">\n\t\t\t\t@sidebar\n\t\t\t</ul>\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/dropdown.templ",
    "content": "// actions\n// https://daisyui.com/components/dropdown\npackage components\n\ntype DropdownProps struct {\n\tLabel     string\n\tClass     string\n\tListClass string\n\tItems     []DropdownItem\n}\n\ntype DropdownItem struct {\n\tLabel string\n\tAttrs templ.Attributes\n}\n\ntempl Dropdown(props DropdownProps) {\n\t<details class={ \"dropdown\", props.Class }>\n\t\t<summary class=\"btn m-1\">{ props.Label }</summary>\n\t\t<ul class={ \"menu dropdown-content\", props.ListClass }>\n\t\t\tfor _, di := range props.Items {\n\t\t\t\t<li><a { di.Attrs... }>{ di.Label }</a></li>\n\t\t\t}\n\t\t</ul>\n\t</details>\n}\n"
  },
  {
    "path": "internal/views/components/fab.templ",
    "content": "// actions\n// https://daisyui.com/components/fab\npackage components\n\ntype FABProps struct {\n\tClass       string\n\tToggle      any // string or templ.Component\n\tToggleClass string\n\tClose       templ.Component\n\tMainAction  templ.Component\n}\n\ntempl FAB(props FABProps) {\n\t<div class={ \"fab\", props.Class }>\n\t\t<div tabindex=\"0\" role=\"button\" class={ \"btn\", props.ToggleClass }>\n\t\t\tif t, ok := props.Toggle.(string); ok {\n\t\t\t\t{ t }\n\t\t\t} else {\n\t\t\t\t@props.Toggle.(templ.Component)\n\t\t\t}\n\t\t</div>\n\t\tif props.Close != nil {\n\t\t\t<div class=\"fab-close\">\n\t\t\t\t@props.Close\n\t\t\t</div>\n\t\t}\n\t\tif props.MainAction != nil {\n\t\t\t<div class=\"fab-main-action\">\n\t\t\t\t@props.MainAction\n\t\t\t</div>\n\t\t}\n\t\t{ children... }\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/features.templ",
    "content": "// data_display\npackage components\n\ntype FeaturesProps struct {\n\tTitle    string\n\tFeatures []FeatureProps\n}\n\ntype FeatureProps struct {\n\tIcon        templ.Component\n\tTitle       string\n\tDescription string\n\tURL         string\n}\n\ntempl Features(props FeaturesProps) {\n\t<div class=\"py-12 px-4\">\n\t\t<div class=\"max-w-screen-xl mx-auto text-base-content/80\">\n\t\t\tif props.Title != \"\" {\n\t\t\t\t<h2 class=\"sm:text-4xl text-2xl font-bold text-center mb-16\">{ props.Title }</h2>\n\t\t\t}\n\t\t\t<div class=\"grid lg:grid-cols-3 md:grid-cols-2 gap-12 max-md:max-w-lg mx-auto\">\n\t\t\t\tfor _, feature := range props.Features {\n\t\t\t\t\t@Feature(feature)\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n}\n\ntempl Feature(feature FeatureProps) {\n\t<div\n\t\tclass={\n\t\t\t\"flex flex-col justify-between items-center rounded-box group p-8 text-center\",\n\t\t\t\"hover:bg-base-300 hover:text-base-content hover:shadow-xl transition-all duration-300\",\n\t\t}\n\t>\n\t\t@feature.Icon\n\t\tif feature.Title != \"\" {\n\t\t\t<h3 class=\"text-xl font-semibold mb-3\">{ feature.Title }</h3>\n\t\t}\n\t\t<p class=\"text-base-content/70 group-hover:text-base-content text-sm\">{ feature.Description }</p>\n\t\tif feature.URL != \"\" {\n\t\t\t<a href={ templ.SafeURL(feature.URL) } class=\"mt-2 link link-primary\">Learn more</a>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/file_input.templ",
    "content": "// data_input\n// https://daisyui.com/components/file-input\npackage components\n\ntype FileInputProps struct {\n\tName            string\n\tLabel           string\n\tValue           string\n\tDescription     string\n\tAttrs           templ.Attributes\n\tDisabledMessage string\n\tRequired        bool\n\tSize            string\n}\n\ntempl FileInput(props FileInputProps) {\n\t<fieldset\n\t\tclass=\"fieldset tooltip tooltip-top w-full\"\n\t\tif props.DisabledMessage != \"\" {\n\t\t\tdata-tip={ props.DisabledMessage }\n\t\t}\n\t>\n\t\tif props.Label != \"\" {\n\t\t\t<legend class=\"fieldset-legend\">{ props.Label }</legend>\n\t\t}\n\t\t<input\n\t\t\ttype=\"file\"\n\t\t\tclass={\n\t\t\t\t\"file-input w-full\",\n\t\t\t\ttempl.KV(\"file-input-xs\", props.Size == \"xs\"),\n\t\t\t\ttempl.KV(\"file-input-sm\", props.Size == \"sm\"),\n\t\t\t\ttempl.KV(\"file-input-lg\", props.Size == \"lg\"),\n\t\t\t\ttempl.KV(\"file-input-xl\", props.Size == \"xl\"),\n\t\t\t}\n\t\t\tname={ props.Name }\n\t\t\tif props.DisabledMessage != \"\" {\n\t\t\t\tdisabled\n\t\t\t}\n\t\t\t{ props.Attrs... }\n\t\t/>\n\t\tif props.Description != \"\" {\n\t\t\t<label class=\"fieldset-label\">{ props.Description }</label>\n\t\t}\n\t</fieldset>\n}\n"
  },
  {
    "path": "internal/views/components/footer.templ",
    "content": "// layout\n// https://daisyui.com/components/footer\npackage components\n\ntype FooterProps struct {\n\tIcon        templ.Component\n\tName        string\n\tDescription string\n\tCopyright   string\n\tAnchors     []AnchorProps\n}\n\ntempl Footer(props FooterProps) {\n\t<footer class=\"footer bg-base-200 text-base-content p-10 mt-24\">\n\t\t{ children... }\n\t</footer>\n\t<footer class=\"footer bg-base-200 text-base-content border-base-300 border-t px-10 py-4\">\n\t\t<aside class=\"grid-flow-col items-center\">\n\t\t\tif props.Icon != nil {\n\t\t\t\t<div class=\"w-6 h-6\">\n\t\t\t\t\t@props.Icon\n\t\t\t\t</div>\n\t\t\t}\n\t\t\t<p>\n\t\t\t\tif props.Copyright != \"\" {\n\t\t\t\t\t<span>&copy; { props.Copyright }</span>\n\t\t\t\t}\n\t\t\t\t{ props.Name }\n\t\t\t\t<br/>\n\t\t\t\t{ props.Description }\n\t\t\t</p>\n\t\t</aside>\n\t\t<nav class=\"md:place-self-center md:justify-self-end\">\n\t\t\t<div class=\"grid grid-flow-col gap-4\">\n\t\t\t\tfor _, anchor := range props.Anchors {\n\t\t\t\t\t@Anchor(anchor)\n\t\t\t\t}\n\t\t\t</div>\n\t\t</nav>\n\t</footer>\n}\n\ntempl FooterNav(title string, links []AnchorProps) {\n\t<nav>\n\t\t<h6 class=\"footer-title\">{ title }</h6>\n\t\tfor _, link := range links {\n\t\t\t<a { link.Attrs... } class=\"link link-hover\">{ link.Label }</a>\n\t\t}\n\t</nav>\n}\n"
  },
  {
    "path": "internal/views/components/hero.templ",
    "content": "// layout\n// https://daisyui.com/components/hero\npackage components\n\ntype HeroProps struct {\n\tSource  string\n\tAlt     string\n\tReverse bool\n\tClass   string\n}\n\ntempl Hero(props HeroProps) {\n\t<div class={ \"hero\", props.Class }>\n\t\t<div\n\t\t\tclass={\n\t\t\t\t\"hero-content\",\n\t\t\t\t\"flex-col\",\n\t\t\t\ttempl.KV(\"xl:flex-row\", !props.Reverse),\n\t\t\t\ttempl.KV(\"xl:flex-row-reverse\", props.Reverse),\n\t\t\t}\n\t\t>\n\t\t\tif props.Source != \"\" {\n\t\t\t\t<img\n\t\t\t\t\tsrc={ props.Source }\n\t\t\t\t\talt={ props.Alt }\n\t\t\t\t\tclass=\"max-w-sm rounded-box shadow-2xl\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\t<div>\n\t\t\t\t{ children... }\n\t\t\t</div>\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/hover_3d_card.templ",
    "content": "// data_display\npackage components\n\ntempl Hover3DCard() {\n\t<div class=\"hover-3d\">\n\t\t{ children... }\n\t\t<div></div>\n\t\t<div></div>\n\t\t<div></div>\n\t\t<div></div>\n\t\t<div></div>\n\t\t<div></div>\n\t\t<div></div>\n\t\t<div></div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/infinite_scroll.templ",
    "content": "// data_display\npackage components\n\nimport \"fmt\"\n\ntempl InfiniteScrollTable(rows []templ.Component) {\n\t@Table(\n\t\t[]templ.Component{PlainText(\"Name\"), PlainText(\"Email\")},\n\t\trows,\n\t\tnil,\n\t)\n\t<div class=\"flex justify-center\"><span id=\"spinner\" class=\"htmx-indicator loading loading-spinner\"></span></div>\n}\n\ntempl InfiniteScrollRows(rows []templ.Component) {\n\tfor _, r := range rows {\n\t\t@r\n\t}\n}\n\ntempl InfiniteScrollRow(name, email string, page int, hasMore bool) {\n\t<tr\n\t\tif hasMore {\n\t\t\thx-get={ fmt.Sprintf(\"/infinite-scroll-rows?page=%d\", page+1) }\n\t\t\thx-target=\"this\"\n\t\t\thx-trigger=\"intersect once\"\n\t\t\thx-swap=\"afterend\"\n\t\t\thx-indicator=\"#spinner\"\n\t\t}\n\t>\n\t\t<td>{ name }</td>\n\t\t<td>{ email }</td>\n\t</tr>\n}\n"
  },
  {
    "path": "internal/views/components/input.templ",
    "content": "// data_input\npackage components\n\ntype InputProps struct {\n\t// common\n\tName            string\n\tLabel           string\n\tType            string // defaults to \"text\"\n\tValue           string\n\tPlaceholder     string\n\tDescription     string\n\tError           string\n\tDisabledMessage string\n\tSize            string // xs sm lg xl, default: md\n\tRequired        bool\n\tIcon            templ.Component\n\tAttrs           templ.Attributes\n\n\t// text input\n\tMinLength     string\n\tMaxLength     string\n\tPattern       string\n\tValidatorHint string\n\n\t// integer/decimal input\n\tMin string\n\tMax string\n\n\t// decimal input\n\tStep string\n}\n\ntempl Input(props InputProps) {\n\t<fieldset class=\"fieldset\">\n\t\tif props.Label != \"\" {\n\t\t\t<legend class=\"fieldset-legend\">{ props.Label }</legend>\n\t\t}\n\t\t<label\n\t\t\tfor={ props.Name }\n\t\t\tclass={\n\t\t\t\t\"input validator tooltip tooltip-top\",\n\t\t\t\ttempl.KV(\"tooltip tooltip-top\", props.DisabledMessage != \"\"),\n\t\t\t\ttempl.KV(\"input-xs\", props.Size == \"xs\"),\n\t\t\t\ttempl.KV(\"input-sm\", props.Size == \"sm\"),\n\t\t\t\ttempl.KV(\"input-lg\", props.Size == \"lg\"),\n\t\t\t\ttempl.KV(\"input-xl\", props.Size == \"xl\"),\n\t\t\t}\n\t\t\tif props.DisabledMessage != \"\" {\n\t\t\t\tdata-tip={ props.DisabledMessage }\n\t\t\t}\n\t\t>\n\t\t\tif props.Icon != nil {\n\t\t\t\t@props.Icon\n\t\t\t}\n\t\t\t<input\n\t\t\t\tname={ props.Name }\n\t\t\t\tif props.Type == \"\" {\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t} else {\n\t\t\t\t\ttype={ props.Type }\n\t\t\t\t}\n\t\t\t\tvalue={ props.Value }\n\t\t\t\tplaceholder={ props.Placeholder }\n\t\t\t\tif props.Required {\n\t\t\t\t\trequired\n\t\t\t\t}\n\t\t\t\tif props.Pattern != \"\" {\n\t\t\t\t\tpattern={ props.Pattern }\n\t\t\t\t}\n\t\t\t\tif props.ValidatorHint != \"\" {\n\t\t\t\t\ttitle={ props.ValidatorHint }\n\t\t\t\t}\n\t\t\t\tif props.DisabledMessage != \"\" {\n\t\t\t\t\tdisabled\n\t\t\t\t}\n\t\t\t\t{ props.Attrs... }\n\t\t\t/>\n\t\t</label>\n\t\tif props.Description != \"\" {\n\t\t\t<div class=\"label\">{ props.Description }</div>\n\t\t}\n\t\tif props.Error != \"\" {\n\t\t\t<p class=\"text-xs text-error max-w-xs\">{ props.Error }</p>\n\t\t}\n\t\tif props.ValidatorHint != \"\" {\n\t\t\t<p class=\"validator-hint hidden text-xs max-w-xs !mt-0\">{ props.ValidatorHint }</p>\n\t\t}\n\t</fieldset>\n}\n"
  },
  {
    "path": "internal/views/components/lazy_load.templ",
    "content": "// data_display\npackage components\n\ntempl LazyLoad(url string) {\n\t<div\n\t\thx-get={ url }\n\t\thx-trigger=\"load\"\n\t\thx-target=\"this\"\n\t\tclass=\"flex justify-center items-center py-8\"\n\t>\n\t\t<span class=\"loading loading-spinner\"></span>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/menu.templ",
    "content": "// navigation\n// https://daisyui.com/components/menu\npackage components\n\ntype MenuProps struct {\n\tTitle string\n\tClass string\n}\n\ntempl Menu(props MenuProps) {\n\t<ul class={ \"menu\", props.Class }>\n\t\tif props.Title != \"\" {\n\t\t\t<h2 class=\"font-bold\">{ props.Title }</h2>\n\t\t}\n\t\t{ children... }\n\t</ul>\n}\n\ntype MenuItemProps struct {\n\tLabel     string\n\tAttrs     templ.Attributes\n\tIcon      templ.Component\n\tIconAfter bool\n}\n\ntempl MenuItem(props MenuItemProps) {\n\t<li>\n\t\t<a { props.Attrs... }>\n\t\t\tif props.Icon != nil && !props.IconAfter {\n\t\t\t\t@props.Icon\n\t\t\t}\n\t\t\t{ props.Label }\n\t\t\tif props.Icon != nil && props.IconAfter {\n\t\t\t\t@props.Icon\n\t\t\t}\n\t\t</a>\n\t\t<ul>\n\t\t\t{ children... }\n\t\t</ul>\n\t</li>\n}\n\ntype SubmenuProps struct {\n\tTitle     string\n\tAttrs     templ.Attributes\n\tIcon      templ.Component\n\tIconAfter bool\n}\n\ntempl Submenu(props SubmenuProps) {\n\t<li>\n\t\t<details { props.Attrs... }>\n\t\t\t<summary>\n\t\t\t\tif props.Icon != nil && !props.IconAfter {\n\t\t\t\t\t@props.Icon\n\t\t\t\t}\n\t\t\t\t{ props.Title }\n\t\t\t\tif props.Icon != nil && props.IconAfter {\n\t\t\t\t\t@props.Icon\n\t\t\t\t}\n\t\t\t</summary>\n\t\t\t<ul>\n\t\t\t\t{ children... }\n\t\t\t</ul>\n\t\t</details>\n\t</li>\n}\n"
  },
  {
    "path": "internal/views/components/modal.templ",
    "content": "// actions\n// https://daisyui.com/components/modal\npackage components\n\nimport \"fmt\"\n\ntype ModalProps struct {\n\tID    string\n\tLabel any\n}\n\ntempl Modal(props ModalProps) {\n\t@modalWrapper(\n\t\tprops,\n\t\ttempl.Attributes{\"onclick\": fmt.Sprintf(\"%s.showModal()\", props.ID)},\n\t) {\n\t\t{ children... }\n\t}\n}\n\ntempl modalWrapper(props ModalProps, attrs templ.Attributes) {\n\t// you can use a string or a templ.Component as the 'label'\n\t// of the modal button\n\tif s, ok := props.Label.(string); ok {\n\t\t<div class=\"btn\" { attrs... }>\n\t\t\t{ s }\n\t\t</div>\n\t} else if c, ok := props.Label.(templ.Component); ok {\n\t\t@c\n\t}\n\t<dialog id={ props.ID } class=\"modal\">\n\t\t<div class=\"modal-box\">\n\t\t\t{ children... }\n\t\t</div>\n\t\t<form method=\"dialog\" class=\"modal-backdrop\">\n\t\t\t<button>close</button>\n\t\t</form>\n\t</dialog>\n}\n"
  },
  {
    "path": "internal/views/components/pagination.templ",
    "content": "// navigation\n// https://daisyui.com/components/pagination\npackage components\n\nimport \"fmt\"\n\ntype PaginationProps struct {\n\tURL      string\n\tPage     int\n\tLow      int\n\tHigh     int\n\tMaxPages int\n}\n\ntempl Pagination(id string, props PaginationProps) {\n\t<div id={ id }>\n\t\t<!-- paginated content goes here -->\n\t\t{ children... }\n\t\t<!-- -->\n\t\t<div class=\"join\">\n\t\t\t@PaginationButton(id, props.URL, 1, props.Page == 1) {\n\t\t\t\t@AnglesLeft()\n\t\t\t}\n\t\t\t@PaginationButton(id, props.URL, props.Page-1, props.Page == 1) {\n\t\t\t\t@ChevronLeft()\n\t\t\t}\n\t\t\tfor i := props.Low; i <= props.High; i++ {\n\t\t\t\t@PaginationButton(id, props.URL, i+1, props.Page == i+1) {\n\t\t\t\t\t{ fmt.Sprintf(\"%d\", i+1) }\n\t\t\t\t}\n\t\t\t}\n\t\t\t@PaginationButton(id, props.URL, props.Page+1, props.Page == props.MaxPages) {\n\t\t\t\t@ChevronRight()\n\t\t\t}\n\t\t\t@PaginationButton(id, props.URL, props.MaxPages, props.Page == props.MaxPages) {\n\t\t\t\t@AnglesRight()\n\t\t\t}\n\t\t</div>\n\t</div>\n}\n\ntempl PaginationButton(id, url string, urlPage int, disabled bool) {\n\t<button\n\t\tif url != \"\" {\n\t\t\thx-get={ fmt.Sprintf(\"%s?page=%d\", url, urlPage) }\n\t\t\thx-target={ fmt.Sprintf(\"#%s\", id) }\n\t\t\thx-swap=\"outerHTML\"\n\t\t}\n\t\tclass={\n\t\t\t\"join-item btn btn-square disabled:opacity-40\",\n\t\t\ttempl.KV(\"btn-disabled\", disabled),\n\t\t}\n\t\tif disabled {\n\t\t\tdisabled\n\t\t}\n\t>\n\t\t{ children... }\n\t</button>\n}\n\ntempl AnglesRight() {\n\t<svg\n\t\tclass=\"w-4 h-4\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t>\n\t\t<path\n\t\t\td=\"M6 17L11 12L6 7M13 17L18 12L13 7\"\n\t\t\tclass=\"stroke-base-content\"\n\t\t\tstroke-width=\"2\"\n\t\t\tstroke-linecap=\"round\"\n\t\t\tstroke-linejoin=\"round\"\n\t\t></path>\n\t</svg>\n}\n\ntempl AnglesLeft() {\n\t<svg\n\t\tclass=\"w-4 h-4\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t>\n\t\t<path\n\t\t\td=\"M18 17L13 12L18 7M11 17L6 12L11 7\"\n\t\t\tclass=\"stroke-base-content\"\n\t\t\tstroke-width=\"2\"\n\t\t\tstroke-linecap=\"round\"\n\t\t\tstroke-linejoin=\"round\"\n\t\t></path>\n\t</svg>\n}\n\ntempl ChevronRight() {\n\t<svg\n\t\tclass=\"w-4 h-4\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t>\n\t\t<path\n\t\t\td=\"M9 6L15 12L9 18\"\n\t\t\tclass=\"stroke-base-content\"\n\t\t\tstroke-width=\"2\"\n\t\t\tstroke-linecap=\"round\"\n\t\t\tstroke-linejoin=\"round\"\n\t\t></path>\n\t</svg>\n}\n\ntempl ChevronLeft() {\n\t<svg\n\t\tclass=\"w-4 h-4\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t>\n\t\t<path\n\t\t\td=\"M15 6L9 12L15 18\"\n\t\t\tclass=\"stroke-base-content\"\n\t\t\tstroke-width=\"2\"\n\t\t\tstroke-linecap=\"round\"\n\t\t\tstroke-linejoin=\"round\"\n\t\t></path>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/components/pricing.templ",
    "content": "// data_display\npackage components\n\nimport \"slices\"\n\ntype PricingProps struct {\n\tChecked bool\n\tPrices  []PriceProps\n}\n\ntype PriceProps struct {\n\tTitle            string\n\tDescription      string\n\tPriceMonthly     string\n\tPerMonthly       string\n\tPriceAnnually    string\n\tPerAnnually      string\n\tPerUser          bool\n\tPromotion        string\n\tIncludedFeatures []string\n\tExcludedFeatures []string\n\tCallToAction     PriceButtonProps\n\tFooter           templ.Component\n}\n\ntype PriceButtonProps struct {\n\tLabel string\n\tAttrs templ.Attributes\n}\n\n// NOTE: Requires Alpine.js\ntempl Pricing(props PricingProps) {\n\t<script src=\"/static/js/alpine.js\" defer></script>\n\t<div x-data=\"{ yearly: true }\" class=\"w-full mx-auto py-8 max-w-screen-xl\">\n\t\t<div class=\"max-w-xs mx-auto my-6\">\n\t\t\t@Toggle(ToggleProps{\n\t\t\t\tBefore:    \"Billed monthly\",\n\t\t\t\tAfter:     \"Billed annually\",\n\t\t\t\tName:      \"period\",\n\t\t\t\tChecked:   props.Checked,\n\t\t\t\tHighlight: true,\n\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\"x-on:click\": \"yearly = !yearly\",\n\t\t\t\t},\n\t\t\t})\n\t\t</div>\n\t\t@PriceGrid(props.Prices)\n\t</div>\n}\n\ntempl PriceGrid(prices []PriceProps) {\n\t<div\n\t\tid=\"price-grid\"\n\t\tclass={ \"grid auto-cols-fr grid-flow-row lg:grid-flow-col pt-4 w-full mx-auto gap-4\",\n            templ.KV(\"gap-8\", slices.ContainsFunc(prices, func(pp PriceProps) bool {\n                    return pp.Promotion != \"\"\n                })) }\n\t>\n\t\tfor i := range prices {\n\t\t\t@Price(prices[i], nil)\n\t\t}\n\t</div>\n}\n\ntempl Price(price PriceProps, footer templ.Component) {\n\t<div class={ \"relative\", templ.KV(\"scale-110\", price.Promotion != \"\") }>\n\t\t<div\n\t\t\tclass={\n\t\t\t\t\"card rounded-box w-full max-w-xs p-6 mx-auto shadow-xl shadow-base-300\",\n\t\t\t\t\"bg-gradient-to-br from-base-200 dark:from-base-300 via-base-100 to-base-200 dark:to-base-300\",\n\t\t\t\ttempl.KV(\"ring-base-content/60\", price.Promotion == \"\"),\n\t\t\t\ttempl.KV(\"ring-1 ring-accent\", price.Promotion != \"\"),\n\t\t\t}\n\t\t>\n\t\t\tif price.Promotion != \"\" {\n\t\t\t\t<span class=\"absolute top-0 right-0 bg-accent px-2 rounded-tr-box rounded-bl-box\">\n\t\t\t\t\t{ price.Promotion }\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t<div class=\"card-title text-2xl mt-8\">\n\t\t\t\t<h2 class=\"mx-auto\">{ price.Title }</h2>\n\t\t\t</div>\n\t\t\t<p x-show=\"yearly\" class=\"text-center text-3xl font-bold mt-8\">\n\t\t\t\t{ price.PriceAnnually }\n\t\t\t\t<span class=\"text-xs font-normal\">\n\t\t\t\t\t{ price.PerAnnually }\n\t\t\t\t</span>\n\t\t\t\tif price.PerUser {\n\t\t\t\t\t<span class=\"text-sm font-normal\">\n\t\t\t\t\t\t{ \" / user\" }\n\t\t\t\t\t</span>\n\t\t\t\t}\n\t\t\t</p>\n\t\t\t<p x-show=\"!yearly\" class=\"text-center text-3xl font-bold mt-8\">\n\t\t\t\t{ price.PriceMonthly } <span class=\"text-xs font-normal\">{ price.PerMonthly }</span>\n\t\t\t</p>\n\t\t\t<button { price.CallToAction.Attrs... }>\n\t\t\t\t{ price.CallToAction.Label }\n\t\t\t</button>\n\t\t\t<div class=\"text-sm mt-8\">\n\t\t\t\t<ul class=\"space-y-4\">\n\t\t\t\t\tfor i := range price.IncludedFeatures {\n\t\t\t\t\t\t<li class=\"flex items-center space-x-2\">\n\t\t\t\t\t\t\t<svg class=\"w-4 h-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\">\n\t\t\t\t\t\t\t\t<path class=\"fill-base-content\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M21.5821 5.54289C21.9726 5.93342 21.9726 6.56658 21.5821 6.95711L10.2526 18.2867C9.86452 18.6747 9.23627 18.6775 8.84475 18.293L2.29929 11.8644C1.90527 11.4774 1.89956 10.8443 2.28655 10.4503C2.67354 10.0562 3.30668 10.0505 3.70071 10.4375L9.53911 16.1717L20.1679 5.54289C20.5584 5.15237 21.1916 5.15237 21.5821 5.54289Z\"></path>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t<span>{ price.IncludedFeatures[i] }</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t\tif len(price.ExcludedFeatures) > 0 {\n\t\t\t\t\t<div class=\"divider !my-2\"></div>\n\t\t\t\t}\n\t\t\t\t<ul class=\"space-y-4\">\n\t\t\t\t\tfor i := range price.ExcludedFeatures {\n\t\t\t\t\t\t<li class=\"flex items-center space-x-2 pl-6\">\n\t\t\t\t\t\t\t<span class=\"text-base-content/50\">{ price.ExcludedFeatures[i] }</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t\tif footer != nil {\n\t\t\t\t@footer\n\t\t\t}\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/radio.templ",
    "content": "// data_input\n// https://daisyui.com/components/radio\npackage components\n\ntype RadioProps struct {\n\tName   string\n\tValues map[string]string\n\tClass  string\n\tSize   string\n}\n\ntempl Radio(props RadioProps) {\n\t<div class=\"space-y-2 w-full\">\n\t\tfor l, v := range props.Values {\n\t\t\t<label for={ props.Name } class=\"label cursor-pointer grid grid-cols-7\">\n\t\t\t\t<span\n\t\t\t\t\tclass={\n\t\t\t\t\t\t\"col-span-6 text-wrap\",\n\t\t\t\t\t\ttempl.KV(\"text-xs\", props.Size == \"xs\"),\n\t\t\t\t\t\ttempl.KV(\"text-sm\", props.Size == \"sm\"),\n\t\t\t\t\t\ttempl.KV(\"text-lg\", props.Size == \"lg\"),\n\t\t\t\t\t\ttempl.KV(\"text-xl\", props.Size == \"xl\"),\n\t\t\t\t\t}\n\t\t\t\t>{ l }</span>\n\t\t\t\t<input\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname={ props.Name }\n\t\t\t\t\tvalue={ v }\n\t\t\t\t\tclass={\n\t\t\t\t\t\t\"radio col-span-1\", props.Class,\n\t\t\t\t\t\ttempl.KV(\"radio-xs\", props.Size == \"xs\"),\n\t\t\t\t\t\ttempl.KV(\"radio-sm\", props.Size == \"sm\"),\n\t\t\t\t\t\ttempl.KV(\"radio-lg\", props.Size == \"lg\"),\n\t\t\t\t\t\ttempl.KV(\"radio-xl\", props.Size == \"xl\"),\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t</label>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/range.templ",
    "content": "// data_input\n// https://daisyui.com/components/range\npackage components\n\nimport \"fmt\"\n\ntype RangeProps struct {\n\tID    string\n\tLabel string\n\tName  string\n\tValue int\n\tMin   int\n\tMax   int\n\tStep  int\n\tClass string\n\tSize  string\n}\n\n// Note: usage requires alpine.js\ntempl Range(props RangeProps) {\n\t<script src=\"/static/js/alpine.js\" defer></script>\n\t<div class=\"form-control\">\n\t\t<label\n\t\t\tclass=\"label space-x-1\"\n\t\t\tx-data={ fmt.Sprintf(\"{ value: %d }\", props.Value) }\n\t\t>\n\t\t\tif props.Label != \"\" {\n\t\t\t\t<span\n\t\t\t\t\tclass={\n\t\t\t\t\t\ttempl.KV(\"text-xs\", props.Size == \"xs\"),\n\t\t\t\t\t\ttempl.KV(\"text-sm\", props.Size == \"sm\"),\n\t\t\t\t\t\ttempl.KV(\"text-lg\", props.Size == \"lg\"),\n\t\t\t\t\t\ttempl.KV(\"text-xl\", props.Size == \"xl\"),\n\t\t\t\t\t}\n\t\t\t\t>{ props.Label }</span>\n\t\t\t}\n\t\t\t<input\n\t\t\t\ttype=\"range\"\n\t\t\t\tif props.ID != \"\" {\n\t\t\t\t\tid={ props.ID }\n\t\t\t\t}\n\t\t\t\tname={ props.Name }\n\t\t\t\tmin={ fmt.Sprintf(\"%d\", props.Min) }\n\t\t\t\tmax={ fmt.Sprintf(\"%d\", props.Max) }\n\t\t\t\tx-model=\"value\"\n\t\t\t\tclass={\n\t\t\t\t\t\"range\", props.Class,\n\t\t\t\t\ttempl.KV(\"range-xs\", props.Size == \"xs\"),\n\t\t\t\t\ttempl.KV(\"range-sm\", props.Size == \"sm\"),\n\t\t\t\t\ttempl.KV(\"range-lg\", props.Size == \"lg\"),\n\t\t\t\t\ttempl.KV(\"range-xl\", props.Size == \"xl\"),\n\t\t\t\t}\n\t\t\t\tstep={ fmt.Sprintf(\"%d\", props.Step) }\n\t\t\t/>\n\t\t\t<div x-text=\"value\" class=\"w-full max-w-7\"></div>\n\t\t</label>\n\t</div>\n}\n\n// Note: usage requires datastar.js\ntempl DatastarRange(props RangeProps) {\n\t<script type=\"module\" src=\"/static/js/datastar.js\"></script>\n\t<div class=\"form-control\">\n\t\t<label\n\t\t\tclass=\"label space-x-1\"\n\t\t\tdata-signals={ fmt.Sprintf(\"{value: %d}\", props.Value) }\n\t\t>\n\t\t\tif props.Label != \"\" {\n\t\t\t\t<span\n\t\t\t\t\tclass={\n\t\t\t\t\t\ttempl.KV(\"text-xs\", props.Size == \"xs\"),\n\t\t\t\t\t\ttempl.KV(\"text-sm\", props.Size == \"sm\"),\n\t\t\t\t\t\ttempl.KV(\"text-lg\", props.Size == \"lg\"),\n\t\t\t\t\t\ttempl.KV(\"text-xl\", props.Size == \"xl\"),\n\t\t\t\t\t}\n\t\t\t\t>{ props.Label }</span>\n\t\t\t}\n\t\t\t<input\n\t\t\t\ttype=\"range\"\n\t\t\t\tif props.ID != \"\" {\n\t\t\t\t\tid={ props.ID }\n\t\t\t\t}\n\t\t\t\tname={ props.Name }\n\t\t\t\tmin={ fmt.Sprintf(\"%d\", props.Min) }\n\t\t\t\tmax={ fmt.Sprintf(\"%d\", props.Max) }\n\t\t\t\tclass={\n\t\t\t\t\t\"range\", props.Class,\n\t\t\t\t\ttempl.KV(\"range-xs\", props.Size == \"xs\"),\n\t\t\t\t\ttempl.KV(\"range-sm\", props.Size == \"sm\"),\n\t\t\t\t\ttempl.KV(\"range-lg\", props.Size == \"lg\"),\n\t\t\t\t\ttempl.KV(\"range-xl\", props.Size == \"xl\"),\n\t\t\t\t}\n\t\t\t\tstep={ fmt.Sprintf(\"%d\", props.Step) }\n\t\t\t\tdata-bind-value\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tclass=\"w-full max-w-7\"\n\t\t\t\tdata-text=\"$value\"\n\t\t\t></div>\n\t\t</label>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/rating.templ",
    "content": "// data_input\n// https://daisyui.com/components/rating\npackage components\n\nimport \"fmt\"\n\ntype RatingProps struct {\n\tName  string\n\tMin   int\n\tMax   int\n\tClass string\n\tValue int\n}\n\ntempl Rating(props RatingProps) {\n\t<div class=\"rating\">\n\t\tfor i := props.Min; i <= props.Max; i++ {\n\t\t\tif i == 0 {\n\t\t\t\t<input\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname={ props.Name }\n\t\t\t\t\tvalue={ fmt.Sprintf(\"%d\", i) }\n\t\t\t\t\tclass=\"rating-hidden\"\n\t\t\t\t/>\n\t\t\t} else {\n\t\t\t\t<input\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname={ props.Name }\n\t\t\t\t\tvalue={ fmt.Sprintf(\"%d\", i) }\n\t\t\t\t\tclass={ \"mask mask-star-2 bg-yellow-400\", props.Class }\n\t\t\t\t\tif i+1 == props.Max {\n\t\t\t\t\t\tchecked=\"checked\"\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t}\n\t\t}\n\t</div>\n}\n\ntempl RatingDisplay(props RatingProps) {\n\t<div class=\"rating\">\n\t\tfor i := props.Min; i <= props.Max; i++ {\n\t\t\tif i == 0 {\n\t\t\t\t<input\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname={ props.Name }\n\t\t\t\t\tvalue={ fmt.Sprintf(\"%d\", i) }\n\t\t\t\t\tclass=\"rating-hidden cursor-default\"\n\t\t\t\t\tdisabled\n\t\t\t\t/>\n\t\t\t} else {\n\t\t\t\t<input\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname={ props.Name }\n\t\t\t\t\tvalue={ fmt.Sprintf(\"%d\", i) }\n\t\t\t\t\tclass={ \"mask mask-star-2 bg-accent cursor-default\", props.Class }\n\t\t\t\t\tif i == props.Value {\n\t\t\t\t\t\tchecked=\"checked\"\n\t\t\t\t\t}\n\t\t\t\t\tdisabled\n\t\t\t\t/>\n\t\t\t}\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/select.templ",
    "content": "// data_input\n// https://daisyui.com/components/select\npackage components\n\ntype SelectProps struct {\n\tID          string\n\tLabel       string\n\tName        string\n\tDescription string\n\tClass       string\n\tSize        string\n\tRequired    bool\n\tOptions     []SelectOption\n\tAttrs       templ.Attributes\n}\n\ntype SelectOption struct {\n\tLabel    string\n\tValue    string\n\tSelected bool\n\tDisabled bool\n}\n\ntempl Select(props SelectProps) {\n\t<fieldset class=\"fieldset\">\n\t\tif props.Label != \"\" {\n\t\t\t<legend class=\"fieldset-legend\">{ props.Label }</legend>\n\t\t}\n\t\t<select\n\t\t\tclass={\n\t\t\t\t\"select w-full\",\n\t\t\t\tprops.Class,\n\t\t\t\ttempl.KV(\"select-xs\", props.Size == \"xs\"),\n\t\t\t\ttempl.KV(\"select-sm\", props.Size == \"sm\"),\n\t\t\t\ttempl.KV(\"select-lg\", props.Size == \"lg\"),\n\t\t\t\ttempl.KV(\"select-xl\", props.Size == \"xl\"),\n\t\t\t}\n\t\t\tif props.ID != \"\" {\n\t\t\t\tid={ props.ID }\n\t\t\t}\n\t\t\tname={ props.Name }\n\t\t\tif props.Required {\n\t\t\t\trequired\n\t\t\t}\n\t\t\t{ props.Attrs... }\n\t\t>\n\t\t\t@SelectOptions(props.Options)\n\t\t</select>\n\t\tif props.Description != \"\" {\n\t\t\t<span class=\"label\">{ props.Description }</span>\n\t\t}\n\t</fieldset>\n}\n\ntempl SelectOptions(options []SelectOption) {\n\tfor i := range options {\n\t\t<option\n\t\t\tif options[i].Selected {\n\t\t\t\tselected\n\t\t\t}\n\t\t\tif options[i].Disabled {\n\t\t\t\tdisabled\n\t\t\t}\n\t\t\tvalue={ options[i].Value }\n\t\t>\n\t\t\t{ options[i].Label }\n\t\t</option>\n\t}\n}\n"
  },
  {
    "path": "internal/views/components/skeleton.templ",
    "content": "// feedback\n// https://daisyui.com/components/skeleton\npackage components\n\ntempl Skeleton() {\n\t<div class=\"flex flex-col gap-4\">\n\t\t<div class=\"skeleton h-32 w-full\"></div>\n\t\t<div class=\"skeleton h-4 w-28\"></div>\n\t\t<div class=\"skeleton h-4 w-full\"></div>\n\t\t<div class=\"skeleton h-4 w-full\"></div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/stats.templ",
    "content": "// data_display\n// https://daisyui.com/components/stat\npackage components\n\ntype StatProps struct {\n\tTitle       string\n\tValue       string\n\tDescription string\n}\n\ntempl Stats() {\n\t<div class=\"stats stats-horizontal shadow-sm\">\n\t\t{ children... }\n\t</div>\n}\n\ntempl Stat(props StatProps) {\n\t<div class=\"stat\">\n\t\t<div class=\"stat-title\">{ props.Title }</div>\n\t\t<div class=\"stat-value\">{ props.Value }</div>\n\t\tif props.Description != \"\" {\n\t\t\t<div class=\"stat-desc\">{ props.Description }</div>\n\t\t}\n\t\t<div class=\"stat-actions\">\n\t\t\t{ children... }\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/status.templ",
    "content": "// feedback\npackage components\n\nimport \"fmt\"\n\ntype StatusProps struct {\n\tCode              int\n\tTitle             string\n\tDescription       string\n\tReturnButtonLabel string\n\tReturnButtonAttrs templ.Attributes\n}\n\ntempl Status(props StatusProps) {\n\t<section class=\"grid min-h-dvh place-content-center px-4\">\n\t\t<div class=\"text-center\">\n\t\t\t<h1 class=\"text-9xl font-black text-base-content/70\">\n\t\t\t\t{ fmt.Sprintf(\"%d\", props.Code) }\n\t\t\t</h1>\n\t\t\t<p class=\"text-2xl font-bold tracking-tight text-base-content sm:text-4xl\">\n\t\t\t\t{ props.Title }\n\t\t\t</p>\n\t\t\t<p class=\"mt-4 text-base-content/70\">\n\t\t\t\t{ props.Description }\n\t\t\t</p>\n\t\t\t<a\n\t\t\t\t{ props.ReturnButtonAttrs... }\n\t\t\t\tclass=\"mt-4 btn btn-primary\"\n\t\t\t>\n\t\t\t\t{ props.ReturnButtonLabel }\n\t\t\t</a>\n\t\t</div>\n\t</section>\n}\n"
  },
  {
    "path": "internal/views/components/steps.templ",
    "content": "// navigation\n// https://daisyui.com/components/steps\npackage components\n\ntype StepProps struct {\n\tLabel string\n\tDone  bool\n\tAttrs templ.Attributes\n}\n\ntempl Steps() {\n\t<ul class=\"steps\">\n\t\t{ children... }\n\t</ul>\n}\n\ntempl Step(props StepProps) {\n\t<li\n\t\tclass={ \"step\", templ.KV(\"step-primary\", props.Done) }\n\t>\n\t\t<a { props.Attrs... }>{ props.Label }</a>\n\t</li>\n}\n"
  },
  {
    "path": "internal/views/components/swap.templ",
    "content": "// actions\n// https://daisyui.com/components/swap\npackage components\n\ntype SwapProps struct {\n\tOn    templ.Component\n\tOff   templ.Component\n\tClass string\n}\n\ntempl Swap(props SwapProps) {\n\t<label class={ \"swap\", props.Class }>\n\t\t<input type=\"checkbox\"/>\n\t\t<div class=\"swap-on\">\n\t\t\t@props.On\n\t\t</div>\n\t\t<div class=\"swap-off\">\n\t\t\t@props.Off\n\t\t</div>\n\t</label>\n}\n"
  },
  {
    "path": "internal/views/components/table.templ",
    "content": "// data_display\n// https://daisyui.com/components/table\npackage components\n\ntempl Table(headers []templ.Component, rows []templ.Component, attrs templ.Attributes) {\n\t<div class=\"overflow-x-auto\">\n\t\t<table { attrs... } class=\"table\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\tfor _, header := range headers {\n\t\t\t\t\t\t<th>\n\t\t\t\t\t\t\t@header\n\t\t\t\t\t\t</th>\n\t\t\t\t\t}\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\tfor _, trow := range rows {\n\t\t\t\t\t@trow\n\t\t\t\t}\n\t\t\t</tbody>\n\t\t</table>\n\t</div>\n}\n\n// Component to use as plain text when\n// templ.Component is used as argument\ntempl PlainText(content string) {\n\t{ content }\n}\n"
  },
  {
    "path": "internal/views/components/tabs.templ",
    "content": "// navigation\n// https://daisyui.com/components/tab\npackage components\n\ntype TabsProps struct {\n\tName         string\n\tClass        string\n\tTabs         []TabProps\n\tContentClass string\n}\n\ntype TabProps struct {\n\tLabel   string\n\tContent templ.Component\n}\n\ntempl Tabs(props TabsProps) {\n\t<div role=\"tablist\" class={ \"tabs\", props.Class }>\n\t\tfor i, tab := range props.Tabs {\n\t\t\t<input\n\t\t\t\ttype=\"radio\"\n\t\t\t\tname={ props.Name }\n\t\t\t\trole=\"tab\"\n\t\t\t\tclass=\"tab\"\n\t\t\t\taria-label={ tab.Label }\n\t\t\t\tif i == 0 {\n\t\t\t\t\tchecked=\"checked\"\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<div class={ \"tab-content\", props.ContentClass }>\n\t\t\t\t@tab.Content\n\t\t\t</div>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/testimonial.templ",
    "content": "// data_display\npackage components\n\nimport \"fmt\"\n\ntype TestimonialProps []TestimonialProp\n\ntype TestimonialProp struct {\n\tAvatar  templ.Component\n\tName    string\n\tRating  int\n\tContent string\n}\n\ntempl TestimonialGrid(title string, props TestimonialProps) {\n\t<section>\n\t\t<div class=\"mx-auto max-w-screen-xl px-4 py-12 sm:px-6 lg:px-8 lg:py-16\">\n\t\t\t<h2 class=\"text-center text-4xl font-bold tracking-tight sm:text-5xl\">\n\t\t\t\t{ title }\n\t\t\t</h2>\n\t\t\t<div class=\"mt-8 [column-fill:_balance] sm:columns-2 sm:gap-6 lg:columns-3 lg:gap-8\">\n\t\t\t\tfor i := range props {\n\t\t\t\t\t<div class=\"mb-8 sm:break-inside-avoid\">\n\t\t\t\t\t\t<blockquote class=\"rounded-lg bg-base-300 p-6 shadow-sm sm:p-8\">\n\t\t\t\t\t\t\t<div class=\"flex items-center gap-4\">\n\t\t\t\t\t\t\t\tif props[i].Avatar != nil {\n\t\t\t\t\t\t\t\t\t@props[i].Avatar\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t@RatingDisplay(RatingProps{\n\t\t\t\t\t\t\t\t\t\tName:  fmt.Sprintf(\"review-rating-%d\", i),\n\t\t\t\t\t\t\t\t\t\tMin:   1,\n\t\t\t\t\t\t\t\t\t\tMax:   5,\n\t\t\t\t\t\t\t\t\t\tValue: props[i].Rating,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t<p class=\"mt-0.5 text-lg font-medium\">{ props[i].Name }</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<p class=\"mt-4\">\n\t\t\t\t\t\t\t\t{ props[i].Content }\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t</blockquote>\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</section>\n}\n"
  },
  {
    "path": "internal/views/components/text_rotate.templ",
    "content": "// data_display\npackage components\n\ntype TextRotateProps struct {\n\tClass string\n\tItems []TextRotateItem\n}\n\ntype TextRotateItem struct {\n\tText  string\n\tClass string\n}\n\ntempl TextRotate(props TextRotateProps) {\n\t<span class={ \"text-rotate\", props.Class }>\n\t\t<span>\n\t\t\tfor _, item := range props.Items {\n\t\t\t\t<span class={ item.Class }>{ item.Text }</span>\n\t\t\t}\n\t\t</span>\n\t</span>\n}\n"
  },
  {
    "path": "internal/views/components/textarea.templ",
    "content": "// data_input\n// https://daisyui.com/components/textarea\npackage components\n\nimport \"fmt\"\n\ntype TextareaProps struct {\n\tID          string\n\tLabel       string\n\tName        string\n\tPlaceholder string\n\tValue       string\n\tDescription string\n\tErr         string\n\tClass       string\n\tSize        string\n\tRequired    bool\n\tRows        int\n\tAttrs       templ.Attributes\n}\n\ntempl Textarea(props TextareaProps) {\n\t<fieldset class=\"fieldset\">\n\t\tif props.Label != \"\" {\n\t\t\t<legend class=\"fieldset-legend\">{ props.Label }</legend>\n\t\t}\n\t\t<textarea\n\t\t\t{ props.Attrs... }\n\t\t\tif props.ID != \"\" {\n\t\t\t\tid={ props.ID }\n\t\t\t}\n\t\t\tname={ props.Name }\n\t\t\tplaceholder={ props.Placeholder }\n\t\t\tclass={\n\t\t\t\t\"textarea\",\n\t\t\t\tprops.Class,\n\t\t\t\ttempl.KV(\"textarea-error\", props.Err != \"\"),\n\t\t\t\ttempl.KV(\"textarea-xs\", props.Size == \"xs\"),\n\t\t\t\ttempl.KV(\"textarea-sm\", props.Size == \"sm\"),\n\t\t\t\ttempl.KV(\"textarea-lg\", props.Size == \"lg\"),\n\t\t\t\ttempl.KV(\"textarea-xl\", props.Size == \"xl\"),\n\t\t\t}\n\t\t\tif props.Rows > 0 {\n\t\t\t\trows={ fmt.Sprintf(\"%d\", props.Rows) }\n\t\t\t} else {\n\t\t\t\trows=\"3\"\n\t\t\t}\n\t\t\tif props.Required {\n\t\t\t\trequired\n\t\t\t}\n\t\t>\n\t\t\t{ props.Value }\n\t\t</textarea>\n\t\tif props.Description != \"\" {\n\t\t\t<div class=\"label\">{ props.Description }</div>\n\t\t}\n\t\t<div class=\"h-6 !p-0 fieldset-label text-error text-sm\">{ props.Err }</div>\n\t</fieldset>\n}\n"
  },
  {
    "path": "internal/views/components/time_slot_picker.templ",
    "content": "// data_input\npackage components\n\nimport \"time\"\n\ntype TimeSlotPickerProps struct {\n\tID          string\n\tCurrentDate time.Time\n\tTimeSlots   []TimeSlot\n\tPickerURL   string\n\tReserveURL  string\n}\n\ntype TimeSlot struct {\n\tStart time.Time\n\tEnd   time.Time\n}\n\nfunc (x *TimeSlotPickerProps) Days() []time.Time {\n\tdate := time.Date(x.CurrentDate.Year(), x.CurrentDate.Month(), x.CurrentDate.Day(), 0, 0, 0, 0, x.CurrentDate.Location())\n\tdates := make([]time.Time, 7)\n\tdates[0] = date\n\tfor i := range 6 {\n\t\tdate = date.Add(24 * time.Hour)\n\t\tdates[i+1] = date\n\t}\n\treturn dates\n}\n\nfunc (x *TimeSlotPickerProps) GetSlots(day time.Time) []TimeSlot {\n\tslots := make([]TimeSlot, 0)\n\tnow := time.Now().UTC()\n\tnow = time.Date(\n\t\tnow.Year(), now.Month(), now.Day(),\n\t\tnow.Hour(), 0, 0, 0,\n\t\tnow.Location()).Add(time.Duration(24-now.Hour()) * time.Hour)\n\tfor _, s := range x.TimeSlots {\n\t\tif s.Start.After(now) && s.Start.Format(\"20060102\") == day.Format(\"20060102\") {\n\t\t\tslots = append(slots, s)\n\t\t}\n\t}\n\treturn slots\n}\n\ntempl TimeSlotPicker(props TimeSlotPickerProps) {\n\t<div id={ props.ID } class=\"p-4\">\n\t\t<div class=\"grid grid-cols-7 gap-1 h-[500px] w-full max-w-screen-xl\">\n\t\t\tfor _, day := range props.Days() {\n\t\t\t\t@timeSlotPickerDay(props, day)\n\t\t\t}\n\t\t</div>\n\t\t@timeSlotPickerControls(props)\n\t</div>\n}\n\ntempl timeSlotPickerDay(props TimeSlotPickerProps, day time.Time) {\n\t<div\n\t\tclass={\n\t\t\t\"flex flex-col space-y-2 border border-base-content rounded-box text-sm overflow-y-auto\",\n\t\t\ttempl.KV(\"border-primary\", time.Now().UTC().Format(\"20060102\") == day.Format(\"20060102\")),\n\t\t}\n\t>\n\t\t<div class=\"text-center pt-1\">\n\t\t\t<span>{ day.Format(\"Mon Jan 02\") }</span>\n\t\t\t<div class=\"divider !my-0 !py-0\"></div>\n\t\t</div>\n\t\t<ul class=\"space-y-1\">\n\t\t\tfor _, slot := range props.GetSlots(day) {\n\t\t\t\t{{ slotName := \"time_slot_\" + slot.Start.Format(\"200601021504\") }}\n\t\t\t\t@Modal(ModalProps{\n\t\t\t\t\tID: slotName,\n\t\t\t\t\tLabel: timeSlotButton(\n\t\t\t\t\t\tslot,\n\t\t\t\t\t\ttempl.Attributes{\"onclick\": slotName + \".showModal()\"},\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t) {\n\t\t\t\t\t@timeSlotModalContent(slot, slotName, props.ReserveURL)\n\t\t\t\t}\n\t\t\t}\n\t\t</ul>\n\t</div>\n}\n\ntempl timeSlotButton(slot TimeSlot, attrs templ.Attributes) {\n\t<button class=\"btn btn-sm btn-ghost w-full\" { attrs... }>\n\t\t{ slot.Start.Format(\"15:04\") } - { slot.End.Format(\"15:04\") }\n\t</button>\n}\n\ntempl timeSlotModalContent(slot TimeSlot, slotName, reserveURL string) {\n\t<div>\n\t\t<div class=\"flex items-center space-x-2\">\n\t\t\t<div class=\"flex justify-center items-center\">\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"h-8 w-8\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t>\n\t\t\t\t\t<path class=\"stroke-current\" d=\"M2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C22 4.92893 22 7.28595 22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12Z\" stroke-width=\"1.5\"></path>\n\t\t\t\t\t<path class=\"stroke-current\" d=\"M10.125 8.875C10.125 7.83947 10.9645 7 12 7C13.0355 7 13.875 7.83947 13.875 8.875C13.875 9.56245 13.505 10.1635 12.9534 10.4899C12.478 10.7711 12 11.1977 12 11.75V13\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n\t\t\t\t\t<circle class=\"fill-current\" cx=\"12\" cy=\"16\" r=\"1\"></circle>\n\t\t\t\t</svg>\n\t\t\t</div>\n\t\t\t<p class=\"col-span-7\">\n\t\t\t\tReserve a time slot <b>{ slot.Start.Format(\"15:04\") }</b> - <b>{ slot.End.Format(\"15:04\") }</b>, <b>{ slot.Start.Format(\"Monday January 02\") }</b>?\n\t\t\t</p>\n\t\t</div>\n\t\t<div class=\"flex justify-between items-center mt-8\">\n\t\t\t<button\n\t\t\t\tid=\"modal-confirm-reservation\"\n\t\t\t\tclass=\"btn btn-sm btn-primary\"\n\t\t\t\thx-post={ reserveURL + \"?start=\" + slot.Start.Format(\"2006-01-02-15-04\") + \"&end=\" + slot.End.Format(\"2006-01-02-15-04\") }\n\t\t\t>\n\t\t\t\tReserve\n\t\t\t</button>\n\t\t\t<button class=\"btn btn-sm\" { templ.Attributes{\"onclick\": slotName + \".close()\"}... }>\n\t\t\t\tCancel\n\t\t\t</button>\n\t\t</div>\n\t\t<script>\n            ((modal) => {\n                document.addEventListener(\"htmx:afterRequest\", (evt) => {\n                    if (evt.detail.elt.id === \"modal-confirm-reservation\" && evt.detail.successful) {\n                        modal.close()\n                    }\n                })\n            })(document.currentScript.closest(\"dialog.modal\"))\n        </script>\n\t</div>\n}\n\ntempl timeSlotPickerControls(props TimeSlotPickerProps) {\n\t<div class=\"flex justify-between items-center py-2\">\n\t\t<button\n\t\t\thx-get={ props.PickerURL + \"?date=\" + props.CurrentDate.Add(time.Duration(-7*24)*time.Hour).Format(\"2006-01-02\") }\n\t\t\thx-target={ \"#\" + props.ID }\n\t\t\thx-swap=\"outerHTML\"\n\t\t\tclass={ \"btn btn-ghost btn-sm disabled:opacity-50\", }\n\t\t\tif props.CurrentDate.Format(\"2006-01-02\") == time.Now().UTC().Format(\"2006-01-02\") {\n\t\t\t\tdisabled\n\t\t\t}\n\t\t>\n\t\t\t@chevronLeft()\n\t\t</button>\n\t\t<button\n\t\t\thx-get={ props.PickerURL + \"?date=\" + props.CurrentDate.Add(time.Duration(7*24)*time.Hour).Format(\"2006-01-02\") }\n\t\t\thx-target={ \"#\" + props.ID }\n\t\t\thx-swap=\"outerHTML\"\n\t\t\tclass=\"btn btn-ghost btn-sm\"\n\t\t>\n\t\t\t@chevronRight()\n\t\t</button>\n\t</div>\n}\n\ntempl chevronLeft() {\n\t<svg\n\t\tclass=\"h-6 w-6\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t>\n\t\t<path class=\"stroke-base-content\" d=\"M15 6L9 12L15 18\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n\t</svg>\n}\n\ntempl chevronRight() {\n\t<svg\n\t\tclass=\"h-6 w-6\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tfill=\"none\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t>\n\t\t<path class=\"stroke-base-content\" d=\"M9 6L15 12L9 18\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/components/timeline.templ",
    "content": "// data_display\n// https://daisyui.com/components/timeline\npackage components\n\ntype TimelineProps []TimelineProp\n\ntype TimelineProp struct {\n\tStart  string\n\tMiddle templ.Component\n\tEnd    string\n}\n\ntempl Timeline(props TimelineProps) {\n\t<ul class=\"timeline\">\n\t\tfor i, prop := range props {\n\t\t\t<li>\n\t\t\t\tif i > 0 {\n\t\t\t\t\t<hr/>\n\t\t\t\t}\n\t\t\t\tif prop.Start != \"\" {\n\t\t\t\t\t<div class=\"timeline-start\">{ prop.Start }</div>\n\t\t\t\t}\n\t\t\t\tif prop.Middle != nil {\n\t\t\t\t\t<div class=\"timeline-middle\">\n\t\t\t\t\t\t@prop.Middle\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t\tif prop.End != \"\" {\n\t\t\t\t\t<div class=\"timeline-end\">{ prop.End }</div>\n\t\t\t\t}\n\t\t\t\tif i < len(props) - 1 {\n\t\t\t\t\t<hr/>\n\t\t\t\t}\n\t\t\t</li>\n\t\t}\n\t</ul>\n}\n\ntempl TimelineCheckbox(checked bool) {\n\t<svg\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\tviewBox=\"0 0 20 20\"\n\t\tfill=\"currentColor\"\n\t\tclass={ \"h-5 w-5\", templ.KV(\"fill-primary\", checked) }\n\t>\n\t\t<path\n\t\t\tfill-rule=\"evenodd\"\n\t\t\td=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z\"\n\t\t\tclip-rule=\"evenodd\"\n\t\t></path>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/components/toast.templ",
    "content": "// feedback\n// https://daisyui.com/components/toast\npackage components\n\ntype ToastProps struct {\n\tName       string\n\tToastClass string\n\tAlertClass string\n}\n\ntempl Toast(props ToastProps) {\n\t<div name={ props.Name } class={ \"toast\", props.ToastClass }>\n\t\t<div class={ \"alert\", props.AlertClass }>\n\t\t\t{ children... }\n\t\t</div>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/toggle.templ",
    "content": "// data_input\n// https://daisyui.com/components/toggle\npackage components\n\ntype ToggleProps struct {\n\tID        string\n\tBefore    string\n\tAfter     string\n\tName      string\n\tChecked   bool\n\tClass     string\n\tHighlight bool\n\tAttrs     templ.Attributes\n\tSize      string\n}\n\ntempl Toggle(props ToggleProps) {\n\t<div class=\"flex justify-center\">\n\t\t<label class=\"label cursor-pointer space-x-2 mx-auto\">\n\t\t\tif props.Before != \"\" {\n\t\t\t\t<span\n\t\t\t\t\tclass={\n\t\t\t\t\t\ttempl.KV(\"text-primary\", props.Highlight && !props.Checked),\n\t\t\t\t\t\ttempl.KV(\"text-xs\", props.Size == \"xs\"),\n\t\t\t\t\t\ttempl.KV(\"text-sm\", props.Size == \"sm\"),\n\t\t\t\t\t\ttempl.KV(\"text-lg\", props.Size == \"lg\"),\n\t\t\t\t\t\ttempl.KV(\"text-xl\", props.Size == \"xl\"),\n\t\t\t\t\t}\n\t\t\t\t>\n\t\t\t\t\t{ props.Before }\n\t\t\t\t</span>\n\t\t\t}\n\t\t\t<input\n\t\t\t\t{ props.Attrs... }\n\t\t\t\ttype=\"checkbox\"\n\t\t\t\tif props.ID != \"\" {\n\t\t\t\t\tid={ props.ID }\n\t\t\t\t}\n\t\t\t\tname={ props.Name }\n\t\t\t\tclass={\n\t\t\t\t\t\"toggle\", props.Class,\n\t\t\t\t\ttempl.KV(\"toggle-xs\", props.Size == \"xs\"),\n\t\t\t\t\ttempl.KV(\"toggle-sm\", props.Size == \"sm\"),\n\t\t\t\t\ttempl.KV(\"toggle-lg\", props.Size == \"lg\"),\n\t\t\t\t\ttempl.KV(\"toggle-xl\", props.Size == \"xl\"),\n\t\t\t\t}\n\t\t\t\tif props.Checked {\n\t\t\t\t\tchecked=\"checked\"\n\t\t\t\t}\n\t\t\t\tif props.Highlight {\n\t\t\t\t\tonclick=\"toggler(event)\"\n\t\t\t\t}\n\t\t\t/>\n\t\t\tif props.After != \"\" {\n\t\t\t\t<span\n\t\t\t\t\tclass={\n\t\t\t\t\t\t\"label-text\",\n\t\t\t\t\t\ttempl.KV(\"text-primary\", props.Highlight && props.Checked),\n\t\t\t\t\t}\n\t\t\t\t>\n\t\t\t\t\t{ props.After }\n\t\t\t\t</span>\n\t\t\t}\n\t\t</label>\n\t\tif props.Highlight {\n\t\t\t<script>\n                function toggler(evt) {\n                    evt.target.previousElementSibling.classList.toggle(\"text-primary\")\n                    evt.target.nextElementSibling.classList.toggle(\"text-primary\")\n                }\n            </script>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/components/tooltip.templ",
    "content": "// feedback\n// https://daisyui.com/components/tooltip\npackage components\n\ntype TooltipProps struct {\n\tTip   string\n\tClass string\n}\n\ntempl Tooltip(props TooltipProps) {\n\t<div class={ \"tooltip\", props.Class } data-tip={ props.Tip }>\n\t\t{ children... }\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/custom/toast.templ",
    "content": "package custom\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\ntempl ToastErrorConfirm(errs ...string) {\n\t@components.Toast(\n\t\tcomponents.ToastProps{\n\t\t\tName:       \"toast-error\",\n\t\t\tToastClass: \"toast-top toast-center\",\n\t\t\tAlertClass: \"alert-error\",\n\t\t},\n\t) {\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tclass=\"h-6 w-6 shrink-0 stroke-current\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t>\n\t\t\t<path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z\"></path>\n\t\t</svg>\n\t\t<div class=\"w-full max-w-xs text-sm text-start text-wrap\">\n\t\t\t<ul class=\"list-disc pl-2\">\n\t\t\t\tfor _, e := range errs {\n\t\t\t\t\t<li>{ e }</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t\t<button onclick=\"remover(event)\" class=\"btn btn-error\">OK</button>\n\t\t<script>\n            function remover(evt) {\n                evt.target.closest(\"div[name=toast-error]\").remove()\n            }\n        </script>\n\t}\n}\n\ntempl HXToastInfoFade(messages ...string) {\n\t@components.Toast(\n\t\tcomponents.ToastProps{\n\t\t\tName:       \"toast-info\",\n\t\t\tToastClass: \"toast-bottom toast-end w-full max-w-xs\",\n\t\t\tAlertClass: \"alert-info w-full max-w-xs space-x-4\",\n\t\t},\n\t) {\n\t\t<svg class=\"h-6 w-6\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t<path class=\"stroke-info-content\" d=\"M12 17V11\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n\t\t\t<circle class=\"fill-info-content\" cx=\"1\" cy=\"1\" r=\"1\" transform=\"matrix(1 0 0 -1 11 9)\"></circle>\n\t\t\t<path class=\"stroke-info-content\" d=\"M22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C21.5093 4.43821 21.8356 5.80655 21.9449 8\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n\t\t</svg>\n\t\t<div class=\"w-full max-w-xs text-sm text-start text-wrap\">\n\t\t\t<ul\n\t\t\t\tclass={ templ.KV(\"list-disc\", len(messages) > 1) }\n\t\t\t>\n\t\t\t\tfor _, m := range messages {\n\t\t\t\t\t<li>{ m }</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t\t<script>\n\t\t\tdocument.addEventListener(\"htmx:afterSettle\", (evt) => {\n\t\t\t\tlet els = document.querySelectorAll(\"div[name=toast-info]\")\n\t\t\t\tlet el = els[els.length-1]\n\n\t\t\t\tif (el !== undefined) {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tel.remove()\n\t\t\t\t\t}, 5000)\n\t\t\t\t}\n\t\t\t})\n        </script>\n\t}\n}\n"
  },
  {
    "path": "internal/views/embed.go",
    "content": "package views\n\nimport \"embed\"\n\n//go:embed components/*.templ\nvar ComponentFS embed.FS\n"
  },
  {
    "path": "internal/views/examples/accordion.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n/*\nAccordion with input type 'checkbox': multiple rows can be open at a time.\n*/\n\ntempl AccordionWithCheckbox() {\n\t<div class=\"w-full flex join join-vertical pt-4\">\n\t\t@components.AccordionRow(components.AccordionRowProps{Label: \"Label 1\", Name: \"accordion-example-1\"}) {\n\t\t\t<p class=\"pt-4\">Label 1 content</p>\n\t\t}\n\t\t@components.AccordionRow(components.AccordionRowProps{Label: \"Label 2\", Name: \"accordion-example-2\"}) {\n\t\t\t<h2 class=\"text-xl font-bold py-4\">Content 2</h2>\n\t\t\t<p>Label 2 content</p>\n\t\t}\n\t\t@components.AccordionRow(components.AccordionRowProps{Label: \"Label 3\", Name: \"accordion-example-3\"}) {\n\t\t\t<h2 class=\"text-xl font-bold py-4\">Content 3</h2>\n\t\t\t<ul class=\"list-disc [&>li]:ml-4\">\n\t\t\t\t<li>Item 1</li>\n\t\t\t\t<li>Item 2</li>\n\t\t\t\t<li>Item 3</li>\n\t\t\t</ul>\n\t\t}\n\t</div>\n}\n\n// example\n/*\nAccordion with input type 'radio': only a single row can be open at a time.\n*/\n\ntempl AccordionWithRadio() {\n\t<div class=\"w-full flex join join-vertical pt-4\">\n\t\t@components.AccordionRow(components.AccordionRowProps{Label: \"Label 1\", Name: \"accordion-example-2\", Type: \"radio\"}) {\n\t\t\t<p class=\"pt-4\">Label 1 content</p>\n\t\t}\n\t\t@components.AccordionRow(components.AccordionRowProps{Label: \"Label 2\", Name: \"accordion-example-2\", Type: \"radio\"}) {\n\t\t\t<h2 class=\"text-xl font-bold py-4\">Content 2</h2>\n\t\t\t<p>Label 2 content</p>\n\t\t}\n\t\t@components.AccordionRow(components.AccordionRowProps{Label: \"Label 3\", Name: \"accordion-example-2\", Type: \"radio\"}) {\n\t\t\t<h2 class=\"text-xl font-bold py-4\">Content 3</h2>\n\t\t\t<ul class=\"list-disc [&>li]:ml-4\">\n\t\t\t\t<li>Item 1</li>\n\t\t\t\t<li>Item 2</li>\n\t\t\t\t<li>Item 3</li>\n\t\t\t</ul>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/active_search.templ",
    "content": "package examples\n\nimport (\n\t\"fmt\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n)\n\n// example\n// Active search input for a table\ntempl ActiveSearchExampleTable() {\n\t<div class=\"h-[600px]\">\n\t\t@ActiveSearchExample(\n\t\t\t\"active-search-example-table\",\n\t\t\t[]templ.Component{\n\t\t\t\tcomponents.PlainText(\"First name\"),\n\t\t\t\tcomponents.PlainText(\"Last name\"),\n\t\t\t\tcomponents.PlainText(\"Email\"),\n\t\t\t},\n\t\t\tactiveSearchTableDataComponents(),\n\t\t)\n\t</div>\n}\n\ntempl ActiveSearchExample(id string, headers []templ.Component, rows []templ.Component) {\n\t<div class=\"py-8\">\n\t\t@components.ActiveSearchInput(\n\t\t\tcomponents.ActiveSearchInputProps{\n\t\t\t\tID:     \"active-search-example-input\",\n\t\t\t\tURL:    \"/active-search\",\n\t\t\t\tTarget: fmt.Sprintf(\"#%s > tbody\", id),\n\t\t\t\tInputProps: components.InputProps{\n\t\t\t\t\tIcon:        searchIcon(),\n\t\t\t\t\tName:        \"active-search-example\",\n\t\t\t\t\tType:        \"search\",\n\t\t\t\t\tPlaceholder: \"Filter table...\",\n\t\t\t\t\tSize:        \"sm\",\n\t\t\t\t},\n\t\t\t})\n\t\t@components.Table(\n\t\t\theaders,\n\t\t\tactiveSearchTableDataComponents(),\n\t\t\ttempl.Attributes{\"id\": \"active-search-example-table\"},\n\t\t)\n\t</div>\n}\n\ntempl searchIcon() {\n\t<svg\n\t\tclass=\"w-5 h-5\"\n\t\tviewBox=\"0 0 32 32\"\n\t\tversion=\"1.1\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\t\txmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\"\n\t>\n\t\t<g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n\t\t\t<g class=\"fill-base-content/60\" id=\"Icon-Set\" sketch:type=\"MSLayerGroup\" transform=\"translate(-256.000000, -1139.000000)\">\n\t\t\t\t<path d=\"M269.46,1163.45 C263.17,1163.45 258.071,1158.44 258.071,1152.25 C258.071,1146.06 263.17,1141.04 269.46,1141.04 C275.75,1141.04 280.85,1146.06 280.85,1152.25 C280.85,1158.44 275.75,1163.45 269.46,1163.45 L269.46,1163.45 Z M287.688,1169.25 L279.429,1161.12 C281.591,1158.77 282.92,1155.67 282.92,1152.25 C282.92,1144.93 276.894,1139 269.46,1139 C262.026,1139 256,1144.93 256,1152.25 C256,1159.56 262.026,1165.49 269.46,1165.49 C272.672,1165.49 275.618,1164.38 277.932,1162.53 L286.224,1170.69 C286.629,1171.09 287.284,1171.09 287.688,1170.69 C288.093,1170.3 288.093,1169.65 287.688,1169.25 L287.688,1169.25 Z\" id=\"search\" sketch:type=\"MSShapeGroup\"></path>\n\t\t\t</g>\n\t\t</g>\n\t</svg>\n}\n\nfunc activeSearchTableDataComponents() []templ.Component {\n\tcoms := make([]templ.Component, len(ActiveSearchTableData))\n\tfor i := range ActiveSearchTableData {\n\t\tcoms[i] = ActiveSearchTableRow(\n\t\t\tActiveSearchTableData[i].FirstName,\n\t\t\tActiveSearchTableData[i].LastName,\n\t\t\tActiveSearchTableData[i].Email)\n\t}\n\treturn coms\n}\n\nvar ActiveSearchTableData = []struct {\n\tFirstName string\n\tLastName  string\n\tEmail     string\n}{\n\t{FirstName: \"John\", LastName: \"Smith\", Email: \"john.smith@email.com\"},\n\t{FirstName: \"Emily\", LastName: \"Johnson\", Email: \"emily.johnson@email.com\"},\n\t{FirstName: \"Michael\", LastName: \"Brown\", Email: \"michael.brown@email.com\"},\n\t{FirstName: \"Jessica\", LastName: \"Williams\", Email: \"jessica.williams@email.com\"},\n\t{FirstName: \"David\", LastName: \"Jones\", Email: \"david.jones@email.com\"},\n\t{FirstName: \"Sarah\", LastName: \"Miller\", Email: \"sarah.miller@email.com\"},\n\t{FirstName: \"Christopher\", LastName: \"Davis\", Email: \"chris.davis@email.com\"},\n\t{FirstName: \"Amanda\", LastName: \"Wilson\", Email: \"amanda.wilson@email.com\"},\n\t{FirstName: \"James\", LastName: \"Taylor\", Email: \"james.taylor@email.com\"},\n\t{FirstName: \"Laura\", LastName: \"Moore\", Email: \"laura.moore@email.com\"},\n}\n\ntempl ActiveSearchTableRows(rows []templ.Component) {\n\tfor _, r := range rows {\n\t\t@r\n\t}\n}\n\ntempl ActiveSearchTableRow(firstName, lastName, email string) {\n\t<tr>\n\t\t<td>{ firstName }</td>\n\t\t<td>{ lastName }</td>\n\t\t<td>{ email }</td>\n\t</tr>\n}\n"
  },
  {
    "path": "internal/views/examples/alert.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Info-type alert\ntempl AlertInfoExample() {\n\t<div class=\"max-w-md mx-auto pt-4\">\n\t\t@components.AlertInfo(\n\t\t\t\"Your profile has been successfully updated. Please review your changes.\",\n\t\t)\n\t</div>\n}\n\n// example\n// Success-type alert\ntempl AlertSuccessExample() {\n\t<div class=\"max-w-md mx-auto pt-4\">\n\t\t@components.AlertSuccess(\n\t\t\t\"Your payment was processed successfully! Thank you for your purchase.\",\n\t\t) {\n\t\t\t<button class=\"btn btn-sm\">OK</button>\n\t\t}\n\t</div>\n}\n\n// example\n// Warning-type alert\ntempl AlertWarningExample() {\n\t<div class=\"max-w-md mx-auto pt-4\">\n\t\t@components.AlertWarning(\n\t\t\t\"Your password will expire in 7 days. Please update it to avoid any disruptions.\",\n\t\t)\n\t</div>\n}\n\n// example\n// Error-type alert\ntempl AlertErrorExample() {\n\t<div class=\"max-w-md mx-auto pt-4\">\n\t\t@components.AlertError(\n\t\t\t\"Failed to connect to the server. Please try again later or contact support if the issue persists.\",\n\t\t) {\n\t\t\t<button class=\"btn btn-sm\">OK</button>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/anchor.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Basic anchor\ntempl BasicAnchor() {\n\t@components.Anchor(components.AnchorProps{\n\t\tLabel: \"Basic anchor\",\n\t\tClass: \"link\",\n\t})\n}\n\n// example\n// Primary anchor\ntempl PrimaryAnchor() {\n\t@components.Anchor(components.AnchorProps{\n\t\tLabel: \"Primary anchor\",\n\t\tClass: \"link link-primary\",\n\t})\n}\n\n// example\n// Anchor with icon\ntempl AnchorWithIcon() {\n\t@components.Anchor(components.AnchorProps{\n\t\tLabel:    \"GitHub profile\",\n\t\tLeftIcon: GithubIcon(),\n\t\tClass:    \"link\",\n\t})\n}\n\n// example\n// Socials anchors\ntempl SocialAnchors() {\n\t<div class=\"mx-auto\">\n\t\t<div class=\"flex space-x-4\">\n\t\t\t@components.Anchor(components.AnchorProps{LeftIcon: XIcon()})\n\t\t\t@components.Anchor(components.AnchorProps{LeftIcon: YoutubeIcon()})\n\t\t\t@components.Anchor(components.AnchorProps{LeftIcon: FacebookIcon()})\n\t\t\t@components.Anchor(components.AnchorProps{LeftIcon: GithubIcon()})\n\t\t\t@components.Anchor(components.AnchorProps{LeftIcon: LinkedInIcon()})\n\t\t</div>\n\t</div>\n}\n\ntempl XIcon() {\n\t<svg\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\tx=\"0px\"\n\t\ty=\"0px\"\n\t\tviewBox=\"0 0 50 50\"\n\t\tclass=\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\"\n\t>\n\t\t<path d=\"M 5.9199219 6 L 20.582031 27.375 L 6.2304688 44 L 9.4101562 44 L 21.986328 29.421875 L 31.986328 44 L 44 44 L 28.681641 21.669922 L 42.199219 6 L 39.029297 6 L 27.275391 19.617188 L 17.933594 6 L 5.9199219 6 z M 9.7167969 8 L 16.880859 8 L 40.203125 42 L 33.039062 42 L 9.7167969 8 z\"></path>\n\t</svg>\n}\n\ntempl YoutubeIcon() {\n\t<svg\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tclass=\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\"\n\t>\n\t\t<path\n\t\t\td=\"M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z\"\n\t\t></path>\n\t</svg>\n}\n\ntempl FacebookIcon() {\n\t<svg\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tclass=\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\"\n\t>\n\t\t<path\n\t\t\td=\"M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z\"\n\t\t></path>\n\t</svg>\n}\n\ntempl GithubIcon() {\n\t<svg\n\t\tclass=\"h-6 w-6 inline-block mr-1\"\n\t\tviewBox=\"0 0 20 20\"\n\t\tversion=\"1.1\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\t>\n\t\t<g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n\t\t\t<g class=\"fill-base-content/80 hover:fill-base-content group-hover:fill-base-content\" id=\"Dribbble-Light-Preview\" transform=\"translate(-140.000000, -7559.000000)\">\n\t\t\t\t<g id=\"icons\" transform=\"translate(56.000000, 160.000000)\">\n\t\t\t\t\t<path d=\"M94,7399 C99.523,7399 104,7403.59 104,7409.253 C104,7413.782 101.138,7417.624 97.167,7418.981 C96.66,7419.082 96.48,7418.762 96.48,7418.489 C96.48,7418.151 96.492,7417.047 96.492,7415.675 C96.492,7414.719 96.172,7414.095 95.813,7413.777 C98.04,7413.523 100.38,7412.656 100.38,7408.718 C100.38,7407.598 99.992,7406.684 99.35,7405.966 C99.454,7405.707 99.797,7404.664 99.252,7403.252 C99.252,7403.252 98.414,7402.977 96.505,7404.303 C95.706,7404.076 94.85,7403.962 94,7403.958 C93.15,7403.962 92.295,7404.076 91.497,7404.303 C89.586,7402.977 88.746,7403.252 88.746,7403.252 C88.203,7404.664 88.546,7405.707 88.649,7405.966 C88.01,7406.684 87.619,7407.598 87.619,7408.718 C87.619,7412.646 89.954,7413.526 92.175,7413.785 C91.889,7414.041 91.63,7414.493 91.54,7415.156 C90.97,7415.418 89.522,7415.871 88.63,7414.304 C88.63,7414.304 88.101,7413.319 87.097,7413.247 C87.097,7413.247 86.122,7413.234 87.029,7413.87 C87.029,7413.87 87.684,7414.185 88.139,7415.37 C88.139,7415.37 88.726,7417.2 91.508,7416.58 C91.513,7417.437 91.522,7418.245 91.522,7418.489 C91.522,7418.76 91.338,7419.077 90.839,7418.982 C86.865,7417.627 84,7413.783 84,7409.253 C84,7403.59 88.478,7399 94,7399\"></path>\n\t\t\t\t</g>\n\t\t\t</g>\n\t\t</g>\n\t</svg>\n}\n\ntempl LinkedInIcon() {\n\t<svg\n\t\tclass=\"h-6 w-6 fill-base-content/80 hover:fill-base-content inline-block mr-1\"\n\t\tviewBox=\"0 0 32 32\"\n\t\tversion=\"1.1\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t>\n\t\t<path d=\"M28.778 1.004h-25.56c-0.008-0-0.017-0-0.027-0-1.199 0-2.172 0.964-2.186 2.159v25.672c0.014 1.196 0.987 2.161 2.186 2.161 0.010 0 0.019-0 0.029-0h25.555c0.008 0 0.018 0 0.028 0 1.2 0 2.175-0.963 2.194-2.159l0-0.002v-25.67c-0.019-1.197-0.994-2.161-2.195-2.161-0.010 0-0.019 0-0.029 0h0.001zM9.9 26.562h-4.454v-14.311h4.454zM7.674 10.293c-1.425 0-2.579-1.155-2.579-2.579s1.155-2.579 2.579-2.579c1.424 0 2.579 1.154 2.579 2.578v0c0 0.001 0 0.002 0 0.004 0 1.423-1.154 2.577-2.577 2.577-0.001 0-0.002 0-0.003 0h0zM26.556 26.562h-4.441v-6.959c0-1.66-0.034-3.795-2.314-3.795-2.316 0-2.669 1.806-2.669 3.673v7.082h-4.441v-14.311h4.266v1.951h0.058c0.828-1.395 2.326-2.315 4.039-2.315 0.061 0 0.121 0.001 0.181 0.003l-0.009-0c4.5 0 5.332 2.962 5.332 6.817v7.855z\"></path>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/examples/avatar.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Multiple avatar sizes\ntempl MultipleAvatarSizes() {\n\t<div class=\"flex justify-center items-center space-x-4 pt-4\">\n\t\t@components.Avatar(components.AvatarProps{\n\t\t\tContainerClass: \"rounded w-8\", Source: \"/static/images/avatar.jpg\"})\n\t\t@components.Avatar(components.AvatarProps{\n\t\t\tContainerClass: \"rounded w-12\", Source: \"/static/images/avatar.jpg\"})\n\t\t@components.Avatar(components.AvatarProps{\n\t\t\tContainerClass: \"rounded w-16\", Source: \"/static/images/avatar.jpg\"})\n\t\t@components.Avatar(components.AvatarProps{\n\t\t\tContainerClass: \"rounded w-20\", Source: \"/static/images/avatar.jpg\"})\n\t\t@components.Avatar(components.AvatarProps{\n\t\t\tContainerClass: \"rounded w-24\", Source: \"/static/images/avatar.jpg\"})\n\t</div>\n}\n\n// example\n// Avatar group\ntempl GroupOfAvatars() {\n\t<div class=\"flex justify-center items-center space-x-4 pt-4\">\n\t\t@components.AvatarGroup(\"-space-x-8\") {\n\t\t\t@components.Avatar(components.AvatarProps{\n\t\t\t\tContainerClass: \"rounded-full w-12\", Source: \"/static/images/avatar.jpg\"})\n\t\t\t@components.Avatar(components.AvatarProps{\n\t\t\t\tContainerClass: \"rounded-full w-12\", Source: \"/static/images/avatar.jpg\"})\n\t\t\t@components.Avatar(components.AvatarProps{\n\t\t\t\tContainerClass: \"rounded-full w-12\", Source: \"/static/images/avatar.jpg\"})\n\t\t\t@components.Avatar(components.AvatarProps{\n\t\t\t\tContainerClass: \"rounded-full w-12\", Source: \"/static/images/avatar.jpg\"})\n\t\t\t@components.Avatar(components.AvatarProps{\n\t\t\t\tContainerClass: \"rounded-full w-12\", Source: \"/static/images/avatar.jpg\"})\n\t\t}\n\t</div>\n}\n\n// example\n// Avatar with online/offline indicator\ntempl OnlineAndOffline() {\n\t<div class=\"flex justify-center items-center space-x-4 pt-4\">\n\t\t@components.Avatar(components.AvatarProps{\n\t\t\tAvatarClass:    \"avatar-online\",\n\t\t\tContainerClass: \"rounded-full w-12\",\n\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t})\n\t\t@components.Avatar(components.AvatarProps{\n\t\t\tAvatarClass:    \"avatar-offline\",\n\t\t\tContainerClass: \"rounded-full w-12\",\n\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t})\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/banner.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BannerExample() {\n\t@components.Banner(components.BannerProps{\n\t\tTitle: basicBannerTitle(),\n\t\tDescription: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nSapiente iure non, quia perspiciatis sed temporibus quos nihil, voluptatibus tempore \nplaceat ipsa est facilis, nobis illum in magni illo neque libero.`,\n\t}) {\n\t\t<a class=\"btn btn-primary\">\n\t\t\tGet started\n\t\t</a>\n\t\t<a class=\"btn btn-neutral\">\n\t\t\tLearn more\n\t\t</a>\n\t}\n}\n\ntempl basicBannerTitle() {\n\t<h1 class=\"text-3xl font-extrabold sm:text-5xl\">\n\t\tLorem ipsum dolor.\n\t\t<strong class=\"font-extrabold text-primary sm:block\">Sit amet consectetur. </strong>\n\t</h1>\n}\n"
  },
  {
    "path": "internal/views/examples/breadcrumbs.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BreadcrumbsExample() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Breadcrumbs(\n\t\t\tcomponents.BreadcrumbsProps{\n\t\t\t\t{\n\t\t\t\t\tLabel: \"Laptops\",\n\t\t\t\t\tAttrs: templ.Attributes{\"href\": \"/laptops\", \"class\": \"link\"},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLabel: \"Macbooks\",\n\t\t\t\t\tAttrs: templ.Attributes{\"href\": \"/laptops/macbooks\", \"class\": \"link\"},\n\t\t\t\t},\n\t\t\t\t{Label: \"Macbook Pro 14\"},\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/card.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Basic card\ntempl BasicCard() {\n\t<div class=\"flex justify-center items-center py-4\">\n\t\t@components.Card(\n\t\t\tcomponents.CardProps{\n\t\t\t\tTitle:   \"This is a card\",\n\t\t\t\tContent: \"And this is the card's content.\",\n\t\t\t\tClass:   \"bg-base-100 w-96 shadow-xl\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Card with image\ntempl BasicCardWithImage() {\n\t<div class=\"flex justify-center items-center py-4\">\n\t\t@components.Card(\n\t\t\tcomponents.CardProps{\n\t\t\t\tTitle:   \"Card with image\",\n\t\t\t\tContent: \"Card with image content\",\n\t\t\t\tSource:  \"/static/images/avatar.jpg\",\n\t\t\t\tAlt:     \"avatar image\",\n\t\t\t\tClass:   \"card-bordered bg-base-100 w-96 shadow-xl\",\n\t\t\t},\n\t\t) {\n\t\t\t<button class=\"btn btn-sm btn-primary\">Contact</button>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/carousel.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl CarouselExample() {\n\t<div class=\"max-h-80 pt-4 max-w-screen-md\">\n\t\t@components.Carousel(\n\t\t\tcomponents.CarouselProps{\n\t\t\t\t{Source: \"/static/images/avatar.jpg\", Alt: \"avatar image\"},\n\t\t\t\t{Source: \"/static/images/avatar.jpg\", Alt: \"avatar image\"},\n\t\t\t\t{Source: \"/static/images/avatar.jpg\", Alt: \"avatar image\"},\n\t\t\t\t{Source: \"/static/images/avatar.jpg\", Alt: \"avatar image\"},\n\t\t\t\t{Source: \"/static/images/avatar.jpg\", Alt: \"avatar image\"},\n\t\t\t\t{Source: \"/static/images/avatar.jpg\", Alt: \"avatar image\"},\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/chat.templ",
    "content": "package examples\n\nimport (\n\t\"time\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n)\n\n// example\ntempl BasicChat() {\n\t<div class=\"w-full max-w-screen-sm rounded-box mx-auto border border-base-content/30 p-4\">\n\t\t@components.Chat(components.ChatProps{\n\t\t\t{\n\t\t\t\tAvatarURL: \"/static/images/avatar.jpg\",\n\t\t\t\tSender:    \"Me\",\n\t\t\t\tTime:      time.Now().UTC().Add(-4 * time.Minute).Format(\"15:04:05\"),\n\t\t\t\tMessage: `I started learning how to cook more dishes from scratch, \nand it's been way more satisfying than I expected. Last night, I made homemade pasta!`,\n\t\t\t\tFooter:   \"✓✓\",\n\t\t\t\tLocation: \"start\",\n\t\t\t\tClass:    \"chat-bubble-primary\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatarURL: \"/static/images/avatar-reverse.jpg\",\n\t\t\t\tSender:    \"Myself\",\n\t\t\t\tTime:      time.Now().UTC().Add(-2 * time.Minute).Format(\"15:04:05\"),\n\t\t\t\tMessage: `That's awesome! Homemade pasta is no joke—it's a workout, \ntoo! Did you use a pasta machine, or go for the classic rolling pin method?`,\n\t\t\t\tFooter:   \"✓✓\",\n\t\t\t\tLocation: \"end\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatarURL: \"/static/images/avatar.jpg\",\n\t\t\t\tSender:    \"Me\",\n\t\t\t\tTime:      time.Now().UTC().Add(-1 * time.Minute).Format(\"15:04:05\"),\n\t\t\t\tMessage: `Went old-school with the rolling pin! Took forever, but it \nwas worth it. I made a simple marinara sauce to go with it, and honestly, it was better \nthan what I usually order.`,\n\t\t\t\tFooter:   \"✓✓\",\n\t\t\t\tLocation: \"start\",\n\t\t\t\tClass:    \"chat-bubble-primary\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatarURL: \"/static/images/avatar-reverse.jpg\",\n\t\t\t\tSender:    \"Myself\",\n\t\t\t\tTime:      time.Now().UTC().Format(\"15:04:05\"),\n\t\t\t\tMessage: `Love it! Next up, you've got to try ravioli. It's a bit \nmore work, but filling them with something like ricotta and spinach makes it feel \nsuper fancy. You'll impress everyone!`,\n\t\t\t\tFooter:   \"✓✓\",\n\t\t\t\tLocation: \"end\",\n\t\t\t},\n\t\t})\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/checkbox.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Different size checkboxes\ntempl DifferentSizeCheckboxes() {\n\t<div class=\"flex flex-col space-y-4 mx-auto pt-4\">\n\t\t@components.Checkbox(\n\t\t\tcomponents.CheckboxProps{\n\t\t\t\tBefore:  \"Remember me\",\n\t\t\t\tName:    \"remember_me\",\n\t\t\t\tChecked: false,\n\t\t\t\tSize:    \"xs\",\n\t\t\t},\n\t\t)\n\t\t@components.Checkbox(\n\t\t\tcomponents.CheckboxProps{\n\t\t\t\tBefore:  \"Remember me\",\n\t\t\t\tName:    \"remember_me\",\n\t\t\t\tChecked: false,\n\t\t\t\tSize:    \"sm\",\n\t\t\t},\n\t\t)\n\t\t@components.Checkbox(\n\t\t\tcomponents.CheckboxProps{\n\t\t\t\tBefore:  \"Remember me\",\n\t\t\t\tName:    \"remember_me\",\n\t\t\t\tChecked: false,\n\t\t\t},\n\t\t)\n\t\t@components.Checkbox(\n\t\t\tcomponents.CheckboxProps{\n\t\t\t\tBefore:  \"Remember me\",\n\t\t\t\tName:    \"remember_me\",\n\t\t\t\tChecked: false,\n\t\t\t\tSize:    \"lg\",\n\t\t\t},\n\t\t)\n\t\t@components.Checkbox(\n\t\t\tcomponents.CheckboxProps{\n\t\t\t\tBefore:  \"Remember me\",\n\t\t\t\tName:    \"remember_me\",\n\t\t\t\tChecked: false,\n\t\t\t\tSize:    \"xl\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Primary color checkbox with label after\ntempl PrimaryCheckbox() {\n\t<div class=\"mx-auto pt-4\">\n\t\t@components.Checkbox(\n\t\t\tcomponents.CheckboxProps{\n\t\t\t\tAfter:   \"Remember me\",\n\t\t\t\tName:    \"remember_me\",\n\t\t\t\tChecked: true,\n\t\t\t\tClass:   \"checkbox-primary\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/collapse.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Basic collapse\ntempl CollapseExample() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Collapse(\n\t\t\tcomponents.CollapseProps{\n\t\t\t\tTitle:        \"Click me to show/hide content\",\n\t\t\t\tTitleClass:   \"text-xl font-medium\",\n\t\t\t\tClass:        \"collapse-plus bg-base-300\",\n\t\t\t\tContentClass: \"bg-base-200\",\n\t\t\t}) {\n\t\t\t<div class=\"pt-4\">\n\t\t\t\t<p>Collapse content</p>\n\t\t\t</div>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/combobox.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicCombobox() {\n\t<div class=\"h-96\">\n\t\t<form hx-post=\"/combobox-submit/example_combo\" class=\"space-x-4\">\n\t\t\t@components.Combobox(components.ComboboxProps{\n\t\t\t\tName:  \"example_combo\",\n\t\t\t\tLabel: \"Example\",\n\t\t\t\tURL:   \"/combobox/%s/%s\",\n\t\t\t\tOptions: []string{\n\t\t\t\t\t\"Thing 1\", \"Thing 2\", \"Thing 3\", \"Thing 4\", \"Thing 5\", \"Thing 6\", \"Thing 7\",\n\t\t\t\t},\n\t\t\t})\n\t\t\t<button type=\"submit\" class=\"btn btn-sm btn-primary\">Submit</button>\n\t\t\t<script>\n\t\t\t\t// update the form to only include half of the input values\n\t\t\t\t// corresponding to the combobox's name since it will contain enabled checkbox values as well\n\t\t\t\t((form) => {\n\t\t\t\t\tform.addEventListener(\"htmx:configRequest\", (evt) => {\n\t\t\t\t\t\tlet values = evt.detail.parameters[\"example_combo\"]\n\t\t\t\t\t\tif (values !== undefined) {\n\t\t\t\t\t\t\tevt.detail.parameters[\"example_combo\"] = values.slice(0, Math.floor(values.length / 2))\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})(document.currentScript.parentElement)\n\t\t\t</script>\n\t\t</form>\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/countdown.templ",
    "content": "package examples\n\nimport (\n\t\"github.com/haatos/goshipit/internal/views/components\"\n\t\"time\"\n)\n\n// example\ntempl CountdownFullExample() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Countdown(\n\t\t\tcomponents.CountdownProps{\n\t\t\t\tExpires: time.Now().UTC().Add(25*time.Hour + 10*time.Second),\n\t\t\t\tDays:    true,\n\t\t\t\tHours:   true,\n\t\t\t\tSeconds: true,\n\t\t\t\tMinutes: true,\n\t\t\t})\n\t</div>\n}\n\n// example\ntempl CountdownHoursExample() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Countdown(\n\t\t\tcomponents.CountdownProps{\n\t\t\t\tExpires: time.Now().UTC().Add(10*time.Hour + 10*time.Second),\n\t\t\t\tHours:   true,\n\t\t\t\tSeconds: true,\n\t\t\t\tMinutes: true,\n\t\t\t})\n\t</div>\n}\n\n// example\ntempl CountdownMinutesExample() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Countdown(\n\t\t\tcomponents.CountdownProps{\n\t\t\t\tExpires: time.Now().UTC().Add(15*time.Minute + 10*time.Second),\n\t\t\t\tSeconds: true,\n\t\t\t\tMinutes: true,\n\t\t\t})\n\t</div>\n}\n\n// example\ntempl CountdownSecondsExample() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Countdown(\n\t\t\tcomponents.CountdownProps{\n\t\t\t\tExpires: time.Now().UTC().Add(20 * time.Second),\n\t\t\t\tSeconds: true,\n\t\t\t})\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/date_picker.templ",
    "content": "package examples\n\nimport \"time\"\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicDatePicker() {\n\t{{ now := time.Now().UTC() }}\n\t@components.DatePicker(\n\t\tcomponents.DatePickerProps{\n\t\t\tYear:        now.Year(),\n\t\t\tMonth:       int(now.Month()),\n\t\t\tSelected:    now,\n\t\t\tStartOfWeek: time.Monday,\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "internal/views/examples/diff.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl ImageDiff() {\n\t<div class=\"flex mx-auto pt-4 min-h-[240px] sm:min-h-[300px] lg:min-h-[480px]\">\n\t\t@components.Diff(\n\t\t\tcomponents.DiffProps{\n\t\t\t\tWidth:  16,\n\t\t\t\tHeight: 19,\n\t\t\t\tImage1: components.DiffImage{\n\t\t\t\t\tSource: \"/static/images/diff1.png\", Alt: \"diff image 1\",\n\t\t\t\t},\n\t\t\t\tImage2: components.DiffImage{\n\t\t\t\t\tSource: \"/static/images/diff2.png\", Alt: \"diff image 2\",\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/drawer.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicDrawer() {\n\t<div class=\"w-full h-[400px] flex flex-wrap items-center justify-center overflow-x-hidden\">\n\t\t@DrawerPreview(DrawerExampleToggle(), DrawerExampleMenu())\n\t</div>\n}\n\ntempl DrawerPreview(toggle templ.Component, sidebar templ.Component) {\n\t<div class=\"drawer h-[400px]\">\n\t\t<input id=\"my-drawer\" type=\"checkbox\" class=\"drawer-toggle\"/>\n\t\t<div class=\"flex flex-col items-center justify-center drawer-content\">\n\t\t\t{ children... }\n\t\t\t<label for=\"my-drawer\" class=\"btn btn-primary drawer-button\">\n\t\t\t\t@toggle\n\t\t\t</label>\n\t\t</div>\n\t\t<div class=\"drawer-side h-full absolute\">\n\t\t\t<label for=\"my-drawer\" aria-label=\"close sidebar\" class=\"drawer-overlay\"></label>\n\t\t\t<ul class=\"menu bg-base-200 text-base-content min-h-full w-60 md:w-80 p-4\">\n\t\t\t\t@sidebar\n\t\t\t</ul>\n\t\t</div>\n\t</div>\n}\n\ntempl DrawerExampleToggle() {\n\t<span>Click me</span>\n}\n\ntempl DrawerExampleMenu() {\n\t@components.MenuItem(components.MenuItemProps{Label: \"Section 1\", Attrs: templ.Attributes{\"class\": \"menu-title\"}})\n\t@components.MenuItem(components.MenuItemProps{Label: \"Section 2\", Attrs: templ.Attributes{\"class\": \"menu-title\"}}) {\n\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.1\"}) {\n\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.1.1\"})\n\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.1.2\"})\n\t\t}\n\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.2\"}) {\n\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.2.1\"})\n\t\t}\n\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.3\"})\n\t}\n\t@components.MenuItem(components.MenuItemProps{Label: \"Section 3\", Attrs: templ.Attributes{\"class\": \"menu-title\"}}) {\n\t\t@components.MenuItem(components.MenuItemProps{Label: \"3.1\"})\n\t}\n}\n"
  },
  {
    "path": "internal/views/examples/dropdown.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicDropdown() {\n\t<div class=\"h-48\">\n\t\t@components.Dropdown(\n\t\t\tcomponents.DropdownProps{\n\t\t\t\tLabel: \"Dropdown label\",\n\t\t\t\tItems: []components.DropdownItem{\n\t\t\t\t\t{Label: \"Item 1\"},\n\t\t\t\t\t{Label: \"Item 2\"},\n\t\t\t\t\t{Label: \"Item 3\"},\n\t\t\t\t},\n\t\t\t\tListClass: \"bg-base-200 rounded-box z-50 w-52 p-2 shadow-sm\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/fab.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicFAB() {\n\t<div class=\"h-68 relative\">\n\t\t@components.FAB(\n\t\t\tcomponents.FABProps{\n\t\t\t\tClass:       \"absolute z-1\", // !! preview purpose only\n\t\t\t\tToggle:      \"F\",\n\t\t\t\tToggleClass: \"btn-lg btn-circle\",\n\t\t\t}) {\n\t\t\t<button class=\"btn btn-lg btn-circle\">A</button>\n\t\t\t<button class=\"btn btn-lg btn-circle\">B</button>\n\t\t\t<button class=\"btn btn-lg btn-circle\">C</button>\n\t\t}\n\t</div>\n}\n\n// example\n// FAB with SVGs as toggle and content buttons\ntempl FABWithSVGButtons() {\n\t<div class=\"h-68 relative\">\n\t\t@components.FAB(\n\t\t\tcomponents.FABProps{\n\t\t\t\tClass:       \"absolute z-1\", // !! preview purpose only\n\t\t\t\tToggle:      fabSVGToggle(),\n\t\t\t\tToggleClass: \"btn-lg btn-circle\",\n\t\t\t}) {\n\t\t\t@fabSVGVoiceButton()\n\t\t\t@fabSVGImageButton()\n\t\t\t@fabSVGCameraButton()\n\t\t}\n\t</div>\n}\n\ntempl fabSVGToggle() {\n\t<svg\n\t\taria-label=\"New\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\tfill=\"none\"\n\t\tviewBox=\"0 0 24 24\"\n\t\tstroke-width=\"2\"\n\t\tstroke=\"currentColor\"\n\t\tclass=\"size-6\"\n\t>\n\t\t<path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\"></path>\n\t</svg>\n}\n\ntempl fabSVGVoiceButton() {\n\t<button class=\"btn btn-lg btn-circle\">\n\t\t<svg\n\t\t\taria-label=\"Camera\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tstroke-width=\"1.5\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tclass=\"size-6\"\n\t\t>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\td=\"M6.827 6.175A2.31 2.31 0 0 1 5.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 0 0-1.134-.175 2.31 2.31 0 0 1-1.64-1.055l-.822-1.316a2.192 2.192 0 0 0-1.736-1.039 48.774 48.774 0 0 0-5.232 0 2.192 2.192 0 0 0-1.736 1.039l-.821 1.316Z\"\n\t\t\t></path>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\td=\"M16.5 12.75a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0ZM18.75 10.5h.008v.008h-.008V10.5Z\"\n\t\t\t></path>\n\t\t</svg>\n\t</button>\n}\n\ntempl fabSVGImageButton() {\n\t<button class=\"btn btn-lg btn-circle\">\n\t\t<svg\n\t\t\taria-label=\"Gallery\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tstroke-width=\"1.5\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tclass=\"size-6\"\n\t\t>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\td=\"m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z\"\n\t\t\t></path>\n\t\t</svg>\n\t</button>\n}\n\ntempl fabSVGCameraButton() {\n\t<button class=\"btn btn-lg btn-circle\">\n\t\t<svg\n\t\t\taria-label=\"Voice\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"none\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tstroke-width=\"1.5\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tclass=\"size-6\"\n\t\t>\n\t\t\t<path\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\td=\"M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z\"\n\t\t\t></path>\n\t\t</svg>\n\t</button>\n}\n\n// example\n// FAB flower\ntempl FABFlowerExample() {\n\t<div class=\"h-68 relative\">\n\t\t@components.FAB(components.FABProps{\n\t\t\tClass:       \"fab-flower absolute z-1\", // !! absolute & z-1 preview purpose only\n\t\t\tToggle:      \"F\",\n\t\t\tToggleClass: \"btn btn-lg btn-circle\",\n\t\t\tMainAction:  fabFlowerMainAction(),\n\t\t}) {\n\t\t\t<button class=\"btn btn-lg btn-circle\">A</button>\n\t\t\t<button class=\"btn btn-lg btn-circle\">B</button>\n\t\t\t<button class=\"btn btn-lg btn-circle\">C</button>\n\t\t\t<button class=\"btn btn-lg btn-circle\">D</button>\n\t\t}\n\t</div>\n}\n\ntempl fabFlowerMainAction() {\n\t<button class=\"btn btn-lg btn-circle btn-primary\">M</button>\n}\n"
  },
  {
    "path": "internal/views/examples/features.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl FeaturesExample() {\n\t@components.Features(\n\t\tcomponents.FeaturesProps{\n\t\t\tTitle: \"Discover our exclusive features\",\n\t\t\tFeatures: []components.FeatureProps{\n\t\t\t\t{\n\t\t\t\t\tIcon:        CustomizationIcon(),\n\t\t\t\t\tTitle:       \"Customization\",\n\t\t\t\t\tDescription: \"Tailor our product to suit your needs.\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tIcon:        SecurityIcon(),\n\t\t\t\t\tTitle:       \"Security\",\n\t\t\t\t\tDescription: \"Your data is protected by the latest security measures.\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tIcon:        SupportIcon(),\n\t\t\t\t\tTitle:       \"Support\",\n\t\t\t\t\tDescription: \"24/7 customer support for all your inquiries.\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tIcon:        PerformanceIcon(),\n\t\t\t\t\tTitle:       \"Performance\",\n\t\t\t\t\tDescription: \"Experience blazing-fast performance with our product.\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tIcon:  GlobalReachIcon(),\n\t\t\t\t\tTitle: \"Global reach\",\n\t\t\t\t\tDescription: `Tailor our product to suit your needs. Expand your reach \nwith our global network.`,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tIcon:        CommunicationIcon(),\n\t\t\t\t\tTitle:       \"Communication\",\n\t\t\t\t\tDescription: \"Seamless communication for your team.\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t)\n}\n\ntempl CustomizationIcon() {\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" class=\"w-8 mb-6 inline-block\" viewBox=\"0 0 32 32\">\n\t\t<path d=\"M28.068 12h-.128a.934.934 0 0 1-.864-.6.924.924 0 0 1 .2-1.01l.091-.091a2.938 2.938 0 0 0 0-4.147l-1.511-1.51a2.935 2.935 0 0 0-4.146 0l-.091.091A.956.956 0 0 1 20 4.061v-.129A2.935 2.935 0 0 0 17.068 1h-2.136A2.935 2.935 0 0 0 12 3.932v.129a.956.956 0 0 1-1.614.668l-.086-.091a2.935 2.935 0 0 0-4.146 0l-1.516 1.51a2.938 2.938 0 0 0 0 4.147l.091.091a.935.935 0 0 1 .185 1.035.924.924 0 0 1-.854.579h-.128A2.935 2.935 0 0 0 1 14.932v2.136A2.935 2.935 0 0 0 3.932 20h.128a.934.934 0 0 1 .864.6.924.924 0 0 1-.2 1.01l-.091.091a2.938 2.938 0 0 0 0 4.147l1.51 1.509a2.934 2.934 0 0 0 4.147 0l.091-.091a.936.936 0 0 1 1.035-.185.922.922 0 0 1 .579.853v.129A2.935 2.935 0 0 0 14.932 31h2.136A2.935 2.935 0 0 0 20 28.068v-.129a.956.956 0 0 1 1.614-.668l.091.091a2.935 2.935 0 0 0 4.146 0l1.511-1.509a2.938 2.938 0 0 0 0-4.147l-.091-.091a.935.935 0 0 1-.185-1.035.924.924 0 0 1 .854-.58h.128A2.935 2.935 0 0 0 31 17.068v-2.136A2.935 2.935 0 0 0 28.068 12ZM29 17.068a.933.933 0 0 1-.932.932h-.128a2.956 2.956 0 0 0-2.083 5.028l.09.091a.934.934 0 0 1 0 1.319l-1.511 1.509a.932.932 0 0 1-1.318 0l-.09-.091A2.957 2.957 0 0 0 18 27.939v.129a.933.933 0 0 1-.932.932h-2.136a.933.933 0 0 1-.932-.932v-.129a2.951 2.951 0 0 0-5.028-2.082l-.091.091a.934.934 0 0 1-1.318 0l-1.51-1.509a.934.934 0 0 1 0-1.319l.091-.091A2.956 2.956 0 0 0 4.06 18h-.128A.933.933 0 0 1 3 17.068v-2.136A.933.933 0 0 1 3.932 14h.128a2.956 2.956 0 0 0 2.083-5.028l-.09-.091a.933.933 0 0 1 0-1.318l1.51-1.511a.932.932 0 0 1 1.318 0l.09.091A2.957 2.957 0 0 0 14 4.061v-.129A.933.933 0 0 1 14.932 3h2.136a.933.933 0 0 1 .932.932v.129a2.956 2.956 0 0 0 5.028 2.082l.091-.091a.932.932 0 0 1 1.318 0l1.51 1.511a.933.933 0 0 1 0 1.318l-.091.091A2.956 2.956 0 0 0 27.94 14h.128a.933.933 0 0 1 .932.932Z\" data-original=\"#000000\"></path>\n\t\t<path d=\"M16 9a7 7 0 1 0 7 7 7.008 7.008 0 0 0-7-7Zm0 12a5 5 0 1 1 5-5 5.006 5.006 0 0 1-5 5Z\" data-original=\"#000000\"></path>\n\t</svg>\n}\n\ntempl SecurityIcon() {\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" class=\"w-8 mb-6 inline-block\" viewBox=\"0 0 682.667 682.667\">\n\t\t<defs>\n\t\t\t<clipPath id=\"a\" clipPathUnits=\"userSpaceOnUse\">\n\t\t\t\t<path d=\"M0 512h512V0H0Z\" data-original=\"#000000\"></path>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-miterlimit=\"10\" stroke-width=\"40\" clip-path=\"url(#a)\" transform=\"matrix(1.33 0 0 -1.33 0 682.667)\">\n\t\t\t<path d=\"M256 492 60 410.623v-98.925C60 183.674 137.469 68.38 256 20c118.53 48.38 196 163.674 196 291.698v98.925z\" data-original=\"#000000\"></path>\n\t\t\t<path d=\"M178 271.894 233.894 216 334 316.105\" data-original=\"#000000\"></path>\n\t\t</g>\n\t</svg>\n}\n\ntempl SupportIcon() {\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" class=\"w-8 mb-6 inline-block\" viewBox=\"0 0 512.001 512.001\">\n\t\t<path d=\"M271.029 0c-33.091 0-61 27.909-61 61s27.909 61 61 61 60-27.909 60-61-26.909-61-60-61zm66.592 122c-16.485 18.279-40.096 30-66.592 30-26.496 0-51.107-11.721-67.592-30-14.392 15.959-23.408 36.866-23.408 60v15c0 8.291 6.709 15 15 15h151c8.291 0 15-6.709 15-15v-15c0-23.134-9.016-44.041-23.408-60zM144.946 460.404 68.505 307.149c-7.381-14.799-25.345-20.834-40.162-13.493l-19.979 9.897c-7.439 3.689-10.466 12.73-6.753 20.156l90 180c3.701 7.423 12.704 10.377 20.083 6.738l19.722-9.771c14.875-7.368 20.938-25.417 13.53-40.272zM499.73 247.7c-12.301-9-29.401-7.2-39.6 3.9l-82 100.8c-5.7 6-16.5 9.6-22.2 9.6h-69.901c-8.401 0-15-6.599-15-15s6.599-15 15-15h60c16.5 0 30-13.5 30-30s-13.5-30-30-30h-78.6c-7.476 0-11.204-4.741-17.1-9.901-23.209-20.885-57.949-30.947-93.119-22.795-19.528 4.526-32.697 12.415-46.053 22.993l-.445-.361-21.696 19.094L174.28 452h171.749c28.2 0 55.201-13.5 72.001-36l87.999-126c9.9-13.201 7.2-32.399-6.299-42.3z\" data-original=\"#000000\"></path>\n\t</svg>\n}\n\ntempl PerformanceIcon() {\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" class=\"w-8 mb-6 inline-block\" viewBox=\"0 0 24 24\">\n\t\t<g fill-rule=\"evenodd\" clip-rule=\"evenodd\">\n\t\t\t<path d=\"M17.03 8.97a.75.75 0 0 1 0 1.06l-4.2 4.2a.75.75 0 0 1-1.154-.114l-1.093-1.639L8.03 15.03a.75.75 0 0 1-1.06-1.06l3.2-3.2a.75.75 0 0 1 1.154.114l1.093 1.639L15.97 8.97a.75.75 0 0 1 1.06 0z\" data-original=\"#000000\"></path>\n\t\t\t<path d=\"M13.75 9.5a.75.75 0 0 1 .75-.75h2a.75.75 0 0 1 .75.75v2a.75.75 0 0 1-1.5 0v-1.25H14.5a.75.75 0 0 1-.75-.75z\" data-original=\"#000000\"></path>\n\t\t\t<path d=\"M3.095 3.095C4.429 1.76 6.426 1.25 9 1.25h6c2.574 0 4.57.51 5.905 1.845C22.24 4.429 22.75 6.426 22.75 9v6c0 2.574-.51 4.57-1.845 5.905C19.571 22.24 17.574 22.75 15 22.75H9c-2.574 0-4.57-.51-5.905-1.845C1.76 19.571 1.25 17.574 1.25 15V9c0-2.574.51-4.57 1.845-5.905zm1.06 1.06C3.24 5.071 2.75 6.574 2.75 9v6c0 2.426.49 3.93 1.405 4.845.916.915 2.419 1.405 4.845 1.405h6c2.426 0 3.93-.49 4.845-1.405.915-.916 1.405-2.419 1.405-4.845V9c0-2.426-.49-3.93-1.405-4.845C18.929 3.24 17.426 2.75 15 2.75H9c-2.426 0-3.93.49-4.845 1.405z\" data-original=\"#000000\"></path>\n\t\t</g>\n\t</svg>\n}\n\ntempl GlobalReachIcon() {\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" class=\"w-8 mb-6 inline-block\" viewBox=\"0 0 504.69 504.69\">\n\t\t<path d=\"M252.343 262.673c-49.32 0-89.447-40.127-89.447-89.447s40.127-89.447 89.447-89.447 89.447 40.127 89.447 89.447-40.121 89.447-89.447 89.447zm0-158.235c-37.926 0-68.787 30.861-68.787 68.787s30.861 68.787 68.787 68.787 68.787-30.861 68.787-68.787-30.855-68.787-68.787-68.787z\" data-original=\"#000000\"></path>\n\t\t<path d=\"M391.787 405.309c-5.645 0-10.253-4.54-10.325-10.201-.883-70.306-58.819-127.503-129.15-127.503-49.264 0-93.543 27.405-115.561 71.52-8.724 17.473-13.269 36.31-13.517 55.988-.072 5.702-4.757 10.273-10.459 10.201s-10.273-4.757-10.201-10.459c.289-22.814 5.568-44.667 15.691-64.955 25.541-51.164 76.907-82.95 134.047-82.95 81.581 0 148.788 66.349 149.81 147.905.072 5.702-4.494 10.392-10.201 10.459-.046-.005-.087-.005-.134-.005z\" data-original=\"#000000\"></path>\n\t\t<path d=\"M252.343 463.751c-116.569 0-211.408-94.834-211.408-211.408 0-116.569 94.839-211.408 211.408-211.408 116.574 0 211.408 94.839 211.408 211.408 0 116.574-94.834 211.408-211.408 211.408zm0-402.156c-105.18 0-190.748 85.568-190.748 190.748s85.568 190.748 190.748 190.748 190.748-85.568 190.748-190.748S357.523 61.595 252.343 61.595zM71.827 90.07 14.356 32.599c-4.034-4.034-4.034-10.573 0-14.607 4.029-4.034 10.573-4.034 14.607 0l57.466 57.471c4.034 4.034 3.951 10.49 0 14.607-3.792 3.951-11.039 3.698-14.602 0z\" data-original=\"#000000\"></path>\n\t\t<path d=\"M14.717 92.254a10.332 10.332 0 0 1-10.299-9.653L.023 15.751a10.317 10.317 0 0 1 2.929-7.908 10.2 10.2 0 0 1 7.851-3.089L77.56 7.796c5.697.258 10.108 5.093 9.85 10.79s-5.041 10.154-10.79 9.85l-55.224-2.521 3.641 55.327c.377 5.692-3.936 10.614-9.628 10.986a7.745 7.745 0 0 1-.692.026zm403.541-2.184c-4.256-3.796-4.034-10.573 0-14.607l58.116-58.116c4.034-4.034 10.573-4.034 14.607 0s4.034 10.573 0 14.607L432.864 90.07c-4.085 3.951-9.338 4.7-14.606 0z\" data-original=\"#000000\"></path>\n\t\t<path d=\"M489.974 92.254a9.85 9.85 0 0 1-.687-.021c-5.697-.372-10.01-5.294-9.633-10.986l3.641-55.327-55.224 2.515c-5.511.238-10.526-4.147-10.79-9.85-.258-5.702 4.153-10.531 9.85-10.79l66.757-3.042c2.934-.134 5.79.992 7.851 3.089s3.12 4.974 2.929 7.908l-4.401 66.85c-.361 5.465-4.896 9.654-10.293 9.654zM11.711 489.339c-3.791-4.266-4.034-10.573 0-14.607l60.115-60.11c4.029-4.034 10.578-4.034 14.607 0 4.034 4.034 4.034 10.573 0 14.607l-60.115 60.11c-3.827 3.884-11.156 3.884-14.607 0z\" data-original=\"#000000\"></path>\n\t\t<path d=\"M10.327 499.947a10.33 10.33 0 0 1-7.376-3.104 10.312 10.312 0 0 1-2.929-7.902l4.401-66.85c.372-5.697 5.191-10.036 10.986-9.633 5.692.377 10.005 5.294 9.628 10.986l-3.641 55.332 55.224-2.515c5.645-.191 10.531 4.153 10.79 9.85.258 5.697-4.153 10.526-9.85 10.79l-66.763 3.037c-.155.004-.31.009-.47.009zm465.639-13.01-57.708-57.708c-4.034-4.034-4.034-10.573 0-14.607s10.573-4.034 14.607 0l57.708 57.708c4.034 4.034 3.962 10.5 0 14.607-3.817 3.951-10.062 3.951-14.607 0z\" data-original=\"#000000\"></path>\n\t\t<path d=\"M494.359 499.947c-.155 0-.315-.005-.47-.01l-66.757-3.042c-5.702-.263-10.108-5.088-9.85-10.79.263-5.702 5.113-9.984 10.79-9.85l55.219 2.515-3.641-55.332c-.372-5.692 3.941-10.609 9.633-10.986 5.625-.398 10.609 3.946 10.986 9.633l4.401 66.85a10.33 10.33 0 0 1-2.929 7.902 10.323 10.323 0 0 1-7.382 3.11z\" data-original=\"#000000\"></path>\n\t</svg>\n}\n\ntempl CommunicationIcon() {\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" class=\"w-8 mb-6 inline-block\" viewBox=\"0 0 682.667 682.667\">\n\t\t<defs>\n\t\t\t<clipPath id=\"a\" clipPathUnits=\"userSpaceOnUse\">\n\t\t\t\t<path d=\"M0 512h512V0H0Z\" data-original=\"#000000\"></path>\n\t\t\t</clipPath>\n\t\t</defs>\n\t\t<g fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"30\" clip-path=\"url(#a)\" transform=\"matrix(1.33 0 0 -1.33 0 682.667)\">\n\t\t\t<path d=\"M226 15v60c0 16.568-13.432 30-30 30H76c-16.568 0-30-13.432-30-30V15Zm-45 165c0-24.853-20.147-45-45-45s-45 20.147-45 45 20.147 45 45 45 45-20.147 45-45ZM466 15v60c0 16.568-13.432 30-30 30H316c-16.568 0-30-13.432-30-30V15Zm-45 165c0-24.853-20.147-45-45-45s-45 20.147-45 45 20.147 45 45 45 45-20.147 45-45Zm-75 167v-50.294L286 347h-60.002L166 296.706V347h-15c-41.421 0-75 33.579-75 75s33.579 75 75 75h210c41.421 0 75-33.579 75-75s-33.579-75-75-75Zm-105 75h30m-90 0h30m90 0h30\" data-original=\"#000000\"></path>\n\t\t</g>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/examples/file_input.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Different size file inputs\ntempl DifferentSizeFileInputs() {\n\t@components.FileInput(components.FileInputProps{\n\t\tLabel: \"File upload\",\n\t\tSize:  \"xs\",\n\t})\n\t@components.FileInput(components.FileInputProps{\n\t\tLabel: \"File upload\",\n\t\tSize:  \"sm\",\n\t})\n\t@components.FileInput(components.FileInputProps{\n\t\tLabel: \"File upload\",\n\t})\n\t@components.FileInput(components.FileInputProps{\n\t\tLabel: \"File upload\",\n\t\tSize:  \"lg\",\n\t})\n\t@components.FileInput(components.FileInputProps{\n\t\tLabel: \"File upload\",\n\t\tSize:  \"xl\",\n\t})\n}\n"
  },
  {
    "path": "internal/views/examples/footer.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicFooterWithLinks() {\n\t@components.Footer(\n\t\tcomponents.FooterProps{\n\t\t\tIcon:        FooterCompanyInfoIconExample(),\n\t\t\tName:        \"ACME Industries Ltd.\",\n\t\t\tDescription: \"Providing reliable tech since 1992\",\n\t\t\tAnchors: []components.AnchorProps{\n\t\t\t\t{LeftIcon: XIcon()},\n\t\t\t\t{LeftIcon: YoutubeIcon()},\n\t\t\t\t{LeftIcon: FacebookIcon()},\n\t\t\t},\n\t\t},\n\t) {\n\t\t@components.FooterNav(\n\t\t\t\"Services\",\n\t\t\t[]components.AnchorProps{\n\t\t\t\t{Label: \"Branding\"},\n\t\t\t\t{Label: \"Design\"},\n\t\t\t\t{Label: \"Marketing\"},\n\t\t\t\t{Label: \"Advertisement\"},\n\t\t\t},\n\t\t)\n\t\t@components.FooterNav(\n\t\t\t\"Company\",\n\t\t\t[]components.AnchorProps{\n\t\t\t\t{Label: \"About us\"},\n\t\t\t\t{Label: \"Contact\"},\n\t\t\t\t{Label: \"Jobs\"},\n\t\t\t\t{Label: \"Press kit\"},\n\t\t\t},\n\t\t)\n\t\t@components.FooterNav(\n\t\t\t\"Legal\",\n\t\t\t[]components.AnchorProps{\n\t\t\t\t{Label: \"Terms of use\"},\n\t\t\t\t{Label: \"Privacy policy\"},\n\t\t\t\t{Label: \"Cookie policy\"},\n\t\t\t},\n\t\t)\n\t}\n}\n\ntempl FooterCompanyInfoIconExample() {\n\t<svg\n\t\twidth=\"24\"\n\t\theight=\"24\"\n\t\tviewBox=\"0 0 24 24\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\tfill-rule=\"evenodd\"\n\t\tclip-rule=\"evenodd\"\n\t\tclass=\"fill-current\"\n\t>\n\t\t<path\n\t\t\td=\"M22.672 15.226l-2.432.811.841 2.515c.33 1.019-.209 2.127-1.23 2.456-1.15.325-2.148-.321-2.463-1.226l-.84-2.518-5.013 1.677.84 2.517c.391 1.203-.434 2.542-1.831 2.542-.88 0-1.601-.564-1.86-1.314l-.842-2.516-2.431.809c-1.135.328-2.145-.317-2.463-1.229-.329-1.018.211-2.127 1.231-2.456l2.432-.809-1.621-4.823-2.432.808c-1.355.384-2.558-.59-2.558-1.839 0-.817.509-1.582 1.327-1.846l2.433-.809-.842-2.515c-.33-1.02.211-2.129 1.232-2.458 1.02-.329 2.13.209 2.461 1.229l.842 2.515 5.011-1.677-.839-2.517c-.403-1.238.484-2.553 1.843-2.553.819 0 1.585.509 1.85 1.326l.841 2.517 2.431-.81c1.02-.33 2.131.211 2.461 1.229.332 1.018-.21 2.126-1.23 2.456l-2.433.809 1.622 4.823 2.433-.809c1.242-.401 2.557.484 2.557 1.838 0 .819-.51 1.583-1.328 1.847m-8.992-6.428l-5.01 1.675 1.619 4.828 5.011-1.674-1.62-4.829z\"\n\t\t></path>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/examples/hero.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicHero() {\n\t<div class=\"pt-4\">\n\t\t@components.Hero(components.HeroProps{\n\t\t\tSource: \"/static/images/avatar.jpg\",\n\t\t\tAlt:    \"hero avatar\",\n\t\t\tClass:  \"bg-base-200 min-h-[600px]\",\n\t\t}) {\n\t\t\t<div class=\"prose\">\n\t\t\t\t<h1>Lorem ipsum!</h1>\n\t\t\t\t<p>\n\t\t\t\t\tLorem ipsum dolor sit, amet consectetur adipisicing elit.\n\t\t\t\t\tEx quibusdam dicta necessitatibus! Deleniti temporibus iure\n\t\t\t\t\tporro cupiditate dolorum modi voluptate perferendis velit\n\t\t\t\t\ttempora repudiandae expedita, impedit omnis vitae. Laborum,\n\t\t\t\t\tdignissimos?\n\t\t\t\t</p>\n\t\t\t\t<button class=\"btn btn-primary\">Get Started</button>\n\t\t\t</div>\n\t\t}\n\t\t@components.Hero(components.HeroProps{\n\t\t\tSource:  \"/static/images/avatar.jpg\",\n\t\t\tAlt:     \"hero avatar\",\n\t\t\tClass:   \"bg-base-200 min-h-[600px]\",\n\t\t\tReverse: true,\n\t\t}) {\n\t\t\t<div class=\"prose\">\n\t\t\t\t<h1>Lorem ipsum!</h1>\n\t\t\t\t<p>\n\t\t\t\t\tLorem ipsum dolor sit, amet consectetur adipisicing elit.\n\t\t\t\t\tEx quibusdam dicta necessitatibus! Deleniti temporibus iure\n\t\t\t\t\tporro cupiditate dolorum modi voluptate perferendis velit\n\t\t\t\t\ttempora repudiandae expedita, impedit omnis vitae. Laborum,\n\t\t\t\t\tdignissimos?\n\t\t\t\t</p>\n\t\t\t\t<button class=\"btn btn-primary\">Get Started</button>\n\t\t\t</div>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/hover_3d_card.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl Hover3DCardExample() {\n\t@components.Hover3DCard() {\n\t\t@components.Card(\n\t\t\tcomponents.CardProps{\n\t\t\t\tTitle:   \"Hover 3D Card\",\n\t\t\t\tContent: \"This is a hover 3D card. Move your mouse around the card.\",\n\t\t\t\tClass:   \"h-[200px] card-border\",\n\t\t\t},\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "internal/views/examples/infinite_scroll.templ",
    "content": "package examples\n\nimport (\n\t\"fmt\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n)\n\n// example\ntempl InfiniteScrollTableExample() {\n\t@components.Table(\n\t\t[]templ.Component{components.PlainText(\"Name\"), components.PlainText(\"Email\")},\n\t\tinitialRows(),\n\t\tnil,\n\t)\n\t<div class=\"flex justify-center\"><span id=\"spinner\" class=\"htmx-indicator loading loading-spinner\"></span></div>\n}\n\nfunc initialRows() []templ.Component {\n\tdata := make([]templ.Component, 10)\n\tfor i := 0; i < 10; i++ {\n\t\tdata[i] = components.InfiniteScrollRow(\"John Doe\", fmt.Sprintf(\"john.doe%d@email.com\", i), 0, i == 9)\n\t}\n\n\treturn data\n}\n"
  },
  {
    "path": "internal/views/examples/input.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Different size inputs\ntempl DifferentSizeInputs() {\n\t@components.Input(components.InputProps{\n\t\tLabel:       \"Name\",\n\t\tPlaceholder: \"Your name...\",\n\t\tSize:        \"xs\",\n\t})\n\t@components.Input(components.InputProps{\n\t\tLabel:       \"Name\",\n\t\tPlaceholder: \"Your name...\",\n\t\tSize:        \"sm\",\n\t})\n\t@components.Input(components.InputProps{\n\t\tLabel:       \"Name\",\n\t\tPlaceholder: \"Your name...\",\n\t})\n\t@components.Input(components.InputProps{\n\t\tLabel:       \"Name\",\n\t\tPlaceholder: \"Your name...\",\n\t\tSize:        \"lg\",\n\t})\n\t@components.Input(components.InputProps{\n\t\tLabel:       \"Name\",\n\t\tPlaceholder: \"Your name...\",\n\t\tSize:        \"xl\",\n\t})\n}\n\n// example\n// Integer input\ntempl IntegerInput() {\n\t@components.Input(components.InputProps{\n\t\tName:        \"my_number\",\n\t\tType:        \"number\",\n\t\tPlaceholder: \"Give a number...\",\n\t})\n}\n\n// example\n// Decimal input\ntempl DecimalInput() {\n\t@components.Input(components.InputProps{\n\t\tName:        \"my_number\",\n\t\tType:        \"number\",\n\t\tPlaceholder: \"Give a decimal number...\",\n\t\tAttrs: templ.Attributes{\n\t\t\t\"min\":  \"0.00\",\n\t\t\t\"max\":  \"2.00\",\n\t\t\t\"step\": \"0.25\",\n\t\t},\n\t})\n}\n\n// example\n// Password field with validator\ntempl PasswordFieldWithValidator() {\n\t@components.Input(components.InputProps{\n\t\tName:          \"password\",\n\t\tType:          \"password\",\n\t\tPlaceholder:   \"Password\",\n\t\tRequired:      true,\n\t\tPattern:       `(?=.*(\\W|_))(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,255}`,\n\t\tValidatorHint: \"Must be at least 8 characters long, including a digit, lower- and uppercase letter, and a special character\",\n\t\tIcon:          keyIcon(),\n\t\tAttrs: templ.Attributes{\n\t\t\t\"minlength\": \"8\",\n\t\t\t\"maxlength\": \"255\",\n\t\t},\n\t})\n}\n\ntempl keyIcon() {\n\t<svg class=\"fill-current/75 h-5 w-5\" viewBox=\"0 0 32 32\" id=\"icon\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<path d=\"M21,2a8.9977,8.9977,0,0,0-8.6119,11.6118L2,24v6H8L18.3881,19.6118A9,9,0,1,0,21,2Zm0,16a7.0125,7.0125,0,0,1-2.0322-.3022L17.821,17.35l-.8472.8472-3.1811,3.1812L12.4141,20,11,21.4141l1.3787,1.3786-1.5859,1.586L9.4141,23,8,24.4141l1.3787,1.3786L7.1716,28H4V24.8284l9.8023-9.8023.8472-.8474-.3473-1.1467A7,7,0,1,1,21,18Z\"></path>\n\t\t<circle cx=\"22\" cy=\"10\" r=\"2\"></circle>\n\t\t<rect class=\"fill-none\" id=\"_Transparent_Rectangle_\"></rect>\n\t</svg>\n}\n\n// example\n// Email field with validtor\ntempl EmailFieldWithValidator() {\n\t@components.Input(components.InputProps{\n\t\tName:          \"email\",\n\t\tType:          \"email\",\n\t\tPlaceholder:   \"Email\",\n\t\tRequired:      true,\n\t\tPattern:       `^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$`,\n\t\tValidatorHint: \"Please enter a valid email address\",\n\t\tIcon:          emailIcon(),\n\t})\n}\n\ntempl emailIcon() {\n\t<svg class=\"h-5 w-5\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<path class=\"stroke-current/75\" d=\"M4 7.00005L10.2 11.65C11.2667 12.45 12.7333 12.45 13.8 11.65L20 7\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n\t\t<rect class=\"stroke-current/75\" x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" stroke-width=\"1\" stroke-linecap=\"round\"></rect>\n\t</svg>\n}\n\n// example\ntempl SignUpFormExample() {\n\t<div class=\"w-full max-w-xs mx-auto pt-12 pb-4\">\n\t\t<h2 class=\"text-xl text-center mb-8\">Sign Up</h2>\n\t\t@OAuthButtons()\n\t\t<div class=\"divider !my-6\">OR</div>\n\t\t@SignUpForm(\n\t\t\t\"\", \"\",\n\t\t\t\"\", \"\",\n\t\t\t\"\", \"\",\n\t\t\t\"\", \"\",\n\t\t)\n\t</div>\n}\n\n// Sign up form with inline validation\ntempl SignUpForm(\n\tfirstName, firstNameError,\n\tlastName, lastNameError,\n\temail, emailError,\n\tpassword, passwordError string,\n) {\n\t<div class=\"w-full max-w-xs mx-auto\">\n\t\t<div\n\t\t\tclass=\"form space-y-1\"\n\t\t\thx-swap=\"outerHTML\"\n\t\t>\n\t\t\t@components.Input(\n\t\t\t\tcomponents.InputProps{\n\t\t\t\t\tLabel:       \"First name\",\n\t\t\t\t\tName:        \"first_name\",\n\t\t\t\t\tPlaceholder: \"Your first name...\",\n\t\t\t\t\tValue:       firstName,\n\t\t\t\t\tError:       firstNameError,\n\t\t\t\t\tRequired:    true,\n\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\"hx-post\": \"/validate/string/first_name?v=notempty\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t)\n\t\t\t@components.Input(\n\t\t\t\tcomponents.InputProps{\n\t\t\t\t\tLabel:       \"Last name\",\n\t\t\t\t\tName:        \"last_name\",\n\t\t\t\t\tPlaceholder: \"Your last name...\",\n\t\t\t\t\tValue:       lastName,\n\t\t\t\t\tError:       lastNameError,\n\t\t\t\t\tRequired:    true,\n\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\"hx-post\": \"/validate/string/last_name?v=notempty\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t)\n\t\t\t@components.Input(\n\t\t\t\tcomponents.InputProps{\n\t\t\t\t\tLabel:       \"Email\",\n\t\t\t\t\tName:        \"email\",\n\t\t\t\t\tType:        \"email\",\n\t\t\t\t\tPlaceholder: \"Your email...\",\n\t\t\t\t\tValue:       email,\n\t\t\t\t\tError:       emailError,\n\t\t\t\t\tRequired:    true,\n\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\"hx-post\": \"/validate/string/email?v=email\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t)\n\t\t\t@components.Input(\n\t\t\t\tcomponents.InputProps{\n\t\t\t\t\tLabel:         \"Password\",\n\t\t\t\t\tName:          \"password\",\n\t\t\t\t\tType:          \"password\",\n\t\t\t\t\tPlaceholder:   \"Your new password...\",\n\t\t\t\t\tRequired:      true,\n\t\t\t\t\tMinLength:     \"8\",\n\t\t\t\t\tMaxLength:     \"255\",\n\t\t\t\t\tPattern:       `(?=.*(\\W|_))(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,255}`,\n\t\t\t\t\tValidatorHint: \"Must be at least 8 characters long, including a digit, lower- and uppercase letter, and a special character\",\n\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\"hx-post\": \"/validate/string/password?v=hasupper&v=haslower&v=hasdigit\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t)\n\t\t\t<div class=\"pt-4\">\n\t\t\t\t<button type=\"submit\" class=\"w-full btn btn-primary\">\n\t\t\t\t\tSign up\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n}\n\ntempl OAuthButtons() {\n\t<div class=\"w-full max-w-xs flex flex-col space-y-4 items-center justify-center\">\n\t\t@GoogleOAuthLink(\"\")\n\t\t@GithubOAuthLink(\"\")\n\t</div>\n}\n\ntempl GoogleOAuthLink(href string) {\n\t<a\n\t\thref={ templ.SafeURL(href) }\n\t\tclass=\"w-full max-w-sm py-3 flex justify-center gap-2 bg-gray-50 dark:bg-gray-900 hover:bg-gray-100 dark:hover:bg-black text-slate-950 dark:text-slate-50 rounded-box shadow-md transition-colors duration-300\"\n\t>\n\t\t<svg class=\"w-6 h-6\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" fill=\"none\">\n\t\t\t<path d=\"M30.0014 16.3109C30.0014 15.1598 29.9061 14.3198 29.6998 13.4487H16.2871V18.6442H24.1601C24.0014 19.9354 23.1442 21.8798 21.2394 23.1864L21.2127 23.3604L25.4536 26.58L25.7474 26.6087C28.4458 24.1665 30.0014 20.5731 30.0014 16.3109Z\" fill=\"#4285F4\"></path>\n\t\t\t<path d=\"M16.2863 29.9998C20.1434 29.9998 23.3814 28.7553 25.7466 26.6086L21.2386 23.1863C20.0323 24.0108 18.4132 24.5863 16.2863 24.5863C12.5086 24.5863 9.30225 22.1441 8.15929 18.7686L7.99176 18.7825L3.58208 22.127L3.52441 22.2841C5.87359 26.8574 10.699 29.9998 16.2863 29.9998Z\" fill=\"#34A853\"></path>\n\t\t\t<path d=\"M8.15964 18.769C7.85806 17.8979 7.68352 16.9645 7.68352 16.0001C7.68352 15.0356 7.85806 14.1023 8.14377 13.2312L8.13578 13.0456L3.67083 9.64746L3.52475 9.71556C2.55654 11.6134 2.00098 13.7445 2.00098 16.0001C2.00098 18.2556 2.55654 20.3867 3.52475 22.2845L8.15964 18.769Z\" fill=\"#FBBC05\"></path>\n\t\t\t<path d=\"M16.2864 7.4133C18.9689 7.4133 20.7784 8.54885 21.8102 9.4978L25.8419 5.64C23.3658 3.38445 20.1435 2 16.2864 2C10.699 2 5.8736 5.1422 3.52441 9.71549L8.14345 13.2311C9.30229 9.85555 12.5086 7.4133 16.2864 7.4133Z\" fill=\"#EB4335\"></path>\n\t\t</svg>\n\t\t<span>Sign in with Google</span>\n\t</a>\n}\n\ntempl GithubOAuthLink(href string) {\n\t<a\n\t\thref={ templ.SafeURL(href) }\n\t\tclass=\"py-3 px-4 max-w-md flex justify-center items-center bg-gray-600 hover:bg-gray-700 focus:ring-gray-500 focus:ring-offset-gray-200 text-white w-full transition-colors duration-300 text-center text-base font-semibold shadow-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 rounded-box\"\n\t>\n\t\t<svg class=\"w-6 h-6 mr-2\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"currentColor\" class=\"mr-2\" viewBox=\"0 0 1792 1792\">\n\t\t\t<path\n\t\t\t\td=\"M896 128q209 0 385.5 103t279.5 279.5 103 385.5q0 251-146.5 451.5t-378.5 277.5q-27 5-40-7t-13-30q0-3 .5-76.5t.5-134.5q0-97-52-142 57-6 102.5-18t94-39 81-66.5 53-105 20.5-150.5q0-119-79-206 37-91-8-204-28-9-81 11t-92 44l-38 24q-93-26-192-26t-192 26q-16-11-42.5-27t-83.5-38.5-85-13.5q-45 113-8 204-79 87-79 206 0 85 20.5 150t52.5 105 80.5 67 94 39 102.5 18q-39 36-49 103-21 10-45 15t-57 5-65.5-21.5-55.5-62.5q-19-32-48.5-52t-49.5-24l-20-3q-21 0-29 4.5t-5 11.5 9 14 13 12l7 5q22 10 43.5 38t31.5 51l10 23q13 38 44 61.5t67 30 69.5 7 55.5-3.5l23-4q0 38 .5 88.5t.5 54.5q0 18-13 30t-40 7q-232-77-378.5-277.5t-146.5-451.5q0-209 103-385.5t279.5-279.5 385.5-103zm-477 1103q3-7-7-12-10-3-13 2-3 7 7 12 9 6 13-2zm31 34q7-5-2-16-10-9-16-3-7 5 2 16 10 10 16 3zm30 45q9-7 0-19-8-13-17-6-9 5 0 18t17 7zm42 42q8-8-4-19-12-12-20-3-9 8 4 19 12 12 20 3zm57 25q3-11-13-16-15-4-19 7t13 15q15 6 19-6zm63 5q0-13-17-11-16 0-16 11 0 13 17 11 16 0 16-11zm58-10q-2-11-18-9-16 3-14 15t18 8 14-14z\"\n\t\t\t></path>\n\t\t</svg>\n\t\t<span>Sign in with GitHub</span>\n\t</a>\n}\n"
  },
  {
    "path": "internal/views/examples/lazy_load.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl LazyLoadExample() {\n\t@components.LazyLoad(\"/lazy-load\")\n}\n\ntempl LazyLoadResult() {\n\t<div\n\t\tclass={\n\t\t\t\"bg-warning text-warning-content rounded-box\",\n\t\t\t\"w-28 h-28 flex justify-center items-center text-center\",\n\t\t}\n\t>\n\t\tLAZY\n\t\t<br/>\n\t\tLOAD\n\t\t<br/>\n\t\tCOMPLETE\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/menu.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Basic menu\ntempl MenuExample() {\n\t<div class=\"w-full mx-auto max-w-xs pt-4\">\n\t\t@components.Menu(components.MenuProps{Title: \"Basic menu\", Class: \"w-52\"}) {\n\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"Section 1\", Attrs: templ.Attributes{\"class\": \"menu-title\"}})\n\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"Section 2\", Attrs: templ.Attributes{\"class\": \"menu-title\"}}) {\n\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.1\"}) {\n\t\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.1.1\"})\n\t\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.1.2\"})\n\t\t\t\t}\n\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.2\"}) {\n\t\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.2.1\"})\n\t\t\t\t}\n\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.3\"})\n\t\t\t}\n\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"Section 3\", Attrs: templ.Attributes{\"class\": \"menu-title\"}}) {\n\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"3.1\"})\n\t\t\t}\n\t\t}\n\t</div>\n}\n\n// example\n// Menu with a submenu\ntempl MenuWithSubmenusExample() {\n\t<div class=\"w-full mx-auto max-w-xs pt-4 min-h-72\">\n\t\t@components.Menu(components.MenuProps{Class: \"w-52\"}) {\n\t\t\t@components.MenuItem(\n\t\t\t\tcomponents.MenuItemProps{\n\t\t\t\t\tLabel: \"Section 1\",\n\t\t\t\t\tAttrs: templ.Attributes{\"class\": \"menu-title\"},\n\t\t\t\t})\n\t\t\t@components.Submenu(\n\t\t\t\tcomponents.SubmenuProps{\n\t\t\t\t\tTitle: \"Section 2\",\n\t\t\t\t\tAttrs: templ.Attributes{\"open\": \"\"},\n\t\t\t\t},\n\t\t\t) {\n\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.1\"})\n\t\t\t\t@components.MenuItem(components.MenuItemProps{Label: \"2.2\"})\n\t\t\t}\n\t\t}\n\t</div>\n}\n\n// example\n// Menu with icons and a submenu\ntempl DashboardMenuExample() {\n\t@components.Menu(\n\t\tcomponents.MenuProps{Class: \"w-64 bg-base-200 rounded-box\"}) {\n\t\t@components.MenuItem(\n\t\t\tcomponents.MenuItemProps{\n\t\t\t\tLabel: \"Dashboard\",\n\t\t\t\tIcon:  HomeIcon(),\n\t\t\t\tAttrs: templ.Attributes{\"href\": \"#dashboard\"},\n\t\t\t})\n\t\t@components.MenuItem(\n\t\t\tcomponents.MenuItemProps{\n\t\t\t\tLabel: \"Users\",\n\t\t\t\tIcon:  UsersIcon(),\n\t\t\t\tAttrs: templ.Attributes{\"href\": \"#users\"},\n\t\t\t})\n\t\t@components.Submenu(components.SubmenuProps{Title: \"Content\", Icon: ContentIcon()}) {\n\t\t\t@components.MenuItem(\n\t\t\t\tcomponents.MenuItemProps{\n\t\t\t\t\tLabel: \"Posts\",\n\t\t\t\t\tIcon:  PostsIcon(),\n\t\t\t\t\tAttrs: templ.Attributes{\"href\": \"#posts\"},\n\t\t\t\t})\n\t\t\t@components.MenuItem(\n\t\t\t\tcomponents.MenuItemProps{\n\t\t\t\t\tLabel: \"Images\",\n\t\t\t\t\tIcon:  ImagesIcon(),\n\t\t\t\t\tAttrs: templ.Attributes{\"href\": \"#images\"},\n\t\t\t\t})\n\t\t\t@components.MenuItem(\n\t\t\t\tcomponents.MenuItemProps{\n\t\t\t\t\tLabel: \"Videos\",\n\t\t\t\t\tIcon:  VideosIcon(),\n\t\t\t\t\tAttrs: templ.Attributes{\"href\": \"#videos\"},\n\t\t\t\t})\n\t\t}\n\t}\n}\n\ntempl HomeIcon() {\n\t<svg class=\"h-5 w-5 opacity-75\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<path class=\"stroke-current\" d=\"M2 12.2039C2 9.91549 2 8.77128 2.5192 7.82274C3.0384 6.87421 3.98695 6.28551 5.88403 5.10813L7.88403 3.86687C9.88939 2.62229 10.8921 2 12 2C13.1079 2 14.1106 2.62229 16.116 3.86687L18.116 5.10812C20.0131 6.28551 20.9616 6.87421 21.4808 7.82274C22 8.77128 22 9.91549 22 12.2039V13.725C22 17.6258 22 19.5763 20.8284 20.7881C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.7881C2 19.5763 2 17.6258 2 13.725V12.2039Z\" stroke-width=\"1.5\"></path>\n\t\t<path class=\"stroke-current\" d=\"M15 18H9\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n\t</svg>\n}\n\ntempl UsersIcon() {\n\t<svg class=\"h-5 w-5 opacity-75\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<path class=\"stroke-current\" d=\"M16 7C16 9.20914 14.2091 11 12 11C9.79086 11 8 9.20914 8 7C8 4.79086 9.79086 3 12 3C14.2091 3 16 4.79086 16 7Z\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n\t\t<path class=\"stroke-current\" d=\"M12 14C8.13401 14 5 17.134 5 21H19C19 17.134 15.866 14 12 14Z\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n\t</svg>\n}\n\ntempl ContentIcon() {\n\t<svg class=\"h-5 w-5 opacity-75\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<path class=\"stroke-current\" opacity=\"0.5\" d=\"M18 10L13 10\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n\t\t<path class=\"stroke-current\" d=\"M2 6.94975C2 6.06722 2 5.62595 2.06935 5.25839C2.37464 3.64031 3.64031 2.37464 5.25839 2.06935C5.62595 2 6.06722 2 6.94975 2C7.33642 2 7.52976 2 7.71557 2.01738C8.51665 2.09229 9.27652 2.40704 9.89594 2.92051C10.0396 3.03961 10.1763 3.17633 10.4497 3.44975L11 4C11.8158 4.81578 12.2237 5.22367 12.7121 5.49543C12.9804 5.64471 13.2651 5.7626 13.5604 5.84678C14.0979 6 14.6747 6 15.8284 6H16.2021C18.8345 6 20.1506 6 21.0062 6.76946C21.0849 6.84024 21.1598 6.91514 21.2305 6.99383C22 7.84935 22 9.16554 22 11.7979V14C22 17.7712 22 19.6569 20.8284 20.8284C19.6569 22 17.7712 22 14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14V6.94975Z\" stroke-width=\"1.5\"></path>\n\t</svg>\n}\n\ntempl PostsIcon() {\n\t<svg class=\"h-5 w-5 opacity-75\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<path class=\"stroke-current\" d=\"M1 6v12h9V6zm8 11H2V7h7zm-8 3h22v1H1zM1 3h22v1H1zm11 4h11v1H12zm0 3h11v1H12zm0 3h11v1H12zm0 3h11v1H12z\"></path><path fill=\"none\" d=\"M0 0h24v24H0z\"></path>\n\t</svg>\n}\n\ntempl ImagesIcon() {\n\t<svg class=\"h-5 w-5 opacity-75\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<rect width=\"24\" height=\"24\" class=\"fill-base-100\"></rect>\n\t\t<path class=\"stroke-current\" d=\"M21 16V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V18M21 16V4C21 3.44772 20.5523 3 20 3H4C3.44772 3 3 3.44772 3 4V18M21 16L15.4829 12.3219C15.1843 12.1228 14.8019 12.099 14.4809 12.2595L3 18\" stroke-linejoin=\"round\"></path>\n\t\t<circle class=\"stroke-current\" cx=\"8\" cy=\"9\" r=\"2\" stroke-linejoin=\"round\"></circle>\n\t</svg>\n}\n\ntempl VideosIcon() {\n\t<svg class=\"h-5 w-5 opacity-75\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<path class=\"fill-current\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M9.98966 10.91C10.4482 10.609 11.0657 10.5541 11.6048 10.8884L14.9764 12.9785C15.5136 13.3116 15.75 13.8874 15.75 14.4102C15.75 14.933 15.5136 15.5088 14.9764 15.8418L11.6048 17.932C11.0657 18.2662 10.4482 18.2114 9.98966 17.9103C9.539 17.6144 9.25 17.0934 9.25 16.5003V12.32C9.25 11.727 9.539 11.2059 9.98966 10.91ZM10.8129 12.1639C10.7945 12.176 10.75 12.2203 10.75 12.32V16.5003C10.75 16.6 10.7945 16.6443 10.8129 16.6564L10.8142 16.6572L14.186 14.5669C14.2072 14.5538 14.25 14.5085 14.25 14.4102C14.25 14.3118 14.2072 14.2665 14.186 14.2534L10.8145 12.1633L10.8129 12.1639Z\"></path>\n\t\t<path class=\"fill-current\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.69935 1.25001C8.4795 1.24995 8.31094 1.2499 8.16359 1.26571C6.80943 1.41104 5.77295 2.52304 5.71005 3.87007C4.51917 4.22559 3.67058 5.3275 3.65528 6.5913C3.05445 6.77164 2.53621 7.05606 2.11196 7.51432C1.45997 8.21857 1.25792 9.08649 1.25023 10.1003C1.24283 11.075 1.41651 12.3067 1.63219 13.8363L2.07118 16.9499C2.23979 18.146 2.37676 19.1176 2.58989 19.879C2.81286 20.6756 3.14152 21.331 3.75003 21.8349C4.35372 22.3347 5.06993 22.5502 5.91647 22.6518C6.73501 22.75 7.76474 22.75 9.04682 22.75H14.9531C16.2352 22.75 17.265 22.75 18.0835 22.6518C18.9301 22.5502 19.6463 22.3347 20.25 21.8349C20.8585 21.331 21.1871 20.6756 21.4101 19.879C21.6232 19.1176 21.7602 18.146 21.9288 16.9499L22.3678 13.8363C22.5835 12.3067 22.7572 11.075 22.7498 10.1003C22.7421 9.08649 22.54 8.21857 21.888 7.51432C21.4637 7.05595 20.9453 6.77151 20.3443 6.59118C20.3289 5.3275 19.4805 4.22571 18.2897 3.87013C18.2268 2.52307 17.1903 1.41104 15.8362 1.26571C15.6888 1.2499 15.5203 1.24995 15.3004 1.25001H8.69935ZM18.8105 6.32781C18.6734 5.72018 18.1306 5.25001 17.4617 5.25001H6.53787C5.86896 5.25001 5.32618 5.72019 5.18902 6.32785C6.11481 6.24999 7.24973 6.25 8.61594 6.25001H15.384C16.75 6.25 17.8848 6.24999 18.8105 6.32781ZM16.7677 3.75001C16.6611 3.22633 16.2263 2.8162 15.6761 2.75715C15.6198 2.75111 15.5396 2.75001 15.2588 2.75001H8.74099C8.46013 2.75001 8.37993 2.75111 8.32365 2.75715C7.77344 2.8162 7.33862 3.22633 7.2321 3.75001H16.7677ZM3.21267 8.53336C3.51557 8.20618 3.97106 7.98917 4.85612 7.87145C5.75726 7.75159 6.96357 7.75001 8.67239 7.75001H15.3276C17.0364 7.75001 18.2427 7.75159 19.1439 7.87145C20.0289 7.98917 20.4844 8.20618 20.7873 8.53336C21.0832 8.85293 21.2436 9.28782 21.2498 10.1117C21.2563 10.9618 21.1002 12.0828 20.8738 13.6883L20.4509 16.6883C20.2731 17.9491 20.1486 18.821 19.9656 19.4747C19.7894 20.1042 19.582 20.4405 19.2934 20.6795C18.9999 20.9225 18.6058 21.0784 17.9048 21.1625C17.1861 21.2488 16.2465 21.25 14.9046 21.25H9.09536C7.75347 21.25 6.81393 21.2488 6.09519 21.1625C5.39417 21.0784 5.00014 20.9225 4.70664 20.6795C4.41795 20.4405 4.21058 20.1042 4.03437 19.4747C3.8514 18.821 3.7269 17.9491 3.54913 16.6883L3.12616 13.6883C2.89981 12.0828 2.74373 10.9618 2.75018 10.1117C2.75644 9.28782 2.91681 8.85293 3.21267 8.53336Z\"></path>\n\t</svg>\n}\n"
  },
  {
    "path": "internal/views/examples/modal.templ",
    "content": "package examples\n\nimport (\n\t\"fmt\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n)\n\n// example\n// Basic modal\ntempl BasicModal() {\n\t<div class=\"flex justify-center items-center py-8\">\n\t\t@components.Modal(components.ModalProps{ID: \"my_modal\", Label: \"Click me\"}) {\n\t\t\t<h3 class=\"text-3xl\">Modal title</h3>\n\t\t\t<p>Modal content goes here</p>\n\t\t}\n\t</div>\n}\n\n// example\n// Multiple modals\ntempl MultipleModals() {\n\t<div class=\"flex justify-center items-center py-8\">\n\t\t<div class=\"grid grid-cols-3 gap-4\">\n\t\t\tfor i := range 3 {\n\t\t\t\t@components.Modal(components.ModalProps{ID: fmt.Sprintf(\"my_modal_%d\", i), Label: \"Click me\"}) {\n\t\t\t\t\t<h3 class=\"text-3xl\">Modal title { fmt.Sprintf(\"%d\", i) }</h3>\n\t\t\t\t\t<p>Modal content { fmt.Sprintf(\"%d\", i) }</p>\n\t\t\t\t}\n\t\t\t}\n\t\t</div>\n\t</div>\n}\n\n// example\n// Modal with action button\ntempl ModalWithAction() {\n\t<div class=\"flex justify-center items-center py-8\">\n\t\t@components.Modal(components.ModalProps{ID: \"my_modal_actions\", Label: \"Click me\"}) {\n\t\t\t<h3 class=\"text-3xl\">Modal title</h3>\n\t\t\t<p>Modal content goes here</p>\n\t\t\t<div class=\"modal-action\">\n\t\t\t\t<button class=\"btn\" onclick=\"my_modal_actions.close()\">Close</button>\n\t\t\t</div>\n\t\t}\n\t</div>\n}\n\n// example\n// Modal to confirm delete action\ntempl ModalConfirmDelete() {\n\t<div class=\"flex justify-center items-center\">\n\t\t<div class=\"grid grid-cols-3 gap-4\">\n\t\t\tfor i := range 6 {\n\t\t\t\t<div name=\"modal-confirm-example\">\n\t\t\t\t\t@components.Modal(\n\t\t\t\t\t\tcomponents.ModalProps{\n\t\t\t\t\t\t\tID:    fmt.Sprintf(\"modal_confirm_%d\", i),\n\t\t\t\t\t\t\tLabel: modalConfirmDeleteButton(i, templ.Attributes{\"onclick\": fmt.Sprintf(\"modal_confirm_%d.showModal()\", i)}),\n\t\t\t\t\t\t},\n\t\t\t\t\t) {\n\t\t\t\t\t\t<div class=\"flex flex-col gap-8\">\n\t\t\t\t\t\t\t<div class=\"grid grid-cols-9 gap-6\">\n\t\t\t\t\t\t\t\t<div class=\"col-span-2 flex justify-center items-center\">\n\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\tclass=\"col-span-1 h-10 w-10\"\n\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\t\t\t><path class=\"fill-error\" fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm-1.5-5.009c0-.867.659-1.491 1.491-1.491.85 0 1.509.624 1.509 1.491 0 .867-.659 1.509-1.509 1.509-.832 0-1.491-.642-1.491-1.509zM11.172 6a.5.5 0 0 0-.499.522l.306 7a.5.5 0 0 0 .5.478h1.043a.5.5 0 0 0 .5-.478l.305-7a.5.5 0 0 0-.5-.522h-1.655z\"></path></svg>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div class=\"flex justify-center items-center col-span-7\">\n\t\t\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\t\t\tAre you sure you want to delete { fmt.Sprintf(\"%d\", i) }?\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"flex justify-between items-center\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tid=\"modal-confirm-example-delete-button\"\n\t\t\t\t\t\t\t\t\tclass=\"btn btn-error\"\n\t\t\t\t\t\t\t\t\thx-delete={ fmt.Sprintf(\"/modal-confirm?value=%d\", i) }\n\t\t\t\t\t\t\t\t\thx-target=\"closest div[name=modal-confirm-example]\"\n\t\t\t\t\t\t\t\t\thx-swap=\"outerHTML\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button class=\"btn\" { templ.Attributes{\"onclick\": fmt.Sprintf(\"modal_confirm_%d.close()\", i)}... }>\n\t\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<script>\n\t\t\t\t\t\t\t\t((modal) => {\n\t\t\t\t\t\t\t\t\tdocument.addEventListener(\"htmx:afterRequest\", (evt) => {\n\t\t\t\t\t\t\t\t\t\tif (evt.detail.elt.id === \"modal-confirm-example-delete-button\" && evt.detail.successful) {\n\t\t\t\t\t\t\t\t\t\t\tmodal.close()\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t})(document.currentScript.closest(\"dialog.modal\"))\n\t\t\t\t\t\t\t</script>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t</div>\n\t</div>\n}\n\ntempl modalConfirmDeleteButton(i int, attrs templ.Attributes) {\n\t<button { attrs... } class=\"btn\">\n\t\tClick to delete { fmt.Sprintf(\"%d\", i) }\n\t</button>\n}\n"
  },
  {
    "path": "internal/views/examples/pagination.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicPaginationExample() {\n\t@BasicPagination(\n\t\t\"example-pagination\",\n\t\tcomponents.PaginationProps{\n\t\t\tURL:      \"/pagination-pages\",\n\t\t\tPage:     1,\n\t\t\tLow:      1,\n\t\t\tHigh:     7,\n\t\t\tMaxPages: 20,\n\t\t},\n\t\t[][]string{\n\t\t\t{\"Key0\", \"Value0\"},\n\t\t\t{\"Key1\", \"Value1\"},\n\t\t\t{\"Key2\", \"Value2\"},\n\t\t\t{\"Key3\", \"Value3\"},\n\t\t\t{\"Key4\", \"Value4\"},\n\t\t\t{\"Key5\", \"Value5\"},\n\t\t\t{\"Key6\", \"Value6\"},\n\t\t\t{\"Key7\", \"Value7\"},\n\t\t\t{\"Key8\", \"Value8\"},\n\t\t\t{\"Key9\", \"Value9\"},\n\t\t},\n\t)\n}\n\ntempl BasicPagination(id string, p components.PaginationProps, data [][]string) {\n\t@components.Pagination(\"example-pagination\", p) {\n\t\t<div class=\"overflow-x-auto\">\n\t\t\t<table class=\"table\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Key</th>\n\t\t\t\t\t\t<th>Value</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\tfor _, d := range data {\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<td>{ d[0] }</td>\n\t\t\t\t\t\t\t<td>{ d[1] }</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t}\n}\n"
  },
  {
    "path": "internal/views/examples/pricing.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Basic pricing section\ntempl PricingExample() {\n\t@components.Pricing(\n\t\tcomponents.PricingProps{\n\t\t\tChecked: true,\n\t\t\tPrices: []components.PriceProps{\n\t\t\t\t{\n\t\t\t\t\tTitle:            \"Free\",\n\t\t\t\t\tDescription:      \"My free plan\",\n\t\t\t\t\tPriceMonthly:     \"$ 0\",\n\t\t\t\t\tPerMonthly:       \"/ month\",\n\t\t\t\t\tPriceAnnually:    \"$ 0\",\n\t\t\t\t\tPerAnnually:      \"/ month\",\n\t\t\t\t\tIncludedFeatures: []string{\"Feature 1\", \"Feature 2\", \"Feature 3\"},\n\t\t\t\t\tExcludedFeatures: []string{\"Feature 4\", \"Feature 5\"},\n\t\t\t\t\tCallToAction: components.PriceButtonProps{\n\t\t\t\t\t\tLabel: \"Start free\",\n\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\"class\": \"btn btn-outline mt-8\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tTitle:            \"Starter\",\n\t\t\t\t\tDescription:      \"Starter plan\",\n\t\t\t\t\tPriceMonthly:     \"$ 12\",\n\t\t\t\t\tPerMonthly:       \"/ month\",\n\t\t\t\t\tPriceAnnually:    \"$ 10\",\n\t\t\t\t\tPerAnnually:      \"/ month\",\n\t\t\t\t\tIncludedFeatures: []string{\"Feature 1\", \"Feature 2\", \"Feature 3\"},\n\t\t\t\t\tExcludedFeatures: []string{\"Feature 4\", \"Feature 5\"},\n\t\t\t\t\tCallToAction: components.PriceButtonProps{\n\t\t\t\t\t\tLabel: \"Get started\",\n\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\"class\": \"btn btn-primary mt-8\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tTitle:            \"Professional\",\n\t\t\t\t\tDescription:      \"Professional plan\",\n\t\t\t\t\tPriceMonthly:     \"$ 20\",\n\t\t\t\t\tPerMonthly:       \"/ month\",\n\t\t\t\t\tPriceAnnually:    \"$ 16\",\n\t\t\t\t\tPerAnnually:      \"/ month\",\n\t\t\t\t\tIncludedFeatures: []string{\"Feature 1\", \"Feature 2\", \"Feature 3\"},\n\t\t\t\t\tExcludedFeatures: []string{\"Feature 4\", \"Feature 5\"},\n\t\t\t\t\tCallToAction: components.PriceButtonProps{\n\t\t\t\t\t\tLabel: \"Get started\",\n\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\"class\": \"btn btn-primary mt-8\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t)\n}\n\n// example\n// Pricing section with promotion\ntempl PricingWithPromotionExample() {\n\t@components.Pricing(\n\t\tcomponents.PricingProps{\n\t\t\tChecked: true,\n\t\t\tPrices: []components.PriceProps{\n\t\t\t\t{\n\t\t\t\t\tTitle:            \"Free\",\n\t\t\t\t\tDescription:      \"My free plan\",\n\t\t\t\t\tPriceMonthly:     \"$ 0\",\n\t\t\t\t\tPerMonthly:       \"/ month\",\n\t\t\t\t\tPriceAnnually:    \"$ 0\",\n\t\t\t\t\tPerAnnually:      \"/ month\",\n\t\t\t\t\tIncludedFeatures: []string{\"Feature 1\", \"Feature 2\", \"Feature 3\"},\n\t\t\t\t\tExcludedFeatures: []string{\"Feature 4\", \"Feature 5\"},\n\t\t\t\t\tCallToAction: components.PriceButtonProps{\n\t\t\t\t\t\tLabel: \"Start free\",\n\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\"class\": \"btn btn-outline mt-8\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tTitle:            \"Starter\",\n\t\t\t\t\tDescription:      \"Starter plan\",\n\t\t\t\t\tPriceMonthly:     \"$ 12\",\n\t\t\t\t\tPerMonthly:       \"/ month\",\n\t\t\t\t\tPriceAnnually:    \"$ 10\",\n\t\t\t\t\tPerAnnually:      \"/ month\",\n\t\t\t\t\tIncludedFeatures: []string{\"Feature 1\", \"Feature 2\", \"Feature 3\"},\n\t\t\t\t\tExcludedFeatures: []string{\"Feature 4\", \"Feature 5\"},\n\t\t\t\t\tCallToAction: components.PriceButtonProps{\n\t\t\t\t\t\tLabel: \"Get started\",\n\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\"class\": \"btn btn-primary mt-8\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tTitle:            \"Professional\",\n\t\t\t\t\tDescription:      \"Professional plan\",\n\t\t\t\t\tPriceMonthly:     \"$ 20\",\n\t\t\t\t\tPerMonthly:       \"/ month\",\n\t\t\t\t\tPriceAnnually:    \"$ 16\",\n\t\t\t\t\tPerAnnually:      \"/ month\",\n\t\t\t\t\tPromotion:        \"Popular\",\n\t\t\t\t\tIncludedFeatures: []string{\"Feature 1\", \"Feature 2\", \"Feature 3\"},\n\t\t\t\t\tExcludedFeatures: []string{\"Feature 4\", \"Feature 5\"},\n\t\t\t\t\tCallToAction: components.PriceButtonProps{\n\t\t\t\t\t\tLabel: \"Get started\",\n\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\"class\": \"btn btn-primary mt-8\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tTitle:            \"Ultimate\",\n\t\t\t\t\tDescription:      \"Ultimate plan\",\n\t\t\t\t\tPriceMonthly:     \"$ 30\",\n\t\t\t\t\tPerMonthly:       \"/ month\",\n\t\t\t\t\tPriceAnnually:    \"$ 25\",\n\t\t\t\t\tPerAnnually:      \"/ month\",\n\t\t\t\t\tIncludedFeatures: []string{\"Feature 1\", \"Feature 2\", \"Feature 3\", \"Feature 4\", \"Feature 5\"},\n\t\t\t\t\tCallToAction: components.PriceButtonProps{\n\t\t\t\t\t\tLabel: \"Get started\",\n\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\"class\": \"btn btn-primary mt-8\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "internal/views/examples/radio.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Different size radio groups\ntempl DefaultRadio() {\n\t<div class=\"max-w-xs mx-auto pt-4\">\n\t\t@components.Radio(\n\t\t\tcomponents.RadioProps{\n\t\t\t\tName: \"my-radio-group1\",\n\t\t\t\tValues: map[string]string{\n\t\t\t\t\t\"Apples\":  \"apples\",\n\t\t\t\t\t\"Oranges\": \"oranges\",\n\t\t\t\t},\n\t\t\t\tSize: \"xs\",\n\t\t\t},\n\t\t)\n\t\t<div class=\"divider\"></div>\n\t\t@components.Radio(\n\t\t\tcomponents.RadioProps{\n\t\t\t\tName: \"my-radio-group1\",\n\t\t\t\tValues: map[string]string{\n\t\t\t\t\t\"Apples\":  \"apples\",\n\t\t\t\t\t\"Oranges\": \"oranges\",\n\t\t\t\t},\n\t\t\t\tSize: \"sm\",\n\t\t\t},\n\t\t)\n\t\t<div class=\"divider\"></div>\n\t\t@components.Radio(\n\t\t\tcomponents.RadioProps{\n\t\t\t\tName: \"my-radio-group1\",\n\t\t\t\tValues: map[string]string{\n\t\t\t\t\t\"Apples\":  \"apples\",\n\t\t\t\t\t\"Oranges\": \"oranges\",\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t\t<div class=\"divider\"></div>\n\t\t@components.Radio(\n\t\t\tcomponents.RadioProps{\n\t\t\t\tName: \"my-radio-group1\",\n\t\t\t\tValues: map[string]string{\n\t\t\t\t\t\"Apples\":  \"apples\",\n\t\t\t\t\t\"Oranges\": \"oranges\",\n\t\t\t\t},\n\t\t\t\tSize: \"lg\",\n\t\t\t},\n\t\t)\n\t\t<div class=\"divider\"></div>\n\t\t@components.Radio(\n\t\t\tcomponents.RadioProps{\n\t\t\t\tName: \"my-radio-group1\",\n\t\t\t\tValues: map[string]string{\n\t\t\t\t\t\"Apples\":  \"apples\",\n\t\t\t\t\t\"Oranges\": \"oranges\",\n\t\t\t\t},\n\t\t\t\tSize: \"xl\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Primary radio group\ntempl PrimaryRadio() {\n\t<div class=\"max-w-xs mx-auto pt-4\">\n\t\t@components.Radio(\n\t\t\tcomponents.RadioProps{\n\t\t\t\tName: \"my-radio-group2\",\n\t\t\t\tValues: map[string]string{\n\t\t\t\t\t\"Apples\":  \"apples\",\n\t\t\t\t\t\"Oranges\": \"oranges\",\n\t\t\t\t\t\"And something truly special here to see how this works with a longer key\": \"blaaaaa\",\n\t\t\t\t},\n\t\t\t\tClass: \"radio-primary\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/range.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Range component using alpine.js\ntempl BasicRange() {\n\t<div class=\"max-w-sm mx-auto pt-4 space-y-2\">\n\t\t@components.Range(\n\t\t\tcomponents.RangeProps{\n\t\t\t\tName:  \"my-range\",\n\t\t\t\tValue: 25,\n\t\t\t\tMin:   0,\n\t\t\t\tMax:   100,\n\t\t\t\tStep:  5,\n\t\t\t\tSize:  \"xs\",\n\t\t\t},\n\t\t)\n\t\t@components.Range(\n\t\t\tcomponents.RangeProps{\n\t\t\t\tName:  \"my-range\",\n\t\t\t\tValue: 25,\n\t\t\t\tMin:   0,\n\t\t\t\tMax:   100,\n\t\t\t\tStep:  5,\n\t\t\t\tSize:  \"sm\",\n\t\t\t},\n\t\t)\n\t\t@components.Range(\n\t\t\tcomponents.RangeProps{\n\t\t\t\tName:  \"my-range\",\n\t\t\t\tValue: 25,\n\t\t\t\tMin:   0,\n\t\t\t\tMax:   100,\n\t\t\t\tStep:  5,\n\t\t\t},\n\t\t)\n\t\t@components.Range(\n\t\t\tcomponents.RangeProps{\n\t\t\t\tName:  \"my-range\",\n\t\t\t\tValue: 25,\n\t\t\t\tMin:   0,\n\t\t\t\tMax:   100,\n\t\t\t\tStep:  5,\n\t\t\t\tSize:  \"lg\",\n\t\t\t},\n\t\t)\n\t\t@components.Range(\n\t\t\tcomponents.RangeProps{\n\t\t\t\tName:  \"my-range\",\n\t\t\t\tValue: 25,\n\t\t\t\tMin:   0,\n\t\t\t\tMax:   100,\n\t\t\t\tStep:  5,\n\t\t\t\tSize:  \"xl\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Range component using datastar.js\ntempl DatastarRange() {\n\t<div class=\"max-w-sm mx-auto pt-4\">\n\t\t@components.DatastarRange(\n\t\t\tcomponents.RangeProps{\n\t\t\t\tName:  \"my-range\",\n\t\t\t\tValue: 25,\n\t\t\t\tMin:   0,\n\t\t\t\tMax:   100,\n\t\t\t\tStep:  5,\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/rating.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Rating from 1 to 5\ntempl RatingFromOneToFive() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Rating(\n\t\t\tcomponents.RatingProps{\n\t\t\t\tName: \"my-rating\",\n\t\t\t\tMin:  1,\n\t\t\t\tMax:  5,\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Rating from 0 to 5\ntempl RatingFromZeroToFive() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Rating(\n\t\t\tcomponents.RatingProps{\n\t\t\t\tName: \"my-rating2\",\n\t\t\t\tMin:  0,\n\t\t\t\tMax:  5,\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/select.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Different size selects\ntempl DifferentSizeSelects() {\n\t<div class=\"max-w-xs mx-auto pt-4\">\n\t\t@components.Select(\n\t\t\tcomponents.SelectProps{\n\t\t\t\tLabel: \"Make a choice\",\n\t\t\t\tName:  \"my-select\",\n\t\t\t\tOptions: []components.SelectOption{\n\t\t\t\t\t{Label: \"Which one?\", Selected: true, Disabled: true},\n\t\t\t\t\t{Label: \"Apples\", Value: \"apples\"},\n\t\t\t\t\t{Label: \"Oranges\", Value: \"oranges\"},\n\t\t\t\t},\n\t\t\t\tSize: \"xs\",\n\t\t\t},\n\t\t)\n\t\t@components.Select(\n\t\t\tcomponents.SelectProps{\n\t\t\t\tLabel: \"Make a choice\",\n\t\t\t\tName:  \"my-select\",\n\t\t\t\tOptions: []components.SelectOption{\n\t\t\t\t\t{Label: \"Which one?\", Selected: true, Disabled: true},\n\t\t\t\t\t{Label: \"Apples\", Value: \"apples\"},\n\t\t\t\t\t{Label: \"Oranges\", Value: \"oranges\"},\n\t\t\t\t},\n\t\t\t\tSize: \"sm\",\n\t\t\t},\n\t\t)\n\t\t@components.Select(\n\t\t\tcomponents.SelectProps{\n\t\t\t\tLabel: \"Make a choice\",\n\t\t\t\tName:  \"my-select\",\n\t\t\t\tOptions: []components.SelectOption{\n\t\t\t\t\t{Label: \"Which one?\", Selected: true, Disabled: true},\n\t\t\t\t\t{Label: \"Apples\", Value: \"apples\"},\n\t\t\t\t\t{Label: \"Oranges\", Value: \"oranges\"},\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t\t@components.Select(\n\t\t\tcomponents.SelectProps{\n\t\t\t\tLabel: \"Make a choice\",\n\t\t\t\tName:  \"my-select\",\n\t\t\t\tOptions: []components.SelectOption{\n\t\t\t\t\t{Label: \"Which one?\", Selected: true, Disabled: true},\n\t\t\t\t\t{Label: \"Apples\", Value: \"apples\"},\n\t\t\t\t\t{Label: \"Oranges\", Value: \"oranges\"},\n\t\t\t\t},\n\t\t\t\tSize: \"lg\",\n\t\t\t},\n\t\t)\n\t\t@components.Select(\n\t\t\tcomponents.SelectProps{\n\t\t\t\tLabel: \"Make a choice\",\n\t\t\t\tName:  \"my-select\",\n\t\t\t\tOptions: []components.SelectOption{\n\t\t\t\t\t{Label: \"Which one?\", Selected: true, Disabled: true},\n\t\t\t\t\t{Label: \"Apples\", Value: \"apples\"},\n\t\t\t\t\t{Label: \"Oranges\", Value: \"oranges\"},\n\t\t\t\t},\n\t\t\t\tSize: \"xl\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Cascading select\ntempl CascadingSelect() {\n\t<div class=\"max-w-xs mx-auto py-8\">\n\t\t@components.Select(\n\t\t\tcomponents.SelectProps{\n\t\t\t\tLabel: \"Make\",\n\t\t\t\tName:  \"make\",\n\t\t\t\tOptions: []components.SelectOption{\n\t\t\t\t\t{Label: \"Audi\", Value: \"audi\"},\n\t\t\t\t\t{Label: \"BMW\", Value: \"bmw\"},\n\t\t\t\t\t{Label: \"Toyota\", Value: \"toyota\"},\n\t\t\t\t},\n\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\"hx-get\":    \"/models\",\n\t\t\t\t\t\"hx-target\": \"#models\",\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t\t@components.Select(\n\t\t\tcomponents.SelectProps{\n\t\t\t\tLabel: \"Model\",\n\t\t\t\tName:  \"model\",\n\t\t\t\tOptions: []components.SelectOption{\n\t\t\t\t\t{Label: \"A1\", Value: \"a1\"},\n\t\t\t\t\t{Label: \"A4\", Value: \"a4\"},\n\t\t\t\t\t{Label: \"A6\", Value: \"a6\"},\n\t\t\t\t},\n\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\"id\": \"models\",\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/skeleton.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl SkeletonExample() {\n\t<div class=\"max-w-xs mx-auto pt-4\">\n\t\t@components.Skeleton()\n\t</div>\n}"
  },
  {
    "path": "internal/views/examples/stats.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicStats() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Stats() {\n\t\t\t@components.Stat(components.StatProps{\n\t\t\t\tTitle:       \"Downloads\",\n\t\t\t\tValue:       \"31k\",\n\t\t\t\tDescription: \"Jan 1st - Feb 1st\",\n\t\t\t})\n\t\t\t@components.Stat(components.StatProps{\n\t\t\t\tTitle:       \"New Users\",\n\t\t\t\tValue:       \"4,200\",\n\t\t\t\tDescription: \"↗︎ 400 (22%)\",\n\t\t\t})\n\t\t\t@components.Stat(components.StatProps{\n\t\t\t\tTitle:       \"New Registers\",\n\t\t\t\tValue:       \"1,200\",\n\t\t\t\tDescription: \"↘︎ 90 (14%)\",\n\t\t\t})\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/status.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// 404 Not Found status\ntempl StatusNotFound() {\n\t@components.Status(components.StatusProps{\n\t\tCode:              404,\n\t\tTitle:             \"Not Found\",\n\t\tDescription:       \"Looks like there's nothing here...\",\n\t\tReturnButtonLabel: \"Go back\",\n\t})\n}\n\n// example\n// 403 Forbidden status\ntempl StatusForbidden() {\n\t@components.Status(components.StatusProps{\n\t\tCode:              403,\n\t\tTitle:             \"Forbidden\",\n\t\tDescription:       \"Invalid permissions to view this page.\",\n\t\tReturnButtonLabel: \"Go back\",\n\t})\n}\n\n// example\n// 401 Unauthorized status\ntempl StatusUnauthorized() {\n\t@components.Status(components.StatusProps{\n\t\tCode:              401,\n\t\tTitle:             \"Unauthorized\",\n\t\tDescription:       \"This page is only available to authenticated users.\",\n\t\tReturnButtonLabel: \"Go back\",\n\t})\n}\n\n// example\n// 500 Internal Server Error status\ntempl StatusInternalServerError() {\n\t@components.Status(components.StatusProps{\n\t\tCode:              500,\n\t\tTitle:             \"Internal Server Error\",\n\t\tDescription:       \"Something went terribly wrong...\",\n\t\tReturnButtonLabel: \"Go back\",\n\t})\n}\n"
  },
  {
    "path": "internal/views/examples/steps.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicSteps() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Steps() {\n\t\t\t@components.Step(components.StepProps{Label: \"Register\", Done: true})\n\t\t\t@components.Step(components.StepProps{Label: \"Choose plan\", Done: true})\n\t\t\t@components.Step(components.StepProps{Label: \"Purchase\"})\n\t\t\t@components.Step(components.StepProps{Label: \"Receive product\"})\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/swap.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicSwap() {\n\t<div class=\"flex justify-center items-center h-20\">\n\t\t@components.Swap(\n\t\t\tcomponents.SwapProps{\n\t\t\t\tOn:    SwapExampleOn(),\n\t\t\t\tOff:   SwapExampleOff(),\n\t\t\t\tClass: \"swap-flip\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\ntempl SwapExampleOn() {\n\t<span class=\"font-bold text-success\">ON</span>\n}\n\ntempl SwapExampleOff() {\n\t<span class=\"font-bold text-base-content/70\">OFF</span>\n}\n"
  },
  {
    "path": "internal/views/examples/table.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicTable() {\n\t@components.Table(\n\t\t[]templ.Component{\n\t\t\tcomponents.Checkbox(\n\t\t\t\tcomponents.CheckboxProps{\n\t\t\t\t\tName: \"all\",\n\t\t\t\t},\n\t\t\t),\n\t\t\tcomponents.PlainText(\"Name\"),\n\t\t\tcomponents.PlainText(\"Email\"),\n\t\t},\n\t\t[]templ.Component{\n\t\t\tTableExampleRow(\"John Doe\", \"john.doe@example.com\"),\n\t\t\tTableExampleRow(\"Jane Doe\", \"Jane.doe@example.com\"),\n\t\t\tTableExampleRow(\"Jim Smith\", \"jim.smith@example.com\"),\n\t\t\tTableExampleRow(\"Julie Smith\", \"julie.smith@example.com\"),\n\t\t},\n\t\tnil,\n\t)\n}\n\ntempl TableExampleRow(name, email string) {\n\t<tr>\n\t\t<td>\n\t\t\t@components.Checkbox(components.CheckboxProps{Name: email})\n\t\t</td>\n\t\t<td>\n\t\t\t@components.PlainText(name)\n\t\t</td>\n\t\t<td>\n\t\t\t@components.PlainText(email)\n\t\t</td>\n\t</tr>\n}\n"
  },
  {
    "path": "internal/views/examples/tabs.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicTabs() {\n\t@components.Tabs(\n\t\tcomponents.TabsProps{\n\t\t\tName:         \"basic-tabs\",\n\t\t\tClass:        \"tabs-border\",\n\t\t\tContentClass: \"bg-base-100 py-8\",\n\t\t\tTabs: []components.TabProps{\n\t\t\t\t{\n\t\t\t\t\tLabel:   \"Home\",\n\t\t\t\t\tContent: homeTabContent(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLabel:   \"Info\",\n\t\t\t\t\tContent: infoTabContent(),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tLabel:   \"Stats\",\n\t\t\t\t\tContent: statsTabContent(),\n\t\t\t\t},\n\t\t\t},\n\t\t})\n}\n\ntempl homeTabContent() {\n\t<p>This is the home tab</p>\n}\n\ntempl infoTabContent() {\n\t<p>This is the info tab</p>\n}\n\ntempl statsTabContent() {\n\t<p>This is the stats tab</p>\n}\n"
  },
  {
    "path": "internal/views/examples/testimonial.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl TestimonialGridExample() {\n\t@components.TestimonialGrid(\n\t\t\"Read what our customers think\",\n\t\tcomponents.TestimonialProps{\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 5,\n\t\t\t\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas odio minus \nnecessitatibus perspiciatis, aliquid repellat iste.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(\n\t\t\t\t\tcomponents.AvatarProps{\n\t\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\t\tSource:         \"/static/images/avatar.jpg\"},\n\t\t\t\t),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 4,\n\t\t\t\tContent: `maiores quia dicta magni ex labore? Lorem ipsum dolor \nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas odio minus \nnecessitatibus perspiciatis, aliquid repellat iste.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 3,\n\t\t\t\tContent: `Iure impedit, placeat sed provident enim fuga possimus \nducimus est iusto inventore earum aliquid officia minus, maiores quia dicta magni \nex labore? Lorem ipsum dolor sit amet consectetur adipisicing elit. Libero maxime \nquos laboriosam natus illum similique id nam, rerum, sunt veritatis dolorum \naccusamus voluptas odio minus necessitatibus perspiciatis, aliquid repellat iste.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 5,\n\t\t\t\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas odio minus \nnecessitatibus perspiciatis, aliquid repellat iste.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:    \"Jane Doe\",\n\t\t\t\tRating:  5,\n\t\t\t\tContent: \"Lorem ipsum dolor sit amet consectetur adipisicing elit.\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 1,\n\t\t\t\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \nearum aliquid officia minus.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 2,\n\t\t\t\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \nsit amet consectetur adipisicing elit.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 5,\n\t\t\t\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore\nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \nsimilique id nam, rerum, sunt veritatis.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 4,\n\t\t\t\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \nsimilique id nam, rerum.`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tAvatar: components.Avatar(components.AvatarProps{\n\t\t\t\t\tContainerClass: \"rounded h-20\",\n\t\t\t\t\tSource:         \"/static/images/avatar.jpg\",\n\t\t\t\t}),\n\t\t\t\tName:   \"Jane Doe\",\n\t\t\t\tRating: 4,\n\t\t\t\tContent: `Lorem ipsum dolor sit amet consectetur adipisicing elit. \nIure impedit, placeat sed provident enim fuga possimus ducimus est iusto inventore \nearum aliquid officia minus, maiores quia dicta magni ex labore? Lorem ipsum dolor \nsit amet consectetur adipisicing elit. Libero maxime quos laboriosam natus illum \nsimilique id nam, rerum, sunt veritatis dolorum accusamus voluptas.`,\n\t\t\t},\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "internal/views/examples/text_rotate.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl TextRotateExample() {\n\t@components.TextRotate(\n\t\tcomponents.TextRotateProps{\n\t\t\tClass: \"text-5xl font-bold\",\n\t\t\tItems: []components.TextRotateItem{\n\t\t\t\t{Text: \"ONE\", Class: \"text-primary\"},\n\t\t\t\t{Text: \"TWO\", Class: \"text-accent\"},\n\t\t\t\t{Text: \"THREE\", Class: \"text-secondary\"},\n\t\t\t},\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "internal/views/examples/textarea.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Basic textarea\ntempl BasicTextarea() {\n\t<div class=\"pt-4\">\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tName:  \"description\",\n\t\t\t\tClass: \"textarea-bordered resize-none\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Different sizes\ntempl DifferentSizeTextareas() {\n\t<div class=\"pt-4\">\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tClass: \"textarea-bordered resize-none\",\n\t\t\t\tValue: \"Extra small\",\n\t\t\t\tSize:  \"xs\",\n\t\t\t},\n\t\t)\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tClass: \"textarea-bordered resize-none\",\n\t\t\t\tValue: \"Small\",\n\t\t\t\tSize:  \"sm\",\n\t\t\t},\n\t\t)\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tClass: \"textarea-bordered resize-none\",\n\t\t\t\tValue: \"Medium\",\n\t\t\t},\n\t\t)\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tClass: \"textarea-bordered resize-none\",\n\t\t\t\tValue: \"Large\",\n\t\t\t\tSize:  \"lg\",\n\t\t\t},\n\t\t)\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tClass: \"textarea-bordered resize-none\",\n\t\t\t\tValue: \"Extra Large\",\n\t\t\t\tSize:  \"xl\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Textarea with error\ntempl BasicTextareaWithError() {\n\t<div class=\"pt-4\">\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tName:  \"description\",\n\t\t\t\tErr:   \"Description cannot be empty\",\n\t\t\t\tClass: \"textarea-bordered resize-none\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/time_slot_picker.templ",
    "content": "package examples\n\nimport \"time\"\n\n// example\n// Basic time slot picker\ntempl BasicTimeSlotPicker() {\n\t<div hx-get={ \"/timeslotpicker?date=\" + time.Now().UTC().Format(\"2006-01-02\") } hx-trigger=\"intersect\" hx-swap=\"outerHTML\"></div>\n}\n"
  },
  {
    "path": "internal/views/examples/timeline.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicTimeline() {\n\t<div class=\"flex justify-center items-center pt-4\">\n\t\t@components.Timeline(\n\t\t\tcomponents.TimelineProps{\n\t\t\t\t{Start: \"1984\", Middle: components.TimelineCheckbox(true), End: \"First Macintosh computer\"},\n\t\t\t\t{Start: \"1998\", Middle: components.TimelineCheckbox(true), End: \"iMac\"},\n\t\t\t\t{Start: \"2001\", Middle: components.TimelineCheckbox(false), End: \"iPod\"},\n\t\t\t\t{Start: \"2007\", Middle: components.TimelineCheckbox(false), End: \"iPhone\"},\n\t\t\t\t{Start: \"2015\", Middle: components.TimelineCheckbox(false), End: \"Apple Watch\"},\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/toast.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Info-type toast\ntempl InfoToast() {\n\t<div class=\"relative min-h-60\">\n\t\t@components.Toast(\n\t\t\tcomponents.ToastProps{\n\t\t\t\tName:       \"info-toast\",\n\t\t\t\tToastClass: \"absolute toast-end toast-top\",\n\t\t\t\tAlertClass: \"alert-info\",\n\t\t\t},\n\t\t) {\n\t\t\t<span>Info toast</span>\n\t\t}\n\t</div>\n}\n\n// example\n// Warning-type toast\ntempl WarningToast() {\n\t<div class=\"relative min-h-60\">\n\t\t@components.Toast(\n\t\t\tcomponents.ToastProps{\n\t\t\t\tName:       \"warning-toast\",\n\t\t\t\tToastClass: \"absolute toast-end toast-bottom\",\n\t\t\t\tAlertClass: \"alert-warning\",\n\t\t\t},\n\t\t) {\n\t\t\t<span>Warning toast</span>\n\t\t}\n\t</div>\n}\n\n// example\n// Error-type toast\ntempl ErrorToast() {\n\t<div class=\"relative min-h-60\">\n\t\t@components.Toast(\n\t\t\tcomponents.ToastProps{\n\t\t\t\tName:       \"error-toast\",\n\t\t\t\tToastClass: \"absolute toast-center toast-top\",\n\t\t\t\tAlertClass: \"alert-error\",\n\t\t\t},\n\t\t) {\n\t\t\t<span>Error toast</span>\n\t\t}\n\t</div>\n}\n\n// example\n// Info-type toast with button to remove it\ntempl InfoToastConfirm() {\n\t<div class=\"relative min-h-60\">\n\t\t@components.Toast(components.ToastProps{\n\t\t\tName:       \"error-toast\",\n\t\t\tToastClass: \"absolute toast-end toast-top\",\n\t\t\tAlertClass: \"alert-info\",\n\t\t},\n\t\t) {\n\t\t\t<span>Info toast</span>\n\t\t\t<button id=\"toast-remover-btn\" class=\"btn btn-info\">OK</button>\n\t\t\t<script>\n                ((toast) => {\n                    document.getElementById(\"toast-remover-btn\").addEventListener(\"click\", () => {\n                        toast.remove()\n                    })\n                })(document.currentScript.closest(\"div.toast\"))\n            </script>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/toggle.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Different size toggles\ntempl DifferentSizeToggles() {\n\t<div class=\"max-w-52 mx-auto pt-4 space-y-2\">\n\t\t@components.Toggle(\n\t\t\tcomponents.ToggleProps{\n\t\t\t\tBefore: \"Check me out\",\n\t\t\t\tName:   \"checkbox1\",\n\t\t\t\tSize:   \"xs\",\n\t\t\t},\n\t\t)\n\t\t@components.Toggle(\n\t\t\tcomponents.ToggleProps{\n\t\t\t\tBefore: \"Check me out\",\n\t\t\t\tName:   \"checkbox1\",\n\t\t\t\tSize:   \"sm\",\n\t\t\t},\n\t\t)\n\t\t@components.Toggle(\n\t\t\tcomponents.ToggleProps{\n\t\t\t\tBefore: \"Check me out\",\n\t\t\t\tName:   \"checkbox1\",\n\t\t\t},\n\t\t)\n\t\t@components.Toggle(\n\t\t\tcomponents.ToggleProps{\n\t\t\t\tBefore: \"Check me out\",\n\t\t\t\tName:   \"checkbox1\",\n\t\t\t\tSize:   \"lg\",\n\t\t\t},\n\t\t)\n\t\t@components.Toggle(\n\t\t\tcomponents.ToggleProps{\n\t\t\t\tBefore: \"Check me out\",\n\t\t\t\tName:   \"checkbox1\",\n\t\t\t\tSize:   \"xl\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Primary toggle with label after\ntempl PrimaryToggle() {\n\t<div class=\"max-w-52 mx-auto pt-4\">\n\t\t@components.Toggle(\n\t\t\tcomponents.ToggleProps{\n\t\t\t\tAfter:   \"Check me out\",\n\t\t\t\tName:    \"checkbox2\",\n\t\t\t\tChecked: true,\n\t\t\t\tClass:   \"toggle-primary\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\n// Primary toggle with highlight\ntempl PrimaryToggleWithHighlight() {\n\t<div class=\"max-w-xs mx-auto pt-4\">\n\t\t@components.Toggle(\n\t\t\tcomponents.ToggleProps{\n\t\t\t\tBefore:    \"Paid monthly\",\n\t\t\t\tAfter:     \"Paid annually\",\n\t\t\t\tName:      \"checkbox3\",\n\t\t\t\tHighlight: true,\n\t\t\t\tClass:     \"toggle-primary\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/examples/tooltip.templ",
    "content": "package examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\n// Basic tooltip at the top\ntempl BasicTooltip() {\n\t<div class=\"min-h-60 flex justify-center items-center\">\n\t\t@components.Tooltip(components.TooltipProps{Tip: \"Hello\"}) {\n\t\t\t<button class=\"btn\">Hover me</button>\n\t\t}\n\t</div>\n}\n\n// example\n// Error-type tooltip on the bottom\ntempl BasicTooltipError() {\n\t<div class=\"min-h-60 flex justify-center items-center\">\n\t\t@components.Tooltip(\n\t\t\tcomponents.TooltipProps{\n\t\t\t\tTip:   \"Hello\",\n\t\t\t\tClass: \"tooltip-bottom tooltip-error\",\n\t\t\t},\n\t\t) {\n\t\t\t<button class=\"btn\">Hover me</button>\n\t\t}\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/pages/base.templ",
    "content": "package pages\n\nimport (\n\t\"fmt\"\n\t\"github.com/haatos/goshipit/internal\"\n\t\"github.com/haatos/goshipit/internal/model\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n\t\"github.com/haatos/goshipit/internal/views/examples\"\n\t\"time\"\n)\n\ntype Script struct {\n\tSource string\n\tDefer  bool\n}\n\ntempl DefaultHead() {\n\t@Head(\n\t\t\"goship.it\",\n\t\t[]string{\n\t\t\t\"/static/css/tw.css\",\n\t\t\t\"/static/css/custom.css\",\n\t\t\t\"/static/css/chroma.css\",\n\t\t},\n\t\t[]Script{\n\t\t\t{Source: \"/static/js/htmx.min.js\"},\n\t\t},\n\t)\n}\n\ntempl Head(title string, stylesheets []string, scripts []Script) {\n\t<head>\n\t\t<meta charset=\"UTF-8\"/>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>\n\t\t<style>\n\t\t\t@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@500&family=Montserrat:ital,wght@0,100..900;1,100..900&Saira:ital,wght@900&display=swap');\n\t\t</style>\n\t\tfor _, st := range stylesheets {\n\t\t\t<link rel=\"stylesheet\" href={ st }/>\n\t\t}\n\t\tfor _, sc := range scripts {\n\t\t\t<script if sc.Defer {\n\tdefer=\"true\"\n} src={ sc.Source }>\n</script>\n\t\t}\n\t\t<title>{ title }</title>\n\t\t<script>\n            function applyTheme(theme) {\n                document.documentElement.setAttribute('data-theme', theme);\n            }\n\n            function checkAndApplyTheme() {\n                if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n                    applyTheme('night');\n                } else {\n                    applyTheme('light');\n                }\n            }\n            checkAndApplyTheme();\n            window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', checkAndApplyTheme);\n        </script>\n\t</head>\n}\n\ntempl SideNavLayout(head templ.Component) {\n\t<!DOCTYPE html>\n\t<html lang=\"en\">\n\t\t@DefaultHead()\n\t\t<body>\n\t\t\t<div class=\"drawer xl:drawer-open\">\n\t\t\t\t<input id=\"nav-drawer\" type=\"checkbox\" class=\"drawer-toggle\"/>\n\t\t\t\t<div class=\"drawer-content\">\n\t\t\t\t\t<div class=\"flex space-x-1 items-center\">\n\t\t\t\t\t\t<label for=\"nav-drawer\" class=\"cursor-pointer btn btn-ghost drawer-button xl:hidden\">\n\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\t\tclass=\"h-5 w-5\"\n\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\td=\"M4 6h16M4 12h8m-8 6h16\"\n\t\t\t\t\t\t\t\t></path>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"/\"\n\t\t\t\t\t\t\tclass=\"group btn !shadow-none !bg-transparent !border-none flex items-center xl:hidden\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<img class=\"h-10\" src=\"/static/images/goshipit-logo.png\" alt=\"goship.it\"/>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<main class=\"w-full max-w-screen-lg min-h-svh pl-8 pr-8 xl:pr-0\">\n\t\t\t\t\t\t{ children... }\n\t\t\t\t\t</main>\n\t\t\t\t\t@components.Footer(\n\t\t\t\t\t\tcomponents.FooterProps{\n\t\t\t\t\t\t\tName:      \"Haatos Ltd\",\n\t\t\t\t\t\t\tCopyright: fmt.Sprintf(\"%s\", time.Now().UTC().Format(\"2006\")),\n\t\t\t\t\t\t\tAnchors: []components.AnchorProps{\n\t\t\t\t\t\t\t\t{LeftIcon: examples.GithubIcon(), Href: \"https://github.com/haatos\"},\n\t\t\t\t\t\t\t\t{LeftIcon: examples.LinkedInIcon(), Href: \"https://linkedin.com/in/tomihaapalainen\"},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}) {\n\t\t\t\t\t\t@components.FooterNav(\n\t\t\t\t\t\t\t\"Links\",\n\t\t\t\t\t\t\t[]components.AnchorProps{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel: \"DaisyUI 4 components\",\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"name\": \"hx-anchor\",\n\t\t\t\t\t\t\t\t\t\t\"href\": \"https://old.goship.it\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel: \"Getting started\",\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\t\t\"hx-get\":      \"/get-started\",\n\t\t\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel: \"Types\",\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\t\t\"hx-get\":      \"/types\",\n\t\t\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel: \"CLI\",\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\t\t\"hx-get\":      \"/cli\",\n\t\t\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel:    \"GitHub\",\n\t\t\t\t\t\t\t\t\tLeftIcon: examples.GithubIcon(),\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"href\": \"https://github.com/haatos/goshipit\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel: \"About the creator\",\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\t\t\"hx-get\":      \"/about\",\n\t\t\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t@components.FooterNav(\n\t\t\t\t\t\t\t\"Legal\",\n\t\t\t\t\t\t\t[]components.AnchorProps{\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel: \"Privacy policy\",\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\t\t\"hx-get\":      \"/privacy\",\n\t\t\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tLabel: \"Terms of Service\",\n\t\t\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\t\t\"hx-get\":      \"/terms-of-service\",\n\t\t\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t\t@drawerSide(\n\t\t\t\t\t[]components.AnchorProps{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLabel: \"DaisyUI 4 components\",\n\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\"name\": \"hx-anchor\",\n\t\t\t\t\t\t\t\t\"href\": \"https://old.goship.it\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLabel: \"Getting started\",\n\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\"hx-get\":      \"/get-started\",\n\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLabel: \"Types\",\n\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\"hx-get\":      \"/types\",\n\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLabel: \"CLI\",\n\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\"name\":        \"hx-anchor\",\n\t\t\t\t\t\t\t\t\"hx-get\":      \"/cli\",\n\t\t\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLabel:    \"GitHub\",\n\t\t\t\t\t\t\tLeftIcon: examples.GithubIcon(),\n\t\t\t\t\t\t\tAttrs: templ.Attributes{\n\t\t\t\t\t\t\t\t\"href\": \"https://github.com/haatos/goshipit\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t</div>\n\t\t\t<script>\n\t\t\t\t// check request status before htmx swap\n\t\t\t\t// set swapping incoming html to true and isError to false\n\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", function() {\n\t\t\t\t\tdocument.addEventListener(\"htmx:beforeSwap\", function(evt) {\n\t\t\t\t\t\tif (evt.detail.xhr.status === 422 || evt.detail.xhr.status === 403 || evt.detail.xhr.status == 500) {\n\t\t\t\t\t\t\tevt.detail.shouldSwap = true;\n\t\t\t\t\t\t\tevt.detail.isError = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t</script>\n\t\t\t<script>\n\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", () => {\n\t\t\t\t\tdocument.addEventListener(\"htmx:afterRequest\", (evt) => {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tevt.detail.successful &&\n\t\t\t\t\t\t\tevt.detail.elt.getAttribute(\"name\") === \"hx-anchor\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tdocument.querySelector(\"input.drawer-toggle\").checked = false\n\t\t\t\t\t\t\tdocument.querySelector(\"body\").scrollIntoView({behavior: \"smooth\", block: \"start\"})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t</script>\n\t\t\t<script>\n\t\t\t\tfunction activeMenuLink() {\n\t\t\t\t   document.querySelectorAll(\".menu a\").forEach(link => link.classList.remove(\"menu-active\"));\n\t\t\t\t   const activeLink = document.querySelector(`.menu a[hx-get=\"${window.location.pathname}\"]`);\n\t\t\t\t   if (activeLink) {\n\t\t\t\t\t   activeLink.classList.add(\"menu-active\");\n\t\t\t\t   }\n\t\t\t\t}\n\n\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", () => {\n\t\t\t\t\tdocument.addEventListener(\"htmx:afterSwap\", function(event) {\n\t\t\t\t\t\tactiveMenuLink()\n\t\t\t\t\t})\n\n\t\t\t\t\tactiveMenuLink()\n\t\t\t\t})\n\t\t\t</script>\n\t\t\t<script>\n\t\t\t\tfunction reloadStylesheetsIfNeeded() {\n\t\t\t\t\t// Check if styles are missing\n\t\t\t\t\tconst bodyStyles = window.getComputedStyle(document.body);\n\t\t\t\t\tif (!bodyStyles || bodyStyles.display === 'none' || bodyStyles.display === '') {\n\t\t\t\t\t// Styles are missing, reload all stylesheets\n\t\t\t\t\tconst stylesheets = document.querySelectorAll('link[rel=\"stylesheet\"]');\n\t\t\t\t\tstylesheets.forEach((stylesheet) => {\n\t\t\t\t\t\tconst href = stylesheet.getAttribute('href').split('?')[0];\n\t\t\t\t\t\tstylesheet.setAttribute('href', `${href}?reload=${Date.now()}`);\n\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Handle page show event\n\t\t\t\twindow.addEventListener('pageshow', function(event) {\n\t\t\t\t\tif (event.persisted) {\n\t\t\t\t\treloadStylesheetsIfNeeded();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Handle visibility change event\n\t\t\t\tdocument.addEventListener('visibilitychange', function() {\n\t\t\t\t\tif (document.visibilityState === 'visible') {\n\t\t\t\t\treloadStylesheetsIfNeeded();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t</script>\n\t\t</body>\n\t</html>\n}\n\ntempl drawerSide(anchors []components.AnchorProps) {\n\t<div class=\"drawer-side\">\n\t\t<label for=\"nav-drawer\" aria-label=\"close sidebar\" class=\"drawer-overlay\"></label>\n\t\t<ul class=\"menu bg-base-200 text-base-content min-h-full w-[330px] p-4 space-y-2\">\n\t\t\t<li class=\"pb-4\">\n\t\t\t\t<a href=\"/\" class=\"group hover:!bg-transparent flex justify-center items-center font-saira-black text-6xl bg-clip-text text-transparent bg-gradient-to-br from-primary/60 via-base-content to-primary/60\">\n\t\t\t\t\tGSI\n\t\t\t\t</a>\n\t\t\t</li>\n\t\t\t<div id=\"my-active-search\" class=\"pl-1\">\n\t\t\t\t@components.ActiveSearchInput(\n\t\t\t\t\tcomponents.ActiveSearchInputProps{\n\t\t\t\t\t\tID:     \"component-search-input\",\n\t\t\t\t\t\tURL:    \"/components/search\",\n\t\t\t\t\t\tTarget: \"#search-dropdown-side\",\n\t\t\t\t\t\tInputProps: components.InputProps{\n\t\t\t\t\t\t\tIcon:        searchIcon(),\n\t\t\t\t\t\t\tName:        \"search\",\n\t\t\t\t\t\t\tType:        \"search\",\n\t\t\t\t\t\t\tPlaceholder: \"Search...\",\n\t\t\t\t\t\t\tSize:        \"sm\",\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t<div class=\"relative w-full max-w-xs\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tid=\"search-dropdown-side\"\n\t\t\t\t\t\tclass=\"w-full max-w-xs absolute top-2 left-0 z-50 rounded-box bg-base-200\"\n\t\t\t\t\t></div>\n\t\t\t\t</div>\n\t\t\t\t<script>\n\t\t\t\t\tdocument.addEventListener(\"click\", (evt) => {\n\t\t\t\t\t\tlet activeSearch = evt.target.closest(\"#my-active-search\")\n\t\t\t\t\t\tif (activeSearch === null) {\n\t\t\t\t\t\t\tlet activeSearchDiv = document.getElementById(\"my-active-search\")\n\t\t\t\t\t\t\tactiveSearchDiv.querySelectorAll(\"div[name=search-list-item]\").forEach(el => {\n\t\t\t\t\t\t\t\tel.remove()\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tactiveSearchDiv.querySelector(\"form\").reset()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t</script>\n\t\t\t</div>\n\t\t\t<!-- Sidebar content here -->\n\t\t\tfor _, a := range anchors {\n\t\t\t\t<li>\n\t\t\t\t\t@components.Anchor(a)\n\t\t\t\t</li>\n\t\t\t}\n\t\t\t<div class=\"divider\"></div>\n\t\t\t<div hx-get=\"/component-anchors\" hx-swap=\"outerHTML\" hx-trigger=\"intersect once\"></div>\n\t\t</ul>\n\t</div>\n}\n\ntempl searchIcon() {\n\t<svg\n\t\tclass=\"w-5 h-5\"\n\t\tviewBox=\"0 0 32 32\"\n\t\tversion=\"1.1\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\t\txmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\"\n\t>\n\t\t<g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n\t\t\t<g class=\"fill-base-content/60\" id=\"Icon-Set\" sketch:type=\"MSLayerGroup\" transform=\"translate(-256.000000, -1139.000000)\">\n\t\t\t\t<path d=\"M269.46,1163.45 C263.17,1163.45 258.071,1158.44 258.071,1152.25 C258.071,1146.06 263.17,1141.04 269.46,1141.04 C275.75,1141.04 280.85,1146.06 280.85,1152.25 C280.85,1158.44 275.75,1163.45 269.46,1163.45 L269.46,1163.45 Z M287.688,1169.25 L279.429,1161.12 C281.591,1158.77 282.92,1155.67 282.92,1152.25 C282.92,1144.93 276.894,1139 269.46,1139 C262.026,1139 256,1144.93 256,1152.25 C256,1159.56 262.026,1165.49 269.46,1165.49 C272.672,1165.49 275.618,1164.38 277.932,1162.53 L286.224,1170.69 C286.629,1171.09 287.284,1171.09 287.688,1170.69 C288.093,1170.3 288.093,1169.65 287.688,1169.25 L287.688,1169.25 Z\" id=\"search\" sketch:type=\"MSShapeGroup\"></path>\n\t\t\t</g>\n\t\t</g>\n\t</svg>\n}\n\ntype ComponentSearchItem struct {\n\tCategory string\n\tName     string\n}\n\ntempl ComponentSearchListItems(cs []ComponentSearchItem) {\n\tfor i := range cs {\n\t\t<div name=\"search-list-item\" class=\"m-2 px-2 py-1 bg-base-100 rounded-box cursor-pointer\">\n\t\t\t<a\n\t\t\t\tname=\"component-search-anchor\"\n\t\t\t\thref={ templ.SafeURL(fmt.Sprintf(\"/components/%s/%s\", cs[i].Category, cs[i].Name)) }\n\t\t\t>\n\t\t\t\t<p class=\"text-xs text-base-content/75\">\n\t\t\t\t\t{ internal.SnakeCaseToCapitalized(cs[i].Category) }\n\t\t\t\t</p>\n\t\t\t\t<p class=\"font-bold\">\n\t\t\t\t\t{ internal.SnakeCaseToCapitalized(cs[i].Name) }\n\t\t\t\t</p>\n\t\t\t</a>\n\t\t</div>\n\t}\n}\n\ntempl ComponentAnchors(keys []string, m model.ComponentCodeMap) {\n\t<ul class=\"w-full menu\">\n\t\tfor _, k := range keys {\n\t\t\t<li>\n\t\t\t\t<h4 class=\"menu-title\">{ internal.SnakeCaseToCapitalized(k) }</h4>\n\t\t\t\t<ul>\n\t\t\t\t\tfor _, c := range m[k] {\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\tname=\"hx-anchor\"\n\t\t\t\t\t\t\t\thx-get={ fmt.Sprintf(\"/components/%s/%s\", k, c.Name) }\n\t\t\t\t\t\t\t\thx-target=\"main\"\n\t\t\t\t\t\t\t\thx-swap=\"innerHTML\"\n\t\t\t\t\t\t\t\thx-push-url=\"true\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{ c.Label }\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t</li>\n\t\t}\n\t</ul>\n}\n"
  },
  {
    "path": "internal/views/pages/cli.templ",
    "content": "package pages\n\ntempl CLIPage(html string) {\n\t@SideNavLayout(nil) {\n\t\t@CLIPageMain(html)\n\t}\n}\n\ntempl CLIPageMain(html string) {\n\t<div class=\"prose max-w-screen-lg mt-8\">\n\t\t@templ.Raw(html)\n\t</div>\n}\n"
  },
  {
    "path": "internal/views/pages/client_error.templ",
    "content": "package pages\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\ntempl NotFound() {\n\t@SideNavLayout(nil) {\n\t\t@components.Status(components.StatusProps{\n\t\t\tCode:              404,\n\t\t\tTitle:             \"Not Found\",\n\t\t\tDescription:       \"There seems to be nothing here.\",\n\t\t\tReturnButtonLabel: \"Go back home\",\n\t\t\tReturnButtonAttrs: templ.Attributes{\n\t\t\t\t\"hx-get\":      \"/\",\n\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t},\n\t\t})\n\t}\n}\n\ntempl Forbidden(message string) {\n\t@SideNavLayout(nil) {\n\t\t@components.Status(components.StatusProps{\n\t\t\tCode:              403,\n\t\t\tTitle:             \"Forbidden\",\n\t\t\tDescription:       \"Invalid permissions to acces this page.\",\n\t\t\tReturnButtonLabel: \"Go back home\",\n\t\t\tReturnButtonAttrs: templ.Attributes{\n\t\t\t\t\"hx-get\":      \"/\",\n\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t},\n\t\t})\n\t}\n}\n\ntempl Unauthorized() {\n\t@SideNavLayout(nil) {\n\t\t@components.Status(\n\t\t\tcomponents.StatusProps{\n\t\t\t\tCode:              401,\n\t\t\t\tTitle:             \"Unauthorized\",\n\t\t\t\tDescription:       \"This page is for authenticated users only.\",\n\t\t\t\tReturnButtonLabel: \"Go back home\",\n\t\t\t\tReturnButtonAttrs: templ.Attributes{\n\t\t\t\t\t\"hx-get\":      \"/\",\n\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "internal/views/pages/component.templ",
    "content": "package pages\n\nimport (\n\t\"github.com/haatos/goshipit/internal/markdown\"\n\t\"github.com/haatos/goshipit/internal/model\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n\t\"github.com/haatos/goshipit/internal/views/scripts\"\n)\n\ntempl ComponentPage(cc model.ComponentCode, examples []templ.Component) {\n\t@SideNavLayout(nil) {\n\t\t@ComponentMain(cc, examples)\n\t}\n\t@scripts.CodeCopyButtonScript()\n}\n\ntempl ComponentMain(cc model.ComponentCode, examples []templ.Component) {\n\t<div class=\"w-full min-h-svh pt-8\">\n\t\t<section class=\"relative w-full\">\n\t\t\t<h1 class=\"text-4xl font-bold pb-8\">\n\t\t\t\t{ cc.Label }\n\t\t\t\tif cc.DaisyUIURL != \"\" {\n\t\t\t\t\t@components.Anchor(components.AnchorProps{\n\t\t\t\t\t\tLabel:     \"@DaisyUI\",\n\t\t\t\t\t\tHref:      cc.DaisyUIURL,\n\t\t\t\t\t\tClass:     \"text-sm link link-primary\",\n\t\t\t\t\t\tAttrs:     templ.Attributes{\"target\": \"_blank\"},\n\t\t\t\t\t\tRightIcon: externalLinkIcon(),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t</h1>\n\t\t\t<div class=\"prose !max-w-screen-lg text-justify\">\n\t\t\t\t@templ.Raw(markdown.GetHTMLFromMarkdown([]byte(cc.Description)))\n\t\t\t</div>\n\t\t\tif cc.Code != \"\" {\n\t\t\t\t<h2 class=\"text-2xl font-bold pt-12 pb-8\">Code</h2>\n\t\t\t\t<div class=\"relative w-full flex flex-col\">\n\t\t\t\t\t@templ.Raw(markdown.GetHTMLFromMarkdown([]byte(cc.Code)))\n\t\t\t\t</div>\n\t\t\t}\n\t\t\tif len(examples) > 0 {\n\t\t\t\t<h2 class=\"text-2xl font-bold pt-12 pb-8\">Examples</h2>\n\t\t\t}\n\t\t\t<div class=\"w-full flex flex-col space-y-8\">\n\t\t\t\tfor _, example := range examples {\n\t\t\t\t\t@example\n\t\t\t\t}\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\t@scripts.HXCodeCopyButtonScript()\n}\n\ntempl externalLinkIcon() {\n\t<svg class=\"h-4 w-4 inline-block\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t<g>\n\t\t\t<path\n\t\t\t\tclass=\"stroke-primary group-hover:opacity-70\"\n\t\t\t\td=\"M10.0002 5H8.2002C7.08009 5 6.51962 5 6.0918 5.21799C5.71547 5.40973 5.40973 5.71547 5.21799 6.0918C5 6.51962 5 7.08009 5 8.2002V15.8002C5 16.9203 5 17.4801 5.21799 17.9079C5.40973 18.2842 5.71547 18.5905 6.0918 18.7822C6.5192 19 7.07899 19 8.19691 19H15.8031C16.921 19 17.48 19 17.9074 18.7822C18.2837 18.5905 18.5905 18.2839 18.7822 17.9076C19 17.4802 19 16.921 19 15.8031V14M20 9V4M20 4H15M20 4L13 11\"\n\t\t\t\tstroke-width=\"2\"\n\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t></path>\n\t\t</g>\n\t</svg>\n}\n\ntempl ComponentExampleCode(code string) {\n\t<div class=\"relative w-full flex flex-col mt-4\">\n\t\t@templ.Raw(markdown.GetHTMLFromMarkdown([]byte(code)))\n\t</div>\n\t@scripts.HXCodeCopyButtonScript()\n}\n\ntempl RawHTML(html string) {\n\t@templ.Raw(html)\n}\n\ntempl ComponentExampleTabs(title, description string, tabs templ.Component) {\n\tif title != \"\" {\n\t\t<h2 class=\"text-lg\">{ title }</h2>\n\t}\n\t@templ.Raw(markdown.GetHTMLFromMarkdown([]byte(description)))\n\t@tabs\n}\n\ntempl ComponentTabs(name string, tabs []components.TabProps) {\n\t@components.Tabs(\n\t\tcomponents.TabsProps{\n\t\t\tName:         name,\n\t\t\tClass:        \"tabs-border\",\n\t\t\tContentClass: \"bg-base-100 border-base-300 rounded-box p-4 overflow-x-auto\",\n\t\t\tTabs:         tabs,\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "internal/views/pages/index.templ",
    "content": "package pages\n\nimport (\n\t\"github.com/haatos/goshipit/internal/views/components\"\n\t\"github.com/haatos/goshipit/internal/views/scripts\"\n)\n\ntempl IndexPage() {\n\t@SideNavLayout(nil) {\n\t\t@IndexPageContent()\n\t}\n}\n\ntempl IndexPageContent() {\n\t@openSourceToast()\n\t<div class=\"w-full space-y-12\">\n\t\t<div class=\"pt-12 lg:pt-24 pb-8 lg:pb-12 flex flex-col lg:flex-row w-full max-w-screen-md mx-auto\">\n\t\t\t<div class=\"hero\">\n\t\t\t\t<div class=\"flex flex-col text-6xl sm:text-7xl md:text-8xl font-saira-black text-transparent bg-clip-text bg-gradient-to-br from-primary/60 via-base-content to-primary/60 uppercase\">\n\t\t\t\t\t<span>Go</span>\n\t\t\t\t\t<span class=\"pl-[50px] sm:pl-[52px] md:pl-[78px]\">Ship</span>\n\t\t\t\t\t<span class=\"pl-[98px] sm:pl-[104px] md:pl-[142px]\">.it</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"flex justify-center items-center w-full max-w-72 sm:max-w-lg mx-auto text-xl sm:text-2xl lg:max-w-5xl pt-8 lg:pt-2\">\n\t\t\t\t<ul class=\"flex flex-col justify-center items-center space-y-1\">\n\t\t\t\t\t<p class=\"text-base-content/60 font-bold text-center md:text-start\">\n\t\t\t\t\t\tThe component library to\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"text-base-content/60 font-bold text-center md:text-start\">\n\t\t\t\t\t\tgive your Go applications\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"text-base-content/60 font-bold text-center md:text-start\">\n\t\t\t\t\t\ta running start\n\t\t\t\t\t</p>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"max-w-screen-md mx-auto prose\">\n\t\t\t<p>Now updated to DaisyUI5</p>\n\t\t\t<ul>\n\t\t\t\t<li>Updated changed class names</li>\n\t\t\t\t<li>Refactored Input-component</li>\n\t\t\t\t<li>\n\t\t\t\t\tRemoved Form-component. Just use \n\t\t\t\t\t<a href=\"https://daisyui.com/components/form\">\n\t\t\t\t\t\tDaisyUI\n\t\t\t\t\t\t@externalLinkIcon()\n\t\t\t\t\t</a>\n\t\t\t\t\tdirectly\n\t\t\t\t</li>\n\t\t\t\t<li>\n\t\t\t\t\tRemoved Join-component. Just use \n\t\t\t\t\t<a href=\"https://daisyui.com/components/join\">\n\t\t\t\t\t\tDaisyUI\n\t\t\t\t\t\t@externalLinkIcon()\n\t\t\t\t\t</a> directly\n\t\t\t\t</li>\n\t\t\t\t<li>\n\t\t\t\t\tRemoved Stack-component. Just use \n\t\t\t\t\t<a href=\"https://daisyui.com/components/stack\">\n\t\t\t\t\t\tDaisyUI\n\t\t\t\t\t\t@externalLinkIcon()\n\t\t\t\t\t</a> directly\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\t\t@components.Features(\n\t\t\tcomponents.FeaturesProps{\n\t\t\t\tFeatures: []components.FeatureProps{\n\t\t\t\t\t{\n\t\t\t\t\t\tIcon:        goIcon(),\n\t\t\t\t\t\tTitle:       \"Golang\",\n\t\t\t\t\t\tDescription: \"simple and efficient programming language ideal for building scalable, high-performance applications\",\n\t\t\t\t\t\tURL:         \"https://go.dev\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIcon:        templIcon(),\n\t\t\t\t\t\tTitle:       \"Templ\",\n\t\t\t\t\t\tDescription: \"fast, type-safe templating engine for Go to create HTML templates using Go code\",\n\t\t\t\t\t\tURL:         \"https://templ.guide\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIcon:        htmxIcon(),\n\t\t\t\t\t\tTitle:       \"HTMX\",\n\t\t\t\t\t\tDescription: \"lightweight JavaScript library to simplify building dynamic, interactive web applications\",\n\t\t\t\t\t\tURL:         \"https://htmx.org\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIcon:        tailwindcssIcon(),\n\t\t\t\t\t\tTitle:       \"TailwindCSS\",\n\t\t\t\t\t\tDescription: \"utility-first CSS framework to create flexible and efficient modern web interfaces\",\n\t\t\t\t\t\tURL:         \"https://tailwindcss.com\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIcon:        daisyuiIcon(),\n\t\t\t\t\t\tTitle:       \"DaisyUI\",\n\t\t\t\t\t\tDescription: \"component library to create attractive, responsive user interfaces with minimal custom styling\",\n\t\t\t\t\t\tURL:         \"https://daisyui.com\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIcon:        modelIcon(),\n\t\t\t\t\t\tTitle:       \"Types\",\n\t\t\t\t\t\tDescription: \"optional component arguments to simplify usage and reduce boilerplate code\",\n\t\t\t\t\t\tURL:         \"https://goship.it/types\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t)\n\t\t<section class=\"prose w-full max-w-screen-sm mx-auto\">\n\t\t\t<h2>Develop with the stack you love and go ship it</h2>\n\t\t\t<p>\n\t\t\t\tgoship.it is a Golang + Templ + HTMX (+ TailwindCSS + DaisyUI) component library that enables you to quickly develop an application using the GOTH stack, and put it in the hands of potential customers as quickly as possible.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tThe library contains DaisyUI components translated into <i>Templ</i> components that can be easily customized using both TailwindCSS and DaisyUI.\n\t\t\t</p>\n\t\t\t<p>\n\t\t\t\tExamples here use <a href=\"https://echo.labstack.com/\" class=\"link\">Echo</a> as the router. For usage with other routers or frameworks, refer to the integration guides found at <a href=\"https://templ.guide/integrations/web-frameworks\" class=\"link\">templ.guide</a> to see examples of rendering in different frameworks/libraries.\n\t\t\t</p>\n\t\t</section>\n\t</div>\n}\n\ntempl openSourceToast() {\n\t<div name=\"oss-toast\" class=\"toast toast-top toast-center text-sm\">\n\t\t<div class=\"alert\">\n\t\t\t<div class=\"flex items-center space-x-4\">\n\t\t\t\t<p>\n\t\t\t\t\tgoship.it is now open source,\n\t\t\t\t\t<br class=\"block sm:hidden\"/>\n\t\t\t\t\tsee the repository <a target=\"_blank\" href=\"https://github.com/haatos/goshipit\" class=\"link\">here</a>\n\t\t\t\t</p>\n\t\t\t\t<div class=\"flex flex-col space-y-1\">\n\t\t\t\t\t<button\n\t\t\t\t\t\tonclick=\"dismissOSSToast();\"\n\t\t\t\t\t\tclass=\"btn btn-xs btn-primary\"\n\t\t\t\t\t>\n\t\t\t\t\t\tOK\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<script>\n\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", function() {\n\t\t\t\t\tlet cookieBarState = localStorage.getItem(\"oss-toast-shown\");\n\t\t\t\t\tif (cookieBarState !== null) {\n\t\t\t\t\t\tdocument.querySelector(\"div[name=oss-toast]\").remove();\n\t\t\t\t\t}\n\t\t\t\t})\n\n                function dismissOSSToast() {\n\t\t\t\t\tlocalStorage.setItem(\"oss-toast-shown\", \"true\");\n\t\t\t\t\tdocument.querySelector(\"div[name=oss-toast]\").remove()\n                }\n            </script>\n\t\t</div>\n\t</div>\n}\n\ntempl goIcon() {\n\t<svg\n\t\tclass=\"w-32 h-32\"\n\t\tviewBox=\"0 -160 512 512\"\n\t\tversion=\"1.1\"\n\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\t\tpreserveAspectRatio=\"xMidYMid\"\n\t>\n\t\t<g>\n\t\t\t<path d=\"M292.533152,13.2950639 L293.657233,14.0455076 C306.869315,22.7704678 316.342129,34.7361275 322.574244,49.1946331 C324.069951,51.4381943 323.072813,52.6846171 320.081398,53.4324709 L315.017741,54.7277932 C303.571167,57.6768058 294.487155,60.1566573 283.191384,63.10567 L276.74841,64.7843862 C274.428264,65.3583626 273.787695,65.1170696 271.320433,62.3073717 L270.972336,61.9081465 C267.453024,57.9195933 264.816991,55.2559574 260.154613,52.878088 L259.255961,52.4353326 C243.551033,44.7075107 228.344673,46.9510719 214.135452,56.1746012 C197.184101,67.1431227 188.459141,83.3466202 188.708425,103.538671 C188.95771,123.481438 202.668362,139.93422 222.361843,142.67635 C239.313195,144.919911 253.522416,138.937081 264.740222,126.223568 C266.983783,123.481438 268.978059,120.490023 271.470905,117.000039 L223.358982,117.000039 C218.124006,117.000039 216.877583,113.759339 218.622575,109.521501 L219.486848,107.487264 C222.690544,100.033179 227.659682,89.3185944 230.887235,83.1925665 L231.591356,81.8743455 C232.452883,80.3801337 234.202861,78.3609287 237.568203,78.3609287 L317.791861,78.3603482 C321.394911,66.9456209 327.24084,56.159659 335.038473,45.9539335 C353.236247,22.0226141 375.17329,9.55838523 404.838154,4.32340907 C430.265181,-0.163713323 454.196501,2.32913245 475.884259,17.0369225 C495.577741,30.4982897 507.792685,48.6960639 511.033385,72.6273834 C515.271222,106.280802 505.549124,133.702105 482.365658,157.134856 C465.912876,173.836922 445.720825,184.306875 422.537359,189.043282 C415.806676,190.289704 409.075992,190.538989 402.594593,191.286843 C379.909697,190.788274 359.219077,184.306875 341.769156,169.3498 C329.496056,158.740849 321.041799,145.701725 316.840932,130.522127 C313.926247,136.409796 310.44016,142.04853 306.370746,147.412757 C288.422257,171.094792 264.989506,185.802582 235.324641,189.791135 C210.894753,193.031835 188.209856,188.295428 168.26709,173.338353 C149.820031,159.378417 139.350079,140.931358 136.607949,117.997177 C133.367249,90.8251575 141.344356,66.3952689 157.797138,44.9567952 C175.496343,21.7733295 198.929093,7.06553943 227.59682,1.8305633 C250.59563,-2.32879605 272.633891,0.235689133 292.533152,13.2950639 L292.533152,13.2950639 Z M411.120284,49.0171223 L410.322415,49.1946331 C387.138949,54.4296092 372.181875,69.1373993 366.697614,92.5701496 C362.210492,112.014347 371.683306,131.707829 389.631795,139.684935 C403.342447,145.667765 417.053099,144.919911 430.265181,138.189228 C449.958663,127.96856 460.6779,112.014347 461.924323,90.575873 C461.675038,87.3351735 461.675038,84.8423277 461.176469,82.3494819 C456.739764,57.9476028 434.511926,44.025432 411.120284,49.0171223 L411.120284,49.0171223 Z M116.415898,94.5644262 C117.413036,94.5644262 117.911605,95.3122799 117.911605,96.3094183 L117.413036,102.292248 C117.413036,103.289387 116.415898,104.03724 115.668044,104.03724 L61.3240061,103.787956 C60.3268678,103.787956 60.0775833,103.040102 60.5761524,102.292248 L64.0661365,96.0601337 C64.5647057,95.3122799 65.561844,94.5644262 66.5589823,94.5644262 L116.415898,94.5644262 Z M121.900159,71.6302451 C122.897297,71.6302451 123.395866,72.3780988 123.146581,73.1259525 L121.152305,79.1087824 C120.90302,80.1059207 119.905882,80.6044899 118.908744,80.6044899 L0.99713831,80.8537744 C0,80.8537744 -0.249284578,80.3552053 0.249284578,79.6073515 L5.48426071,72.8766679 C5.98282987,72.1288142 7.22925276,71.6302451 8.22639107,71.6302451 L121.900159,71.6302451 Z M134.862957,48.6960639 C135.860095,48.6960639 136.109379,49.4439176 135.61081,50.1917714 L131.372973,56.6731704 C130.874403,57.4210241 129.62798,58.1688779 128.880127,58.1688779 L38.6391096,57.9195933 C37.6419713,57.9195933 37.3926867,57.4210241 37.8912558,56.6731704 L43.126232,49.9424868 C43.6248011,49.1946331 44.871224,48.6960639 45.8683623,48.6960639 L134.862957,48.6960639 Z\" fill=\"#00ACD7\" fill-rule=\"nonzero\"></path>\n\t\t</g>\n\t</svg>\n}\n\ntempl templIcon() {\n\t<div class=\"h-32 flex justify-center items-center\">\n\t\t<img src=\"/static/images/templ.png\" alt=\"templ\" class=\"max-h-12 mx-auto\"/>\n\t</div>\n}\n\ntempl htmxIcon() {\n\t<div class=\"h-32 flex justify-center items-center text-4xl md:text-6xl font-bold \">\n\t\t<span>{ \"<\" }</span><span class=\"text-[#3d72d7]\">/</span><span>{ \">\" }</span>\n\t</div>\n}\n\ntempl tailwindcssIcon() {\n\t<div class=\"h-32 flex justify-center items-center\">\n\t\t<svg\n\t\t\tclass=\"w-20 h-20 mx-auto\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\trole=\"img\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tfill=\"#38bdf8\"\n\t\t><title>Tailwind CSS icon</title><path d=\"M12.001,4.8c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 C13.666,10.618,15.027,12,18.001,12c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C16.337,6.182,14.976,4.8,12.001,4.8z M6.001,12c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 c1.177,1.194,2.538,2.576,5.512,2.576c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C10.337,13.382,8.976,12,6.001,12z\"></path></svg>\n\t</div>\n}\n\ntempl daisyuiIcon() {\n\t<div class=\"h-32 flex justify-center items-center\">\n\t\t<svg\n\t\t\tclass=\"w-20 h-20\"\n\t\t\tviewBox=\"0 0 1024 1024\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t>\n\t\t\t<rect x=\"256\" y=\"670.72\" width=\"512\" height=\"256\" rx=\"128\" fill=\"#1AD1A5\"></rect>\n\t\t\t<circle cx=\"512\" cy=\"353.28\" r=\"256\" fill=\"white\"></circle>\n\t\t\t<circle cx=\"512\" cy=\"353.28\" r=\"261\" stroke=\"black\" stroke-opacity=\"0.2\" stroke-width=\"10\"></circle>\n\t\t\t<circle cx=\"512\" cy=\"353.28\" r=\"114.688\" fill=\"#FF9903\"></circle>\n\t\t</svg>\n\t</div>\n}\n\ntempl modelIcon() {\n\t<div class=\"h-32 flex justify-center items-center\">\n\t\t<svg class=\"fill-secondary/75 w-20 h-20\" viewBox=\"0 0 32 32\" id=\"icon\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t<path d=\"M27.4473,16.1055,23,13.3818V7a1,1,0,0,0-.5527-.8945l-6-3a1.0008,1.0008,0,0,0-.8946,0l-6,3A1,1,0,0,0,9,7v6.3818L3.5527,16.1055A1,1,0,0,0,3,17v7a1,1,0,0,0,.5527.8945l6,3a1.001,1.001,0,0,0,.8946,0L16,25.1182l5.5527,2.7763a1.001,1.001,0,0,0,.8946,0l6-3A1,1,0,0,0,29,24V17A1,1,0,0,0,28.4473,16.1055ZM21,13.3818l-4,2V10.6182l4-2ZM16,5.1182,19.7637,7,16,8.8818,12.2363,7Zm-5,3.5,4,2v4.7636l-4-2ZM9,25.3818l-4-2V18.6182l4,2Zm1-6.5L6.2363,17,10,15.1182,13.7637,17Zm1,1.7364,4-2v4.7636l-4,2Zm10,4.7636-4-2V18.6182l4,2Zm1-6.5L18.2363,17,22,15.1182,25.7637,17Zm5,4.5-4,2V20.6182l4-2Z\"></path>\n\t\t\t<rect id=\"_Transparent_Rectangle_\" data-name=\"<Transparent Rectangle>\" class=\"fill-none\" width=\"32\" height=\"32\"></rect>\n\t\t</svg>\n\t</div>\n}\n\ntempl AboutPage() {\n\t@SideNavLayout(nil) {\n\t\t@AboutPageMain()\n\t}\n}\n\ntempl AboutPageMain() {\n\t<div class=\"flex flex-col justify-center items-center w-full max-w-screen-md mx-auto px-8 xl:px-0 min-h-svh pb-24\">\n\t\t<div class=\"hero\">\n\t\t\t<div class=\"hero-content !px-4 lg:!px-0 flex-col-reverse lg:flex-row-reverse\">\n\t\t\t\t<img\n\t\t\t\t\tsrc=\"/static/images/profile-long.jpg\"\n\t\t\t\t\tclass=\"hidden lg:block max-w-[240px] rounded-box\"\n\t\t\t\t/>\n\t\t\t\t<img\n\t\t\t\t\tsrc=\"/static/images/profile.jpg\"\n\t\t\t\t\tclass=\"lg:hidden max-w-[240px] rounded-box\"\n\t\t\t\t/>\n\t\t\t\t<div>\n\t\t\t\t\t<h1 class=\"text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold\">\n\t\t\t\t\t\tHi, my name is <span class=\"text-primary text-5xl md:text-8xl\">Tomi</span>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<p class=\"pt-6\">\n\t\t\t\t\t\tI'm a software developer from Finland. I'm a creative problem solver\n\t\t\t\t\t\twho enjoys creating quality driven software.\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"pt-6\">\n\t\t\t\t\t\tMany of my hobby projects are available on <a href=\"https://github.com/haatos\" class=\"link\">Github</a>, mostly written in\n\t\t\t\t\t\t<span class=\"text-primary font-bold\">Go</span> and <span class=\"text-primary font-bold\">Python</span>,\n\t\t\t\t\t\twith some <span class=\"text-primary font-bold\">Javascript</span> (React & Nextjs) sprinkled in.\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"pt-6\">\n\t\t\t\t\t\tMy website <a href=\"https://haatos.com\" class=\"link\">haatos.com </a> contains articles on learning programming (using Go), and a few more advanced tutorials on how to create specific functionality for your web applications.\n\t\t\t\t\t</p>\n\t\t\t\t\t<p class=\"pt-6\">\n\t\t\t\t\t\tYou can reach me on <a href=\"https://linkedin.com/in/tomihaapalainen\" class=\"link link-primary\">LinkedIn</a>\n\t\t\t\t\t\tor by emailing me at <a href=\"mailto:tomi@haatos.com\" class=\"link link-primary\">tomi@haatos.com</a>.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n}\n\ntempl GettingStartedPage(html string) {\n\t@SideNavLayout(nil) {\n\t\t@GettingStartedPageMain(html)\n\t}\n\t@scripts.CodeCopyButtonScript()\n}\n\ntempl GettingStartedPageMain(html string) {\n\t<div class=\"prose !max-w-screen-lg pt-8\">\n\t\t@templ.Raw(html)\n\t</div>\n\t@scripts.HXCodeCopyButtonScript()\n}\n\ntempl TypesPage(html string) {\n\t@SideNavLayout(nil) {\n\t\t@TypesPageMain(html)\n\t}\n\t@scripts.CodeCopyButtonScript()\n}\n\ntempl TypesPageMain(html string) {\n\t<div class=\"prose !max-w-screen-lg pt-8\">\n\t\t@templ.Raw(html)\n\t</div>\n\t@scripts.HXCodeCopyButtonScript()\n}\n\ntempl PrivacyPage(domain, contactEmail string) {\n\t@SideNavLayout(nil) {\n\t\t@PrivacyMain(domain, contactEmail)\n\t}\n}\n\ntempl PrivacyMain(domain, contactEmail string) {\n\t<section class=\"w-full max-w-screen-md mx-auto px-8 xl:px-0 prose pt-12 pb-32 min-h-screen flex flex-col text-justify\">\n\t\t<h1>\n\t\t\tPrivacy Policy for { domain }\n\t\t</h1>\n\t\t<p>\n\t\t\tAt { domain }, the privacy of our visitors is of utmost importance to us.\n\t\t\tThis Privacy Policy document outlines the types of personal information that\n\t\t\tis received and collected by { domain } and how it is used.\n\t\t</p>\n\t\t<h2>\n\t\t\tInformation We Collect\n\t\t</h2>\n\t\t<p>\n\t\t\tPersonal Information: When you visit { domain }, we may collect personal information\n\t\t\tthat you voluntarily provide to us, such as your name, email address, and any other\n\t\t\tinformation you choose to provide when contacting us or signing up for our services.\n\t\t</p>\n\t\t<p>\n\t\t\tLog Files: Like many other websites, { domain } makes use of log files. The information\n\t\t\tinside the log files includes internet protocol (IP) addresses, type of browser,\n\t\t\tInternet Service Provider (ISP), date/time stamp, referring/exit pages, and number of\n\t\t\tclicks to analyze trends, administer the site, track user's movement around the site,\n\t\t\tand gather demographic information. IP addresses and other such information are not\n\t\t\tlinked to any information that is personally identifiable.\n\t\t</p>\n\t\t<p>\n\t\t\tCookies and Web Beacons: { domain } uses cookies to store information about visitors'\n\t\t\tpreferences, to record user-specific information on which pages the user accesses or\n\t\t\tvisits, and to customize web page content based on visitors' browser type or other\n\t\t\tinformation that the visitor sends via their browser.\n\t\t</p>\n\t\t<h2>\n\t\t\tHow We Use Your Information\n\t\t</h2>\n\t\t<ul>\n\t\t\t<li>\n\t\t\t\tWe may use the information we collect from you to personalize your experience and to provide you with better service.\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\tYour information helps us to more effectively respond to your customer service requests and support needs.\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\tWe may periodically send promotional emails about new products, special offers, or\n\t\t\t\tother information which we think you may find interesting using the email address\n\t\t\t\twhich you have provided.\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\tWe may use the information to improve our products and services.\n\t\t\t</li>\n\t\t</ul>\n\t\t<h2>\n\t\t\tDisclosure of Information\n\t\t</h2>\n\t\t<p>\n\t\t\t{ domain } does not sell, trade, or otherwise transfer your personally identifiable\n\t\t\tinformation to outside parties. This does not include trusted third parties who\n\t\t\tassist us in operating our website, conducting our business, or servicing you, so\n\t\t\tlong as those parties agree to keep this information confidential. We may also release\n\t\t\tyour information when we believe release is appropriate to comply with the law, enforce\n\t\t\tour site policies, or protect ours or others' rights, property, or safety.\n\t\t</p>\n\t\t<h2>\n\t\t\tConsent\n\t\t</h2>\n\t\t<p>\n\t\t\tBy using our website, you hereby consent to our Privacy Policy and agree to its terms.\n\t\t</p>\n\t\t<h2>\n\t\t\tUpdates\n\t\t</h2>\n\t\t<p>\n\t\t\tThis Privacy Policy may change from time to time, and all updates will be posted on this page.\n\t\t</p>\n\t\t<p>\n\t\t\tIf you require any more information or have any questions about our Privacy Policy,\n\t\t\tplease feel free to contact us through email at { contactEmail }.\n\t\t</p>\n\t</section>\n}\n\ntempl TermsOfService(domain, contactEmail string) {\n\t@SideNavLayout(nil) {\n\t\t@TermsOfServiceMain(domain, contactEmail)\n\t}\n}\n\ntempl TermsOfServiceMain(domain, contactEmail string) {\n\t<section class=\"prose pt-12 pb-32 px-8 xl:px-0 w-full mx-auto max-w-screen-md min-h-screen flex flex-col text-justify\">\n\t\t<h1>Terms of Service for { domain }</h1>\n\t\t<p>\n\t\t\tThese Terms of Service govern your use of { domain }. By accessing or using { domain },\n\t\t\tyou agree to be bound by these Terms of Service.\n\t\t</p>\n\t\t<h2>Use of Content</h2>\n\t\t<p>\n\t\t\tThe content provided on { domain } is for your general information and personal use only.\n\t\t\tIt is subject to change without notice.\n\t\t</p>\n\t\t<p>\n\t\t\tReproduction of any material from { domain } is prohibited unless it is in accordance\n\t\t\twith the copyright notice, which forms part of these terms and conditions.\n\t\t</p>\n\t\t<p>\n\t\t\tAll trademarks reproduced on { domain }, which are not the property of, or licensed\n\t\t\tto the operator, are acknowledged on the website.\n\t\t</p>\n\t\t<h2>User Conduct</h2>\n\t\t<p>\n\t\t\tYou agree not to use { domain }<span>for</span> any unlawful purpose or in any way that could damage,\n\t\t\tdisable, overburden, or impair the site or interfere with any other party's use and enjoyment\n\t\t\tof { domain }.\n\t\t</p>\n\t\t<p>\n\t\t\tYou must not attempt to gain unauthorized access to { domain }, the server on which it is stored,\n\t\t\tor any server, computer, or database connected to { domain }.\n\t\t</p>\n\t\t<h2>Links to Other Websites</h2>\n\t\t<p>\n\t\t\t{ domain } may contain links to other websites. These links are provided for your convenience\n\t\t\tto provide further information. They do not signify that we endorse the website(s).\n\t\t\tWe have no responsibility for the content of the linked website(s).\n\t\t</p>\n\t\t<h2>Limitation of Liability</h2>\n\t\t<p>\n\t\t\tIn no event shall { domain } or its owners, operators, or affiliates be liable for any direct,\n\t\t\tindirect, punitive, incidental, special, or consequential damages arising out of, or in any way\n\t\t\tconnected with, the use of { domain } or with the delay or inability to use { domain }.\n\t\t</p>\n\t\t<h2>Indemnity</h2>\n\t\t<p>\n\t\t\tYou agree to indemnify and hold { domain } and its owners, operators, and affiliates harmless\n\t\t\tfrom any claim or demand, including reasonable attorneys' fees, made by any third party due to\n\t\t\tor arising out of your breach of these Terms of Service or your violation of any law or the rights\n\t\t\tof a third party.\n\t\t</p>\n\t\t<h2>Changes to Terms of Service</h2>\n\t\t<p>\n\t\t\t{ domain } reserves the right to revise these Terms of Service at any time without notice.\n\t\t\tBy using { domain }, you are agreeing to be bound by the then-current version of these\n\t\t\tTerms of Service.\n\t\t</p>\n\t\t<p>\n\t\t\tIf you have any questions about these Terms of Service, please contact us at { contactEmail }.\n\t\t</p>\n\t</section>\n}\n"
  },
  {
    "path": "internal/views/pages/server_error.templ",
    "content": "package pages\n\nimport (\n\t\"fmt\"\n\t\"github.com/haatos/goshipit/internal\"\n\t\"github.com/haatos/goshipit/internal/views/components\"\n)\n\ntempl InternalServerError() {\n\t@SideNavLayout(nil) {\n\t\t@SideNavLayout(nil) {\n\t\t\t@components.Status(\n\t\t\t\tcomponents.StatusProps{\n\t\t\t\t\tCode:              500,\n\t\t\t\t\tTitle:             \"Internal Server Error\",\n\t\t\t\t\tDescription:       fmt.Sprintf(\"Something went terribly wrong! Please contact us at %s if the problem persists.\", internal.Settings.ContactEmail),\n\t\t\t\t\tReturnButtonLabel: \"Go back home\",\n\t\t\t\t\tReturnButtonAttrs: templ.Attributes{\n\t\t\t\t\t\t\"hx-get\":      \"/\",\n\t\t\t\t\t\t\"hx-target\":   \"main\",\n\t\t\t\t\t\t\"hx-swap\":     \"innerHTML\",\n\t\t\t\t\t\t\"hx-push-url\": \"true\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/views/scripts/copy_button.templ",
    "content": "package scripts\n\ntempl CodeCopyButtonScript() {\n\t<script>\n\t\tdocument.addEventListener(\"DOMContentLoaded\", function() {\n\t\t\tlet blocks = document.querySelectorAll(\"pre.chroma\");\n\t\t\tblocks.forEach((block) => {\n\t\t\t\tlet btn = block.querySelector(\"button[name=copy-btn]\");\n\t\t\t\tif (btn === null && navigator.clipboard) {\n\t\t\t\t\tlet button = document.createElement(\"button\");\n\n\t\t\t\t\tlet svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\t\t\t\t\tlet path = document.createElementNS(\"http://www.w3.org/2000/svg\", 'path');\n\t\t\t\t\tsvg.setAttribute(\"class\", \"w-8 h-8\")\n\t\t\t\t\tsvg.setAttribute(\"viewBox\", \"0 0 24 24\")\n\t\t\t\t\tsvg.setAttribute(\"fill\", \"none\")\n\t\t\t\t\tsvg.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\")\n\t\t\t\t\tpath.setAttribute(\"class\", \"fill-slate-100\")\n\t\t\t\t\tpath.setAttribute(\"fill-rule\", \"evenodd\")\n\t\t\t\t\tpath.setAttribute(\"clip-rule\", \"evenodd\")\n\t\t\t\t\tpath.setAttribute(\"d\", \"M19.5 16.5L19.5 4.5L18.75 3.75H9L8.25 4.5L8.25 7.5L5.25 7.5L4.5 8.25V20.25L5.25 21H15L15.75 20.25V17.25H18.75L19.5 16.5ZM15.75 15.75L15.75 8.25L15 7.5L9.75 7.5V5.25L18 5.25V15.75H15.75ZM6 9L14.25 9L14.25 19.5L6 19.5L6 9Z\")\n\t\t\t\t\tsvg.appendChild(path)\n\t\t\t\t\tbutton.appendChild(svg)\n\t\t\t\t\tbutton.setAttribute(\"name\", \"copy-btn\")\n\t\t\t\t\tblock.appendChild(button);\n\n\t\t\t\t\tbutton.addEventListener(\"click\", async () => {\n\t\t\t\t\t\tawait copyCode(block, button);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tasync function copyCode(block, button) {\n\t\t\t\tlet code = block.querySelector(\"code\");\n\t\t\t\tlet text = code.innerText.split(\"\\n\\n\").join(\"\\n\");\n\n\t\t\t\tawait navigator.clipboard.writeText(text);\n\t\t\t\t// visual feedback that task is completed\n\t\t\t\tbutton.querySelector(\"path\").classList.remove(\"fill-slate-100\")\n\t\t\t\tbutton.querySelector(\"path\").classList.add(\"fill-emerald-300\")\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tbutton.querySelector(\"path\").classList.remove(\"fill-slate-300\")\n\t\t\t\t\tbutton.querySelector(\"path\").classList.add(\"fill-slate-100\")\n\t\t\t\t}, 500);\n\t\t\t}\n\t\t})\n\t</script>\n}\n\ntempl HXCodeCopyButtonScript() {\n\t<script>\n\t\tdocument.addEventListener(\"htmx:afterSettle\", function() {\n\t\t\tlet blocks = document.querySelectorAll(\"pre.chroma\");\n\t\t\tblocks.forEach((block) => {\n\t\t\t\tlet btn = block.querySelector(\"button[name=copy-btn]\");\n\t\t\t\tif (btn === null && navigator.clipboard) {\n\t\t\t\t\tlet button = document.createElement(\"button\");\n\n\t\t\t\t\tlet svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\t\t\t\t\tlet path = document.createElementNS(\"http://www.w3.org/2000/svg\", 'path');\n\t\t\t\t\tsvg.setAttribute(\"class\", \"w-8 h-8\")\n\t\t\t\t\tsvg.setAttribute(\"viewBox\", \"0 0 24 24\")\n\t\t\t\t\tsvg.setAttribute(\"fill\", \"none\")\n\t\t\t\t\tsvg.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\")\n\t\t\t\t\tpath.setAttribute(\"class\", \"fill-slate-100\")\n\t\t\t\t\tpath.setAttribute(\"fill-rule\", \"evenodd\")\n\t\t\t\t\tpath.setAttribute(\"clip-rule\", \"evenodd\")\n\t\t\t\t\tpath.setAttribute(\"d\", \"M19.5 16.5L19.5 4.5L18.75 3.75H9L8.25 4.5L8.25 7.5L5.25 7.5L4.5 8.25V20.25L5.25 21H15L15.75 20.25V17.25H18.75L19.5 16.5ZM15.75 15.75L15.75 8.25L15 7.5L9.75 7.5V5.25L18 5.25V15.75H15.75ZM6 9L14.25 9L14.25 19.5L6 19.5L6 9Z\")\n\t\t\t\t\tsvg.appendChild(path)\n\t\t\t\t\tbutton.appendChild(svg)\n\t\t\t\t\tbutton.setAttribute(\"name\", \"copy-btn\")\n\t\t\t\t\tblock.appendChild(button);\n\n\t\t\t\t\tbutton.addEventListener(\"click\", async () => {\n\t\t\t\t\t\tawait copyCode(block, button);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tasync function copyCode(block, button) {\n\t\t\t\tlet code = block.querySelector(\"code\");\n\t\t\t\tlet text = code.innerText.split(\"\\n\\n\").join(\"\\n\");\n\n\t\t\t\tawait navigator.clipboard.writeText(text);\n\t\t\t\t// visual feedback that task is completed\n\t\t\t\tbutton.querySelector(\"path\").classList.toggle(\"fill-emerald-300\")\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tbutton.querySelector(\"path\").classList.toggle(\"fill-emerald-300\")\n\t\t\t\t}, 700);\n\t\t\t}\n\t\t})\n\t</script>\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"devDependencies\": {\n    \"@tailwindcss/cli\": \"^4.1.18\",\n    \"@tailwindcss/typography\": \"^0.5.19\",\n    \"daisyui\": \"^5.5.19\",\n    \"tailwindcss\": \"^4.1.18\"\n  },\n  \"scripts\": {\n    \"build:css\": \"npx @tailwindcss/cli -i input.css -o ./public/static/css/tw.css --watch\"\n  }\n}\n"
  },
  {
    "path": "readme.md",
    "content": "# GoShip.it\n\nGolang + Templ + HTMX (+ TailwindCSS + DaisyUI) component library to enhance developing an application using the GOTH stack.\n\nThe library contains DaisyUI components translated into Templ components that can be easily customized using both TailwindCSS and DaisyUI.\n\nUpdated to support DaisyUI 5. If you're looking for DaisyUI 4 compatible components, take a look [here](https://old.goship.it)\n\n## Getting started\n\nInstall node dependencies:\n`npm i -D`\n\nBuild TailwindCSS:\n`make tw`\n\nGenerate component code/json, generate templates and run the server:\n`make dev`\n\n## Code/data generation\n\n`cmd/generate/main.go` is used to generate JSON, markdown and Go code from source code. JSON is used to store and load component and example component source code to be displayed in HTML. The generator also generates a markdown file that contains up-to-date types for components (from `internal/model/components.go`), and .go file containing a mapping of example names to _templ_ components.\n\n## Contributing\n\nComponents are placed in individual .templ files in `internal/views/components/`. The name of the file is used as the name of the component (converted from snake_case to Capitalized Component Name). The .templ file starts with a category name as a comment, e.g. `// data_display`.\n\nFor example\n\n`internal/views/components/accordion.templ`\n\n```go\n// data_display\npackage components\n\ntype AccordionRowProps struct {\n\tLabel string\n\tType  string\n\tName  string\n}\n\ntempl AccordionRow(props AccordionRowProps) {\n\t<div class=\"collapse collapse-arrow bg-base-200 join-item\">\n\t\t<input type=\"checkbox\" name=\"templ-accordion\"/>\n\t\t<div class=\"collapse-title text-xl font-medium\">{ label }</div>\n\t\t<div class=\"collapse-content bg-base-300\">\n\t\t\t{ children... }\n\t\t</div>\n\t</div>\n}\n```\n\nEach component also has an examples file with a corresponding name in `internal/views/examples/`. The file can contain multiple examples, each starting with a comment `// example` with any lines below this line belonging to the example up to the next `// example` line or EOF. E.g.:\n\n`internal/views/examples/textarea.templ`\n\n```go\npackage examples\n\nimport \"github.com/haatos/goshipit/internal/views/components\"\n\n// example\ntempl BasicTextarea() {\n\t<div class=\"pt-4\">\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tName:  \"description\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n\n// example\ntempl BasicTextareaWithError() {\n\t<div class=\"pt-4\">\n\t\t@components.Textarea(\n\t\t\tcomponents.TextareaProps{\n\t\t\t\tLabel: \"Description\",\n\t\t\t\tName:  \"description\",\n\t\t\t\tErr:   \"Description cannot be empty\",\n\t\t\t},\n\t\t)\n\t</div>\n}\n```\n\nSome examples have corresponding handler functions to provide dummy data for the component to display its usage. E.g. `internal/handler/components.go` contains the handler for lazy-loading example:\n\n```go\n// LazyLoadExample\nfunc GetLazyLoadExample(c echo.Context) error {\n\ttime.Sleep(2 * time.Second)\n\n\treturn render(c, http.StatusOK, examples.LazyLoadResult())\n}\n\n// LazyLoadExample\n```\n\nThe handler must be enclosed with the name of the example component as comment on both sides of the handler's function(s).\n\n## CLI\n\nTo install the goship.it CLI, run `go install github.com/haatos/goshipit/cmd/gsi`, or clone the repository and build it yourself: `go build -o gsi cmd/gsi/main.go`.\n\n### Usage\n\nAdd components by running `gsi add button`. Components are added to _internal/views/components_ folder.\n\nTo see a list of all (and installed components) run `gsi list`.\n\nTo remove a component, run `gsi remove button`.\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "/* to disable code block CSS from tailwind/typography, we use another code highlighter */\nconst disabledCss = {\n  \"code::before\": false,\n  \"code::after\": false,\n  \"blockquote p:first-of-type::before\": false,\n  \"blockquote p:last-of-type::after\": false,\n  pre: false,\n  code: false,\n  \"pre code\": false,\n  \"code::before\": false,\n  \"code::after\": false,\n};\n\nmodule.exports = {\n  content: [\"internal/views/**/*.templ\"],\n  theme: {\n    extend: {\n      /* disable code block CSS */\n      typography: {\n        DEFAULT: { css: disabledCss },\n        sm: { css: disabledCss },\n        lg: { css: disabledCss },\n        xl: { css: disabledCss },\n        \"2xl\": { css: disabledCss },\n      },\n    },\n  },\n};\n"
  }
]