detached e08572c

feat(web): show releases as one card with prose notes and the latest release in About

commit
e08572cdbcb35f78e9849a172ea0dd69ef5105b9
author
brice · · 2026-10-22 05:47 UTC
committer
brice · · 2026-10-22 08:51 UTC
parent
5d69f2b
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
10 files · +518 -304
M internal/adapters/web/fragments.go +1 -1
@@ -167,7 +167,7 @@ func (l *liveStream) gone(ctx context.Context, name string) ([]fragment, error)
167167 func (l *liveStream) repoPage(ctx context.Context, we ports.WatchEvent) ([]fragment, error) {
168168 switch ev := we.Event.(type) {
169169 case domain.ReleasePublished, domain.ReleaseUpdated, domain.ReleaseDeleted, domain.ReleaseUnpublished:
170- if l.view == "releases" || l.view == "release" {
170+ if l.view == "releases" || l.view == "release" || l.view == "summary" {
171171 return gap, nil // notes, assets, latest or visibility changed: reload
172172 }
173173 return nil, nil
@@ -167,7 +167,7 @@ func (l *liveStream) gone(ctx context.Context, name string) ([]fragment, error)
167 func (l *liveStream) repoPage(ctx context.Context, we ports.WatchEvent) ([]fragment, error) {167 func (l *liveStream) repoPage(ctx context.Context, we ports.WatchEvent) ([]fragment, error) {
168 switch ev := we.Event.(type) {168 switch ev := we.Event.(type) {
169 case domain.ReleasePublished, domain.ReleaseUpdated, domain.ReleaseDeleted, domain.ReleaseUnpublished:169 case domain.ReleasePublished, domain.ReleaseUpdated, domain.ReleaseDeleted, domain.ReleaseUnpublished:
170- if l.view == "releases" || l.view == "release" {170+ if l.view == "releases" || l.view == "release" || l.view == "summary" {
171 return gap, nil // notes, assets, latest or visibility changed: reload171 return gap, nil // notes, assets, latest or visibility changed: reload
172 }172 }
173 return nil, nil173 return nil, nil
M internal/adapters/web/fragments_test.go +3 -3
@@ -101,8 +101,8 @@ func TestMRPushedHeadSignal(t *testing.T) {
101101 }
102102 }
103103
104-// Release lifecycle events invalidate the release pages without putting notes
105-// or asset metadata in SSE payloads. Other views need no release fragments.
104+// Release lifecycle events invalidate release pages and the summary's release
105+// fact without putting notes or asset metadata in SSE payloads.
106106 func TestReleaseLiveUpdates(t *testing.T) {
107107 for _, ev := range []domain.Event{domain.ReleasePublished{}, domain.ReleaseUpdated{}, domain.ReleaseDeleted{}, domain.ReleaseUnpublished{}} {
108108 we := ports.WatchEvent{Event: ev}
@@ -111,7 +111,7 @@ func TestReleaseLiveUpdates(t *testing.T) {
111111 st := &liveStream{repo: "proj", view: view}
112112 got, err := st.render(t.Context(), we)
113113 require.NoError(t, err)
114- if view == "release" || view == "releases" {
114+ if view == "release" || view == "releases" || view == "summary" {
115115 assert.Equal(t, gap, got)
116116 } else {
117117 assert.Empty(t, got)
@@ -101,8 +101,8 @@ func TestMRPushedHeadSignal(t *testing.T) {
101 }101 }
102 }102 }
103 103
104-// Release lifecycle events invalidate the release pages without putting notes104+// Release lifecycle events invalidate release pages and the summary's release
105-// or asset metadata in SSE payloads. Other views need no release fragments.105+// fact without putting notes or asset metadata in SSE payloads.
106 func TestReleaseLiveUpdates(t *testing.T) {106 func TestReleaseLiveUpdates(t *testing.T) {
107 for _, ev := range []domain.Event{domain.ReleasePublished{}, domain.ReleaseUpdated{}, domain.ReleaseDeleted{}, domain.ReleaseUnpublished{}} {107 for _, ev := range []domain.Event{domain.ReleasePublished{}, domain.ReleaseUpdated{}, domain.ReleaseDeleted{}, domain.ReleaseUnpublished{}} {
108 we := ports.WatchEvent{Event: ev}108 we := ports.WatchEvent{Event: ev}
@@ -111,7 +111,7 @@ func TestReleaseLiveUpdates(t *testing.T) {
111 st := &liveStream{repo: "proj", view: view}111 st := &liveStream{repo: "proj", view: view}
112 got, err := st.render(t.Context(), we)112 got, err := st.render(t.Context(), we)
113 require.NoError(t, err)113 require.NoError(t, err)
114- if view == "release" || view == "releases" {114+ if view == "release" || view == "releases" || view == "summary" {
115 assert.Equal(t, gap, got)115 assert.Equal(t, gap, got)
116 } else {116 } else {
117 assert.Empty(t, got)117 assert.Empty(t, got)
M internal/adapters/web/pages.templ +8 -0
@@ -115,6 +115,14 @@ templ summaryRail(p SummaryPage) {
115115 if p.Latest != nil {
116116 @latestTagFact(*p.Latest)
117117 }
118+ if r := p.Release; r != nil {
119+ <dt>release</dt>
120+ <dd>
121+ <a href={ templ.SafeURL(r.Href) }>{ r.Tag }</a>{ " · " }
122+ <time datetime={ r.WhenAt } title={ r.WhenAt }>{ r.When }</time>{ " · " }
123+ <a href={ templ.SafeURL(r.AllHref) }>all releases</a>
124+ </dd>
125+ }
118126 </dl>
119127 </section>
120128 if len(p.Recent) > 0 {
@@ -115,6 +115,14 @@ templ summaryRail(p SummaryPage) {
115 if p.Latest != nil {115 if p.Latest != nil {
116 @latestTagFact(*p.Latest)116 @latestTagFact(*p.Latest)
117 }117 }
118+ if r := p.Release; r != nil {
119+ <dt>release</dt>
120+ <dd>
121+ <a href={ templ.SafeURL(r.Href) }>{ r.Tag }</a>{ " · " }
122+ <time datetime={ r.WhenAt } title={ r.WhenAt }>{ r.When }</time>{ " · " }
123+ <a href={ templ.SafeURL(r.AllHref) }>all releases</a>
124+ </dd>
125+ }
118 </dl>126 </dl>
119 </section>127 </section>
120 if len(p.Recent) > 0 {128 if len(p.Recent) > 0 {
M internal/adapters/web/pages_templ.go +371 -261
@@ -534,25 +534,135 @@ func summaryRail(p SummaryPage) templ.Component {
534534 return templ_7745c5c3_Err
535535 }
536536 }
537- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</dl></section>")
537+ if r := p.Release; r != nil {
538+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<dt>release</dt><dd><a href=\"")
539+ if templ_7745c5c3_Err != nil {
540+ return templ_7745c5c3_Err
541+ }
542+ var templ_7745c5c3_Var27 templ.SafeURL
543+ templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href))
544+ if templ_7745c5c3_Err != nil {
545+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 36}
546+ }
547+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
548+ if templ_7745c5c3_Err != nil {
549+ return templ_7745c5c3_Err
550+ }
551+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\">")
552+ if templ_7745c5c3_Err != nil {
553+ return templ_7745c5c3_Err
554+ }
555+ var templ_7745c5c3_Var28 string
556+ templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(r.Tag)
557+ if templ_7745c5c3_Err != nil {
558+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 46}
559+ }
560+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
561+ if templ_7745c5c3_Err != nil {
562+ return templ_7745c5c3_Err
563+ }
564+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</a>")
565+ if templ_7745c5c3_Err != nil {
566+ return templ_7745c5c3_Err
567+ }
568+ var templ_7745c5c3_Var29 string
569+ templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
570+ if templ_7745c5c3_Err != nil {
571+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 60}
572+ }
573+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
574+ if templ_7745c5c3_Err != nil {
575+ return templ_7745c5c3_Err
576+ }
577+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " <time datetime=\"")
578+ if templ_7745c5c3_Err != nil {
579+ return templ_7745c5c3_Err
580+ }
581+ var templ_7745c5c3_Var30 string
582+ templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
583+ if templ_7745c5c3_Err != nil {
584+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 30}
585+ }
586+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var30)
587+ if templ_7745c5c3_Err != nil {
588+ return templ_7745c5c3_Err
589+ }
590+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "\" title=\"")
591+ if templ_7745c5c3_Err != nil {
592+ return templ_7745c5c3_Err
593+ }
594+ var templ_7745c5c3_Var31 string
595+ templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
596+ if templ_7745c5c3_Err != nil {
597+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 49}
598+ }
599+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var31)
600+ if templ_7745c5c3_Err != nil {
601+ return templ_7745c5c3_Err
602+ }
603+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\">")
604+ if templ_7745c5c3_Err != nil {
605+ return templ_7745c5c3_Err
606+ }
607+ var templ_7745c5c3_Var32 string
608+ templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(r.When)
609+ if templ_7745c5c3_Err != nil {
610+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 60}
611+ }
612+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
613+ if templ_7745c5c3_Err != nil {
614+ return templ_7745c5c3_Err
615+ }
616+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</time>")
617+ if templ_7745c5c3_Err != nil {
618+ return templ_7745c5c3_Err
619+ }
620+ var templ_7745c5c3_Var33 string
621+ templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
622+ if templ_7745c5c3_Err != nil {
623+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 77}
624+ }
625+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
626+ if templ_7745c5c3_Err != nil {
627+ return templ_7745c5c3_Err
628+ }
629+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, " <a href=\"")
630+ if templ_7745c5c3_Err != nil {
631+ return templ_7745c5c3_Err
632+ }
633+ var templ_7745c5c3_Var34 templ.SafeURL
634+ templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.AllHref))
635+ if templ_7745c5c3_Err != nil {
636+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 123, Col: 39}
637+ }
638+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
639+ if templ_7745c5c3_Err != nil {
640+ return templ_7745c5c3_Err
641+ }
642+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\">all releases</a></dd>")
643+ if templ_7745c5c3_Err != nil {
644+ return templ_7745c5c3_Err
645+ }
646+ }
647+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</dl></section>")
538648 if templ_7745c5c3_Err != nil {
539649 return templ_7745c5c3_Err
540650 }
541651 if len(p.Recent) > 0 {
542- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"")
652+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"")
543653 if templ_7745c5c3_Err != nil {
544654 return templ_7745c5c3_Err
545655 }
546- var templ_7745c5c3_Var27 templ.SafeURL
547- templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref))
656+ var templ_7745c5c3_Var35 templ.SafeURL
657+ templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref))
548658 if templ_7745c5c3_Err != nil {
549- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 105}
659+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 129, Col: 105}
550660 }
551- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
661+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
552662 if templ_7745c5c3_Err != nil {
553663 return templ_7745c5c3_Err
554664 }
555- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "\">View all</a></h2>")
665+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\">View all</a></h2>")
556666 if templ_7745c5c3_Err != nil {
557667 return templ_7745c5c3_Err
558668 }
@@ -560,7 +670,7 @@ func summaryRail(p SummaryPage) templ.Component {
560670 if templ_7745c5c3_Err != nil {
561671 return templ_7745c5c3_Err
562672 }
563- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</section>")
673+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</section>")
564674 if templ_7745c5c3_Err != nil {
565675 return templ_7745c5c3_Err
566676 }
@@ -572,7 +682,7 @@ func summaryRail(p SummaryPage) templ.Component {
572682 }
573683 }
574684 if len(p.Outline) > 0 && p.Readme != nil {
575- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>")
685+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>")
576686 if templ_7745c5c3_Err != nil {
577687 return templ_7745c5c3_Err
578688 }
@@ -580,7 +690,7 @@ func summaryRail(p SummaryPage) templ.Component {
580690 if templ_7745c5c3_Err != nil {
581691 return templ_7745c5c3_Err
582692 }
583- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</section>")
693+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "</section>")
584694 if templ_7745c5c3_Err != nil {
585695 return templ_7745c5c3_Err
586696 }
@@ -606,12 +716,12 @@ func Refs(l Layout, p RefsPage) templ.Component {
606716 }()
607717 }
608718 ctx = templ.InitializeContext(ctx)
609- templ_7745c5c3_Var28 := templ.GetChildren(ctx)
610- if templ_7745c5c3_Var28 == nil {
611- templ_7745c5c3_Var28 = templ.NopComponent
719+ templ_7745c5c3_Var36 := templ.GetChildren(ctx)
720+ if templ_7745c5c3_Var36 == nil {
721+ templ_7745c5c3_Var36 = templ.NopComponent
612722 }
613723 ctx = templ.ClearChildren(ctx)
614- templ_7745c5c3_Var29 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
724+ templ_7745c5c3_Var37 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
615725 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
616726 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
617727 if !templ_7745c5c3_IsBuffer {
@@ -623,7 +733,7 @@ func Refs(l Layout, p RefsPage) templ.Component {
623733 }()
624734 }
625735 ctx = templ.InitializeContext(ctx)
626- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>")
736+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>")
627737 if templ_7745c5c3_Err != nil {
628738 return templ_7745c5c3_Err
629739 }
@@ -631,32 +741,32 @@ func Refs(l Layout, p RefsPage) templ.Component {
631741 if templ_7745c5c3_Err != nil {
632742 return templ_7745c5c3_Err
633743 }
634- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</table>")
744+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "</table>")
635745 if templ_7745c5c3_Err != nil {
636746 return templ_7745c5c3_Err
637747 }
638748 if p.Note != "" {
639- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<p class=\"note\">")
749+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<p class=\"note\">")
640750 if templ_7745c5c3_Err != nil {
641751 return templ_7745c5c3_Err
642752 }
643- var templ_7745c5c3_Var30 string
644- templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
753+ var templ_7745c5c3_Var38 string
754+ templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
645755 if templ_7745c5c3_Err != nil {
646- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 154, Col: 27}
756+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 162, Col: 27}
647757 }
648- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
758+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
649759 if templ_7745c5c3_Err != nil {
650760 return templ_7745c5c3_Err
651761 }
652- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</p>")
762+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</p>")
653763 if templ_7745c5c3_Err != nil {
654764 return templ_7745c5c3_Err
655765 }
656766 }
657767 return nil
658768 })
659- templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var29), templ_7745c5c3_Buffer)
769+ templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var37), templ_7745c5c3_Buffer)
660770 if templ_7745c5c3_Err != nil {
661771 return templ_7745c5c3_Err
662772 }
@@ -680,112 +790,112 @@ func refRow(kind string, r RefRow) templ.Component {
680790 }()
681791 }
682792 ctx = templ.InitializeContext(ctx)
683- templ_7745c5c3_Var31 := templ.GetChildren(ctx)
684- if templ_7745c5c3_Var31 == nil {
685- templ_7745c5c3_Var31 = templ.NopComponent
793+ templ_7745c5c3_Var39 := templ.GetChildren(ctx)
794+ if templ_7745c5c3_Var39 == nil {
795+ templ_7745c5c3_Var39 = templ.NopComponent
686796 }
687797 ctx = templ.ClearChildren(ctx)
688- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<tr")
798+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "<tr")
689799 if templ_7745c5c3_Err != nil {
690800 return templ_7745c5c3_Err
691801 }
692802 if r.Cursor {
693- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, " data-cursor")
803+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, " data-cursor")
694804 if templ_7745c5c3_Err != nil {
695805 return templ_7745c5c3_Err
696806 }
697807 }
698- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "><td class=\"c-kind mute\">")
808+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "><td class=\"c-kind mute\">")
699809 if templ_7745c5c3_Err != nil {
700810 return templ_7745c5c3_Err
701811 }
702- var templ_7745c5c3_Var32 string
703- templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(kind)
812+ var templ_7745c5c3_Var40 string
813+ templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(kind)
704814 if templ_7745c5c3_Err != nil {
705- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 161, Col: 32}
815+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 169, Col: 32}
706816 }
707- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
817+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
708818 if templ_7745c5c3_Err != nil {
709819 return templ_7745c5c3_Err
710820 }
711- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</td><td class=\"c-name\"><a href=\"")
821+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-name\"><a href=\"")
712822 if templ_7745c5c3_Err != nil {
713823 return templ_7745c5c3_Err
714824 }
715- var templ_7745c5c3_Var33 templ.SafeURL
716- templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href))
825+ var templ_7745c5c3_Var41 templ.SafeURL
826+ templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href))
717827 if templ_7745c5c3_Err != nil {
718- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 34}
828+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 34}
719829 }
720- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
830+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
721831 if templ_7745c5c3_Err != nil {
722832 return templ_7745c5c3_Err
723833 }
724- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "\">")
834+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "\">")
725835 if templ_7745c5c3_Err != nil {
726836 return templ_7745c5c3_Err
727837 }
728- var templ_7745c5c3_Var34 string
729- templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)
838+ var templ_7745c5c3_Var42 string
839+ templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)
730840 if templ_7745c5c3_Err != nil {
731- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 45}
841+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 45}
732842 }
733- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
843+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
734844 if templ_7745c5c3_Err != nil {
735845 return templ_7745c5c3_Err
736846 }
737- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</a> ")
847+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "</a> ")
738848 if templ_7745c5c3_Err != nil {
739849 return templ_7745c5c3_Err
740850 }
741851 if r.Default {
742- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "<span class=\"pill\">default</span>")
852+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "<span class=\"pill\">default</span>")
743853 if templ_7745c5c3_Err != nil {
744854 return templ_7745c5c3_Err
745855 }
746856 }
747- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "</td><td class=\"c-sha\">")
857+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</td><td class=\"c-sha\">")
748858 if templ_7745c5c3_Err != nil {
749859 return templ_7745c5c3_Err
750860 }
751861 if r.CHref != "" {
752- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<a href=\"")
862+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<a href=\"")
753863 if templ_7745c5c3_Err != nil {
754864 return templ_7745c5c3_Err
755865 }
756- var templ_7745c5c3_Var35 templ.SafeURL
757- templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref))
866+ var templ_7745c5c3_Var43 templ.SafeURL
867+ templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref))
758868 if templ_7745c5c3_Err != nil {
759- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 36}
869+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 36}
760870 }
761- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
871+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
762872 if templ_7745c5c3_Err != nil {
763873 return templ_7745c5c3_Err
764874 }
765- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "\">")
875+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "\">")
766876 if templ_7745c5c3_Err != nil {
767877 return templ_7745c5c3_Err
768878 }
769- var templ_7745c5c3_Var36 string
770- templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)
879+ var templ_7745c5c3_Var44 string
880+ templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)
771881 if templ_7745c5c3_Err != nil {
772- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 48}
882+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 48}
773883 }
774- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
884+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
775885 if templ_7745c5c3_Err != nil {
776886 return templ_7745c5c3_Err
777887 }
778- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "</a>")
888+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</a>")
779889 if templ_7745c5c3_Err != nil {
780890 return templ_7745c5c3_Err
781891 }
782892 } else {
783- var templ_7745c5c3_Var37 string
784- templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)
893+ var templ_7745c5c3_Var45 string
894+ templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)
785895 if templ_7745c5c3_Err != nil {
786- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 172, Col: 13}
896+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 180, Col: 13}
787897 }
788- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
898+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
789899 if templ_7745c5c3_Err != nil {
790900 return templ_7745c5c3_Err
791901 }
@@ -794,69 +904,69 @@ func refRow(kind string, r RefRow) templ.Component {
794904 if templ_7745c5c3_Err != nil {
795905 return templ_7745c5c3_Err
796906 }
797- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "</td><td class=\"c-sub\">")
907+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "</td><td class=\"c-sub\">")
798908 if templ_7745c5c3_Err != nil {
799909 return templ_7745c5c3_Err
800910 }
801- var templ_7745c5c3_Var38 string
802- templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject)
911+ var templ_7745c5c3_Var46 string
912+ templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject)
803913 if templ_7745c5c3_Err != nil {
804- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 176, Col: 31}
914+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 184, Col: 31}
805915 }
806- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
916+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
807917 if templ_7745c5c3_Err != nil {
808918 return templ_7745c5c3_Err
809919 }
810- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-when dim\">")
920+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</td><td class=\"c-when dim\">")
811921 if templ_7745c5c3_Err != nil {
812922 return templ_7745c5c3_Err
813923 }
814924 if r.WhenAt != "" {
815- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "<time datetime=\"")
925+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "<time datetime=\"")
816926 if templ_7745c5c3_Err != nil {
817927 return templ_7745c5c3_Err
818928 }
819- var templ_7745c5c3_Var39 string
820- templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
929+ var templ_7745c5c3_Var47 string
930+ templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
821931 if templ_7745c5c3_Err != nil {
822- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 29}
932+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 29}
823933 }
824- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39)
934+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var47)
825935 if templ_7745c5c3_Err != nil {
826936 return templ_7745c5c3_Err
827937 }
828- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "\" title=\"")
938+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" title=\"")
829939 if templ_7745c5c3_Err != nil {
830940 return templ_7745c5c3_Err
831941 }
832- var templ_7745c5c3_Var40 string
833- templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
942+ var templ_7745c5c3_Var48 string
943+ templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
834944 if templ_7745c5c3_Err != nil {
835- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 48}
945+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 48}
836946 }
837- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40)
947+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var48)
838948 if templ_7745c5c3_Err != nil {
839949 return templ_7745c5c3_Err
840950 }
841- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "\">")
951+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "\">")
842952 if templ_7745c5c3_Err != nil {
843953 return templ_7745c5c3_Err
844954 }
845- var templ_7745c5c3_Var41 string
846- templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(r.When)
955+ var templ_7745c5c3_Var49 string
956+ templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(r.When)
847957 if templ_7745c5c3_Err != nil {
848- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 59}
958+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 59}
849959 }
850- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
960+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
851961 if templ_7745c5c3_Err != nil {
852962 return templ_7745c5c3_Err
853963 }
854- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</time>")
964+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</time>")
855965 if templ_7745c5c3_Err != nil {
856966 return templ_7745c5c3_Err
857967 }
858968 }
859- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "</td></tr>")
969+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "</td></tr>")
860970 if templ_7745c5c3_Err != nil {
861971 return templ_7745c5c3_Err
862972 }
@@ -880,12 +990,12 @@ func refsRail(p RefsPage) templ.Component {
880990 }()
881991 }
882992 ctx = templ.InitializeContext(ctx)
883- templ_7745c5c3_Var42 := templ.GetChildren(ctx)
884- if templ_7745c5c3_Var42 == nil {
885- templ_7745c5c3_Var42 = templ.NopComponent
993+ templ_7745c5c3_Var50 := templ.GetChildren(ctx)
994+ if templ_7745c5c3_Var50 == nil {
995+ templ_7745c5c3_Var50 = templ.NopComponent
886996 }
887997 ctx = templ.ClearChildren(ctx)
888- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>")
998+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>")
889999 if templ_7745c5c3_Err != nil {
8901000 return templ_7745c5c3_Err
8911001 }
@@ -893,7 +1003,7 @@ func refsRail(p RefsPage) templ.Component {
8931003 if templ_7745c5c3_Err != nil {
8941004 return templ_7745c5c3_Err
8951005 }
896- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</section>")
1006+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</section>")
8971007 if templ_7745c5c3_Err != nil {
8981008 return templ_7745c5c3_Err
8991009 }
@@ -918,12 +1028,12 @@ func State(l Layout, p StatePage) templ.Component {
9181028 }()
9191029 }
9201030 ctx = templ.InitializeContext(ctx)
921- templ_7745c5c3_Var43 := templ.GetChildren(ctx)
922- if templ_7745c5c3_Var43 == nil {
923- templ_7745c5c3_Var43 = templ.NopComponent
1031+ templ_7745c5c3_Var51 := templ.GetChildren(ctx)
1032+ if templ_7745c5c3_Var51 == nil {
1033+ templ_7745c5c3_Var51 = templ.NopComponent
9241034 }
9251035 ctx = templ.ClearChildren(ctx)
926- templ_7745c5c3_Var44 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
1036+ templ_7745c5c3_Var52 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
9271037 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
9281038 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
9291039 if !templ_7745c5c3_IsBuffer {
@@ -935,51 +1045,51 @@ func State(l Layout, p StatePage) templ.Component {
9351045 }()
9361046 }
9371047 ctx = templ.InitializeContext(ctx)
938- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">")
1048+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">")
9391049 if templ_7745c5c3_Err != nil {
9401050 return templ_7745c5c3_Err
9411051 }
942- var templ_7745c5c3_Var45 string
943- templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code)
1052+ var templ_7745c5c3_Var53 string
1053+ templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code)
9441054 if templ_7745c5c3_Err != nil {
945- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 196, Col: 30}
1055+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 204, Col: 30}
9461056 }
947- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
1057+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
9481058 if templ_7745c5c3_Err != nil {
9491059 return templ_7745c5c3_Err
9501060 }
951- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</p><h1 id=\"state-title\">")
1061+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "</p><h1 id=\"state-title\">")
9521062 if templ_7745c5c3_Err != nil {
9531063 return templ_7745c5c3_Err
9541064 }
955- var templ_7745c5c3_Var46 string
956- templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
1065+ var templ_7745c5c3_Var54 string
1066+ templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
9571067 if templ_7745c5c3_Err != nil {
958- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 197, Col: 33}
1068+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 205, Col: 33}
9591069 }
960- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
1070+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
9611071 if templ_7745c5c3_Err != nil {
9621072 return templ_7745c5c3_Err
9631073 }
964- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "</h1>")
1074+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>")
9651075 if templ_7745c5c3_Err != nil {
9661076 return templ_7745c5c3_Err
9671077 }
9681078 for _, line := range p.Lines {
969- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "<p class=\"dim\">")
1079+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">")
9701080 if templ_7745c5c3_Err != nil {
9711081 return templ_7745c5c3_Err
9721082 }
973- var templ_7745c5c3_Var47 string
974- templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(line)
1083+ var templ_7745c5c3_Var55 string
1084+ templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(line)
9751085 if templ_7745c5c3_Err != nil {
976- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 199, Col: 25}
1086+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 207, Col: 25}
9771087 }
978- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
1088+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
9791089 if templ_7745c5c3_Err != nil {
9801090 return templ_7745c5c3_Err
9811091 }
982- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</p>")
1092+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>")
9831093 if templ_7745c5c3_Err != nil {
9841094 return templ_7745c5c3_Err
9851095 }
@@ -990,49 +1100,49 @@ func State(l Layout, p StatePage) templ.Component {
9901100 return templ_7745c5c3_Err
9911101 }
9921102 }
993- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "<p class=\"state-back\">")
1103+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<p class=\"state-back\">")
9941104 if templ_7745c5c3_Err != nil {
9951105 return templ_7745c5c3_Err
9961106 }
9971107 for _, b := range p.Back {
998- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "<a href=\"")
1108+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "<a href=\"")
9991109 if templ_7745c5c3_Err != nil {
10001110 return templ_7745c5c3_Err
10011111 }
1002- var templ_7745c5c3_Var48 templ.SafeURL
1003- templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href))
1112+ var templ_7745c5c3_Var56 templ.SafeURL
1113+ templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href))
10041114 if templ_7745c5c3_Err != nil {
1005- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 36}
1115+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 36}
10061116 }
1007- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
1117+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56))
10081118 if templ_7745c5c3_Err != nil {
10091119 return templ_7745c5c3_Err
10101120 }
1011- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "\">")
1121+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "\">")
10121122 if templ_7745c5c3_Err != nil {
10131123 return templ_7745c5c3_Err
10141124 }
1015- var templ_7745c5c3_Var49 string
1016- templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label)
1125+ var templ_7745c5c3_Var57 string
1126+ templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label)
10171127 if templ_7745c5c3_Err != nil {
1018- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 48}
1128+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 48}
10191129 }
1020- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
1130+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))
10211131 if templ_7745c5c3_Err != nil {
10221132 return templ_7745c5c3_Err
10231133 }
1024- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</a>")
1134+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</a>")
10251135 if templ_7745c5c3_Err != nil {
10261136 return templ_7745c5c3_Err
10271137 }
10281138 }
1029- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "</p></section>")
1139+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</p></section>")
10301140 if templ_7745c5c3_Err != nil {
10311141 return templ_7745c5c3_Err
10321142 }
10331143 return nil
10341144 })
1035- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var44), templ_7745c5c3_Buffer)
1145+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var52), templ_7745c5c3_Buffer)
10361146 if templ_7745c5c3_Err != nil {
10371147 return templ_7745c5c3_Err
10381148 }
@@ -1061,12 +1171,12 @@ func Login(l Layout, p LoginPage) templ.Component {
10611171 }()
10621172 }
10631173 ctx = templ.InitializeContext(ctx)
1064- templ_7745c5c3_Var50 := templ.GetChildren(ctx)
1065- if templ_7745c5c3_Var50 == nil {
1066- templ_7745c5c3_Var50 = templ.NopComponent
1174+ templ_7745c5c3_Var58 := templ.GetChildren(ctx)
1175+ if templ_7745c5c3_Var58 == nil {
1176+ templ_7745c5c3_Var58 = templ.NopComponent
10671177 }
10681178 ctx = templ.ClearChildren(ctx)
1069- templ_7745c5c3_Var51 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
1179+ templ_7745c5c3_Var59 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
10701180 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
10711181 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
10721182 if !templ_7745c5c3_IsBuffer {
@@ -1078,75 +1188,75 @@ func Login(l Layout, p LoginPage) templ.Component {
10781188 }()
10791189 }
10801190 ctx = templ.InitializeContext(ctx)
1081- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")
1191+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")
10821192 if templ_7745c5c3_Err != nil {
10831193 return templ_7745c5c3_Err
10841194 }
1085- var templ_7745c5c3_Var52 string
1086- templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
1195+ var templ_7745c5c3_Var60 string
1196+ templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
10871197 if templ_7745c5c3_Err != nil {
1088- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 221, Col: 33}
1198+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 229, Col: 33}
10891199 }
1090- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))
1200+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var60))
10911201 if templ_7745c5c3_Err != nil {
10921202 return templ_7745c5c3_Err
10931203 }
1094- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>")
1204+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "</h1>")
10951205 if templ_7745c5c3_Err != nil {
10961206 return templ_7745c5c3_Err
10971207 }
10981208 for _, line := range p.Lines {
1099- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">")
1209+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "<p class=\"dim\">")
11001210 if templ_7745c5c3_Err != nil {
11011211 return templ_7745c5c3_Err
11021212 }
1103- var templ_7745c5c3_Var53 string
1104- templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(line)
1213+ var templ_7745c5c3_Var61 string
1214+ templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(line)
11051215 if templ_7745c5c3_Err != nil {
1106- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 223, Col: 25}
1216+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 231, Col: 25}
11071217 }
1108- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
1218+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))
11091219 if templ_7745c5c3_Err != nil {
11101220 return templ_7745c5c3_Err
11111221 }
1112- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>")
1222+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</p>")
11131223 if templ_7745c5c3_Err != nil {
11141224 return templ_7745c5c3_Err
11151225 }
11161226 }
1117- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<form class=\"state-act\" method=\"post\" action=\"")
1227+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<form class=\"state-act\" method=\"post\" action=\"")
11181228 if templ_7745c5c3_Err != nil {
11191229 return templ_7745c5c3_Err
11201230 }
1121- var templ_7745c5c3_Var54 templ.SafeURL
1122- templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action))
1231+ var templ_7745c5c3_Var62 templ.SafeURL
1232+ templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action))
11231233 if templ_7745c5c3_Err != nil {
1124- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 225, Col: 73}
1234+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 233, Col: 73}
11251235 }
1126- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
1236+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))
11271237 if templ_7745c5c3_Err != nil {
11281238 return templ_7745c5c3_Err
11291239 }
1130- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">")
1240+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">")
11311241 if templ_7745c5c3_Err != nil {
11321242 return templ_7745c5c3_Err
11331243 }
1134- var templ_7745c5c3_Var55 string
1135- templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)
1244+ var templ_7745c5c3_Var63 string
1245+ templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)
11361246 if templ_7745c5c3_Err != nil {
1137- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 226, Col: 56}
1247+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 234, Col: 56}
11381248 }
1139- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
1249+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63))
11401250 if templ_7745c5c3_Err != nil {
11411251 return templ_7745c5c3_Err
11421252 }
1143- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")
1253+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")
11441254 if templ_7745c5c3_Err != nil {
11451255 return templ_7745c5c3_Err
11461256 }
11471257 return nil
11481258 })
1149- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var51), templ_7745c5c3_Buffer)
1259+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var59), templ_7745c5c3_Buffer)
11501260 if templ_7745c5c3_Err != nil {
11511261 return templ_7745c5c3_Err
11521262 }
@@ -1172,12 +1282,12 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component {
11721282 }()
11731283 }
11741284 ctx = templ.InitializeContext(ctx)
1175- templ_7745c5c3_Var56 := templ.GetChildren(ctx)
1176- if templ_7745c5c3_Var56 == nil {
1177- templ_7745c5c3_Var56 = templ.NopComponent
1285+ templ_7745c5c3_Var64 := templ.GetChildren(ctx)
1286+ if templ_7745c5c3_Var64 == nil {
1287+ templ_7745c5c3_Var64 = templ.NopComponent
11781288 }
11791289 ctx = templ.ClearChildren(ctx)
1180- templ_7745c5c3_Var57 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
1290+ templ_7745c5c3_Var65 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
11811291 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
11821292 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
11831293 if !templ_7745c5c3_IsBuffer {
@@ -1189,88 +1299,88 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component {
11891299 }()
11901300 }
11911301 ctx = templ.InitializeContext(ctx)
1192- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")
1302+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")
11931303 if templ_7745c5c3_Err != nil {
11941304 return templ_7745c5c3_Err
11951305 }
1196- var templ_7745c5c3_Var58 string
1197- templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
1306+ var templ_7745c5c3_Var66 string
1307+ templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
11981308 if templ_7745c5c3_Err != nil {
1199- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 238, Col: 33}
1309+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 246, Col: 33}
12001310 }
1201- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
1311+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))
12021312 if templ_7745c5c3_Err != nil {
12031313 return templ_7745c5c3_Err
12041314 }
1205- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"")
1315+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"")
12061316 if templ_7745c5c3_Err != nil {
12071317 return templ_7745c5c3_Err
12081318 }
1209- var templ_7745c5c3_Var59 string
1210- templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)
1319+ var templ_7745c5c3_Var67 string
1320+ templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)
12111321 if templ_7745c5c3_Err != nil {
1212- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 87}
1322+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 87}
12131323 }
1214- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var59)
1324+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67)
12151325 if templ_7745c5c3_Err != nil {
12161326 return templ_7745c5c3_Err
12171327 }
1218- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "\" data-finish=\"")
1328+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "\" data-finish=\"")
12191329 if templ_7745c5c3_Err != nil {
12201330 return templ_7745c5c3_Err
12211331 }
1222- var templ_7745c5c3_Var60 string
1223- templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)
1332+ var templ_7745c5c3_Var68 string
1333+ templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)
12241334 if templ_7745c5c3_Err != nil {
1225- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 112}
1335+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 112}
12261336 }
1227- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var60)
1337+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var68)
12281338 if templ_7745c5c3_Err != nil {
12291339 return templ_7745c5c3_Err
12301340 }
1231- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "\">")
1341+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "\">")
12321342 if templ_7745c5c3_Err != nil {
12331343 return templ_7745c5c3_Err
12341344 }
1235- var templ_7745c5c3_Var61 string
1236- templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)
1345+ var templ_7745c5c3_Var69 string
1346+ templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)
12371347 if templ_7745c5c3_Err != nil {
1238- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 125}
1348+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 125}
12391349 }
1240- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))
1350+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))
12411351 if templ_7745c5c3_Err != nil {
12421352 return templ_7745c5c3_Err
12431353 }
1244- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")
1354+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")
12451355 if templ_7745c5c3_Err != nil {
12461356 return templ_7745c5c3_Err
12471357 }
12481358 for _, line := range p.Lines {
1249- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "<p class=\"dim\">")
1359+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "<p class=\"dim\">")
12501360 if templ_7745c5c3_Err != nil {
12511361 return templ_7745c5c3_Err
12521362 }
1253- var templ_7745c5c3_Var62 string
1254- templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(line)
1363+ var templ_7745c5c3_Var70 string
1364+ templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(line)
12551365 if templ_7745c5c3_Err != nil {
1256- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 244, Col: 25}
1366+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 252, Col: 25}
12571367 }
1258- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))
1368+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))
12591369 if templ_7745c5c3_Err != nil {
12601370 return templ_7745c5c3_Err
12611371 }
1262- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "</p>")
1372+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "</p>")
12631373 if templ_7745c5c3_Err != nil {
12641374 return templ_7745c5c3_Err
12651375 }
12661376 }
1267- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")
1377+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")
12681378 if templ_7745c5c3_Err != nil {
12691379 return templ_7745c5c3_Err
12701380 }
12711381 return nil
12721382 })
1273- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var57), templ_7745c5c3_Buffer)
1383+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var65), templ_7745c5c3_Buffer)
12741384 if templ_7745c5c3_Err != nil {
12751385 return templ_7745c5c3_Err
12761386 }
@@ -1295,12 +1405,12 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component {
12951405 }()
12961406 }
12971407 ctx = templ.InitializeContext(ctx)
1298- templ_7745c5c3_Var63 := templ.GetChildren(ctx)
1299- if templ_7745c5c3_Var63 == nil {
1300- templ_7745c5c3_Var63 = templ.NopComponent
1408+ templ_7745c5c3_Var71 := templ.GetChildren(ctx)
1409+ if templ_7745c5c3_Var71 == nil {
1410+ templ_7745c5c3_Var71 = templ.NopComponent
13011411 }
13021412 ctx = templ.ClearChildren(ctx)
1303- templ_7745c5c3_Var64 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
1413+ templ_7745c5c3_Var72 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
13041414 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
13051415 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
13061416 if !templ_7745c5c3_IsBuffer {
@@ -1312,231 +1422,231 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component {
13121422 }()
13131423 }
13141424 ctx = templ.InitializeContext(ctx)
1315- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">")
1425+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">")
13161426 if templ_7745c5c3_Err != nil {
13171427 return templ_7745c5c3_Err
13181428 }
1319- var templ_7745c5c3_Var65 string
1320- templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows)))
1429+ var templ_7745c5c3_Var73 string
1430+ templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows)))
13211431 if templ_7745c5c3_Err != nil {
1322- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 254, Col: 81}
1432+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 262, Col: 81}
13231433 }
1324- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))
1434+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73))
13251435 if templ_7745c5c3_Err != nil {
13261436 return templ_7745c5c3_Err
13271437 }
1328- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>")
1438+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>")
13291439 if templ_7745c5c3_Err != nil {
13301440 return templ_7745c5c3_Err
13311441 }
13321442 if len(p.Rows) > 0 {
1333- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>")
1443+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>")
13341444 if templ_7745c5c3_Err != nil {
13351445 return templ_7745c5c3_Err
13361446 }
13371447 for _, r := range p.Rows {
1338- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "<tr><td class=\"c-name\">")
1448+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "<tr><td class=\"c-name\">")
13391449 if templ_7745c5c3_Err != nil {
13401450 return templ_7745c5c3_Err
13411451 }
1342- var templ_7745c5c3_Var66 string
1343- templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)
1452+ var templ_7745c5c3_Var74 string
1453+ templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)
13441454 if templ_7745c5c3_Err != nil {
1345- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 270, Col: 34}
1455+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 278, Col: 34}
13461456 }
1347- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))
1457+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))
13481458 if templ_7745c5c3_Err != nil {
13491459 return templ_7745c5c3_Err
13501460 }
1351- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</td><td class=\"c-when nowrap\"><time")
1461+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "</td><td class=\"c-when nowrap\"><time")
13521462 if templ_7745c5c3_Err != nil {
13531463 return templ_7745c5c3_Err
13541464 }
13551465 if r.CreatedAt != "" {
1356- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " datetime=\"")
1466+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, " datetime=\"")
13571467 if templ_7745c5c3_Err != nil {
13581468 return templ_7745c5c3_Err
13591469 }
1360- var templ_7745c5c3_Var67 string
1361- templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt)
1470+ var templ_7745c5c3_Var75 string
1471+ templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt)
13621472 if templ_7745c5c3_Err != nil {
1363- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 274, Col: 32}
1473+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 282, Col: 32}
13641474 }
1365- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67)
1475+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)
13661476 if templ_7745c5c3_Err != nil {
13671477 return templ_7745c5c3_Err
13681478 }
1369- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"")
1479+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "\"")
13701480 if templ_7745c5c3_Err != nil {
13711481 return templ_7745c5c3_Err
13721482 }
13731483 }
1374- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, ">")
1484+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, ">")
13751485 if templ_7745c5c3_Err != nil {
13761486 return templ_7745c5c3_Err
13771487 }
1378- var templ_7745c5c3_Var68 string
1379- templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created)
1488+ var templ_7745c5c3_Var76 string
1489+ templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created)
13801490 if templ_7745c5c3_Err != nil {
1381- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 276, Col: 20}
1491+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 284, Col: 20}
13821492 }
1383- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))
1493+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))
13841494 if templ_7745c5c3_Err != nil {
13851495 return templ_7745c5c3_Err
13861496 }
1387- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "</time></td><td class=\"c-when nowrap\"><time")
1497+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "</time></td><td class=\"c-when nowrap\"><time")
13881498 if templ_7745c5c3_Err != nil {
13891499 return templ_7745c5c3_Err
13901500 }
13911501 if r.LastUsedAt != "" {
1392- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " datetime=\"")
1502+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, " datetime=\"")
13931503 if templ_7745c5c3_Err != nil {
13941504 return templ_7745c5c3_Err
13951505 }
1396- var templ_7745c5c3_Var69 string
1397- templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt)
1506+ var templ_7745c5c3_Var77 string
1507+ templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt)
13981508 if templ_7745c5c3_Err != nil {
1399- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 281, Col: 33}
1509+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 289, Col: 33}
14001510 }
1401- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var69)
1511+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77)
14021512 if templ_7745c5c3_Err != nil {
14031513 return templ_7745c5c3_Err
14041514 }
1405- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"")
1515+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "\"")
14061516 if templ_7745c5c3_Err != nil {
14071517 return templ_7745c5c3_Err
14081518 }
14091519 }
1410- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, ">")
1520+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, ">")
14111521 if templ_7745c5c3_Err != nil {
14121522 return templ_7745c5c3_Err
14131523 }
1414- var templ_7745c5c3_Var70 string
1415- templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed)
1524+ var templ_7745c5c3_Var78 string
1525+ templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed)
14161526 if templ_7745c5c3_Err != nil {
1417- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 283, Col: 21}
1527+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 291, Col: 21}
14181528 }
1419- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))
1529+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78))
14201530 if templ_7745c5c3_Err != nil {
14211531 return templ_7745c5c3_Err
14221532 }
1423- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</time></td><td class=\"c-sync\">")
1533+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</time></td><td class=\"c-sync\">")
14241534 if templ_7745c5c3_Err != nil {
14251535 return templ_7745c5c3_Err
14261536 }
14271537 if r.Synced {
1428- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "yes")
1538+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "yes")
14291539 if templ_7745c5c3_Err != nil {
14301540 return templ_7745c5c3_Err
14311541 }
14321542 } else {
1433- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "no")
1543+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "no")
14341544 if templ_7745c5c3_Err != nil {
14351545 return templ_7745c5c3_Err
14361546 }
14371547 }
1438- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "</td><td class=\"c-act\"><form method=\"post\" action=\"")
1548+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "</td><td class=\"c-act\"><form method=\"post\" action=\"")
14391549 if templ_7745c5c3_Err != nil {
14401550 return templ_7745c5c3_Err
14411551 }
1442- var templ_7745c5c3_Var71 templ.SafeURL
1443- templ_7745c5c3_Var71, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove))
1552+ var templ_7745c5c3_Var79 templ.SafeURL
1553+ templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove))
14441554 if templ_7745c5c3_Err != nil {
1445- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 293, Col: 60}
1555+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 301, Col: 60}
14461556 }
1447- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var71))
1557+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))
14481558 if templ_7745c5c3_Err != nil {
14491559 return templ_7745c5c3_Err
14501560 }
1451- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"")
1561+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"")
14521562 if templ_7745c5c3_Err != nil {
14531563 return templ_7745c5c3_Err
14541564 }
1455- var templ_7745c5c3_Var72 string
1456- templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name)
1565+ var templ_7745c5c3_Var80 string
1566+ templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name)
14571567 if templ_7745c5c3_Err != nil {
1458- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 294, Col: 89}
1568+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 302, Col: 89}
14591569 }
1460- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var72)
1570+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)
14611571 if templ_7745c5c3_Err != nil {
14621572 return templ_7745c5c3_Err
14631573 }
1464- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "\">Remove</button></form></td></tr>")
1574+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\">Remove</button></form></td></tr>")
14651575 if templ_7745c5c3_Err != nil {
14661576 return templ_7745c5c3_Err
14671577 }
14681578 }
1469- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "</tbody></table>")
1579+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "</tbody></table>")
14701580 if templ_7745c5c3_Err != nil {
14711581 return templ_7745c5c3_Err
14721582 }
14731583 } else {
1474- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "<p class=\"lede dim\">no passkeys yet.</p>")
1584+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "<p class=\"lede dim\">no passkeys yet.</p>")
14751585 if templ_7745c5c3_Err != nil {
14761586 return templ_7745c5c3_Err
14771587 }
14781588 }
1479- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, " ")
1589+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, " ")
14801590 if templ_7745c5c3_Err != nil {
14811591 return templ_7745c5c3_Err
14821592 }
14831593 if p.Full {
1484- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "<p class=\"dim\">")
1594+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "<p class=\"dim\">")
14851595 if templ_7745c5c3_Err != nil {
14861596 return templ_7745c5c3_Err
14871597 }
1488- var templ_7745c5c3_Var73 string
1489- templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max))
1598+ var templ_7745c5c3_Var81 string
1599+ templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max))
14901600 if templ_7745c5c3_Err != nil {
1491- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 305, Col: 31}
1601+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 313, Col: 31}
14921602 }
1493- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73))
1603+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))
14941604 if templ_7745c5c3_Err != nil {
14951605 return templ_7745c5c3_Err
14961606 }
1497- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, " passkeys are registered, the most there can be. Remove one to add another.</p>")
1607+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, " passkeys are registered, the most there can be. Remove one to add another.</p>")
14981608 if templ_7745c5c3_Err != nil {
14991609 return templ_7745c5c3_Err
15001610 }
15011611 } else {
1502- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"")
1612+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"")
15031613 if templ_7745c5c3_Err != nil {
15041614 return templ_7745c5c3_Err
15051615 }
1506- var templ_7745c5c3_Var74 string
1507- templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)
1616+ var templ_7745c5c3_Var82 string
1617+ templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)
15081618 if templ_7745c5c3_Err != nil {
1509- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 90}
1619+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 90}
15101620 }
1511- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var74)
1621+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var82)
15121622 if templ_7745c5c3_Err != nil {
15131623 return templ_7745c5c3_Err
15141624 }
1515- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-finish=\"")
1625+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "\" data-finish=\"")
15161626 if templ_7745c5c3_Err != nil {
15171627 return templ_7745c5c3_Err
15181628 }
1519- var templ_7745c5c3_Var75 string
1520- templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)
1629+ var templ_7745c5c3_Var83 string
1630+ templ_7745c5c3_Var83, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)
15211631 if templ_7745c5c3_Err != nil {
1522- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 115}
1632+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 115}
15231633 }
1524- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)
1634+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var83)
15251635 if templ_7745c5c3_Err != nil {
15261636 return templ_7745c5c3_Err
15271637 }
1528- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\">Add a passkey</button></form>")
1638+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "\">Add a passkey</button></form>")
15291639 if templ_7745c5c3_Err != nil {
15301640 return templ_7745c5c3_Err
15311641 }
15321642 }
1533- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")
1643+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")
15341644 if templ_7745c5c3_Err != nil {
15351645 return templ_7745c5c3_Err
15361646 }
15371647 return nil
15381648 })
1539- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var64), templ_7745c5c3_Buffer)
1649+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var72), templ_7745c5c3_Buffer)
15401650 if templ_7745c5c3_Err != nil {
15411651 return templ_7745c5c3_Err
15421652 }
@@ -534,25 +534,135 @@ func summaryRail(p SummaryPage) templ.Component {
534 return templ_7745c5c3_Err534 return templ_7745c5c3_Err
535 }535 }
536 }536 }
537- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</dl></section>")537+ if r := p.Release; r != nil {
538+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<dt>release</dt><dd><a href=\"")
539+ if templ_7745c5c3_Err != nil {
540+ return templ_7745c5c3_Err
541+ }
542+ var templ_7745c5c3_Var27 templ.SafeURL
543+ templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href))
544+ if templ_7745c5c3_Err != nil {
545+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 36}
546+ }
547+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
548+ if templ_7745c5c3_Err != nil {
549+ return templ_7745c5c3_Err
550+ }
551+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\">")
552+ if templ_7745c5c3_Err != nil {
553+ return templ_7745c5c3_Err
554+ }
555+ var templ_7745c5c3_Var28 string
556+ templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(r.Tag)
557+ if templ_7745c5c3_Err != nil {
558+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 46}
559+ }
560+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
561+ if templ_7745c5c3_Err != nil {
562+ return templ_7745c5c3_Err
563+ }
564+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</a>")
565+ if templ_7745c5c3_Err != nil {
566+ return templ_7745c5c3_Err
567+ }
568+ var templ_7745c5c3_Var29 string
569+ templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
570+ if templ_7745c5c3_Err != nil {
571+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 60}
572+ }
573+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
574+ if templ_7745c5c3_Err != nil {
575+ return templ_7745c5c3_Err
576+ }
577+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " <time datetime=\"")
578+ if templ_7745c5c3_Err != nil {
579+ return templ_7745c5c3_Err
580+ }
581+ var templ_7745c5c3_Var30 string
582+ templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
583+ if templ_7745c5c3_Err != nil {
584+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 30}
585+ }
586+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var30)
587+ if templ_7745c5c3_Err != nil {
588+ return templ_7745c5c3_Err
589+ }
590+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "\" title=\"")
591+ if templ_7745c5c3_Err != nil {
592+ return templ_7745c5c3_Err
593+ }
594+ var templ_7745c5c3_Var31 string
595+ templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
596+ if templ_7745c5c3_Err != nil {
597+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 49}
598+ }
599+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var31)
600+ if templ_7745c5c3_Err != nil {
601+ return templ_7745c5c3_Err
602+ }
603+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\">")
604+ if templ_7745c5c3_Err != nil {
605+ return templ_7745c5c3_Err
606+ }
607+ var templ_7745c5c3_Var32 string
608+ templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(r.When)
609+ if templ_7745c5c3_Err != nil {
610+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 60}
611+ }
612+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
613+ if templ_7745c5c3_Err != nil {
614+ return templ_7745c5c3_Err
615+ }
616+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</time>")
617+ if templ_7745c5c3_Err != nil {
618+ return templ_7745c5c3_Err
619+ }
620+ var templ_7745c5c3_Var33 string
621+ templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
622+ if templ_7745c5c3_Err != nil {
623+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 77}
624+ }
625+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
626+ if templ_7745c5c3_Err != nil {
627+ return templ_7745c5c3_Err
628+ }
629+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, " <a href=\"")
630+ if templ_7745c5c3_Err != nil {
631+ return templ_7745c5c3_Err
632+ }
633+ var templ_7745c5c3_Var34 templ.SafeURL
634+ templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.AllHref))
635+ if templ_7745c5c3_Err != nil {
636+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 123, Col: 39}
637+ }
638+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
639+ if templ_7745c5c3_Err != nil {
640+ return templ_7745c5c3_Err
641+ }
642+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\">all releases</a></dd>")
643+ if templ_7745c5c3_Err != nil {
644+ return templ_7745c5c3_Err
645+ }
646+ }
647+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</dl></section>")
538 if templ_7745c5c3_Err != nil {648 if templ_7745c5c3_Err != nil {
539 return templ_7745c5c3_Err649 return templ_7745c5c3_Err
540 }650 }
541 if len(p.Recent) > 0 {651 if len(p.Recent) > 0 {
542- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"")652+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"")
543 if templ_7745c5c3_Err != nil {653 if templ_7745c5c3_Err != nil {
544 return templ_7745c5c3_Err654 return templ_7745c5c3_Err
545 }655 }
546- var templ_7745c5c3_Var27 templ.SafeURL656+ var templ_7745c5c3_Var35 templ.SafeURL
547- templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref))657+ templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref))
548 if templ_7745c5c3_Err != nil {658 if templ_7745c5c3_Err != nil {
549- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 105}659+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 129, Col: 105}
550 }660 }
551- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))661+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
552 if templ_7745c5c3_Err != nil {662 if templ_7745c5c3_Err != nil {
553 return templ_7745c5c3_Err663 return templ_7745c5c3_Err
554 }664 }
555- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "\">View all</a></h2>")665+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\">View all</a></h2>")
556 if templ_7745c5c3_Err != nil {666 if templ_7745c5c3_Err != nil {
557 return templ_7745c5c3_Err667 return templ_7745c5c3_Err
558 }668 }
@@ -560,7 +670,7 @@ func summaryRail(p SummaryPage) templ.Component {
560 if templ_7745c5c3_Err != nil {670 if templ_7745c5c3_Err != nil {
561 return templ_7745c5c3_Err671 return templ_7745c5c3_Err
562 }672 }
563- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</section>")673+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</section>")
564 if templ_7745c5c3_Err != nil {674 if templ_7745c5c3_Err != nil {
565 return templ_7745c5c3_Err675 return templ_7745c5c3_Err
566 }676 }
@@ -572,7 +682,7 @@ func summaryRail(p SummaryPage) templ.Component {
572 }682 }
573 }683 }
574 if len(p.Outline) > 0 && p.Readme != nil {684 if len(p.Outline) > 0 && p.Readme != nil {
575- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>")685+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>")
576 if templ_7745c5c3_Err != nil {686 if templ_7745c5c3_Err != nil {
577 return templ_7745c5c3_Err687 return templ_7745c5c3_Err
578 }688 }
@@ -580,7 +690,7 @@ func summaryRail(p SummaryPage) templ.Component {
580 if templ_7745c5c3_Err != nil {690 if templ_7745c5c3_Err != nil {
581 return templ_7745c5c3_Err691 return templ_7745c5c3_Err
582 }692 }
583- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</section>")693+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "</section>")
584 if templ_7745c5c3_Err != nil {694 if templ_7745c5c3_Err != nil {
585 return templ_7745c5c3_Err695 return templ_7745c5c3_Err
586 }696 }
@@ -606,12 +716,12 @@ func Refs(l Layout, p RefsPage) templ.Component {
606 }()716 }()
607 }717 }
608 ctx = templ.InitializeContext(ctx)718 ctx = templ.InitializeContext(ctx)
609- templ_7745c5c3_Var28 := templ.GetChildren(ctx)719+ templ_7745c5c3_Var36 := templ.GetChildren(ctx)
610- if templ_7745c5c3_Var28 == nil {720+ if templ_7745c5c3_Var36 == nil {
611- templ_7745c5c3_Var28 = templ.NopComponent721+ templ_7745c5c3_Var36 = templ.NopComponent
612 }722 }
613 ctx = templ.ClearChildren(ctx)723 ctx = templ.ClearChildren(ctx)
614- templ_7745c5c3_Var29 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {724+ templ_7745c5c3_Var37 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
615 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context725 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
616 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)726 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
617 if !templ_7745c5c3_IsBuffer {727 if !templ_7745c5c3_IsBuffer {
@@ -623,7 +733,7 @@ func Refs(l Layout, p RefsPage) templ.Component {
623 }()733 }()
624 }734 }
625 ctx = templ.InitializeContext(ctx)735 ctx = templ.InitializeContext(ctx)
626- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>")736+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>")
627 if templ_7745c5c3_Err != nil {737 if templ_7745c5c3_Err != nil {
628 return templ_7745c5c3_Err738 return templ_7745c5c3_Err
629 }739 }
@@ -631,32 +741,32 @@ func Refs(l Layout, p RefsPage) templ.Component {
631 if templ_7745c5c3_Err != nil {741 if templ_7745c5c3_Err != nil {
632 return templ_7745c5c3_Err742 return templ_7745c5c3_Err
633 }743 }
634- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</table>")744+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "</table>")
635 if templ_7745c5c3_Err != nil {745 if templ_7745c5c3_Err != nil {
636 return templ_7745c5c3_Err746 return templ_7745c5c3_Err
637 }747 }
638 if p.Note != "" {748 if p.Note != "" {
639- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<p class=\"note\">")749+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<p class=\"note\">")
640 if templ_7745c5c3_Err != nil {750 if templ_7745c5c3_Err != nil {
641 return templ_7745c5c3_Err751 return templ_7745c5c3_Err
642 }752 }
643- var templ_7745c5c3_Var30 string753+ var templ_7745c5c3_Var38 string
644- templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)754+ templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
645 if templ_7745c5c3_Err != nil {755 if templ_7745c5c3_Err != nil {
646- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 154, Col: 27}756+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 162, Col: 27}
647 }757 }
648- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))758+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
649 if templ_7745c5c3_Err != nil {759 if templ_7745c5c3_Err != nil {
650 return templ_7745c5c3_Err760 return templ_7745c5c3_Err
651 }761 }
652- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</p>")762+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</p>")
653 if templ_7745c5c3_Err != nil {763 if templ_7745c5c3_Err != nil {
654 return templ_7745c5c3_Err764 return templ_7745c5c3_Err
655 }765 }
656 }766 }
657 return nil767 return nil
658 })768 })
659- templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var29), templ_7745c5c3_Buffer)769+ templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var37), templ_7745c5c3_Buffer)
660 if templ_7745c5c3_Err != nil {770 if templ_7745c5c3_Err != nil {
661 return templ_7745c5c3_Err771 return templ_7745c5c3_Err
662 }772 }
@@ -680,112 +790,112 @@ func refRow(kind string, r RefRow) templ.Component {
680 }()790 }()
681 }791 }
682 ctx = templ.InitializeContext(ctx)792 ctx = templ.InitializeContext(ctx)
683- templ_7745c5c3_Var31 := templ.GetChildren(ctx)793+ templ_7745c5c3_Var39 := templ.GetChildren(ctx)
684- if templ_7745c5c3_Var31 == nil {794+ if templ_7745c5c3_Var39 == nil {
685- templ_7745c5c3_Var31 = templ.NopComponent795+ templ_7745c5c3_Var39 = templ.NopComponent
686 }796 }
687 ctx = templ.ClearChildren(ctx)797 ctx = templ.ClearChildren(ctx)
688- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<tr")798+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "<tr")
689 if templ_7745c5c3_Err != nil {799 if templ_7745c5c3_Err != nil {
690 return templ_7745c5c3_Err800 return templ_7745c5c3_Err
691 }801 }
692 if r.Cursor {802 if r.Cursor {
693- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, " data-cursor")803+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, " data-cursor")
694 if templ_7745c5c3_Err != nil {804 if templ_7745c5c3_Err != nil {
695 return templ_7745c5c3_Err805 return templ_7745c5c3_Err
696 }806 }
697 }807 }
698- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "><td class=\"c-kind mute\">")808+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "><td class=\"c-kind mute\">")
699 if templ_7745c5c3_Err != nil {809 if templ_7745c5c3_Err != nil {
700 return templ_7745c5c3_Err810 return templ_7745c5c3_Err
701 }811 }
702- var templ_7745c5c3_Var32 string812+ var templ_7745c5c3_Var40 string
703- templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(kind)813+ templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(kind)
704 if templ_7745c5c3_Err != nil {814 if templ_7745c5c3_Err != nil {
705- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 161, Col: 32}815+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 169, Col: 32}
706 }816 }
707- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))817+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
708 if templ_7745c5c3_Err != nil {818 if templ_7745c5c3_Err != nil {
709 return templ_7745c5c3_Err819 return templ_7745c5c3_Err
710 }820 }
711- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</td><td class=\"c-name\"><a href=\"")821+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-name\"><a href=\"")
712 if templ_7745c5c3_Err != nil {822 if templ_7745c5c3_Err != nil {
713 return templ_7745c5c3_Err823 return templ_7745c5c3_Err
714 }824 }
715- var templ_7745c5c3_Var33 templ.SafeURL825+ var templ_7745c5c3_Var41 templ.SafeURL
716- templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href))826+ templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href))
717 if templ_7745c5c3_Err != nil {827 if templ_7745c5c3_Err != nil {
718- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 34}828+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 34}
719 }829 }
720- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))830+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
721 if templ_7745c5c3_Err != nil {831 if templ_7745c5c3_Err != nil {
722 return templ_7745c5c3_Err832 return templ_7745c5c3_Err
723 }833 }
724- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "\">")834+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "\">")
725 if templ_7745c5c3_Err != nil {835 if templ_7745c5c3_Err != nil {
726 return templ_7745c5c3_Err836 return templ_7745c5c3_Err
727 }837 }
728- var templ_7745c5c3_Var34 string838+ var templ_7745c5c3_Var42 string
729- templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)839+ templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)
730 if templ_7745c5c3_Err != nil {840 if templ_7745c5c3_Err != nil {
731- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 45}841+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 45}
732 }842 }
733- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))843+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
734 if templ_7745c5c3_Err != nil {844 if templ_7745c5c3_Err != nil {
735 return templ_7745c5c3_Err845 return templ_7745c5c3_Err
736 }846 }
737- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</a> ")847+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "</a> ")
738 if templ_7745c5c3_Err != nil {848 if templ_7745c5c3_Err != nil {
739 return templ_7745c5c3_Err849 return templ_7745c5c3_Err
740 }850 }
741 if r.Default {851 if r.Default {
742- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "<span class=\"pill\">default</span>")852+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "<span class=\"pill\">default</span>")
743 if templ_7745c5c3_Err != nil {853 if templ_7745c5c3_Err != nil {
744 return templ_7745c5c3_Err854 return templ_7745c5c3_Err
745 }855 }
746 }856 }
747- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "</td><td class=\"c-sha\">")857+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</td><td class=\"c-sha\">")
748 if templ_7745c5c3_Err != nil {858 if templ_7745c5c3_Err != nil {
749 return templ_7745c5c3_Err859 return templ_7745c5c3_Err
750 }860 }
751 if r.CHref != "" {861 if r.CHref != "" {
752- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<a href=\"")862+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<a href=\"")
753 if templ_7745c5c3_Err != nil {863 if templ_7745c5c3_Err != nil {
754 return templ_7745c5c3_Err864 return templ_7745c5c3_Err
755 }865 }
756- var templ_7745c5c3_Var35 templ.SafeURL866+ var templ_7745c5c3_Var43 templ.SafeURL
757- templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref))867+ templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref))
758 if templ_7745c5c3_Err != nil {868 if templ_7745c5c3_Err != nil {
759- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 36}869+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 36}
760 }870 }
761- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))871+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
762 if templ_7745c5c3_Err != nil {872 if templ_7745c5c3_Err != nil {
763 return templ_7745c5c3_Err873 return templ_7745c5c3_Err
764 }874 }
765- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "\">")875+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "\">")
766 if templ_7745c5c3_Err != nil {876 if templ_7745c5c3_Err != nil {
767 return templ_7745c5c3_Err877 return templ_7745c5c3_Err
768 }878 }
769- var templ_7745c5c3_Var36 string879+ var templ_7745c5c3_Var44 string
770- templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)880+ templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)
771 if templ_7745c5c3_Err != nil {881 if templ_7745c5c3_Err != nil {
772- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 48}882+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 48}
773 }883 }
774- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))884+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
775 if templ_7745c5c3_Err != nil {885 if templ_7745c5c3_Err != nil {
776 return templ_7745c5c3_Err886 return templ_7745c5c3_Err
777 }887 }
778- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "</a>")888+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</a>")
779 if templ_7745c5c3_Err != nil {889 if templ_7745c5c3_Err != nil {
780 return templ_7745c5c3_Err890 return templ_7745c5c3_Err
781 }891 }
782 } else {892 } else {
783- var templ_7745c5c3_Var37 string893+ var templ_7745c5c3_Var45 string
784- templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)894+ templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short)
785 if templ_7745c5c3_Err != nil {895 if templ_7745c5c3_Err != nil {
786- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 172, Col: 13}896+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 180, Col: 13}
787 }897 }
788- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))898+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
789 if templ_7745c5c3_Err != nil {899 if templ_7745c5c3_Err != nil {
790 return templ_7745c5c3_Err900 return templ_7745c5c3_Err
791 }901 }
@@ -794,69 +904,69 @@ func refRow(kind string, r RefRow) templ.Component {
794 if templ_7745c5c3_Err != nil {904 if templ_7745c5c3_Err != nil {
795 return templ_7745c5c3_Err905 return templ_7745c5c3_Err
796 }906 }
797- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "</td><td class=\"c-sub\">")907+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "</td><td class=\"c-sub\">")
798 if templ_7745c5c3_Err != nil {908 if templ_7745c5c3_Err != nil {
799 return templ_7745c5c3_Err909 return templ_7745c5c3_Err
800 }910 }
801- var templ_7745c5c3_Var38 string911+ var templ_7745c5c3_Var46 string
802- templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject)912+ templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject)
803 if templ_7745c5c3_Err != nil {913 if templ_7745c5c3_Err != nil {
804- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 176, Col: 31}914+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 184, Col: 31}
805 }915 }
806- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))916+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
807 if templ_7745c5c3_Err != nil {917 if templ_7745c5c3_Err != nil {
808 return templ_7745c5c3_Err918 return templ_7745c5c3_Err
809 }919 }
810- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-when dim\">")920+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</td><td class=\"c-when dim\">")
811 if templ_7745c5c3_Err != nil {921 if templ_7745c5c3_Err != nil {
812 return templ_7745c5c3_Err922 return templ_7745c5c3_Err
813 }923 }
814 if r.WhenAt != "" {924 if r.WhenAt != "" {
815- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "<time datetime=\"")925+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "<time datetime=\"")
816 if templ_7745c5c3_Err != nil {926 if templ_7745c5c3_Err != nil {
817 return templ_7745c5c3_Err927 return templ_7745c5c3_Err
818 }928 }
819- var templ_7745c5c3_Var39 string929+ var templ_7745c5c3_Var47 string
820- templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)930+ templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
821 if templ_7745c5c3_Err != nil {931 if templ_7745c5c3_Err != nil {
822- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 29}932+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 29}
823 }933 }
824- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39)934+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var47)
825 if templ_7745c5c3_Err != nil {935 if templ_7745c5c3_Err != nil {
826 return templ_7745c5c3_Err936 return templ_7745c5c3_Err
827 }937 }
828- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "\" title=\"")938+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" title=\"")
829 if templ_7745c5c3_Err != nil {939 if templ_7745c5c3_Err != nil {
830 return templ_7745c5c3_Err940 return templ_7745c5c3_Err
831 }941 }
832- var templ_7745c5c3_Var40 string942+ var templ_7745c5c3_Var48 string
833- templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)943+ templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt)
834 if templ_7745c5c3_Err != nil {944 if templ_7745c5c3_Err != nil {
835- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 48}945+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 48}
836 }946 }
837- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40)947+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var48)
838 if templ_7745c5c3_Err != nil {948 if templ_7745c5c3_Err != nil {
839 return templ_7745c5c3_Err949 return templ_7745c5c3_Err
840 }950 }
841- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "\">")951+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "\">")
842 if templ_7745c5c3_Err != nil {952 if templ_7745c5c3_Err != nil {
843 return templ_7745c5c3_Err953 return templ_7745c5c3_Err
844 }954 }
845- var templ_7745c5c3_Var41 string955+ var templ_7745c5c3_Var49 string
846- templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(r.When)956+ templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(r.When)
847 if templ_7745c5c3_Err != nil {957 if templ_7745c5c3_Err != nil {
848- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 59}958+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 59}
849 }959 }
850- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))960+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
851 if templ_7745c5c3_Err != nil {961 if templ_7745c5c3_Err != nil {
852 return templ_7745c5c3_Err962 return templ_7745c5c3_Err
853 }963 }
854- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</time>")964+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</time>")
855 if templ_7745c5c3_Err != nil {965 if templ_7745c5c3_Err != nil {
856 return templ_7745c5c3_Err966 return templ_7745c5c3_Err
857 }967 }
858 }968 }
859- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "</td></tr>")969+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "</td></tr>")
860 if templ_7745c5c3_Err != nil {970 if templ_7745c5c3_Err != nil {
861 return templ_7745c5c3_Err971 return templ_7745c5c3_Err
862 }972 }
@@ -880,12 +990,12 @@ func refsRail(p RefsPage) templ.Component {
880 }()990 }()
881 }991 }
882 ctx = templ.InitializeContext(ctx)992 ctx = templ.InitializeContext(ctx)
883- templ_7745c5c3_Var42 := templ.GetChildren(ctx)993+ templ_7745c5c3_Var50 := templ.GetChildren(ctx)
884- if templ_7745c5c3_Var42 == nil {994+ if templ_7745c5c3_Var50 == nil {
885- templ_7745c5c3_Var42 = templ.NopComponent995+ templ_7745c5c3_Var50 = templ.NopComponent
886 }996 }
887 ctx = templ.ClearChildren(ctx)997 ctx = templ.ClearChildren(ctx)
888- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>")998+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>")
889 if templ_7745c5c3_Err != nil {999 if templ_7745c5c3_Err != nil {
890 return templ_7745c5c3_Err1000 return templ_7745c5c3_Err
891 }1001 }
@@ -893,7 +1003,7 @@ func refsRail(p RefsPage) templ.Component {
893 if templ_7745c5c3_Err != nil {1003 if templ_7745c5c3_Err != nil {
894 return templ_7745c5c3_Err1004 return templ_7745c5c3_Err
895 }1005 }
896- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</section>")1006+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</section>")
897 if templ_7745c5c3_Err != nil {1007 if templ_7745c5c3_Err != nil {
898 return templ_7745c5c3_Err1008 return templ_7745c5c3_Err
899 }1009 }
@@ -918,12 +1028,12 @@ func State(l Layout, p StatePage) templ.Component {
918 }()1028 }()
919 }1029 }
920 ctx = templ.InitializeContext(ctx)1030 ctx = templ.InitializeContext(ctx)
921- templ_7745c5c3_Var43 := templ.GetChildren(ctx)1031+ templ_7745c5c3_Var51 := templ.GetChildren(ctx)
922- if templ_7745c5c3_Var43 == nil {1032+ if templ_7745c5c3_Var51 == nil {
923- templ_7745c5c3_Var43 = templ.NopComponent1033+ templ_7745c5c3_Var51 = templ.NopComponent
924 }1034 }
925 ctx = templ.ClearChildren(ctx)1035 ctx = templ.ClearChildren(ctx)
926- templ_7745c5c3_Var44 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {1036+ templ_7745c5c3_Var52 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
927 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context1037 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
928 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)1038 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
929 if !templ_7745c5c3_IsBuffer {1039 if !templ_7745c5c3_IsBuffer {
@@ -935,51 +1045,51 @@ func State(l Layout, p StatePage) templ.Component {
935 }()1045 }()
936 }1046 }
937 ctx = templ.InitializeContext(ctx)1047 ctx = templ.InitializeContext(ctx)
938- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">")1048+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">")
939 if templ_7745c5c3_Err != nil {1049 if templ_7745c5c3_Err != nil {
940 return templ_7745c5c3_Err1050 return templ_7745c5c3_Err
941 }1051 }
942- var templ_7745c5c3_Var45 string1052+ var templ_7745c5c3_Var53 string
943- templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code)1053+ templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code)
944 if templ_7745c5c3_Err != nil {1054 if templ_7745c5c3_Err != nil {
945- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 196, Col: 30}1055+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 204, Col: 30}
946 }1056 }
947- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))1057+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
948 if templ_7745c5c3_Err != nil {1058 if templ_7745c5c3_Err != nil {
949 return templ_7745c5c3_Err1059 return templ_7745c5c3_Err
950 }1060 }
951- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</p><h1 id=\"state-title\">")1061+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "</p><h1 id=\"state-title\">")
952 if templ_7745c5c3_Err != nil {1062 if templ_7745c5c3_Err != nil {
953 return templ_7745c5c3_Err1063 return templ_7745c5c3_Err
954 }1064 }
955- var templ_7745c5c3_Var46 string1065+ var templ_7745c5c3_Var54 string
956- templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)1066+ templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
957 if templ_7745c5c3_Err != nil {1067 if templ_7745c5c3_Err != nil {
958- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 197, Col: 33}1068+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 205, Col: 33}
959 }1069 }
960- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))1070+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
961 if templ_7745c5c3_Err != nil {1071 if templ_7745c5c3_Err != nil {
962 return templ_7745c5c3_Err1072 return templ_7745c5c3_Err
963 }1073 }
964- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "</h1>")1074+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>")
965 if templ_7745c5c3_Err != nil {1075 if templ_7745c5c3_Err != nil {
966 return templ_7745c5c3_Err1076 return templ_7745c5c3_Err
967 }1077 }
968 for _, line := range p.Lines {1078 for _, line := range p.Lines {
969- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "<p class=\"dim\">")1079+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">")
970 if templ_7745c5c3_Err != nil {1080 if templ_7745c5c3_Err != nil {
971 return templ_7745c5c3_Err1081 return templ_7745c5c3_Err
972 }1082 }
973- var templ_7745c5c3_Var47 string1083+ var templ_7745c5c3_Var55 string
974- templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(line)1084+ templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(line)
975 if templ_7745c5c3_Err != nil {1085 if templ_7745c5c3_Err != nil {
976- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 199, Col: 25}1086+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 207, Col: 25}
977 }1087 }
978- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))1088+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
979 if templ_7745c5c3_Err != nil {1089 if templ_7745c5c3_Err != nil {
980 return templ_7745c5c3_Err1090 return templ_7745c5c3_Err
981 }1091 }
982- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</p>")1092+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>")
983 if templ_7745c5c3_Err != nil {1093 if templ_7745c5c3_Err != nil {
984 return templ_7745c5c3_Err1094 return templ_7745c5c3_Err
985 }1095 }
@@ -990,49 +1100,49 @@ func State(l Layout, p StatePage) templ.Component {
990 return templ_7745c5c3_Err1100 return templ_7745c5c3_Err
991 }1101 }
992 }1102 }
993- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "<p class=\"state-back\">")1103+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<p class=\"state-back\">")
994 if templ_7745c5c3_Err != nil {1104 if templ_7745c5c3_Err != nil {
995 return templ_7745c5c3_Err1105 return templ_7745c5c3_Err
996 }1106 }
997 for _, b := range p.Back {1107 for _, b := range p.Back {
998- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "<a href=\"")1108+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "<a href=\"")
999 if templ_7745c5c3_Err != nil {1109 if templ_7745c5c3_Err != nil {
1000 return templ_7745c5c3_Err1110 return templ_7745c5c3_Err
1001 }1111 }
1002- var templ_7745c5c3_Var48 templ.SafeURL1112+ var templ_7745c5c3_Var56 templ.SafeURL
1003- templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href))1113+ templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href))
1004 if templ_7745c5c3_Err != nil {1114 if templ_7745c5c3_Err != nil {
1005- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 36}1115+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 36}
1006 }1116 }
1007- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))1117+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56))
1008 if templ_7745c5c3_Err != nil {1118 if templ_7745c5c3_Err != nil {
1009 return templ_7745c5c3_Err1119 return templ_7745c5c3_Err
1010 }1120 }
1011- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "\">")1121+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "\">")
1012 if templ_7745c5c3_Err != nil {1122 if templ_7745c5c3_Err != nil {
1013 return templ_7745c5c3_Err1123 return templ_7745c5c3_Err
1014 }1124 }
1015- var templ_7745c5c3_Var49 string1125+ var templ_7745c5c3_Var57 string
1016- templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label)1126+ templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label)
1017 if templ_7745c5c3_Err != nil {1127 if templ_7745c5c3_Err != nil {
1018- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 48}1128+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 48}
1019 }1129 }
1020- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))1130+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))
1021 if templ_7745c5c3_Err != nil {1131 if templ_7745c5c3_Err != nil {
1022 return templ_7745c5c3_Err1132 return templ_7745c5c3_Err
1023 }1133 }
1024- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</a>")1134+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</a>")
1025 if templ_7745c5c3_Err != nil {1135 if templ_7745c5c3_Err != nil {
1026 return templ_7745c5c3_Err1136 return templ_7745c5c3_Err
1027 }1137 }
1028 }1138 }
1029- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "</p></section>")1139+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</p></section>")
1030 if templ_7745c5c3_Err != nil {1140 if templ_7745c5c3_Err != nil {
1031 return templ_7745c5c3_Err1141 return templ_7745c5c3_Err
1032 }1142 }
1033 return nil1143 return nil
1034 })1144 })
1035- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var44), templ_7745c5c3_Buffer)1145+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var52), templ_7745c5c3_Buffer)
1036 if templ_7745c5c3_Err != nil {1146 if templ_7745c5c3_Err != nil {
1037 return templ_7745c5c3_Err1147 return templ_7745c5c3_Err
1038 }1148 }
@@ -1061,12 +1171,12 @@ func Login(l Layout, p LoginPage) templ.Component {
1061 }()1171 }()
1062 }1172 }
1063 ctx = templ.InitializeContext(ctx)1173 ctx = templ.InitializeContext(ctx)
1064- templ_7745c5c3_Var50 := templ.GetChildren(ctx)1174+ templ_7745c5c3_Var58 := templ.GetChildren(ctx)
1065- if templ_7745c5c3_Var50 == nil {1175+ if templ_7745c5c3_Var58 == nil {
1066- templ_7745c5c3_Var50 = templ.NopComponent1176+ templ_7745c5c3_Var58 = templ.NopComponent
1067 }1177 }
1068 ctx = templ.ClearChildren(ctx)1178 ctx = templ.ClearChildren(ctx)
1069- templ_7745c5c3_Var51 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {1179+ templ_7745c5c3_Var59 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
1070 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context1180 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
1071 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)1181 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
1072 if !templ_7745c5c3_IsBuffer {1182 if !templ_7745c5c3_IsBuffer {
@@ -1078,75 +1188,75 @@ func Login(l Layout, p LoginPage) templ.Component {
1078 }()1188 }()
1079 }1189 }
1080 ctx = templ.InitializeContext(ctx)1190 ctx = templ.InitializeContext(ctx)
1081- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")1191+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")
1082 if templ_7745c5c3_Err != nil {1192 if templ_7745c5c3_Err != nil {
1083 return templ_7745c5c3_Err1193 return templ_7745c5c3_Err
1084 }1194 }
1085- var templ_7745c5c3_Var52 string1195+ var templ_7745c5c3_Var60 string
1086- templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)1196+ templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
1087 if templ_7745c5c3_Err != nil {1197 if templ_7745c5c3_Err != nil {
1088- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 221, Col: 33}1198+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 229, Col: 33}
1089 }1199 }
1090- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))1200+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var60))
1091 if templ_7745c5c3_Err != nil {1201 if templ_7745c5c3_Err != nil {
1092 return templ_7745c5c3_Err1202 return templ_7745c5c3_Err
1093 }1203 }
1094- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>")1204+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "</h1>")
1095 if templ_7745c5c3_Err != nil {1205 if templ_7745c5c3_Err != nil {
1096 return templ_7745c5c3_Err1206 return templ_7745c5c3_Err
1097 }1207 }
1098 for _, line := range p.Lines {1208 for _, line := range p.Lines {
1099- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">")1209+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "<p class=\"dim\">")
1100 if templ_7745c5c3_Err != nil {1210 if templ_7745c5c3_Err != nil {
1101 return templ_7745c5c3_Err1211 return templ_7745c5c3_Err
1102 }1212 }
1103- var templ_7745c5c3_Var53 string1213+ var templ_7745c5c3_Var61 string
1104- templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(line)1214+ templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(line)
1105 if templ_7745c5c3_Err != nil {1215 if templ_7745c5c3_Err != nil {
1106- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 223, Col: 25}1216+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 231, Col: 25}
1107 }1217 }
1108- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))1218+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))
1109 if templ_7745c5c3_Err != nil {1219 if templ_7745c5c3_Err != nil {
1110 return templ_7745c5c3_Err1220 return templ_7745c5c3_Err
1111 }1221 }
1112- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>")1222+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</p>")
1113 if templ_7745c5c3_Err != nil {1223 if templ_7745c5c3_Err != nil {
1114 return templ_7745c5c3_Err1224 return templ_7745c5c3_Err
1115 }1225 }
1116 }1226 }
1117- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<form class=\"state-act\" method=\"post\" action=\"")1227+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<form class=\"state-act\" method=\"post\" action=\"")
1118 if templ_7745c5c3_Err != nil {1228 if templ_7745c5c3_Err != nil {
1119 return templ_7745c5c3_Err1229 return templ_7745c5c3_Err
1120 }1230 }
1121- var templ_7745c5c3_Var54 templ.SafeURL1231+ var templ_7745c5c3_Var62 templ.SafeURL
1122- templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action))1232+ templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action))
1123 if templ_7745c5c3_Err != nil {1233 if templ_7745c5c3_Err != nil {
1124- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 225, Col: 73}1234+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 233, Col: 73}
1125 }1235 }
1126- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))1236+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))
1127 if templ_7745c5c3_Err != nil {1237 if templ_7745c5c3_Err != nil {
1128 return templ_7745c5c3_Err1238 return templ_7745c5c3_Err
1129 }1239 }
1130- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">")1240+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">")
1131 if templ_7745c5c3_Err != nil {1241 if templ_7745c5c3_Err != nil {
1132 return templ_7745c5c3_Err1242 return templ_7745c5c3_Err
1133 }1243 }
1134- var templ_7745c5c3_Var55 string1244+ var templ_7745c5c3_Var63 string
1135- templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)1245+ templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)
1136 if templ_7745c5c3_Err != nil {1246 if templ_7745c5c3_Err != nil {
1137- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 226, Col: 56}1247+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 234, Col: 56}
1138 }1248 }
1139- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))1249+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63))
1140 if templ_7745c5c3_Err != nil {1250 if templ_7745c5c3_Err != nil {
1141 return templ_7745c5c3_Err1251 return templ_7745c5c3_Err
1142 }1252 }
1143- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")1253+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")
1144 if templ_7745c5c3_Err != nil {1254 if templ_7745c5c3_Err != nil {
1145 return templ_7745c5c3_Err1255 return templ_7745c5c3_Err
1146 }1256 }
1147 return nil1257 return nil
1148 })1258 })
1149- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var51), templ_7745c5c3_Buffer)1259+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var59), templ_7745c5c3_Buffer)
1150 if templ_7745c5c3_Err != nil {1260 if templ_7745c5c3_Err != nil {
1151 return templ_7745c5c3_Err1261 return templ_7745c5c3_Err
1152 }1262 }
@@ -1172,12 +1282,12 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component {
1172 }()1282 }()
1173 }1283 }
1174 ctx = templ.InitializeContext(ctx)1284 ctx = templ.InitializeContext(ctx)
1175- templ_7745c5c3_Var56 := templ.GetChildren(ctx)1285+ templ_7745c5c3_Var64 := templ.GetChildren(ctx)
1176- if templ_7745c5c3_Var56 == nil {1286+ if templ_7745c5c3_Var64 == nil {
1177- templ_7745c5c3_Var56 = templ.NopComponent1287+ templ_7745c5c3_Var64 = templ.NopComponent
1178 }1288 }
1179 ctx = templ.ClearChildren(ctx)1289 ctx = templ.ClearChildren(ctx)
1180- templ_7745c5c3_Var57 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {1290+ templ_7745c5c3_Var65 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
1181 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context1291 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
1182 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)1292 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
1183 if !templ_7745c5c3_IsBuffer {1293 if !templ_7745c5c3_IsBuffer {
@@ -1189,88 +1299,88 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component {
1189 }()1299 }()
1190 }1300 }
1191 ctx = templ.InitializeContext(ctx)1301 ctx = templ.InitializeContext(ctx)
1192- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")1302+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">")
1193 if templ_7745c5c3_Err != nil {1303 if templ_7745c5c3_Err != nil {
1194 return templ_7745c5c3_Err1304 return templ_7745c5c3_Err
1195 }1305 }
1196- var templ_7745c5c3_Var58 string1306+ var templ_7745c5c3_Var66 string
1197- templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)1307+ templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title)
1198 if templ_7745c5c3_Err != nil {1308 if templ_7745c5c3_Err != nil {
1199- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 238, Col: 33}1309+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 246, Col: 33}
1200 }1310 }
1201- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))1311+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))
1202 if templ_7745c5c3_Err != nil {1312 if templ_7745c5c3_Err != nil {
1203 return templ_7745c5c3_Err1313 return templ_7745c5c3_Err
1204 }1314 }
1205- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"")1315+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"")
1206 if templ_7745c5c3_Err != nil {1316 if templ_7745c5c3_Err != nil {
1207 return templ_7745c5c3_Err1317 return templ_7745c5c3_Err
1208 }1318 }
1209- var templ_7745c5c3_Var59 string1319+ var templ_7745c5c3_Var67 string
1210- templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)1320+ templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)
1211 if templ_7745c5c3_Err != nil {1321 if templ_7745c5c3_Err != nil {
1212- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 87}1322+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 87}
1213 }1323 }
1214- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var59)1324+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67)
1215 if templ_7745c5c3_Err != nil {1325 if templ_7745c5c3_Err != nil {
1216 return templ_7745c5c3_Err1326 return templ_7745c5c3_Err
1217 }1327 }
1218- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "\" data-finish=\"")1328+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "\" data-finish=\"")
1219 if templ_7745c5c3_Err != nil {1329 if templ_7745c5c3_Err != nil {
1220 return templ_7745c5c3_Err1330 return templ_7745c5c3_Err
1221 }1331 }
1222- var templ_7745c5c3_Var60 string1332+ var templ_7745c5c3_Var68 string
1223- templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)1333+ templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)
1224 if templ_7745c5c3_Err != nil {1334 if templ_7745c5c3_Err != nil {
1225- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 112}1335+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 112}
1226 }1336 }
1227- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var60)1337+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var68)
1228 if templ_7745c5c3_Err != nil {1338 if templ_7745c5c3_Err != nil {
1229 return templ_7745c5c3_Err1339 return templ_7745c5c3_Err
1230 }1340 }
1231- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "\">")1341+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "\">")
1232 if templ_7745c5c3_Err != nil {1342 if templ_7745c5c3_Err != nil {
1233 return templ_7745c5c3_Err1343 return templ_7745c5c3_Err
1234 }1344 }
1235- var templ_7745c5c3_Var61 string1345+ var templ_7745c5c3_Var69 string
1236- templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)1346+ templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button)
1237 if templ_7745c5c3_Err != nil {1347 if templ_7745c5c3_Err != nil {
1238- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 125}1348+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 125}
1239 }1349 }
1240- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))1350+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))
1241 if templ_7745c5c3_Err != nil {1351 if templ_7745c5c3_Err != nil {
1242 return templ_7745c5c3_Err1352 return templ_7745c5c3_Err
1243 }1353 }
1244- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")1354+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")
1245 if templ_7745c5c3_Err != nil {1355 if templ_7745c5c3_Err != nil {
1246 return templ_7745c5c3_Err1356 return templ_7745c5c3_Err
1247 }1357 }
1248 for _, line := range p.Lines {1358 for _, line := range p.Lines {
1249- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "<p class=\"dim\">")1359+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "<p class=\"dim\">")
1250 if templ_7745c5c3_Err != nil {1360 if templ_7745c5c3_Err != nil {
1251 return templ_7745c5c3_Err1361 return templ_7745c5c3_Err
1252 }1362 }
1253- var templ_7745c5c3_Var62 string1363+ var templ_7745c5c3_Var70 string
1254- templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(line)1364+ templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(line)
1255 if templ_7745c5c3_Err != nil {1365 if templ_7745c5c3_Err != nil {
1256- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 244, Col: 25}1366+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 252, Col: 25}
1257 }1367 }
1258- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))1368+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))
1259 if templ_7745c5c3_Err != nil {1369 if templ_7745c5c3_Err != nil {
1260 return templ_7745c5c3_Err1370 return templ_7745c5c3_Err
1261 }1371 }
1262- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "</p>")1372+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "</p>")
1263 if templ_7745c5c3_Err != nil {1373 if templ_7745c5c3_Err != nil {
1264 return templ_7745c5c3_Err1374 return templ_7745c5c3_Err
1265 }1375 }
1266 }1376 }
1267- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")1377+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>")
1268 if templ_7745c5c3_Err != nil {1378 if templ_7745c5c3_Err != nil {
1269 return templ_7745c5c3_Err1379 return templ_7745c5c3_Err
1270 }1380 }
1271 return nil1381 return nil
1272 })1382 })
1273- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var57), templ_7745c5c3_Buffer)1383+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var65), templ_7745c5c3_Buffer)
1274 if templ_7745c5c3_Err != nil {1384 if templ_7745c5c3_Err != nil {
1275 return templ_7745c5c3_Err1385 return templ_7745c5c3_Err
1276 }1386 }
@@ -1295,12 +1405,12 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component {
1295 }()1405 }()
1296 }1406 }
1297 ctx = templ.InitializeContext(ctx)1407 ctx = templ.InitializeContext(ctx)
1298- templ_7745c5c3_Var63 := templ.GetChildren(ctx)1408+ templ_7745c5c3_Var71 := templ.GetChildren(ctx)
1299- if templ_7745c5c3_Var63 == nil {1409+ if templ_7745c5c3_Var71 == nil {
1300- templ_7745c5c3_Var63 = templ.NopComponent1410+ templ_7745c5c3_Var71 = templ.NopComponent
1301 }1411 }
1302 ctx = templ.ClearChildren(ctx)1412 ctx = templ.ClearChildren(ctx)
1303- templ_7745c5c3_Var64 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {1413+ templ_7745c5c3_Var72 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
1304 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context1414 templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
1305 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)1415 templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
1306 if !templ_7745c5c3_IsBuffer {1416 if !templ_7745c5c3_IsBuffer {
@@ -1312,231 +1422,231 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component {
1312 }()1422 }()
1313 }1423 }
1314 ctx = templ.InitializeContext(ctx)1424 ctx = templ.InitializeContext(ctx)
1315- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">")1425+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">")
1316 if templ_7745c5c3_Err != nil {1426 if templ_7745c5c3_Err != nil {
1317 return templ_7745c5c3_Err1427 return templ_7745c5c3_Err
1318 }1428 }
1319- var templ_7745c5c3_Var65 string1429+ var templ_7745c5c3_Var73 string
1320- templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows)))1430+ templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows)))
1321 if templ_7745c5c3_Err != nil {1431 if templ_7745c5c3_Err != nil {
1322- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 254, Col: 81}1432+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 262, Col: 81}
1323 }1433 }
1324- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))1434+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73))
1325 if templ_7745c5c3_Err != nil {1435 if templ_7745c5c3_Err != nil {
1326 return templ_7745c5c3_Err1436 return templ_7745c5c3_Err
1327 }1437 }
1328- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>")1438+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>")
1329 if templ_7745c5c3_Err != nil {1439 if templ_7745c5c3_Err != nil {
1330 return templ_7745c5c3_Err1440 return templ_7745c5c3_Err
1331 }1441 }
1332 if len(p.Rows) > 0 {1442 if len(p.Rows) > 0 {
1333- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>")1443+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>")
1334 if templ_7745c5c3_Err != nil {1444 if templ_7745c5c3_Err != nil {
1335 return templ_7745c5c3_Err1445 return templ_7745c5c3_Err
1336 }1446 }
1337 for _, r := range p.Rows {1447 for _, r := range p.Rows {
1338- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "<tr><td class=\"c-name\">")1448+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "<tr><td class=\"c-name\">")
1339 if templ_7745c5c3_Err != nil {1449 if templ_7745c5c3_Err != nil {
1340 return templ_7745c5c3_Err1450 return templ_7745c5c3_Err
1341 }1451 }
1342- var templ_7745c5c3_Var66 string1452+ var templ_7745c5c3_Var74 string
1343- templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)1453+ templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name)
1344 if templ_7745c5c3_Err != nil {1454 if templ_7745c5c3_Err != nil {
1345- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 270, Col: 34}1455+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 278, Col: 34}
1346 }1456 }
1347- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))1457+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))
1348 if templ_7745c5c3_Err != nil {1458 if templ_7745c5c3_Err != nil {
1349 return templ_7745c5c3_Err1459 return templ_7745c5c3_Err
1350 }1460 }
1351- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</td><td class=\"c-when nowrap\"><time")1461+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "</td><td class=\"c-when nowrap\"><time")
1352 if templ_7745c5c3_Err != nil {1462 if templ_7745c5c3_Err != nil {
1353 return templ_7745c5c3_Err1463 return templ_7745c5c3_Err
1354 }1464 }
1355 if r.CreatedAt != "" {1465 if r.CreatedAt != "" {
1356- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " datetime=\"")1466+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, " datetime=\"")
1357 if templ_7745c5c3_Err != nil {1467 if templ_7745c5c3_Err != nil {
1358 return templ_7745c5c3_Err1468 return templ_7745c5c3_Err
1359 }1469 }
1360- var templ_7745c5c3_Var67 string1470+ var templ_7745c5c3_Var75 string
1361- templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt)1471+ templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt)
1362 if templ_7745c5c3_Err != nil {1472 if templ_7745c5c3_Err != nil {
1363- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 274, Col: 32}1473+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 282, Col: 32}
1364 }1474 }
1365- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67)1475+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)
1366 if templ_7745c5c3_Err != nil {1476 if templ_7745c5c3_Err != nil {
1367 return templ_7745c5c3_Err1477 return templ_7745c5c3_Err
1368 }1478 }
1369- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"")1479+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "\"")
1370 if templ_7745c5c3_Err != nil {1480 if templ_7745c5c3_Err != nil {
1371 return templ_7745c5c3_Err1481 return templ_7745c5c3_Err
1372 }1482 }
1373 }1483 }
1374- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, ">")1484+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, ">")
1375 if templ_7745c5c3_Err != nil {1485 if templ_7745c5c3_Err != nil {
1376 return templ_7745c5c3_Err1486 return templ_7745c5c3_Err
1377 }1487 }
1378- var templ_7745c5c3_Var68 string1488+ var templ_7745c5c3_Var76 string
1379- templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created)1489+ templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created)
1380 if templ_7745c5c3_Err != nil {1490 if templ_7745c5c3_Err != nil {
1381- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 276, Col: 20}1491+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 284, Col: 20}
1382 }1492 }
1383- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))1493+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))
1384 if templ_7745c5c3_Err != nil {1494 if templ_7745c5c3_Err != nil {
1385 return templ_7745c5c3_Err1495 return templ_7745c5c3_Err
1386 }1496 }
1387- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "</time></td><td class=\"c-when nowrap\"><time")1497+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "</time></td><td class=\"c-when nowrap\"><time")
1388 if templ_7745c5c3_Err != nil {1498 if templ_7745c5c3_Err != nil {
1389 return templ_7745c5c3_Err1499 return templ_7745c5c3_Err
1390 }1500 }
1391 if r.LastUsedAt != "" {1501 if r.LastUsedAt != "" {
1392- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " datetime=\"")1502+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, " datetime=\"")
1393 if templ_7745c5c3_Err != nil {1503 if templ_7745c5c3_Err != nil {
1394 return templ_7745c5c3_Err1504 return templ_7745c5c3_Err
1395 }1505 }
1396- var templ_7745c5c3_Var69 string1506+ var templ_7745c5c3_Var77 string
1397- templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt)1507+ templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt)
1398 if templ_7745c5c3_Err != nil {1508 if templ_7745c5c3_Err != nil {
1399- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 281, Col: 33}1509+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 289, Col: 33}
1400 }1510 }
1401- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var69)1511+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77)
1402 if templ_7745c5c3_Err != nil {1512 if templ_7745c5c3_Err != nil {
1403 return templ_7745c5c3_Err1513 return templ_7745c5c3_Err
1404 }1514 }
1405- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"")1515+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "\"")
1406 if templ_7745c5c3_Err != nil {1516 if templ_7745c5c3_Err != nil {
1407 return templ_7745c5c3_Err1517 return templ_7745c5c3_Err
1408 }1518 }
1409 }1519 }
1410- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, ">")1520+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, ">")
1411 if templ_7745c5c3_Err != nil {1521 if templ_7745c5c3_Err != nil {
1412 return templ_7745c5c3_Err1522 return templ_7745c5c3_Err
1413 }1523 }
1414- var templ_7745c5c3_Var70 string1524+ var templ_7745c5c3_Var78 string
1415- templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed)1525+ templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed)
1416 if templ_7745c5c3_Err != nil {1526 if templ_7745c5c3_Err != nil {
1417- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 283, Col: 21}1527+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 291, Col: 21}
1418 }1528 }
1419- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))1529+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78))
1420 if templ_7745c5c3_Err != nil {1530 if templ_7745c5c3_Err != nil {
1421 return templ_7745c5c3_Err1531 return templ_7745c5c3_Err
1422 }1532 }
1423- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</time></td><td class=\"c-sync\">")1533+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</time></td><td class=\"c-sync\">")
1424 if templ_7745c5c3_Err != nil {1534 if templ_7745c5c3_Err != nil {
1425 return templ_7745c5c3_Err1535 return templ_7745c5c3_Err
1426 }1536 }
1427 if r.Synced {1537 if r.Synced {
1428- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "yes")1538+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "yes")
1429 if templ_7745c5c3_Err != nil {1539 if templ_7745c5c3_Err != nil {
1430 return templ_7745c5c3_Err1540 return templ_7745c5c3_Err
1431 }1541 }
1432 } else {1542 } else {
1433- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "no")1543+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "no")
1434 if templ_7745c5c3_Err != nil {1544 if templ_7745c5c3_Err != nil {
1435 return templ_7745c5c3_Err1545 return templ_7745c5c3_Err
1436 }1546 }
1437 }1547 }
1438- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "</td><td class=\"c-act\"><form method=\"post\" action=\"")1548+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "</td><td class=\"c-act\"><form method=\"post\" action=\"")
1439 if templ_7745c5c3_Err != nil {1549 if templ_7745c5c3_Err != nil {
1440 return templ_7745c5c3_Err1550 return templ_7745c5c3_Err
1441 }1551 }
1442- var templ_7745c5c3_Var71 templ.SafeURL1552+ var templ_7745c5c3_Var79 templ.SafeURL
1443- templ_7745c5c3_Var71, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove))1553+ templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove))
1444 if templ_7745c5c3_Err != nil {1554 if templ_7745c5c3_Err != nil {
1445- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 293, Col: 60}1555+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 301, Col: 60}
1446 }1556 }
1447- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var71))1557+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))
1448 if templ_7745c5c3_Err != nil {1558 if templ_7745c5c3_Err != nil {
1449 return templ_7745c5c3_Err1559 return templ_7745c5c3_Err
1450 }1560 }
1451- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"")1561+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"")
1452 if templ_7745c5c3_Err != nil {1562 if templ_7745c5c3_Err != nil {
1453 return templ_7745c5c3_Err1563 return templ_7745c5c3_Err
1454 }1564 }
1455- var templ_7745c5c3_Var72 string1565+ var templ_7745c5c3_Var80 string
1456- templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name)1566+ templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name)
1457 if templ_7745c5c3_Err != nil {1567 if templ_7745c5c3_Err != nil {
1458- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 294, Col: 89}1568+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 302, Col: 89}
1459 }1569 }
1460- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var72)1570+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)
1461 if templ_7745c5c3_Err != nil {1571 if templ_7745c5c3_Err != nil {
1462 return templ_7745c5c3_Err1572 return templ_7745c5c3_Err
1463 }1573 }
1464- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "\">Remove</button></form></td></tr>")1574+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\">Remove</button></form></td></tr>")
1465 if templ_7745c5c3_Err != nil {1575 if templ_7745c5c3_Err != nil {
1466 return templ_7745c5c3_Err1576 return templ_7745c5c3_Err
1467 }1577 }
1468 }1578 }
1469- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "</tbody></table>")1579+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "</tbody></table>")
1470 if templ_7745c5c3_Err != nil {1580 if templ_7745c5c3_Err != nil {
1471 return templ_7745c5c3_Err1581 return templ_7745c5c3_Err
1472 }1582 }
1473 } else {1583 } else {
1474- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "<p class=\"lede dim\">no passkeys yet.</p>")1584+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "<p class=\"lede dim\">no passkeys yet.</p>")
1475 if templ_7745c5c3_Err != nil {1585 if templ_7745c5c3_Err != nil {
1476 return templ_7745c5c3_Err1586 return templ_7745c5c3_Err
1477 }1587 }
1478 }1588 }
1479- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, " ")1589+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, " ")
1480 if templ_7745c5c3_Err != nil {1590 if templ_7745c5c3_Err != nil {
1481 return templ_7745c5c3_Err1591 return templ_7745c5c3_Err
1482 }1592 }
1483 if p.Full {1593 if p.Full {
1484- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "<p class=\"dim\">")1594+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "<p class=\"dim\">")
1485 if templ_7745c5c3_Err != nil {1595 if templ_7745c5c3_Err != nil {
1486 return templ_7745c5c3_Err1596 return templ_7745c5c3_Err
1487 }1597 }
1488- var templ_7745c5c3_Var73 string1598+ var templ_7745c5c3_Var81 string
1489- templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max))1599+ templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max))
1490 if templ_7745c5c3_Err != nil {1600 if templ_7745c5c3_Err != nil {
1491- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 305, Col: 31}1601+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 313, Col: 31}
1492 }1602 }
1493- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73))1603+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))
1494 if templ_7745c5c3_Err != nil {1604 if templ_7745c5c3_Err != nil {
1495 return templ_7745c5c3_Err1605 return templ_7745c5c3_Err
1496 }1606 }
1497- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, " passkeys are registered, the most there can be. Remove one to add another.</p>")1607+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, " passkeys are registered, the most there can be. Remove one to add another.</p>")
1498 if templ_7745c5c3_Err != nil {1608 if templ_7745c5c3_Err != nil {
1499 return templ_7745c5c3_Err1609 return templ_7745c5c3_Err
1500 }1610 }
1501 } else {1611 } else {
1502- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"")1612+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"")
1503 if templ_7745c5c3_Err != nil {1613 if templ_7745c5c3_Err != nil {
1504 return templ_7745c5c3_Err1614 return templ_7745c5c3_Err
1505 }1615 }
1506- var templ_7745c5c3_Var74 string1616+ var templ_7745c5c3_Var82 string
1507- templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)1617+ templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin)
1508 if templ_7745c5c3_Err != nil {1618 if templ_7745c5c3_Err != nil {
1509- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 90}1619+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 90}
1510 }1620 }
1511- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var74)1621+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var82)
1512 if templ_7745c5c3_Err != nil {1622 if templ_7745c5c3_Err != nil {
1513 return templ_7745c5c3_Err1623 return templ_7745c5c3_Err
1514 }1624 }
1515- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-finish=\"")1625+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "\" data-finish=\"")
1516 if templ_7745c5c3_Err != nil {1626 if templ_7745c5c3_Err != nil {
1517 return templ_7745c5c3_Err1627 return templ_7745c5c3_Err
1518 }1628 }
1519- var templ_7745c5c3_Var75 string1629+ var templ_7745c5c3_Var83 string
1520- templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)1630+ templ_7745c5c3_Var83, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish)
1521 if templ_7745c5c3_Err != nil {1631 if templ_7745c5c3_Err != nil {
1522- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 115}1632+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 115}
1523 }1633 }
1524- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)1634+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var83)
1525 if templ_7745c5c3_Err != nil {1635 if templ_7745c5c3_Err != nil {
1526 return templ_7745c5c3_Err1636 return templ_7745c5c3_Err
1527 }1637 }
1528- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\">Add a passkey</button></form>")1638+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "\">Add a passkey</button></form>")
1529 if templ_7745c5c3_Err != nil {1639 if templ_7745c5c3_Err != nil {
1530 return templ_7745c5c3_Err1640 return templ_7745c5c3_Err
1531 }1641 }
1532 }1642 }
1533- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")1643+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>")
1534 if templ_7745c5c3_Err != nil {1644 if templ_7745c5c3_Err != nil {
1535 return templ_7745c5c3_Err1645 return templ_7745c5c3_Err
1536 }1646 }
1537 return nil1647 return nil
1538 })1648 })
1539- templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var64), templ_7745c5c3_Buffer)1649+ templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var72), templ_7745c5c3_Buffer)
1540 if templ_7745c5c3_Err != nil {1650 if templ_7745c5c3_Err != nil {
1541 return templ_7745c5c3_Err1651 return templ_7745c5c3_Err
1542 }1652 }
M internal/adapters/web/releases.templ +16 -9
@@ -40,15 +40,22 @@ templ Releases(l Layout, p ReleaseListPage) {
4040
4141 templ ReleaseDetail(l Layout, p ReleaseDetailPage) {
4242 @Shell(l, nil) {
43- <h1>{ p.Title }</h1>
44- <p>
45- <span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow)
46- if p.SHA != "" {
47- <a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a>
48- }
49- <span class="dim">{ p.Published }</span>
50- </p>
51- <div class="md">@templ.Raw(string(p.Notes))</div>
43+ <section class="mr-card">
44+ <header class="show mr-h">
45+ <h1>{ p.Title }</h1>
46+ <dl class="kv show-kv">
47+ <dt>tag</dt>
48+ <dd><span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow)</dd>
49+ if p.SHA != "" {
50+ <dt>commit</dt>
51+ <dd><a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a></dd>
52+ }
53+ <dt>published</dt>
54+ <dd>{ p.Published }</dd>
55+ </dl>
56+ </header>
57+ <article class="mr-desc prose">@templ.Raw(string(p.Notes))</article>
58+ </section>
5259 <h2>Assets</h2>
5360 if len(p.Assets) == 0 {
5461 <p class="dim">no assets.</p>
@@ -40,15 +40,22 @@ templ Releases(l Layout, p ReleaseListPage) {
40 40
41 templ ReleaseDetail(l Layout, p ReleaseDetailPage) {41 templ ReleaseDetail(l Layout, p ReleaseDetailPage) {
42 @Shell(l, nil) {42 @Shell(l, nil) {
43- <h1>{ p.Title }</h1>43+ <section class="mr-card">
44- <p>44+ <header class="show mr-h">
45- <span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow)45+ <h1>{ p.Title }</h1>
46- if p.SHA != "" {46+ <dl class="kv show-kv">
47- <a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a>47+ <dt>tag</dt>
48- }48+ <dd><span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow)</dd>
49- <span class="dim">{ p.Published }</span>49+ if p.SHA != "" {
50- </p>50+ <dt>commit</dt>
51- <div class="md">@templ.Raw(string(p.Notes))</div>51+ <dd><a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a></dd>
52+ }
53+ <dt>published</dt>
54+ <dd>{ p.Published }</dd>
55+ </dl>
56+ </header>
57+ <article class="mr-desc prose">@templ.Raw(string(p.Notes))</article>
58+ </section>
52 <h2>Assets</h2>59 <h2>Assets</h2>
53 if len(p.Assets) == 0 {60 if len(p.Assets) == 0 {
54 <p class="dim">no assets.</p>61 <p class="dim">no assets.</p>
M internal/adapters/web/releases_templ.go +32 -28 generated file: collapsed
M internal/adapters/web/releases_test.go +10 -1
@@ -38,7 +38,7 @@ func newReleaseFixture(t *testing.T) *releaseFixture {
3838 t.Helper()
3939 repo := repoName(t, "proj")
4040 f := &releaseFixture{svc: mocks.NewReleaseService(t), data: "0123456789"}
41- f.published = domain.Release{ID: 1, Repo: repo, Tag: "stable/v1", Title: "First release", Notes: "# Notes\n\n**Ready** [bad](javascript:alert(1)) <script>alert(1)</script>\n\n[guide](guide.md)", TargetCommitish: strings.Repeat("a", 40), PublishedAt: fixedNow, Prerelease: true}
41+ f.published = domain.Release{ID: 1, Repo: repo, Tag: "stable/v1", Title: "First release", Notes: "# Notes\n\n**Ready** [bad](javascript:alert(1)) <script>alert(1)</script>\n\n[guide](guide.md)\n\n```sh\ncurl https://example.com\n```", TargetCommitish: strings.Repeat("a", 40), PublishedAt: fixedNow, Prerelease: true}
4242 f.draft = domain.Release{ID: 2, Repo: repo, Tag: "unpublished", Title: "Secret draft", Draft: true, MakeLatest: true}
4343 f.asset = domain.ReleaseAsset{ID: 7, ReleaseID: 1, Repo: repo, Name: "build.zip", Size: 10, ContentType: "application/zip", Digest: "sha256:" + strings.Repeat("b", 64)}
4444 f.svc.EXPECT().GetRelease(mock.Anything, mock.Anything, repo, mock.Anything).RunAndReturn(func(_ context.Context, p domain.Principal, _ domain.RepoName, ref ports.ReleaseRef) (domain.Release, error) {
@@ -137,6 +137,15 @@ func TestReleasePages(t *testing.T) {
137137 for _, text := range []string{"<strong>Ready</strong>", "build.zip", humanSize(10), "application/zip", `href="/proj/releases/assets/7"`, `href="/proj/tree/stable/v1"`, `href="/proj/commit/` + strings.Repeat("a", 40) + `"`, "view=release"} {
138138 assert.Contains(t, body, text)
139139 }
140+ notes := strings.SplitN(body, `<article class="mr-desc prose">`, 2)
141+ require.Len(t, notes, 2)
142+ notesBody := strings.SplitN(notes[1], "</article>", 2)[0]
143+ assert.Contains(t, notesBody, "<pre")
144+ assert.Contains(t, notesBody, "<code")
145+ assert.Contains(t, notesBody, "curl")
146+ assert.Contains(t, notesBody, "</code></pre>")
147+ assert.Contains(t, notesBody, `<h1 id="md-notes">Notes</h1>`)
148+ assert.Contains(t, body, `<section class="mr-card">`)
140149 assert.NotContains(t, body, "<script>alert")
141150 assert.NotContains(t, body, `href="javascript:`)
142151 assert.Contains(t, body, `href="/proj/blob/stable/v1/guide.md"`)
@@ -38,7 +38,7 @@ func newReleaseFixture(t *testing.T) *releaseFixture {
38 t.Helper()38 t.Helper()
39 repo := repoName(t, "proj")39 repo := repoName(t, "proj")
40 f := &releaseFixture{svc: mocks.NewReleaseService(t), data: "0123456789"}40 f := &releaseFixture{svc: mocks.NewReleaseService(t), data: "0123456789"}
41- f.published = domain.Release{ID: 1, Repo: repo, Tag: "stable/v1", Title: "First release", Notes: "# Notes\n\n**Ready** [bad](javascript:alert(1)) <script>alert(1)</script>\n\n[guide](guide.md)", TargetCommitish: strings.Repeat("a", 40), PublishedAt: fixedNow, Prerelease: true}41+ f.published = domain.Release{ID: 1, Repo: repo, Tag: "stable/v1", Title: "First release", Notes: "# Notes\n\n**Ready** [bad](javascript:alert(1)) <script>alert(1)</script>\n\n[guide](guide.md)\n\n```sh\ncurl https://example.com\n```", TargetCommitish: strings.Repeat("a", 40), PublishedAt: fixedNow, Prerelease: true}
42 f.draft = domain.Release{ID: 2, Repo: repo, Tag: "unpublished", Title: "Secret draft", Draft: true, MakeLatest: true}42 f.draft = domain.Release{ID: 2, Repo: repo, Tag: "unpublished", Title: "Secret draft", Draft: true, MakeLatest: true}
43 f.asset = domain.ReleaseAsset{ID: 7, ReleaseID: 1, Repo: repo, Name: "build.zip", Size: 10, ContentType: "application/zip", Digest: "sha256:" + strings.Repeat("b", 64)}43 f.asset = domain.ReleaseAsset{ID: 7, ReleaseID: 1, Repo: repo, Name: "build.zip", Size: 10, ContentType: "application/zip", Digest: "sha256:" + strings.Repeat("b", 64)}
44 f.svc.EXPECT().GetRelease(mock.Anything, mock.Anything, repo, mock.Anything).RunAndReturn(func(_ context.Context, p domain.Principal, _ domain.RepoName, ref ports.ReleaseRef) (domain.Release, error) {44 f.svc.EXPECT().GetRelease(mock.Anything, mock.Anything, repo, mock.Anything).RunAndReturn(func(_ context.Context, p domain.Principal, _ domain.RepoName, ref ports.ReleaseRef) (domain.Release, error) {
@@ -137,6 +137,15 @@ func TestReleasePages(t *testing.T) {
137 for _, text := range []string{"<strong>Ready</strong>", "build.zip", humanSize(10), "application/zip", `href="/proj/releases/assets/7"`, `href="/proj/tree/stable/v1"`, `href="/proj/commit/` + strings.Repeat("a", 40) + `"`, "view=release"} {137 for _, text := range []string{"<strong>Ready</strong>", "build.zip", humanSize(10), "application/zip", `href="/proj/releases/assets/7"`, `href="/proj/tree/stable/v1"`, `href="/proj/commit/` + strings.Repeat("a", 40) + `"`, "view=release"} {
138 assert.Contains(t, body, text)138 assert.Contains(t, body, text)
139 }139 }
140+ notes := strings.SplitN(body, `<article class="mr-desc prose">`, 2)
141+ require.Len(t, notes, 2)
142+ notesBody := strings.SplitN(notes[1], "</article>", 2)[0]
143+ assert.Contains(t, notesBody, "<pre")
144+ assert.Contains(t, notesBody, "<code")
145+ assert.Contains(t, notesBody, "curl")
146+ assert.Contains(t, notesBody, "</code></pre>")
147+ assert.Contains(t, notesBody, `<h1 id="md-notes">Notes</h1>`)
148+ assert.Contains(t, body, `<section class="mr-card">`)
140 assert.NotContains(t, body, "<script>alert")149 assert.NotContains(t, body, "<script>alert")
141 assert.NotContains(t, body, `href="javascript:`)150 assert.NotContains(t, body, `href="javascript:`)
142 assert.Contains(t, body, `href="/proj/blob/stable/v1/guide.md"`)151 assert.Contains(t, body, `href="/proj/blob/stable/v1/guide.md"`)
M internal/adapters/web/summary.go +21 -0
@@ -68,6 +68,7 @@ func (s *Server) summary(ctx context.Context, r *http.Request) (templ.Component,
6868
6969 p.Facts = s.facts(d, now)
7070 p.Latest = s.latest(ctx, d)
71+ p.Release = s.summaryRelease(ctx, d.repo.Name, now)
7172 p.Actions = s.recentActions(ctx, d.repo.Name, now)
7273
7374 if rd, err := s.readme(ctx, d, ref); err != nil {
@@ -272,3 +273,23 @@ func (s *Server) listRecentActions(ctx context.Context, repo domain.RepoName, no
272273 }
273274 return a, nil
274275 }
276+
277+// summaryRelease uses the same Latest selection as the releases page. A
278+// missing service or an unavailable release must not prevent repository browsing.
279+func (s *Server) summaryRelease(ctx context.Context, repo domain.RepoName, now time.Time) *LatestRelease {
280+ if s.cfg.Releases == nil {
281+ return nil
282+ }
283+ rel, err := s.cfg.Releases.GetRelease(ctx, principal(ctx), repo, ports.ReleaseRef{Latest: true})
284+ if err != nil {
285+ if !errors.Is(err, domain.ErrNotFound) {
286+ log := zerowrap.FromCtx(ctx)
287+ log.Warn().Err(err).Str("repo", repo.String()).Msg("read the latest release")
288+ }
289+ return nil
290+ }
291+ if rel.Draft || rel.PublishedAt.IsZero() {
292+ return nil
293+ }
294+ return &LatestRelease{Tag: rel.Tag, Href: releaseHref(repo.String(), rel.Tag), When: ago(now, rel.PublishedAt), WhenAt: rfc3339(rel.PublishedAt), AllHref: releasesBase(repo.String())}
295+}
@@ -68,6 +68,7 @@ func (s *Server) summary(ctx context.Context, r *http.Request) (templ.Component,
68 68
69 p.Facts = s.facts(d, now)69 p.Facts = s.facts(d, now)
70 p.Latest = s.latest(ctx, d)70 p.Latest = s.latest(ctx, d)
71+ p.Release = s.summaryRelease(ctx, d.repo.Name, now)
71 p.Actions = s.recentActions(ctx, d.repo.Name, now)72 p.Actions = s.recentActions(ctx, d.repo.Name, now)
72 73
73 if rd, err := s.readme(ctx, d, ref); err != nil {74 if rd, err := s.readme(ctx, d, ref); err != nil {
@@ -272,3 +273,23 @@ func (s *Server) listRecentActions(ctx context.Context, repo domain.RepoName, no
272 }273 }
273 return a, nil274 return a, nil
274 }275 }
276+
277+// summaryRelease uses the same Latest selection as the releases page. A
278+// missing service or an unavailable release must not prevent repository browsing.
279+func (s *Server) summaryRelease(ctx context.Context, repo domain.RepoName, now time.Time) *LatestRelease {
280+ if s.cfg.Releases == nil {
281+ return nil
282+ }
283+ rel, err := s.cfg.Releases.GetRelease(ctx, principal(ctx), repo, ports.ReleaseRef{Latest: true})
284+ if err != nil {
285+ if !errors.Is(err, domain.ErrNotFound) {
286+ log := zerowrap.FromCtx(ctx)
287+ log.Warn().Err(err).Str("repo", repo.String()).Msg("read the latest release")
288+ }
289+ return nil
290+ }
291+ if rel.Draft || rel.PublishedAt.IsZero() {
292+ return nil
293+ }
294+ return &LatestRelease{Tag: rel.Tag, Href: releaseHref(repo.String(), rel.Tag), When: ago(now, rel.PublishedAt), WhenAt: rfc3339(rel.PublishedAt), AllHref: releasesBase(repo.String())}
295+}
A internal/adapters/web/summary_releases_test.go +49 -0
@@ -0,0 +1,49 @@
1+// SPDX-License-Identifier: AGPL-3.0-or-later
2+
3+package web
4+
5+import (
6+ "strings"
7+ "testing"
8+ "time"
9+
10+ "github.com/stretchr/testify/assert"
11+ "github.com/stretchr/testify/mock"
12+ "github.com/stretchr/testify/require"
13+
14+ "bnema.dev/ermite/internal/domain"
15+ "bnema.dev/ermite/internal/ports"
16+ "bnema.dev/ermite/internal/ports/mocks"
17+)
18+
19+func TestSummaryRelease(t *testing.T) {
20+ repo := repoName(t, "proj")
21+ for _, tc := range []struct {
22+ name string
23+ release domain.Release
24+ err error
25+ visible bool
26+ }{
27+ {name: "published", release: domain.Release{Tag: "v0.9.1", PublishedAt: fixedNow.Add(-6 * time.Minute)}, visible: true},
28+ {name: "none", err: domain.ErrNotFound},
29+ {name: "draft", release: domain.Release{Tag: "secret", Draft: true, PublishedAt: fixedNow}},
30+ } {
31+ t.Run(tc.name, func(t *testing.T) {
32+ svc := mocks.NewReleaseService(t)
33+ svc.EXPECT().GetRelease(mock.Anything, mock.Anything, repo, ports.ReleaseRef{Latest: true}).Return(tc.release, tc.err).Once()
34+ srv := newTestServer(t, Config{Repos: reposServing(t, publicRepo(t, "proj")), Browse: mocks.NewBrowseService(t), Releases: svc})
35+ rel := srv.summaryRelease(t.Context(), repo, fixedNow)
36+ out := strings.Join(strings.Fields(renderRail(t, SummaryPage{Latest: &LatestTag{Name: "v1", Count: 1}, Release: rel})), " ")
37+ if !tc.visible {
38+ assert.Nil(t, rel)
39+ assert.NotContains(t, out, "<dt>release</dt>")
40+ return
41+ }
42+ require.NotNil(t, rel)
43+ assert.Contains(t, out, `<a href="/proj/releases/tag/v0.9.1">v0.9.1</a> · <time`)
44+ assert.Contains(t, out, `datetime="`+rfc3339(tc.release.PublishedAt)+`"`)
45+ assert.Contains(t, out, `>`+ago(fixedNow, tc.release.PublishedAt)+`</time> · <a href="/proj/releases">all releases</a>`)
46+ assert.Regexp(t, `(?s)<dt>latest tag</dt>.*<dt>release</dt>`, out)
47+ })
48+ }
49+}
@@ -0,0 +1,49 @@
1+// SPDX-License-Identifier: AGPL-3.0-or-later
2+
3+package web
4+
5+import (
6+ "strings"
7+ "testing"
8+ "time"
9+
10+ "github.com/stretchr/testify/assert"
11+ "github.com/stretchr/testify/mock"
12+ "github.com/stretchr/testify/require"
13+
14+ "bnema.dev/ermite/internal/domain"
15+ "bnema.dev/ermite/internal/ports"
16+ "bnema.dev/ermite/internal/ports/mocks"
17+)
18+
19+func TestSummaryRelease(t *testing.T) {
20+ repo := repoName(t, "proj")
21+ for _, tc := range []struct {
22+ name string
23+ release domain.Release
24+ err error
25+ visible bool
26+ }{
27+ {name: "published", release: domain.Release{Tag: "v0.9.1", PublishedAt: fixedNow.Add(-6 * time.Minute)}, visible: true},
28+ {name: "none", err: domain.ErrNotFound},
29+ {name: "draft", release: domain.Release{Tag: "secret", Draft: true, PublishedAt: fixedNow}},
30+ } {
31+ t.Run(tc.name, func(t *testing.T) {
32+ svc := mocks.NewReleaseService(t)
33+ svc.EXPECT().GetRelease(mock.Anything, mock.Anything, repo, ports.ReleaseRef{Latest: true}).Return(tc.release, tc.err).Once()
34+ srv := newTestServer(t, Config{Repos: reposServing(t, publicRepo(t, "proj")), Browse: mocks.NewBrowseService(t), Releases: svc})
35+ rel := srv.summaryRelease(t.Context(), repo, fixedNow)
36+ out := strings.Join(strings.Fields(renderRail(t, SummaryPage{Latest: &LatestTag{Name: "v1", Count: 1}, Release: rel})), " ")
37+ if !tc.visible {
38+ assert.Nil(t, rel)
39+ assert.NotContains(t, out, "<dt>release</dt>")
40+ return
41+ }
42+ require.NotNil(t, rel)
43+ assert.Contains(t, out, `<a href="/proj/releases/tag/v0.9.1">v0.9.1</a> · <time`)
44+ assert.Contains(t, out, `datetime="`+rfc3339(tc.release.PublishedAt)+`"`)
45+ assert.Contains(t, out, `>`+ago(fixedNow, tc.release.PublishedAt)+`</time> · <a href="/proj/releases">all releases</a>`)
46+ assert.Regexp(t, `(?s)<dt>latest tag</dt>.*<dt>release</dt>`, out)
47+ })
48+ }
49+}
M internal/adapters/web/view.go +7 -1
@@ -211,12 +211,18 @@ type SummaryPage struct {
211211 Outline []Heading
212212 AllHref string
213213 // Latest is the newest tag, nil when the repository has none.
214- Latest *LatestTag
214+ Latest *LatestTag
215+ Release *LatestRelease
215216 // Actions is the recent runs of the rail, nil when the viewer cannot read
216217 // CI (or the server runs none).
217218 Actions *RecentActions
218219 }
219220
221+// LatestRelease is the published release selected as Latest by the release service.
222+type LatestRelease struct {
223+ Tag, Href, When, WhenAt, AllHref string
224+}
225+
220226 // RecentActions is the "Recent actions" block of the summary rail: the newest
221227 // runs. With no run the block is in the page but hidden, so that the first
222228 // run reaches it live.
@@ -211,12 +211,18 @@ type SummaryPage struct {
211 Outline []Heading211 Outline []Heading
212 AllHref string212 AllHref string
213 // Latest is the newest tag, nil when the repository has none.213 // Latest is the newest tag, nil when the repository has none.
214- Latest *LatestTag214+ Latest *LatestTag
215+ Release *LatestRelease
215 // Actions is the recent runs of the rail, nil when the viewer cannot read216 // Actions is the recent runs of the rail, nil when the viewer cannot read
216 // CI (or the server runs none).217 // CI (or the server runs none).
217 Actions *RecentActions218 Actions *RecentActions
218 }219 }
219 220
221+// LatestRelease is the published release selected as Latest by the release service.
222+type LatestRelease struct {
223+ Tag, Href, When, WhenAt, AllHref string
224+}
225+
220 // RecentActions is the "Recent actions" block of the summary rail: the newest226 // RecentActions is the "Recent actions" block of the summary rail: the newest
221 // runs. With no run the block is in the page but hidden, so that the first227 // runs. With no run the block is in the page but hidden, so that the first
222 // run reaches it live.228 // run reaches it live.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 42

↑↓ moveenter openesc close