diff --git a/cmd/api/api.go b/cmd/api/api.go
index a7e815a..1e17c63 100644
--- a/cmd/api/api.go
+++ b/cmd/api/api.go
@@ -33,9 +33,9 @@ type CDSViewFieldJSON struct {
//TODO: "https://api.sap.com/api/1.0/container/CDSViews/artifacts?containerType=contentType&$filter=Type%20eq%20'CDSVIEW'&$top=" + fmt.Sprint(top) + "&$skip=" + fmt.Sprint(skip)
-func GetCDSViewField(CDSViewTechnicalName string) error {
+func GetCDSViewField(CDSViewTechnicalName table.TechnicalName) error {
var json CDSViewFieldJSON
- path := "https://api.sap.com/odata/1.0/catalog.svc/CdsViewsContent.CdsViews('" + CDSViewTechnicalName + "')/$value"
+ path := string("https://api.sap.com/odata/1.0/catalog.svc/CdsViewsContent.CdsViews('" + CDSViewTechnicalName + "')/$value")
fmt.Println("Getting: ", CDSViewTechnicalName)
err := RequestJSON(path, &json)
if err != nil {
@@ -60,7 +60,7 @@ func GetCDSViewFields() {
for _, cdsView := range *cdsViews {
var json CDSViewFieldJSON
- path := "https://api.sap.com/odata/1.0/catalog.svc/CdsViewsContent.CdsViews('" + cdsView + "')/$value"
+ path := string("https://api.sap.com/odata/1.0/catalog.svc/CdsViewsContent.CdsViews('" + cdsView + "')/$value")
fmt.Println("Getting: ", cdsView)
err := RequestJSON(path, &json)
if err != nil {
diff --git a/cmd/database/table/cdsView.go b/cmd/database/table/cdsView.go
index 38b0e19..25a43f0 100644
--- a/cmd/database/table/cdsView.go
+++ b/cmd/database/table/cdsView.go
@@ -23,19 +23,19 @@ import (
)
type CDSView struct {
- TechnicalName string `json:"Name"`
- DisplayName string `json:"DisplayName"`
- Description string `json:"Description"`
- Version string `json:"Version"`
- State string `json:"State"`
- CreatedAt int `json:"CreatedAt"`
- ModifiedAt int `json:"ModifiedAt"`
+ TechnicalName `json:"Name"`
+ DisplayName `json:"DisplayName"`
+ Description `json:"Description"`
+ Version `json:"Version"`
+ State `json:"State"`
+ CreatedAt `json:"CreatedAt"`
+ ModifiedAt `json:"ModifiedAt"`
}
//go:embed sql/query_cds_view.sql
var query_cds_view string
-func GetCDSView(TechnicalName string) (*CDSView, error) {
+func GetCDSView(TechnicalName TechnicalName) (*CDSView, error) {
row := database.DB.QueryRow(query_cds_view, TechnicalName)
var CDSView CDSView
@@ -50,15 +50,15 @@ func GetCDSView(TechnicalName string) (*CDSView, error) {
//go:embed sql/query_all_cds_view_technical_names.sql
var query_all_cds_view_technical_names string
-func QueryAllCDSViewTechnicalNames() (*[]string, error) {
+func QueryAllCDSViewTechnicalNames() (*[]TechnicalName, error) {
rows, err := database.DB.Query(query_all_cds_view_technical_names)
if err != nil {
return nil, err
}
- var technicalNames []string
+ var technicalNames []TechnicalName
for rows.Next() {
- var technicalName string
+ var technicalName TechnicalName
err := rows.Scan(&technicalName)
if err != nil {
return nil, err
diff --git a/cmd/database/table/cdsViewField.go b/cmd/database/table/cdsViewField.go
index 711b23e..1c65630 100644
--- a/cmd/database/table/cdsViewField.go
+++ b/cmd/database/table/cdsViewField.go
@@ -23,11 +23,11 @@ import (
)
type CDSViewField struct {
- CDSViewTechnicalName string
- FieldName string `json:"fieldname"`
- Description string `json:"description"`
- DataType string `json:"datatype"`
- FieldLength string `json:"fieldlength"`
+ CDSViewTechnicalName TechnicalName
+ FieldName `json:"fieldname"`
+ Description `json:"description"`
+ DataType `json:"datatype"`
+ FieldLength `json:"fieldlength"`
}
//go:embed sql/query_cds_view_fields.sql
@@ -53,7 +53,7 @@ func GetCDSViewFields(CDSViewTechnicalName string) (*[]CDSViewField, error) {
//go:embed sql/query_cds_view_number_of_fields.sql
var query_cds_view_number_of_fields string
-func GetCDSViewNumberOfFields(CDSViewTechnicalName string) (int, error) {
+func GetCDSViewNumberOfFields(CDSViewTechnicalName TechnicalName) (int, error) {
rows, err := database.DB.Query(query_cds_view_number_of_fields, CDSViewTechnicalName)
if err != nil {
return 0, err
diff --git a/cmd/database/table/field.go b/cmd/database/table/field.go
new file mode 100644
index 0000000..3093a38
--- /dev/null
+++ b/cmd/database/table/field.go
@@ -0,0 +1,135 @@
+package table
+
+import "code.achtarmig.org/pas/ui/field"
+
+// CDS View
+type (
+ TechnicalName string
+ DisplayName string
+ Description string
+ Version string
+ State string
+ CreatedAt int
+ ModifiedAt int
+)
+
+// CDS View Field
+type (
+ FieldName string
+ DataType string
+ FieldLength string
+)
+
+func (t TechnicalName) Info(language string) field.Info {
+ return field.Info{
+ Title: "Technical Name",
+ Details: "Technical Name of the CDS View",
+ }
+}
+
+func (t TechnicalName) String() string {
+ return string(t)
+}
+
+func (t DisplayName) Info(language string) field.Info {
+ return field.Info{
+ Title: "Name",
+ Details: "Name of the CDS View",
+ }
+}
+
+func (t DisplayName) String() string {
+ return string(t)
+}
+
+func (t Description) Info(language string) field.Info {
+ return field.Info{
+ Title: "Description",
+ Details: "Discription",
+ }
+}
+
+func (t Description) String() string {
+ return string(t)
+}
+
+func (t Version) Info(language string) field.Info {
+ return field.Info{
+ Title: "Version",
+ Details: "Version of the CDS View",
+ Justify: field.JustifyRight,
+ }
+}
+
+func (t Version) String() string {
+ return string(t)
+}
+
+func (t State) Info(language string) field.Info {
+ return field.Info{
+ Title: "Release State",
+ Details: "Release State of the CDS View. Non-Released views may not be used",
+ }
+}
+
+func (t State) String() string {
+ return string(t)
+}
+
+func (t CreatedAt) Info(language string) field.Info {
+ return field.Info{
+ Title: "Created At",
+ Details: "Timestamp of creation of the dataset",
+ Justify: field.JustifyRight,
+ }
+}
+
+func (t CreatedAt) Int() int {
+ return int(t)
+}
+
+func (t ModifiedAt) Info(language string) field.Info {
+ return field.Info{
+ Title: "Modified At",
+ Details: "Timestamp of last modification of the dataset",
+ Justify: field.JustifyRight,
+ }
+}
+
+func (t ModifiedAt) Int() int {
+ return int(t)
+}
+
+func (t FieldName) Info(language string) field.Info {
+ return field.Info{
+ Title: "Field",
+ Details: "Name of the CDS View field",
+ }
+}
+
+func (t FieldName) String() string {
+ return string(t)
+}
+
+func (t DataType) Info(language string) field.Info {
+ return field.Info{
+ Title: "Type",
+ Details: "Data type of the CDS View field",
+ }
+}
+
+func (t DataType) String() string {
+ return string(t)
+}
+
+func (t FieldLength) Info(language string) field.Info {
+ return field.Info{
+ Title: "Length",
+ Details: "Length of the CDS View field",
+ Justify: field.JustifyRight,
+ }
+}
+
+func (t FieldLength) String() string {
+ return string(t)
+}
diff --git a/cmd/database/table/keyword.go b/cmd/database/table/keyword.go
index 13c8cd4..b4d48e9 100644
--- a/cmd/database/table/keyword.go
+++ b/cmd/database/table/keyword.go
@@ -23,7 +23,7 @@ import (
)
type Keyword struct {
- CDSViewTechnicalName string
+ CDSViewTechnicalName TechnicalName
Keyword string
}
diff --git a/cmd/model/cdsView.go b/cmd/model/cdsView.go
index b8ea10f..1280188 100644
--- a/cmd/model/cdsView.go
+++ b/cmd/model/cdsView.go
@@ -29,15 +29,16 @@ import (
type CDSViewFieldModel struct {
table.CDSViewField
- DataTypeTitle string
- FieldLengthOut string
- DescriptionOut string
+ FieldNameOut table.FieldName
+ DataTypeTitle table.DataType
+ FieldLengthOut table.FieldLength
+ DescriptionOut table.Description
}
type CDSViewModel struct {
*table.CDSView
- StateTitle string
- TechnicalNameEncoded string
+ StateTitle table.State
+ TechnicalNameEncoded table.TechnicalName
NumberOfFields int
}
@@ -53,8 +54,9 @@ func GetCDSViewModelFields(TechnicalName string) (*[]CDSViewFieldModel, error) {
var fieldsModel []CDSViewFieldModel
for _, field := range *fields {
fieldModel.CDSViewField = field
- fieldModel.DataTypeTitle = englishCases.String(field.DataType)
- fieldModel.FieldLengthOut = strings.TrimLeft(field.FieldLength, "0")
+ fieldModel.FieldNameOut = field.FieldName
+ fieldModel.DataTypeTitle = table.DataType(englishCases.String(field.DataType.String()))
+ fieldModel.FieldLengthOut = table.FieldLength(strings.TrimLeft(field.FieldLength.String(), "0"))
fieldModel.DescriptionOut = field.Description
if fieldModel.DescriptionOut == "" {
fieldModel.DescriptionOut = "-"
@@ -65,7 +67,7 @@ func GetCDSViewModelFields(TechnicalName string) (*[]CDSViewFieldModel, error) {
return &fieldsModel, nil
}
-func GetCDSViewModel(TechnicalName string) (*CDSViewModel, error) {
+func GetCDSViewModel(TechnicalName table.TechnicalName) (*CDSViewModel, error) {
var model CDSViewModel
cdsView, err := table.GetCDSView(TechnicalName)
@@ -75,8 +77,8 @@ func GetCDSViewModel(TechnicalName string) (*CDSViewModel, error) {
model.CDSView = cdsView
- model.StateTitle = englishCases.String(model.State)
- model.TechnicalNameEncoded = strings.Replace(base64.StdEncoding.EncodeToString([]byte(model.TechnicalName)), "=", "", -1)
+ model.StateTitle = table.State(englishCases.String(model.State.String()))
+ model.TechnicalNameEncoded = table.TechnicalName(strings.Replace(base64.StdEncoding.EncodeToString([]byte(model.TechnicalName)), "=", "", -1))
model.NumberOfFields, err = table.GetCDSViewNumberOfFields(TechnicalName)
if err != nil {
diff --git a/cmd/router/router.go b/cmd/router/router.go
index 69ed84f..b6c42c7 100644
--- a/cmd/router/router.go
+++ b/cmd/router/router.go
@@ -18,37 +18,23 @@
package router
import (
- "api-cds-search/cmd/handler"
- "api-cds-search/cmd/search"
- "api-cds-search/cmd/ui"
- "fmt"
"net/http"
+ "code.achtarmig.org/pas/ui/context"
+ "code.achtarmig.org/pas/ui/route"
"github.com/go-chi/chi"
)
func Load() *chi.Mux {
r := chi.NewRouter()
r.Group(func(r chi.Router) {
- ui.Load()
- r.Get("/", handleRoot)
- r.Route("/search", func(r chi.Router) {
- r.Get("/", search.HandleSearch)
- })
- r.Route("/cds", func(r chi.Router) {
- r.Get("/field/", handler.GetCDSField)
- })
+ r.Use(context.Middleware)
+ route.Routes(r)
+ })
+
+ r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ http.Redirect(w, r, "/search", http.StatusFound)
})
- r.Handle("/ui/css/*", http.StripPrefix("/ui/css", http.FileServer(http.Dir("./cmd/ui/css"))))
- r.Handle("/ui/svg/*", http.StripPrefix("/ui/svg", http.FileServer(http.Dir("./cmd/ui/svg"))))
return r
}
-
-func handleRoot(w http.ResponseWriter, r *http.Request) {
- err := ui.Template.ExecuteTemplate(w, "main", nil)
- if err != nil {
- fmt.Println(err)
- return
- }
-}
diff --git a/cmd/search/search.go b/cmd/search/search.go
index bf7f486..c58148b 100644
--- a/cmd/search/search.go
+++ b/cmd/search/search.go
@@ -18,8 +18,8 @@
package search
import (
+ "api-cds-search/cmd/database/table"
"api-cds-search/cmd/model"
- "api-cds-search/cmd/ui"
"errors"
"fmt"
"net/http"
@@ -33,7 +33,7 @@ import (
)
type fuzzyResult struct {
- CDSViewTechnicalName string
+ CDSViewTechnicalName table.TechnicalName
hits int
perfectHits int
averageDistance float32
@@ -54,7 +54,7 @@ var (
ErrNoResults = errors.New("no results")
)
-var searchTargets map[string][]string = make(map[string][]string)
+var searchTargets map[table.TechnicalName][]string = make(map[table.TechnicalName][]string)
var resultsBuffer map[string]*resultBuffer = make(map[string]*resultBuffer)
func Load() error {
@@ -82,8 +82,8 @@ func Load() error {
return nil
}
-func GetSearchTerm(r *http.Request) string {
- return strings.ToLower(r.URL.Query().Get("q"))
+func GetSearchTerm(q string) string {
+ return strings.ToLower(q)
}
func GetPage(r *http.Request) int {
@@ -195,26 +195,7 @@ func BuildBuffer(searchTerm string) error {
return nil
}
-func HandleSearch(w http.ResponseWriter, r *http.Request) {
- searchTerm := GetSearchTerm(r)
-
- buffer, err := GetBuffer(searchTerm)
- if err != nil {
- err := BuildBuffer(searchTerm)
- if err != nil {
- err := ui.Template.ExecuteTemplate(w, "search-placeholder-no-result", nil)
- if err != nil {
- fmt.Println(err)
- }
- return
- }
- buffer, _ = GetBuffer(searchTerm)
- }
-
- buffer.mu.Lock()
- defer buffer.mu.Unlock()
-
- page := GetPage(r)
+func GetPages(buffer *resultBuffer, p int) (int, int) {
var maxPage int
if buffer.hits <= pageStep {
maxPage = 0
@@ -222,9 +203,17 @@ func HandleSearch(w http.ResponseWriter, r *http.Request) {
maxPage = (buffer.hits / pageStep)
}
- if page+1 > maxPage {
- page = maxPage
+ if p+1 > maxPage {
+ return maxPage, maxPage
+ } else if p < 0 {
+ return 0, maxPage
}
+ return p, maxPage
+}
+
+func Search(buffer *resultBuffer, page int, maxPage int) *model.ResultsModel {
+ buffer.mu.Lock()
+ defer buffer.mu.Unlock()
resultsModel := model.NewResultsModel()
for i := page * pageStep; i < page*pageStep+pageStep; i++ {
@@ -241,17 +230,70 @@ func HandleSearch(w http.ResponseWriter, r *http.Request) {
resultsModel.AppendResultsModelViews(cdsView, result.score)
}
- resultsModel.SearchTerm = searchTerm
resultsModel.CurrentPage = page
resultsModel.MaxPage = maxPage
- err = ui.Template.ExecuteTemplate(w, "results", resultsModel)
- if err != nil {
- fmt.Println(err)
- return
- }
+ return resultsModel
}
+/*
+ func HandleSearch(w http.ResponseWriter, r *http.Request) {
+ searchTerm := GetSearchTerm(r)
+
+ buffer, err := GetBuffer(searchTerm)
+ if err != nil {
+ err := BuildBuffer(searchTerm)
+ if err != nil {
+ err := ui.Template.ExecuteTemplate(w, "search-placeholder-no-result", nil)
+ if err != nil {
+ fmt.Println(err)
+ }
+ return
+ }
+ buffer, _ = GetBuffer(searchTerm)
+ }
+
+ buffer.mu.Lock()
+ defer buffer.mu.Unlock()
+
+ page := GetPage(r)
+ var maxPage int
+ if buffer.hits <= pageStep {
+ maxPage = 0
+ } else {
+ maxPage = (buffer.hits / pageStep)
+ }
+
+ if page+1 > maxPage {
+ page = maxPage
+ }
+
+ resultsModel := model.NewResultsModel()
+ for i := page * pageStep; i < page*pageStep+pageStep; i++ {
+ if i > len(buffer.results)-1 {
+ break
+ }
+ result := buffer.results[i]
+ cdsView, err := model.GetCDSViewModel(result.CDSViewTechnicalName)
+ if err != nil {
+ fmt.Println(err)
+ continue
+ }
+
+ resultsModel.AppendResultsModelViews(cdsView, result.score)
+ }
+
+ resultsModel.SearchTerm = searchTerm
+ resultsModel.CurrentPage = page
+ resultsModel.MaxPage = maxPage
+
+ err = ui.Template.ExecuteTemplate(w, "results", resultsModel)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ }
+*/
func ClearOldBuffers() {
for key, buffer := range resultsBuffer {
if time.Since(buffer.createdAt) >= time.Minute*10 {
diff --git a/cmd/ui/css/styles.css b/cmd/ui/css/styles.css
index 3adb48a..8a3ddc0 100644
--- a/cmd/ui/css/styles.css
+++ b/cmd/ui/css/styles.css
@@ -20,6 +20,12 @@
--yellow-5: #e5a50a;
--default-margin: 8px var(--base_margin) 8px var(--base_margin);
+
+ --default-outline: transparent solid 2px;
+ --default-outline-offset: 1px;
+
+ --transiton-outline:
+ outline-offset 0.1s ease-in-out, outline-color 0.1s ease-in-out;
}
@media (prefers-color-scheme: dark) {
@@ -313,13 +319,9 @@ button:active {
}
* {
- outline-offset: 1px;
- outline-style: solid;
- outline-width: 2px;
- outline-color: transparent;
- transition:
- outline-offset 0.1s ease-in-out,
- outline-color 0.1s ease-in-out;
+ outline-offset: var(--default-outline-offset);
+ outline: var(--default-outline);
+ transition: var(--transiton-outline);
}
*:focus-visible {
@@ -412,17 +414,33 @@ button:active {
width: 0%;
height: 0%;
margin: 0%;
- visibility: hidden;
+ border: none;
+ outline: none;
}
.boxed-list > .expander {
border-bottom-color: transparent !important;
- transition: border-bottom 0.15s steps(1, end);
+ transition:
+ var(--transiton-outline),
+ border-bottom 0.15s steps(1, end),
+ border-bottom-right-radius 0.05s 0.1s,
+ border-bottom-left-radius 0.05s 0.1s;
+}
+
+.boxed-list > .active.expander:focus-within {
+ outline-offset: -1px;
+ outline-color: color-mix(in srgb, var(--accent) 50%, transparent);
+ z-index: 1;
}
.expander:has(> .expander-state:checked) {
border-bottom: 1px solid var(--border) !important;
- transition: border-bottom 0.15s steps(1, start);
+ transition:
+ var(--transiton-outline),
+ border-bottom 0.15s steps(1, start),
+ border-bottom-right-radius 0.05s,
+ border-bottom-left-radius 0.05s;
+ transition-delay: 0s;
}
.expander-content {
diff --git a/cmd/ui/html/search-result.html b/cmd/ui/html/search-result.html
index f87e059..37521d6 100644
--- a/cmd/ui/html/search-result.html
+++ b/cmd/ui/html/search-result.html
@@ -11,6 +11,7 @@
{{end}} {{block "result" .}}
-
+
Field Properties
{{template "fields-placeholder" dict "Result" .}}
diff --git a/cmd/view/cdsDetails.go b/cmd/view/cdsDetails.go
new file mode 100644
index 0000000..74b0909
--- /dev/null
+++ b/cmd/view/cdsDetails.go
@@ -0,0 +1,78 @@
+package view
+
+import (
+ "api-cds-search/cmd/model"
+ "fmt"
+ "net/http"
+
+ "code.achtarmig.org/pas/ui/element"
+ "code.achtarmig.org/pas/ui/element/container"
+ "code.achtarmig.org/pas/ui/element/input"
+ "code.achtarmig.org/pas/ui/element/option"
+ "code.achtarmig.org/pas/ui/element/table"
+ "code.achtarmig.org/pas/ui/element/view"
+ "code.achtarmig.org/pas/ui/route"
+)
+
+func cdsDetails() {
+ view.New("CDSDetails", func(p *view.Element) {
+ route.Register("/cds", p)
+ p.Title = "CDSDetails"
+ p.OnRequest = onRequestDetails
+ container.New(p, "Details", func(p *container.Element) {
+ p.Justify = option.JustifyCenter
+ input.New(p, "q", input.TypeText, func(p *input.Element) {
+ p.Placeholder = "CDSViewTechnicalName"
+ p.Shape = option.ShapeRound
+ p.SetHTMX(element.HTMX{
+ Method: http.MethodGet,
+ Target: "#DetailsTable",
+ URL: "/cds",
+ PushURL: true,
+ })
+ })
+ })
+ container.New(p, "", func(p *container.Element) {
+ p.Justify = option.JustifyCenter
+ table.New(p, "DetailsTable", func(p *table.Element) {
+ p.MinWidth = 20
+ p.MaxWidth = 32
+ })
+ })
+ })
+}
+
+func onRequestDetails(e *view.Element, w http.ResponseWriter, r *http.Request) view.ProcessElements {
+ cds, _ := e.GetElement("q").(*input.Element).GetDataText()
+
+ e.Title = fmt.Sprintf("CDSDetails - %s", cds)
+
+ fields, err := model.GetCDSViewModelFields(cds)
+ if err != nil {
+ fmt.Println(err)
+ return view.ProcessElements{}
+ }
+
+ table := e.GetElement("DetailsTable").(*table.Element)
+
+ table.SetData(*fields)
+
+ for _, header := range table.Data.Header {
+ switch header.Name {
+ case "FieldNameOut":
+ header.Option.Font = option.FontMonospaced
+ case "DataTypeTitle":
+ case "FieldLengthOut":
+ header.Option.Font = option.FontMonospaced
+ case "DescriptionOut":
+ default:
+ header.Option.Hidden = true
+ }
+ }
+
+ table.Data.SetFieldOrder("FieldNameOut", "DescriptionOut", "DataTypeTitle", "FieldLengthOut")
+
+ return view.ProcessElements{
+ Partial: []element.ElementInterface{e.GetElement("DetailsTable")},
+ }
+}
diff --git a/cmd/view/load.go b/cmd/view/load.go
new file mode 100644
index 0000000..86f78dd
--- /dev/null
+++ b/cmd/view/load.go
@@ -0,0 +1,6 @@
+package view
+
+func Load() {
+ searchView()
+ cdsDetails()
+}
diff --git a/cmd/view/results.go b/cmd/view/results.go
new file mode 100644
index 0000000..f0cddac
--- /dev/null
+++ b/cmd/view/results.go
@@ -0,0 +1,50 @@
+package view
+
+import (
+ "api-cds-search/cmd/model"
+ "errors"
+ "net/http"
+ "net/url"
+
+ "code.achtarmig.org/pas/ui/element"
+ "code.achtarmig.org/pas/ui/element/boxedlist"
+ "code.achtarmig.org/pas/ui/element/boxedlist/expander"
+ "code.achtarmig.org/pas/ui/element/option"
+ "code.achtarmig.org/pas/ui/element/placeholder"
+ "code.achtarmig.org/pas/ui/element/view"
+)
+
+func results(v *view.Element, m *model.ResultsModel) element.ElementInterface {
+ cont := v.GetElement("SearchResultsContainer")
+ cont.DeleteAllChildren()
+
+ bl, _ := boxedlist.New(cont, "", func(p *boxedlist.Element) {
+ p.MaxWidth = 42
+ p.MinWidth = 20
+ for _, result := range m.Views {
+ expander.New(p, func(p *expander.Element) {
+ p.Title = result.DisplayName.String()
+ p.Subtitle = result.TechnicalName.String()
+ p.PlaceholderHeight = 21 * result.NumberOfFields
+ p.CallbackLazyLoad = func(e *expander.Element, w http.ResponseWriter, r *http.Request) error {
+ http.Redirect(w, r, "/cds?q="+url.QueryEscape(result.TechnicalName.String()), http.StatusSeeOther)
+ return errors.New("redirect")
+ }
+ })
+ }
+ })
+ return bl
+}
+
+func noResults(v *view.Element) element.ElementInterface {
+ cont := v.GetElement("SearchResultsContainer")
+ cont.DeleteAllChildren()
+
+ pl, _ := placeholder.New(cont, "", func(p *placeholder.Element) {
+ p.Icon = option.IconLoupe
+ p.Title = "No Results"
+ p.Subtitle = "Try refining your search term"
+ })
+
+ return pl
+}
diff --git a/cmd/view/search.go b/cmd/view/search.go
new file mode 100644
index 0000000..d8ee915
--- /dev/null
+++ b/cmd/view/search.go
@@ -0,0 +1,152 @@
+package view
+
+import (
+ "api-cds-search/cmd/search"
+ "net/http"
+
+ "code.achtarmig.org/pas/ui/element"
+ "code.achtarmig.org/pas/ui/element/button"
+ "code.achtarmig.org/pas/ui/element/container"
+ "code.achtarmig.org/pas/ui/element/form"
+ "code.achtarmig.org/pas/ui/element/input"
+ "code.achtarmig.org/pas/ui/element/option"
+ "code.achtarmig.org/pas/ui/element/placeholder"
+ "code.achtarmig.org/pas/ui/element/view"
+ "code.achtarmig.org/pas/ui/route"
+)
+
+func noSearch(v *view.Element) element.ElementInterface {
+ cont := v.GetElement("SearchResultsContainer")
+ cont.DeleteAllChildren()
+
+ pl, _ := placeholder.New(cont, "", func(p *placeholder.Element) {
+ p.Icon = option.IconLoupe
+ p.Title = "Search CDS-Views"
+ p.Subtitle = "Find CDS-Views from the Business Accelerator Hub"
+ })
+ return pl
+}
+
+func searchView() {
+ view.New("Search", func(p *view.Element) {
+ route.Register("/search", p)
+ p.Title = "CDS-Search"
+ p.OnRequest = func(v *view.Element, w http.ResponseWriter, r *http.Request) view.ProcessElements {
+ inputQuery := v.GetElement("q").(*input.Element)
+ inputQueryValue, _ := v.GetElement("q").(*input.Element).GetDataText()
+
+ searchTerm := search.GetSearchTerm(inputQueryValue)
+ if inputQueryValue == "" {
+ noSearch(v)
+ }
+
+ inputPage := v.GetElement("p").(*input.Element)
+ inputMaxPage := v.GetElement("MaxPage").(*input.Element)
+
+ currentPage, _ := inputPage.GetDataNumber()
+
+ if inputQuery.GetDataChanged() && inputQueryValue != "" {
+ buf, err := search.GetBuffer(searchTerm)
+ if err != nil {
+ search.BuildBuffer(searchTerm)
+ buf, err = search.GetBuffer(searchTerm)
+ }
+
+ if err != nil {
+ noResults(v)
+ } else {
+ currentPage, maxPage := search.GetPages(buf, currentPage)
+
+ m := search.Search(buf, currentPage, maxPage)
+
+ inputPage.Max = m.MaxPage
+ inputMaxPage.Min = m.MaxPage
+ inputMaxPage.Max = m.MaxPage
+ inputMaxPage.SetData(m.MaxPage)
+
+ results(v, m)
+ }
+ }
+
+ return view.ProcessElements{
+ Partial: []element.ElementInterface{v.GetElement("SearchResultsContainer")},
+ OOBUpdate: []element.ElementInterface{inputPage, inputMaxPage},
+ }
+ }
+ container.New(p, "MainContainer", func(p *container.Element) {
+ p.Justify = option.JustifyCenter
+ form.New(p, "SearchForm", func(p *form.Element) {
+ p.SetHTMX(element.HTMX{
+ Method: http.MethodGet,
+ Target: "#SearchResultsContainer>*",
+ Swap: "outerHTML",
+ URL: "/search",
+ PushURL: true,
+ Params: "q, p",
+ })
+
+ container.New(p, "SearchFormLinked", func(p *container.Element) {
+ p.Justify = option.JustifyCenter
+ p.LinkedHorizontal = true
+ input.New(p, "q", input.TypeText, func(p *input.Element) {
+ p.Placeholder = "Search here"
+ p.Shape = option.ShapeRound
+
+ p.MinWidth = 10
+ p.MaxWidth = 36
+ })
+
+ button.New(p, "SearchButton", func(p *button.Element) {
+ p.Label = "Search"
+ p.DisplayStyle = option.DisplayStyleSuggestedAction
+ p.Shape = option.ShapeRound
+
+ p.MaxWidth = 6
+ })
+ })
+
+ })
+ })
+
+ container.New(p, "CenterPager", func(p *container.Element) {
+ p.Justify = option.JustifyCenter
+ container.New(p, "Pager", func(p *container.Element) {
+ p.MaxWidth = 42
+ p.MinWidth = 10
+ p.Justify = option.JustifyRight
+ p.LinkedHorizontal = true
+ input.New(p, "p", input.TypeNumber, func(p *input.Element) {
+ p.Shape = option.ShapeRound
+
+ p.SetMin = true
+ p.Min = 0
+
+ p.SetMax = true
+ p.Max = 0
+
+ p.MinWidth = 4
+
+ p.SetHTMX(element.HTMX{
+ Method: http.MethodGet,
+ Include: "[name='q'], [name='p']",
+ Target: "#SearchResultsContainer>*",
+ URL: "/search",
+ Swap: "outerHTML",
+ PushURL: true,
+ })
+ })
+ input.New(p, "MaxPage", input.TypeNumber, func(p *input.Element) {
+ p.Disabled = true
+ p.Shape = option.ShapeRound
+ p.MinWidth = 4
+ p.SetMin = true
+ p.SetMax = true
+ })
+ })
+ })
+
+ container.New(p, "SearchResultsContainer", func(p *container.Element) {
+ p.Justify = option.JustifyCenter
+ })
+ })
+}
diff --git a/go.mod b/go.mod
index 0cc19a2..111217a 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module api-cds-search
go 1.23.7
require (
+ code.achtarmig.org/pas/ui v0.0.0-20250517190325-787754158160
github.com/glebarez/go-sqlite v1.22.0
github.com/go-chi/chi v1.5.5
github.com/lithammer/fuzzysearch v1.1.8
@@ -10,8 +11,9 @@ require (
)
require (
+ github.com/brunoga/deep v1.2.4 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
- github.com/google/uuid v1.5.0 // indirect
+ github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.15.0 // indirect
diff --git a/go.sum b/go.sum
index b15d31a..56adc7a 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,215 @@
+code.achtarmig.org/pas/ui v0.0.0-20250423130241-77cad1ae9e1d h1:uGvywYhWyOpo3AStulDAEt/eOVFKbj5wIb/DpdjTusM=
+code.achtarmig.org/pas/ui v0.0.0-20250423130241-77cad1ae9e1d/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430113606-b06d1c915f57 h1:oN6mf0Y+buCL24zHHSYDnZG6h37WLuU47XQ8e6Zrfv8=
+code.achtarmig.org/pas/ui v0.0.0-20250430113606-b06d1c915f57/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430122418-e994dcdf428e h1:sp4HES6StGtWPXGCUtjmJc00HXQqifwgfJ3bpCBkzt0=
+code.achtarmig.org/pas/ui v0.0.0-20250430122418-e994dcdf428e/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430122527-723745a86856 h1:qhZbwO8E8lwnabUBy8I9NapW4gi74wXcuhdkOnPiQSo=
+code.achtarmig.org/pas/ui v0.0.0-20250430122527-723745a86856/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430122621-716d6f1f7ca5 h1:hyxC82CZH+OofqLaDgkpPg0e/OrJ3sKiLAKGec2vwus=
+code.achtarmig.org/pas/ui v0.0.0-20250430122621-716d6f1f7ca5/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430122747-0f082828f3d9 h1:gYoDsaZ4a4ZnX8KzNC/LNshLmkeTu+DZs2gQqp1vysM=
+code.achtarmig.org/pas/ui v0.0.0-20250430122747-0f082828f3d9/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430125057-3c3d7f686e6d h1:mx/ofzGdwbmRgNCDhIHvDMtT8owh6LvVIAdEu2pp+2U=
+code.achtarmig.org/pas/ui v0.0.0-20250430125057-3c3d7f686e6d/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430132955-f3328dc3d2bd h1:LyWYfQWNf1FRf7AEKSTcpuQcnpwpvIS6oOz828Lbq70=
+code.achtarmig.org/pas/ui v0.0.0-20250430132955-f3328dc3d2bd/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430133200-55d5145d392f h1:BwatQO1LJod6vPXUqcR7IlGKVE4z+0MgVEcdoPdsSgE=
+code.achtarmig.org/pas/ui v0.0.0-20250430133200-55d5145d392f/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430140629-19d614a3a17a h1:egpbXwz7V1NqlkUyKMsIKQoJUz30hgabhGCWo6MtGQI=
+code.achtarmig.org/pas/ui v0.0.0-20250430140629-19d614a3a17a/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430183457-ddd4de8d7463 h1:iHoMtL048RLx4rggB5fxl1BzKLDJcjgYPK7nKe4cX8k=
+code.achtarmig.org/pas/ui v0.0.0-20250430183457-ddd4de8d7463/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430184356-704e6170c8f9 h1:TEZklUc7HXxZDu9N1mBI0TUUxqOD6QDPaXv5Di2L4dM=
+code.achtarmig.org/pas/ui v0.0.0-20250430184356-704e6170c8f9/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250430185113-67713d8f187a h1:k8e6d/YHlHWi0OHG5LRMxq84ZfIs6ZYD6rA0fj8hxz0=
+code.achtarmig.org/pas/ui v0.0.0-20250430185113-67713d8f187a/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503122000-14ef7d4aa1fe h1:KYAD8d054+NW/6TFpbCsi1aZhxv1GBZMVgK7bUBjWiE=
+code.achtarmig.org/pas/ui v0.0.0-20250503122000-14ef7d4aa1fe/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503122350-ca09a49145e1 h1:I8sMNf4RN9xrChdrHQNQR2g6VsCab/+kmvwM4Qcwgqc=
+code.achtarmig.org/pas/ui v0.0.0-20250503122350-ca09a49145e1/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503123128-ef12a6cf86a7 h1:7nC74Z99klsKLMvhAfb2aXrgrYJ7nXUEUVltx3I1LSw=
+code.achtarmig.org/pas/ui v0.0.0-20250503123128-ef12a6cf86a7/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503174327-574f87c22162 h1:8HsKiui5rFEuxcbYv0cprgzqhqIcuj75lyqiAv5jLCg=
+code.achtarmig.org/pas/ui v0.0.0-20250503174327-574f87c22162/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503175603-cd58c6b71bae h1:lCYhD2ZjKUbDrUKy/K9G+ggZN1UPtgyITag5X2PyCYQ=
+code.achtarmig.org/pas/ui v0.0.0-20250503175603-cd58c6b71bae/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503175854-ac3566f449e3 h1:4GiyS+c9z2oaM+5Vp7xOZQMJ0LoZ7dwES04TYz/7FrE=
+code.achtarmig.org/pas/ui v0.0.0-20250503175854-ac3566f449e3/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503200130-5cfbd172319e h1:nAa/Z9zPpqOuqD8a88nXmDJutFvRyvL+DrxXkrYecC4=
+code.achtarmig.org/pas/ui v0.0.0-20250503200130-5cfbd172319e/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503200638-86b83511e1ac h1:oCRNrA7iyknOh5IdKSowJHvxrFVsfLyxXFyPKuoZSfY=
+code.achtarmig.org/pas/ui v0.0.0-20250503200638-86b83511e1ac/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503200916-89b2e3372d44 h1:u5g8Uue4hwHvC4mf88KR6UOP2MlOJ20ec+r2nL3larQ=
+code.achtarmig.org/pas/ui v0.0.0-20250503200916-89b2e3372d44/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503202213-fe34a6626602 h1:cM7oU11Hyfguve2IisQ+njmLlShJ2/TMlONPn8mU21w=
+code.achtarmig.org/pas/ui v0.0.0-20250503202213-fe34a6626602/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503202706-191f0ba06ef0 h1:E4KdkkQ7+/JaC8QVERSZF9IgUqrPFLsroLfkw2eCHX8=
+code.achtarmig.org/pas/ui v0.0.0-20250503202706-191f0ba06ef0/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250503202925-88f242608f55 h1:9f7RX0BLAt6TdaZyzi6yJBSoqGpbeKKBKf9GCWerRts=
+code.achtarmig.org/pas/ui v0.0.0-20250503202925-88f242608f55/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504114726-3bde89f2f2fb h1:SvbyZGE4q4fL+KuCxhm3QNvnTKiT1rr7lXvWNZIDHz8=
+code.achtarmig.org/pas/ui v0.0.0-20250504114726-3bde89f2f2fb/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504115809-c8bb4889c67f h1:78c5k3ffa9jC5I1euYdu01csXMST+o0+bmXqALhGzeY=
+code.achtarmig.org/pas/ui v0.0.0-20250504115809-c8bb4889c67f/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504115940-3e79e98097c0 h1:pl+3/Ru4KlRGMvGijDqsXN9DCc5Nuus/wr1piEECIck=
+code.achtarmig.org/pas/ui v0.0.0-20250504115940-3e79e98097c0/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504120250-a9712dd18679 h1:uz95zU0tOZbVNa38n7bwjniHub4j7H53kWRmdPsC+1o=
+code.achtarmig.org/pas/ui v0.0.0-20250504120250-a9712dd18679/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504121523-7fd26ddcd810 h1:Cu0oEI3/BLGCGd4gr+Ha/xPW6CE0VRwqYatTYlRijOk=
+code.achtarmig.org/pas/ui v0.0.0-20250504121523-7fd26ddcd810/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504154112-b35362d1de7a h1:7T/1ys9aL2tT7/1MWFlmO3t+EswMUqQ4G/BrrTAS4mE=
+code.achtarmig.org/pas/ui v0.0.0-20250504154112-b35362d1de7a/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504154732-a2c1862dbe42 h1:kGPimrMs0QMpOmllkdFg1in6yMOcbmBczr1zJdvhExg=
+code.achtarmig.org/pas/ui v0.0.0-20250504154732-a2c1862dbe42/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504155328-7d607cc2b350 h1:CwHrMnI6Q+OZGjxNG4K8pA6mDMCF3BEVm90LnHe255c=
+code.achtarmig.org/pas/ui v0.0.0-20250504155328-7d607cc2b350/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504155925-937597c45faf h1:CkEESNCQbBZr+nm6mP9lC3uO3IbB6I7fwcpWI2fD4ns=
+code.achtarmig.org/pas/ui v0.0.0-20250504155925-937597c45faf/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504160422-82720c4a582f h1:aPwdsIpaR4zCJjXXr9TMCs+AAUfJR2mx/LQFj1H2rUg=
+code.achtarmig.org/pas/ui v0.0.0-20250504160422-82720c4a582f/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504160947-5abddd47fc06 h1:+szpi3rOl/60a1c8rPDqA9vWkpc4S7+83VMHNdIjyqU=
+code.achtarmig.org/pas/ui v0.0.0-20250504160947-5abddd47fc06/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504161605-3e0c61e0de92 h1:l4mhR9E1Ol7u+38u+OxsLkWq6EY+vslaJZ+gPVofVGc=
+code.achtarmig.org/pas/ui v0.0.0-20250504161605-3e0c61e0de92/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504162027-fbb39ad09295 h1:cUyyCcpC+451iGbZWCgp6Ka/BZt6dgOBJjSsAnwUfgg=
+code.achtarmig.org/pas/ui v0.0.0-20250504162027-fbb39ad09295/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250504163359-c5823941f5de h1:QtXmasvjhZJhM9OMzLrzg2t5KnleQJDlryU5nV4SNwI=
+code.achtarmig.org/pas/ui v0.0.0-20250504163359-c5823941f5de/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510123925-70468693fff8 h1:BNXtJ9igWRUvLHEnKh5aPqkLl3fc/Ac8DTxKuv0yPHc=
+code.achtarmig.org/pas/ui v0.0.0-20250510123925-70468693fff8/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510125712-789b656761c6 h1:L1eIHKdnlpUDsNh7jMPA6xoOm/ImXokeDqoYvdk/3vQ=
+code.achtarmig.org/pas/ui v0.0.0-20250510125712-789b656761c6/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510134444-ef0b491dc1fb h1:ZN+XIPVRf89U62M/fE0rFMklqw5Ly6tLk57fTpsp4as=
+code.achtarmig.org/pas/ui v0.0.0-20250510134444-ef0b491dc1fb/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510134646-e5a55632c22d h1:nJGLQOFwGRkERiN9x4UMG2fyb1DmdLZrEjGIAe1ND7U=
+code.achtarmig.org/pas/ui v0.0.0-20250510134646-e5a55632c22d/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510135554-2605d777003e h1:bKkN2NNnzCtfcLvCMvtpjW0yxwt9531wCPnykSUhZys=
+code.achtarmig.org/pas/ui v0.0.0-20250510135554-2605d777003e/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510184256-35a0aab89b29 h1:MCHb7zoyC7RDzqoid99cRcFEOvgyPz++pNlc7zrTuto=
+code.achtarmig.org/pas/ui v0.0.0-20250510184256-35a0aab89b29/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510184612-1bcb7d9999a8 h1:W3l3XlITKMWocvH1NvkTT6qiDsjeYWVVZ7Z0s12EsGM=
+code.achtarmig.org/pas/ui v0.0.0-20250510184612-1bcb7d9999a8/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510184917-9351a88fc4a4 h1:kE+KISIECBxpAKl160aJrwwB/VevHPY2f4o+kd46n8o=
+code.achtarmig.org/pas/ui v0.0.0-20250510184917-9351a88fc4a4/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510185314-cd715ae2581d h1:AE8Nm2o/rzv1gA+x4/tQg1Dql5yXB+rsx7DBhctFhsU=
+code.achtarmig.org/pas/ui v0.0.0-20250510185314-cd715ae2581d/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510185935-a3e4c3080809 h1:SorDBnZy8K858ZlyqjnDKQ0A2/sokXHWTEeEwYP/Y6U=
+code.achtarmig.org/pas/ui v0.0.0-20250510185935-a3e4c3080809/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510190018-7925a85133bd h1:WLV/G50Eq2hmn9NKORB1IlGTCpemT7cALCmAXCjpc6Y=
+code.achtarmig.org/pas/ui v0.0.0-20250510190018-7925a85133bd/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510191623-95ee9bd6e555 h1:ib8e/1Som5oJ2xN2JFoZ4YYMPmpb2ubOxNQgnRcIRAo=
+code.achtarmig.org/pas/ui v0.0.0-20250510191623-95ee9bd6e555/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510191713-c2bb3765e103 h1:YNP0RwIwMFUcva48HYGMDCh4kMPRjc4Ro5r/KzNwP/0=
+code.achtarmig.org/pas/ui v0.0.0-20250510191713-c2bb3765e103/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510192244-e26d63f0c10d h1:ISxGDw+9SV1EXdW8wV/GaBbReIPS/GlmVo/Hd27cdVI=
+code.achtarmig.org/pas/ui v0.0.0-20250510192244-e26d63f0c10d/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510194823-67183feea29d h1:WSY4zHK4c3l9TctKstaOwW9tI6hDlgK9RrxwOAswStg=
+code.achtarmig.org/pas/ui v0.0.0-20250510194823-67183feea29d/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510195045-1ebf277e7b80 h1:AhVQdQPzelUyujK8gHFzdBbyXmxKercHQMGaZd1o9GY=
+code.achtarmig.org/pas/ui v0.0.0-20250510195045-1ebf277e7b80/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510195147-dd8180018555 h1:sERMsf3AvPOoV81S6tVi71RY2uARjuOdEM735V67T6k=
+code.achtarmig.org/pas/ui v0.0.0-20250510195147-dd8180018555/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510195254-844d8b86cd65 h1:9sulVyGp0gbBqzYGyxLsfi0ia5VKeaoTuqoC6uHrx2Y=
+code.achtarmig.org/pas/ui v0.0.0-20250510195254-844d8b86cd65/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510195449-a4edaa18b12b h1:Lw2ODGz5WeSsuSElyB+emJexL3OUFAIAKgLSVpTDfXY=
+code.achtarmig.org/pas/ui v0.0.0-20250510195449-a4edaa18b12b/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250510200645-d30582aba20f h1:w6hwfaooh0R0iFAm4zBkvEYAY9hU+UfUfqiQ02HAecA=
+code.achtarmig.org/pas/ui v0.0.0-20250510200645-d30582aba20f/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511101857-c9522c929e52 h1:W1lARZUamuhbTg9ijdvlDItpoRTa3zFIOPKrSxeqqcU=
+code.achtarmig.org/pas/ui v0.0.0-20250511101857-c9522c929e52/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511102211-fbb465629817 h1:I95XjYlW95GPlhBoVvyEYub64NRL+tXoTRXOOW1DWS8=
+code.achtarmig.org/pas/ui v0.0.0-20250511102211-fbb465629817/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511104020-73c99e4079db h1:3YngqYBJsfj3Lq91y/70vx6lVddtaFbNKhfFuNeS6f4=
+code.achtarmig.org/pas/ui v0.0.0-20250511104020-73c99e4079db/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511104107-3ce0ae192e71 h1:+PYrXO0d0yll+YzrGapWUdHWL5Rz3zHupjtb8n240kE=
+code.achtarmig.org/pas/ui v0.0.0-20250511104107-3ce0ae192e71/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511104937-72d3894969da h1:/lnKZuj9ejYlvsCkuwTh+4DFtyNoVPYBxzrvnhktgMQ=
+code.achtarmig.org/pas/ui v0.0.0-20250511104937-72d3894969da/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511105443-5c1f838d4a0f h1:QDn3alVreFX0vcjQRb2+wwdPJBAIBo+i3hKJTyjBq6o=
+code.achtarmig.org/pas/ui v0.0.0-20250511105443-5c1f838d4a0f/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511151203-13674fd646aa h1:/i5zED2WIpbFet891Bo06cgnz2HWXN5Zm3ZSj1Hf90c=
+code.achtarmig.org/pas/ui v0.0.0-20250511151203-13674fd646aa/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511153040-e11277d114d5 h1:ynqYEdYJp0o/+U6tMAIiWBG6XxwR1lNRuYCiMOp25HY=
+code.achtarmig.org/pas/ui v0.0.0-20250511153040-e11277d114d5/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511153246-1bbaa9a9c064 h1:vQDWG+vKlZvkwRqKpNXjDzwplJ9+7BiKGqpO79NL89A=
+code.achtarmig.org/pas/ui v0.0.0-20250511153246-1bbaa9a9c064/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511154145-4fd1fd0ddc07 h1:wRG5adpk4tkQTd7XVwFpDRT5YIMcwwlAyE3noERdQ3I=
+code.achtarmig.org/pas/ui v0.0.0-20250511154145-4fd1fd0ddc07/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511154410-2b973a9a73be h1:eBv/xQjbJSuZn2P+tSHF0uyaHytiNfuAMO+jTObSNyA=
+code.achtarmig.org/pas/ui v0.0.0-20250511154410-2b973a9a73be/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511161328-dd31f33492f4 h1:PptkC6SxYcHgjhFpCuAhxXzzSBI8vStJgrxHKq8uDDw=
+code.achtarmig.org/pas/ui v0.0.0-20250511161328-dd31f33492f4/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511161424-eefb1ef0cc64 h1:L8OXWZJMcXfLczw7K8L0aRw/+Fc1Cni/e8IN6+8KTb8=
+code.achtarmig.org/pas/ui v0.0.0-20250511161424-eefb1ef0cc64/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511162939-f3eb6979ea6a h1:5Vi25SRFYolW33Z5kuR24WuGTlrYX+3kNz8sN2o6/XE=
+code.achtarmig.org/pas/ui v0.0.0-20250511162939-f3eb6979ea6a/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511163155-3a5297d15113 h1:DfPcOFyP8Cb2OZdIZ0Iut5MaYCQ4uAbCEXR6ARJQpfY=
+code.achtarmig.org/pas/ui v0.0.0-20250511163155-3a5297d15113/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511164038-2cd675ad25b0 h1:z3Iv3TZ2tMwz7u8FfXJy1IOVSDAKlNyEcznTkDmktl0=
+code.achtarmig.org/pas/ui v0.0.0-20250511164038-2cd675ad25b0/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250511170323-e2f03337de02 h1:tlzr0yK00spUfOvOGKW+rrcJkwEzoVQ38ITSJ7Bls9Q=
+code.achtarmig.org/pas/ui v0.0.0-20250511170323-e2f03337de02/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250512111133-6e9e1a71e19a h1:EH516+SqXOQRObBuE7eF0dPmmWM3y62nt3BY2YWvHEU=
+code.achtarmig.org/pas/ui v0.0.0-20250512111133-6e9e1a71e19a/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250513102739-4e7567276b04 h1:2Z6/NpVxFMQXx6XSUQzD0oXjtmXqAmgulmk8A4QnVRQ=
+code.achtarmig.org/pas/ui v0.0.0-20250513102739-4e7567276b04/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250513140013-21a745c1c568 h1:mpBvvdzCNFvSIaQZsZqrKa1Hsv7wPS8NKxYyYRzMQOk=
+code.achtarmig.org/pas/ui v0.0.0-20250513140013-21a745c1c568/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250513142047-00f7ddea00a7 h1:xLyy3vImxIekNtRDUKxCKY8JznlLU35tFWAYYCM2NeY=
+code.achtarmig.org/pas/ui v0.0.0-20250513142047-00f7ddea00a7/go.mod h1:2stpDl/L6Zgd4a/r+fDMsMMuF59aKQbAIeByX1UqiQo=
+code.achtarmig.org/pas/ui v0.0.0-20250513143630-9e4d6dc54a7b h1:nwMTMHUGJ8lR7Zfe2EWV5ejurX7ekPIdp9CY8XRVBvI=
+code.achtarmig.org/pas/ui v0.0.0-20250513143630-9e4d6dc54a7b/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250513143807-63cda742ff1d h1:ysS1jekxniyT2X+6Xs1d7ACyf6zp2P6RvGKQkBgYtcQ=
+code.achtarmig.org/pas/ui v0.0.0-20250513143807-63cda742ff1d/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250513144145-668a268206b5 h1:8kp9Eni8pPzIcrSEscPvv80Vts6g6cQveYn8AbCjua0=
+code.achtarmig.org/pas/ui v0.0.0-20250513144145-668a268206b5/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250513144308-65cccdc5bbfe h1:sCD7tNfcLIIWbdzcgP61gl4KYB66XiXZUuC4jyFSfRA=
+code.achtarmig.org/pas/ui v0.0.0-20250513144308-65cccdc5bbfe/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250513144523-6606ec845bba h1:8VTJw2g4KGPNB0JwjqK6dD4A3DhmkciHtMbJetnIW2k=
+code.achtarmig.org/pas/ui v0.0.0-20250513144523-6606ec845bba/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514120506-952c80d0f738 h1:wFboIbcnfFQH6/Qbkj+UHnllCO9QYo/lwd2BKj6AJyc=
+code.achtarmig.org/pas/ui v0.0.0-20250514120506-952c80d0f738/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514122252-e4f1d325fae8 h1:pj9Q/9f+IEDPGwOMFdzbXlfwyHXYq79tGg5tPVMojkg=
+code.achtarmig.org/pas/ui v0.0.0-20250514122252-e4f1d325fae8/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514122424-5e3d340ca863 h1:+A/EogWV8HgLVlIwD1Kg8GgMU5tGrPJU1Vxq4vyObQw=
+code.achtarmig.org/pas/ui v0.0.0-20250514122424-5e3d340ca863/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514123644-7dcce853ff26 h1:ee7R2Ju5TprjvWRRocQBgRX9kaVViaQQPKUNXnkyAk8=
+code.achtarmig.org/pas/ui v0.0.0-20250514123644-7dcce853ff26/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514124305-a96fa2289ecb h1:LJppDfp+snlTT0GvpbI/56+pLFEz3pz/VSwPn03MLZg=
+code.achtarmig.org/pas/ui v0.0.0-20250514124305-a96fa2289ecb/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514125154-c6cdc00606d3 h1:t9yVH033nfQb0rL/WYWcYZv9/uU5bIDzSijmIAmfmYQ=
+code.achtarmig.org/pas/ui v0.0.0-20250514125154-c6cdc00606d3/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514130353-23c3e2c1ba34 h1:NzbVq44g+3kQ+ZW+NQ2q4zZWCxfg8UeG1niB7lxZTGk=
+code.achtarmig.org/pas/ui v0.0.0-20250514130353-23c3e2c1ba34/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514130600-a6eda5b72022 h1:YAFvQtdvALH2QNuoW3br6o5/2Us/jlYs2cOGDreGx8M=
+code.achtarmig.org/pas/ui v0.0.0-20250514130600-a6eda5b72022/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514131843-bc2592f71ec6 h1:UkKJX5xyAq/6uc5rjlqWHa1p7OjGmBvyoMcwa+JrCgg=
+code.achtarmig.org/pas/ui v0.0.0-20250514131843-bc2592f71ec6/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250514132050-3b11d4bdb25e h1:7cYgy4IYq1ACBef2wNz+k8dZgcPk+WWtiYvE8531S6Y=
+code.achtarmig.org/pas/ui v0.0.0-20250514132050-3b11d4bdb25e/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250515103640-ddb21adf0d29 h1:2vUjuMTAVs/8pmGQVOYpybDY4LLQBePmczbwZHfkGYw=
+code.achtarmig.org/pas/ui v0.0.0-20250515103640-ddb21adf0d29/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250515105216-53b01f136224 h1:PWWH4D+yaBCitO24B4gKMYXV7QTlP78UdYq8Ji59hto=
+code.achtarmig.org/pas/ui v0.0.0-20250515105216-53b01f136224/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250515105337-c5a46ed2a62d h1:tolI3Hxb8enAyKaBcZWDIUCTtEZBrTjWDun6qGqRRpM=
+code.achtarmig.org/pas/ui v0.0.0-20250515105337-c5a46ed2a62d/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250515105849-6f9f30e64064 h1:H78/VvWx090mQX7dKEdGzL90vvTzUwOgYmDoQKh7yvA=
+code.achtarmig.org/pas/ui v0.0.0-20250515105849-6f9f30e64064/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250516145820-afcad1b404f9 h1:lOYW70hhGlVXYV0w3soR3K+erlp+O7br+6zhhGDr9JE=
+code.achtarmig.org/pas/ui v0.0.0-20250516145820-afcad1b404f9/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250516150330-0d4a4f187e99 h1:SQQUM1ZsQXStnzkDgC869AmUHvuoc10rLV0a0UWQuxY=
+code.achtarmig.org/pas/ui v0.0.0-20250516150330-0d4a4f187e99/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250516150408-103956f4ad18 h1:UlnzGHkmabY6BRj7mWDq4aIQdu9kzu62aNLULB2Ndzo=
+code.achtarmig.org/pas/ui v0.0.0-20250516150408-103956f4ad18/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250516183309-055656de4f20 h1:+Ilsu1StGBv3Jk4w6g13XSH1uNdAqiKOcNgZCfyyj/E=
+code.achtarmig.org/pas/ui v0.0.0-20250516183309-055656de4f20/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250516183430-2a5f949482b3 h1:K0RlHqhiWd3yr3RPYUhhVaQLJLIMjwtIQ7SwDE1zkuM=
+code.achtarmig.org/pas/ui v0.0.0-20250516183430-2a5f949482b3/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+code.achtarmig.org/pas/ui v0.0.0-20250517190325-787754158160 h1:nhr5BUMdLRJrj/DnO4LZdsPwgIz3vYvaf08LdND7Eu8=
+code.achtarmig.org/pas/ui v0.0.0-20250517190325-787754158160/go.mod h1:4SnZejrC0bLr2Kq1yt4TBis8lo2hHA8K0m/0B2l6Uo0=
+github.com/brunoga/deep v1.2.4 h1:Aj9E9oUbE+ccbyh35VC/NHlzzjfIVU69BXu2mt2LmL8=
+github.com/brunoga/deep v1.2.4/go.mod h1:GDV6dnXqn80ezsLSZ5Wlv1PdKAWAO4L5PnKYtv2dgaI=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
@@ -6,8 +218,8 @@ github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
-github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
-github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
diff --git a/main.go b/main.go
index 9065ab9..eeffbef 100644
--- a/main.go
+++ b/main.go
@@ -5,18 +5,28 @@ import (
"api-cds-search/cmd/router"
"api-cds-search/cmd/search"
"api-cds-search/cmd/ui"
+ "api-cds-search/cmd/view"
"fmt"
"net/http"
+
+ "code.achtarmig.org/pas/ui/initialize"
+ "code.achtarmig.org/pas/ui/log"
)
func main() {
+ initialize.Init()
+
database.Load()
err := search.Load()
if err != nil {
panic(err)
}
+
ui.Load()
+ view.Load()
+ log.SetPrintError(true)
+
r := router.Load()
fmt.Println("Listening on :8080")