detached d92c6dc

feat(web): make the MR view edge to edge and touch friendly on mobile

Narrow screens drop side margins, force the unified diff without changing
the saved preference, and open menus as bottom sheets. Coarse pointers get
tall line-number targets and a tap-to-select line range for comments.
commit
d92c6dc3247ee58d9be537f6224e1cd009f97236
author
brice · · 2026-10-20 05:11 UTC
parent
cc7ba64
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
15 files · +480 -211
M internal/adapters/web/diff.templ +6 -2
@@ -117,7 +117,7 @@ templ diffViewMenu(p DiffView) {
117117 <details class="menu vmenu">
118118 <summary class="btn" aria-label="Diff view">
119119 if p.Both {
120- <span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">{ viewLabel(p.View) }</span>
120+ <span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">{ viewLabel(p.View) }</span>
121121 } else {
122122 { viewLabel(p.View) }
123123 }
@@ -139,12 +139,16 @@ templ viewLink(p DiffView, view, label, key, href string) {
139139 class="btn vbtn"
140140 data-view={ view }
141141 aria-keyshortcuts={ key }
142+ if view == "split" {
143+ :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false"
144+ :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'"
145+ }
142146 if p.View == view {
143147 aria-current="true"
144148 }
145149 if p.Both {
146150 data-fire={ view }
147- :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false"
151+ :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false"
148152 }
149153 >{ label }<kbd aria-hidden="true">{ key }</kbd></a>
150154 }
@@ -117,7 +117,7 @@ templ diffViewMenu(p DiffView) {
117 <details class="menu vmenu">117 <details class="menu vmenu">
118 <summary class="btn" aria-label="Diff view">118 <summary class="btn" aria-label="Diff view">
119 if p.Both {119 if p.Both {
120- <span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">{ viewLabel(p.View) }</span>120+ <span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">{ viewLabel(p.View) }</span>
121 } else {121 } else {
122 { viewLabel(p.View) }122 { viewLabel(p.View) }
123 }123 }
@@ -139,12 +139,16 @@ templ viewLink(p DiffView, view, label, key, href string) {
139 class="btn vbtn"139 class="btn vbtn"
140 data-view={ view }140 data-view={ view }
141 aria-keyshortcuts={ key }141 aria-keyshortcuts={ key }
142+ if view == "split" {
143+ :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false"
144+ :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'"
145+ }
142 if p.View == view {146 if p.View == view {
143 aria-current="true"147 aria-current="true"
144 }148 }
145 if p.Both {149 if p.Both {
146 data-fire={ view }150 data-fire={ view }
147- :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false"151+ :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false"
148 }152 }
149 >{ label }<kbd aria-hidden="true">{ key }</kbd></a>153 >{ label }<kbd aria-hidden="true">{ key }</kbd></a>
150 }154 }
M internal/adapters/web/diff_templ.go +190 -184
@@ -530,14 +530,14 @@ func diffViewMenu(p DiffView) templ.Component {
530530 return templ_7745c5c3_Err
531531 }
532532 if p.Both {
533- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<span hx-live=\"this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'\">")
533+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<span hx-live=\"this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'\">")
534534 if templ_7745c5c3_Err != nil {
535535 return templ_7745c5c3_Err
536536 }
537537 var templ_7745c5c3_Var22 string
538538 templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(viewLabel(p.View))
539539 if templ_7745c5c3_Err != nil {
540- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 120, Col: 122}
540+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 120, Col: 168}
541541 }
542542 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
543543 if templ_7745c5c3_Err != nil {
@@ -649,58 +649,64 @@ func viewLink(p DiffView, view, label, key, href string) templ.Component {
649649 if templ_7745c5c3_Err != nil {
650650 return templ_7745c5c3_Err
651651 }
652+ if view == "split" {
653+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " :aria-disabled=\"q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false\" :title=\"q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'\"")
654+ if templ_7745c5c3_Err != nil {
655+ return templ_7745c5c3_Err
656+ }
657+ }
652658 if p.View == view {
653- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " aria-current=\"true\"")
659+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, " aria-current=\"true\"")
654660 if templ_7745c5c3_Err != nil {
655661 return templ_7745c5c3_Err
656662 }
657663 }
658664 if p.Both {
659- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, " data-fire=\"")
665+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, " data-fire=\"")
660666 if templ_7745c5c3_Err != nil {
661667 return templ_7745c5c3_Err
662668 }
663669 var templ_7745c5c3_Var28 string
664670 templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.ResolveAttributeValue(view)
665671 if templ_7745c5c3_Err != nil {
666- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 146, Col: 19}
672+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 150, Col: 19}
667673 }
668674 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var28)
669675 if templ_7745c5c3_Err != nil {
670676 return templ_7745c5c3_Err
671677 }
672- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "\" :aria-current=\"q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false\"")
678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "\" :aria-current=\"(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false\"")
673679 if templ_7745c5c3_Err != nil {
674680 return templ_7745c5c3_Err
675681 }
676682 }
677- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, ">")
683+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, ">")
678684 if templ_7745c5c3_Err != nil {
679685 return templ_7745c5c3_Err
680686 }
681687 var templ_7745c5c3_Var29 string
682688 templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(label)
683689 if templ_7745c5c3_Err != nil {
684- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 149, Col: 9}
690+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 153, Col: 9}
685691 }
686692 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
687693 if templ_7745c5c3_Err != nil {
688694 return templ_7745c5c3_Err
689695 }
690- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<kbd aria-hidden=\"true\">")
696+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "<kbd aria-hidden=\"true\">")
691697 if templ_7745c5c3_Err != nil {
692698 return templ_7745c5c3_Err
693699 }
694700 var templ_7745c5c3_Var30 string
695701 templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(key)
696702 if templ_7745c5c3_Err != nil {
697- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 149, Col: 40}
703+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 153, Col: 40}
698704 }
699705 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
700706 if templ_7745c5c3_Err != nil {
701707 return templ_7745c5c3_Err
702708 }
703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "</kbd></a>")
709+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</kbd></a>")
704710 if templ_7745c5c3_Err != nil {
705711 return templ_7745c5c3_Err
706712 }
@@ -731,7 +737,7 @@ func collapseButton() templ.Component {
731737 templ_7745c5c3_Var31 = templ.NopComponent
732738 }
733739 ctx = templ.ClearChildren(ctx)
734- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "<button type=\"button\" aria-keyshortcuts=\"x\" data-js data-fire=\"collapse\" class=\"btn\"><span hx-live=\"this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'\">Collapse all</span><kbd aria-hidden=\"true\">x</kbd></button>")
740+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<button type=\"button\" aria-keyshortcuts=\"x\" data-js data-fire=\"collapse\" class=\"btn\"><span hx-live=\"this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'\">Collapse all</span><kbd aria-hidden=\"true\">x</kbd></button>")
735741 if templ_7745c5c3_Err != nil {
736742 return templ_7745c5c3_Err
737743 }
@@ -763,13 +769,13 @@ func personView(pr Person) templ.Component {
763769 var templ_7745c5c3_Var33 string
764770 templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(pr.Name)
765771 if templ_7745c5c3_Err != nil {
766- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 161, Col: 10}
772+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 165, Col: 10}
767773 }
768774 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
769775 if templ_7745c5c3_Err != nil {
770776 return templ_7745c5c3_Err
771777 }
772- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, " ")
778+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, " ")
773779 if templ_7745c5c3_Err != nil {
774780 return templ_7745c5c3_Err
775781 }
@@ -777,59 +783,59 @@ func personView(pr Person) templ.Component {
777783 var templ_7745c5c3_Var34 string
778784 templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
779785 if templ_7745c5c3_Err != nil {
780- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 10}
786+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 10}
781787 }
782788 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
783789 if templ_7745c5c3_Err != nil {
784790 return templ_7745c5c3_Err
785791 }
786- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "<time datetime=\"")
792+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "<time datetime=\"")
787793 if templ_7745c5c3_Err != nil {
788794 return templ_7745c5c3_Err
789795 }
790796 var templ_7745c5c3_Var35 string
791797 templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.ResolveAttributeValue(pr.WhenAt)
792798 if templ_7745c5c3_Err != nil {
793- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 38}
799+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 38}
794800 }
795801 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var35)
796802 if templ_7745c5c3_Err != nil {
797803 return templ_7745c5c3_Err
798804 }
799- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "\" title=\"")
805+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" title=\"")
800806 if templ_7745c5c3_Err != nil {
801807 return templ_7745c5c3_Err
802808 }
803809 var templ_7745c5c3_Var36 string
804810 templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.ResolveAttributeValue(pr.Abs)
805811 if templ_7745c5c3_Err != nil {
806- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 55}
812+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 55}
807813 }
808814 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var36)
809815 if templ_7745c5c3_Err != nil {
810816 return templ_7745c5c3_Err
811817 }
812- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\">")
818+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "\">")
813819 if templ_7745c5c3_Err != nil {
814820 return templ_7745c5c3_Err
815821 }
816822 var templ_7745c5c3_Var37 string
817823 templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(pr.When)
818824 if templ_7745c5c3_Err != nil {
819- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 67}
825+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 67}
820826 }
821827 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
822828 if templ_7745c5c3_Err != nil {
823829 return templ_7745c5c3_Err
824830 }
825- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</time>")
831+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</time>")
826832 if templ_7745c5c3_Err != nil {
827833 return templ_7745c5c3_Err
828834 }
829835 var templ_7745c5c3_Var38 string
830836 templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(" · " + pr.Abs)
831837 if templ_7745c5c3_Err != nil {
832- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 93}
838+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 93}
833839 }
834840 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
835841 if templ_7745c5c3_Err != nil {
@@ -861,20 +867,20 @@ func commitRail(p CommitPage) templ.Component {
861867 templ_7745c5c3_Var39 = templ.NopComponent
862868 }
863869 ctx = templ.ClearChildren(ctx)
864- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
870+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
865871 if templ_7745c5c3_Err != nil {
866872 return templ_7745c5c3_Err
867873 }
868874 var templ_7745c5c3_Var40 string
869875 templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
870876 if templ_7745c5c3_Err != nil {
871- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 169, Col: 65}
877+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 173, Col: 65}
872878 }
873879 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
874880 if templ_7745c5c3_Err != nil {
875881 return templ_7745c5c3_Err
876882 }
877- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "</span></h2>")
883+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "</span></h2>")
878884 if templ_7745c5c3_Err != nil {
879885 return templ_7745c5c3_Err
880886 }
@@ -882,7 +888,7 @@ func commitRail(p CommitPage) templ.Component {
882888 if templ_7745c5c3_Err != nil {
883889 return templ_7745c5c3_Err
884890 }
885- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "</section>")
891+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</section>")
886892 if templ_7745c5c3_Err != nil {
887893 return templ_7745c5c3_Err
888894 }
@@ -914,230 +920,230 @@ func FileList(files []DiffFile) templ.Component {
914920 }
915921 ctx = templ.ClearChildren(ctx)
916922 if len(files) > fileFilterMin {
917- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "<div class=\"ffilter\"><label for=\"files-filter\" class=\"sr\">filter the changed files</label> <input id=\"files-filter\" type=\"search\" placeholder=\"Filter files…\" autocomplete=\"off\" data-pick=\".files > li\" hx-on:input=\"ermite.filter(this)\"></div>")
923+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<div class=\"ffilter\"><label for=\"files-filter\" class=\"sr\">filter the changed files</label> <input id=\"files-filter\" type=\"search\" placeholder=\"Filter files…\" autocomplete=\"off\" data-pick=\".files > li\" hx-on:input=\"ermite.filter(this)\"></div>")
918924 if templ_7745c5c3_Err != nil {
919925 return templ_7745c5c3_Err
920926 }
921927 }
922- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<ol class=\"files\" aria-label=\"Changed files\">")
928+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<ol class=\"files\" aria-label=\"Changed files\">")
923929 if templ_7745c5c3_Err != nil {
924930 return templ_7745c5c3_Err
925931 }
926932 for _, f := range files {
927- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<li><a href=\"")
933+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "<li><a href=\"")
928934 if templ_7745c5c3_Err != nil {
929935 return templ_7745c5c3_Err
930936 }
931937 var templ_7745c5c3_Var42 templ.SafeURL
932938 templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("#" + f.ID))
933939 if templ_7745c5c3_Err != nil {
934- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 194, Col: 37}
940+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 37}
935941 }
936942 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
937943 if templ_7745c5c3_Err != nil {
938944 return templ_7745c5c3_Err
939945 }
940- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "\" title=\"")
946+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "\" title=\"")
941947 if templ_7745c5c3_Err != nil {
942948 return templ_7745c5c3_Err
943949 }
944950 var templ_7745c5c3_Var43 string
945951 templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path)
946952 if templ_7745c5c3_Err != nil {
947- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 195, Col: 19}
953+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 19}
948954 }
949955 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var43)
950956 if templ_7745c5c3_Err != nil {
951957 return templ_7745c5c3_Err
952958 }
953- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "\" hx-on:click=\"(window.ermiteMR?.openFile || ermite.openFile)(this.hash.slice(1))\"><span class=\"st\" data-st=\"")
959+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "\" hx-on:click=\"(window.ermiteMR?.openFile || ermite.openFile)(this.hash.slice(1))\"><span class=\"st\" data-st=\"")
954960 if templ_7745c5c3_Err != nil {
955961 return templ_7745c5c3_Err
956962 }
957963 var templ_7745c5c3_Var44 string
958964 templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Status)
959965 if templ_7745c5c3_Err != nil {
960- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 40}
966+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 202, Col: 40}
961967 }
962968 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var44)
963969 if templ_7745c5c3_Err != nil {
964970 return templ_7745c5c3_Err
965971 }
966- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "\" title=\"")
972+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "\" title=\"")
967973 if templ_7745c5c3_Err != nil {
968974 return templ_7745c5c3_Err
969975 }
970976 var templ_7745c5c3_Var45 string
971977 templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.ResolveAttributeValue(statusName(f.Status))
972978 if templ_7745c5c3_Err != nil {
973- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 71}
979+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 202, Col: 71}
974980 }
975981 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var45)
976982 if templ_7745c5c3_Err != nil {
977983 return templ_7745c5c3_Err
978984 }
979- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "\">")
985+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\">")
980986 if templ_7745c5c3_Err != nil {
981987 return templ_7745c5c3_Err
982988 }
983989 var templ_7745c5c3_Var46 string
984990 templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(f.Status)
985991 if templ_7745c5c3_Err != nil {
986- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 84}
992+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 202, Col: 84}
987993 }
988994 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
989995 if templ_7745c5c3_Err != nil {
990996 return templ_7745c5c3_Err
991997 }
992- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "</span> <span class=\"nm\"><span class=\"p\">")
998+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</span> <span class=\"nm\"><span class=\"p\">")
993999 if templ_7745c5c3_Err != nil {
9941000 return templ_7745c5c3_Err
9951001 }
9961002 var templ_7745c5c3_Var47 string
9971003 templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(f.Name)
9981004 if templ_7745c5c3_Err != nil {
999- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 46}
1005+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 46}
10001006 }
10011007 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
10021008 if templ_7745c5c3_Err != nil {
10031009 return templ_7745c5c3_Err
10041010 }
1005- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</span>")
1011+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</span>")
10061012 if templ_7745c5c3_Err != nil {
10071013 return templ_7745c5c3_Err
10081014 }
10091015 var templ_7745c5c3_Var48 string
10101016 templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
10111017 if templ_7745c5c3_Err != nil {
1012- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 60}
1018+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 60}
10131019 }
10141020 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
10151021 if templ_7745c5c3_Err != nil {
10161022 return templ_7745c5c3_Err
10171023 }
1018- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "<span class=\"d\"><bdi>")
1024+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "<span class=\"d\"><bdi>")
10191025 if templ_7745c5c3_Err != nil {
10201026 return templ_7745c5c3_Err
10211027 }
10221028 var templ_7745c5c3_Var49 string
10231029 templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(f.Dir)
10241030 if templ_7745c5c3_Err != nil {
1025- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 90}
1031+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 90}
10261032 }
10271033 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
10281034 if templ_7745c5c3_Err != nil {
10291035 return templ_7745c5c3_Err
10301036 }
1031- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</bdi></span></span> ")
1037+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "</bdi></span></span> ")
10321038 if templ_7745c5c3_Err != nil {
10331039 return templ_7745c5c3_Err
10341040 }
10351041 if f.OpenNotes > 0 {
1036- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<span class=\"cn\" title=\"")
1042+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "<span class=\"cn\" title=\"")
10371043 if templ_7745c5c3_Err != nil {
10381044 return templ_7745c5c3_Err
10391045 }
10401046 var templ_7745c5c3_Var50 string
10411047 templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.ResolveAttributeValue(plural(f.OpenNotes, "open comment", "open comments"))
10421048 if templ_7745c5c3_Err != nil {
1043- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 201, Col: 83}
1049+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 205, Col: 83}
10441050 }
10451051 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var50)
10461052 if templ_7745c5c3_Err != nil {
10471053 return templ_7745c5c3_Err
10481054 }
1049- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "\">")
1055+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "\">")
10501056 if templ_7745c5c3_Err != nil {
10511057 return templ_7745c5c3_Err
10521058 }
10531059 var templ_7745c5c3_Var51 string
10541060 templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.OpenNotes))
10551061 if templ_7745c5c3_Err != nil {
1056- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 201, Col: 105}
1062+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 205, Col: 105}
10571063 }
10581064 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51))
10591065 if templ_7745c5c3_Err != nil {
10601066 return templ_7745c5c3_Err
10611067 }
1062- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</span> ")
1068+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</span> ")
10631069 if templ_7745c5c3_Err != nil {
10641070 return templ_7745c5c3_Err
10651071 }
10661072 } else if f.Notes > 0 {
1067- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "<span class=\"cn done\" title=\"")
1073+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<span class=\"cn done\" title=\"")
10681074 if templ_7745c5c3_Err != nil {
10691075 return templ_7745c5c3_Err
10701076 }
10711077 var templ_7745c5c3_Var52 string
10721078 templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.ResolveAttributeValue(plural(f.Notes, "resolved comment", "resolved comments"))
10731079 if templ_7745c5c3_Err != nil {
1074- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 92}
1080+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 207, Col: 92}
10751081 }
10761082 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var52)
10771083 if templ_7745c5c3_Err != nil {
10781084 return templ_7745c5c3_Err
10791085 }
1080- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "\">")
1086+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\">")
10811087 if templ_7745c5c3_Err != nil {
10821088 return templ_7745c5c3_Err
10831089 }
10841090 var templ_7745c5c3_Var53 string
10851091 templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Notes))
10861092 if templ_7745c5c3_Err != nil {
1087- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 110}
1093+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 207, Col: 110}
10881094 }
10891095 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
10901096 if templ_7745c5c3_Err != nil {
10911097 return templ_7745c5c3_Err
10921098 }
1093- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "</span> ")
1099+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "</span> ")
10941100 if templ_7745c5c3_Err != nil {
10951101 return templ_7745c5c3_Err
10961102 }
10971103 }
10981104 if f.Bin {
1099- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<span class=\"n mute\">bin</span>")
1105+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<span class=\"n mute\">bin</span>")
11001106 if templ_7745c5c3_Err != nil {
11011107 return templ_7745c5c3_Err
11021108 }
11031109 } else {
1104- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<span class=\"n\"><span class=\"plus\">+")
1110+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<span class=\"n\"><span class=\"plus\">+")
11051111 if templ_7745c5c3_Err != nil {
11061112 return templ_7745c5c3_Err
11071113 }
11081114 var templ_7745c5c3_Var54 string
11091115 templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Add))
11101116 if templ_7745c5c3_Err != nil {
1111- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 208, Col: 55}
1117+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 212, Col: 55}
11121118 }
11131119 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
11141120 if templ_7745c5c3_Err != nil {
11151121 return templ_7745c5c3_Err
11161122 }
1117- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "</span> <span class=\"minus\">-")
1123+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "</span> <span class=\"minus\">-")
11181124 if templ_7745c5c3_Err != nil {
11191125 return templ_7745c5c3_Err
11201126 }
11211127 var templ_7745c5c3_Var55 string
11221128 templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Del))
11231129 if templ_7745c5c3_Err != nil {
1124- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 208, Col: 99}
1130+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 212, Col: 99}
11251131 }
11261132 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
11271133 if templ_7745c5c3_Err != nil {
11281134 return templ_7745c5c3_Err
11291135 }
1130- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "</span></span>")
1136+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</span></span>")
11311137 if templ_7745c5c3_Err != nil {
11321138 return templ_7745c5c3_Err
11331139 }
11341140 }
1135- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</a></li>")
1141+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</a></li>")
11361142 if templ_7745c5c3_Err != nil {
11371143 return templ_7745c5c3_Err
11381144 }
11391145 }
1140- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</ol>")
1146+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "</ol>")
11411147 if templ_7745c5c3_Err != nil {
11421148 return templ_7745c5c3_Err
11431149 }
@@ -1175,7 +1181,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
11751181 if templ_7745c5c3_Err != nil {
11761182 return templ_7745c5c3_Err
11771183 }
1178- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "<details class=\"")
1184+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "<details class=\"")
11791185 if templ_7745c5c3_Err != nil {
11801186 return templ_7745c5c3_Err
11811187 }
@@ -1188,134 +1194,134 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
11881194 if templ_7745c5c3_Err != nil {
11891195 return templ_7745c5c3_Err
11901196 }
1191- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "\" id=\"")
1197+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\" id=\"")
11921198 if templ_7745c5c3_Err != nil {
11931199 return templ_7745c5c3_Err
11941200 }
11951201 var templ_7745c5c3_Var59 string
11961202 templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID)
11971203 if templ_7745c5c3_Err != nil {
1198- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 223, Col: 11}
1204+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 227, Col: 11}
11991205 }
12001206 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var59)
12011207 if templ_7745c5c3_Err != nil {
12021208 return templ_7745c5c3_Err
12031209 }
1204- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\" data-file=\"")
1210+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "\" data-file=\"")
12051211 if templ_7745c5c3_Err != nil {
12061212 return templ_7745c5c3_Err
12071213 }
12081214 var templ_7745c5c3_Var60 string
12091215 templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Key)
12101216 if templ_7745c5c3_Err != nil {
1211- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 224, Col: 19}
1217+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 228, Col: 19}
12121218 }
12131219 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var60)
12141220 if templ_7745c5c3_Err != nil {
12151221 return templ_7745c5c3_Err
12161222 }
1217- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "\"")
1223+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"")
12181224 if templ_7745c5c3_Err != nil {
12191225 return templ_7745c5c3_Err
12201226 }
12211227 if f.Open {
1222- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, " open")
1228+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, " open")
12231229 if templ_7745c5c3_Err != nil {
12241230 return templ_7745c5c3_Err
12251231 }
12261232 }
1227- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "><summary><span class=\"st\">")
1233+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "><summary><span class=\"st\">")
12281234 if templ_7745c5c3_Err != nil {
12291235 return templ_7745c5c3_Err
12301236 }
12311237 var templ_7745c5c3_Var61 string
12321238 templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(f.Status)
12331239 if templ_7745c5c3_Err != nil {
1234- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 30}
1240+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 30}
12351241 }
12361242 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))
12371243 if templ_7745c5c3_Err != nil {
12381244 return templ_7745c5c3_Err
12391245 }
1240- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</span>")
1246+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "</span>")
12411247 if templ_7745c5c3_Err != nil {
12421248 return templ_7745c5c3_Err
12431249 }
12441250 var templ_7745c5c3_Var62 string
12451251 templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
12461252 if templ_7745c5c3_Err != nil {
1247- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 44}
1253+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 44}
12481254 }
12491255 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))
12501256 if templ_7745c5c3_Err != nil {
12511257 return templ_7745c5c3_Err
12521258 }
1253- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "<span class=\"p\">")
1259+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "<span class=\"p\">")
12541260 if templ_7745c5c3_Err != nil {
12551261 return templ_7745c5c3_Err
12561262 }
12571263 var templ_7745c5c3_Var63 string
12581264 templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(f.Path)
12591265 if templ_7745c5c3_Err != nil {
1260- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 70}
1266+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 70}
12611267 }
12621268 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63))
12631269 if templ_7745c5c3_Err != nil {
12641270 return templ_7745c5c3_Err
12651271 }
1266- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "</span>")
1272+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "</span>")
12671273 if templ_7745c5c3_Err != nil {
12681274 return templ_7745c5c3_Err
12691275 }
12701276 var templ_7745c5c3_Var64 string
12711277 templ_7745c5c3_Var64, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
12721278 if templ_7745c5c3_Err != nil {
1273- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 84}
1279+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 84}
12741280 }
12751281 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var64))
12761282 if templ_7745c5c3_Err != nil {
12771283 return templ_7745c5c3_Err
12781284 }
1279- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "<span class=\"plus\">+")
1285+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "<span class=\"plus\">+")
12801286 if templ_7745c5c3_Err != nil {
12811287 return templ_7745c5c3_Err
12821288 }
12831289 var templ_7745c5c3_Var65 string
12841290 templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Add))
12851291 if templ_7745c5c3_Err != nil {
1286- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 119}
1292+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 119}
12871293 }
12881294 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))
12891295 if templ_7745c5c3_Err != nil {
12901296 return templ_7745c5c3_Err
12911297 }
1292- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "</span>")
1298+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "</span>")
12931299 if templ_7745c5c3_Err != nil {
12941300 return templ_7745c5c3_Err
12951301 }
12961302 var templ_7745c5c3_Var66 string
12971303 templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
12981304 if templ_7745c5c3_Err != nil {
1299- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 133}
1305+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 133}
13001306 }
13011307 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))
13021308 if templ_7745c5c3_Err != nil {
13031309 return templ_7745c5c3_Err
13041310 }
1305- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "<span class=\"minus\">-")
1311+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "<span class=\"minus\">-")
13061312 if templ_7745c5c3_Err != nil {
13071313 return templ_7745c5c3_Err
13081314 }
13091315 var templ_7745c5c3_Var67 string
13101316 templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Del))
13111317 if templ_7745c5c3_Err != nil {
1312- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 169}
1318+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 169}
13131319 }
13141320 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var67))
13151321 if templ_7745c5c3_Err != nil {
13161322 return templ_7745c5c3_Err
13171323 }
1318- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "</span> ")
1324+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "</span> ")
13191325 if templ_7745c5c3_Err != nil {
13201326 return templ_7745c5c3_Err
13211327 }
@@ -1323,36 +1329,36 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
13231329 var templ_7745c5c3_Var68 string
13241330 templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
13251331 if templ_7745c5c3_Err != nil {
1326- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 232, Col: 9}
1332+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 236, Col: 9}
13271333 }
13281334 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))
13291335 if templ_7745c5c3_Err != nil {
13301336 return templ_7745c5c3_Err
13311337 }
1332- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "<span class=\"note\">")
1338+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "<span class=\"note\">")
13331339 if templ_7745c5c3_Err != nil {
13341340 return templ_7745c5c3_Err
13351341 }
13361342 var templ_7745c5c3_Var69 string
13371343 templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(f.Note)
13381344 if templ_7745c5c3_Err != nil {
1339- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 232, Col: 38}
1345+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 236, Col: 38}
13401346 }
13411347 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))
13421348 if templ_7745c5c3_Err != nil {
13431349 return templ_7745c5c3_Err
13441350 }
1345- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "</span>")
1351+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</span>")
13461352 if templ_7745c5c3_Err != nil {
13471353 return templ_7745c5c3_Err
13481354 }
13491355 }
1350- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</summary> ")
1356+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "</summary> ")
13511357 if templ_7745c5c3_Err != nil {
13521358 return templ_7745c5c3_Err
13531359 }
13541360 if f.Lazy {
1355- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, " ")
1361+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, " ")
13561362 if templ_7745c5c3_Err != nil {
13571363 return templ_7745c5c3_Err
13581364 }
@@ -1361,7 +1367,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
13611367 if templ_7745c5c3_Err != nil {
13621368 return templ_7745c5c3_Err
13631369 }
1364- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<div class=\"")
1370+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "<div class=\"")
13651371 if templ_7745c5c3_Err != nil {
13661372 return templ_7745c5c3_Err
13671373 }
@@ -1374,74 +1380,74 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
13741380 if templ_7745c5c3_Err != nil {
13751381 return templ_7745c5c3_Err
13761382 }
1377- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-src=\"")
1383+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\" data-src=\"")
13781384 if templ_7745c5c3_Err != nil {
13791385 return templ_7745c5c3_Err
13801386 }
13811387 var templ_7745c5c3_Var72 string
13821388 templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Src)
13831389 if templ_7745c5c3_Err != nil {
1384- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 239, Col: 69}
1390+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 243, Col: 69}
13851391 }
13861392 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var72)
13871393 if templ_7745c5c3_Err != nil {
13881394 return templ_7745c5c3_Err
13891395 }
1390- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\" data-notes=\"")
1396+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\" data-notes=\"")
13911397 if templ_7745c5c3_Err != nil {
13921398 return templ_7745c5c3_Err
13931399 }
13941400 var templ_7745c5c3_Var73 string
13951401 templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Comments)
13961402 if templ_7745c5c3_Err != nil {
1397- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 239, Col: 95}
1403+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 243, Col: 95}
13981404 }
13991405 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var73)
14001406 if templ_7745c5c3_Err != nil {
14011407 return templ_7745c5c3_Err
14021408 }
1403- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\"><a href=\"")
1409+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "\"><a href=\"")
14041410 if templ_7745c5c3_Err != nil {
14051411 return templ_7745c5c3_Err
14061412 }
14071413 var templ_7745c5c3_Var74 templ.SafeURL
14081414 templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("?from=" + itoa(f.From) + "#" + f.ID))
14091415 if templ_7745c5c3_Err != nil {
1410- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 240, Col: 65}
1416+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 244, Col: 65}
14111417 }
14121418 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))
14131419 if templ_7745c5c3_Err != nil {
14141420 return templ_7745c5c3_Err
14151421 }
1416- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "\">show this file</a></div>")
1422+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "\">show this file</a></div>")
14171423 if templ_7745c5c3_Err != nil {
14181424 return templ_7745c5c3_Err
14191425 }
14201426 } else if len(f.Hunks) > 0 {
1421- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "<div class=\"dscroll\">")
1427+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "<div class=\"dscroll\">")
14221428 if templ_7745c5c3_Err != nil {
14231429 return templ_7745c5c3_Err
14241430 }
14251431 if p.ShowUnified {
1426- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "<table class=\"dt uni\" aria-label=\"")
1432+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "<table class=\"dt uni\" aria-label=\"")
14271433 if templ_7745c5c3_Err != nil {
14281434 return templ_7745c5c3_Err
14291435 }
14301436 var templ_7745c5c3_Var75 string
14311437 templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path + ", unified")
14321438 if templ_7745c5c3_Err != nil {
1433- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 245, Col: 60}
1439+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 249, Col: 60}
14341440 }
14351441 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)
14361442 if templ_7745c5c3_Err != nil {
14371443 return templ_7745c5c3_Err
14381444 }
1439- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "\">")
1445+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "\">")
14401446 if templ_7745c5c3_Err != nil {
14411447 return templ_7745c5c3_Err
14421448 }
14431449 for _, h := range f.Hunks {
1444- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "<tbody>")
1450+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<tbody>")
14451451 if templ_7745c5c3_Err != nil {
14461452 return templ_7745c5c3_Err
14471453 }
@@ -1451,20 +1457,20 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
14511457 return templ_7745c5c3_Err
14521458 }
14531459 }
1454- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<tr class=\"hunk\"><td colspan=\"4\">")
1460+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "<tr class=\"hunk\"><td colspan=\"4\">")
14551461 if templ_7745c5c3_Err != nil {
14561462 return templ_7745c5c3_Err
14571463 }
14581464 var templ_7745c5c3_Var76 string
14591465 templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(h.Header)
14601466 if templ_7745c5c3_Err != nil {
1461- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 251, Col: 51}
1467+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 255, Col: 51}
14621468 }
14631469 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))
14641470 if templ_7745c5c3_Err != nil {
14651471 return templ_7745c5c3_Err
14661472 }
1467- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "</td></tr>")
1473+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "</td></tr>")
14681474 if templ_7745c5c3_Err != nil {
14691475 return templ_7745c5c3_Err
14701476 }
@@ -1474,7 +1480,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
14741480 if templ_7745c5c3_Err != nil {
14751481 return templ_7745c5c3_Err
14761482 }
1477- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "<tr class=\"")
1483+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "<tr class=\"")
14781484 if templ_7745c5c3_Err != nil {
14791485 return templ_7745c5c3_Err
14801486 }
@@ -1487,7 +1493,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
14871493 if templ_7745c5c3_Err != nil {
14881494 return templ_7745c5c3_Err
14891495 }
1490- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "\"><td class=\"ln\">")
1496+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "\"><td class=\"ln\">")
14911497 if templ_7745c5c3_Err != nil {
14921498 return templ_7745c5c3_Err
14931499 }
@@ -1495,7 +1501,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
14951501 if templ_7745c5c3_Err != nil {
14961502 return templ_7745c5c3_Err
14971503 }
1498- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "</td><td class=\"ln\">")
1504+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</td><td class=\"ln\">")
14991505 if templ_7745c5c3_Err != nil {
15001506 return templ_7745c5c3_Err
15011507 }
@@ -1503,20 +1509,20 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
15031509 if templ_7745c5c3_Err != nil {
15041510 return templ_7745c5c3_Err
15051511 }
1506- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</td><td class=\"m\">")
1512+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "</td><td class=\"m\">")
15071513 if templ_7745c5c3_Err != nil {
15081514 return templ_7745c5c3_Err
15091515 }
15101516 var templ_7745c5c3_Var79 string
15111517 templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)
15121518 if templ_7745c5c3_Err != nil {
1513- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 256, Col: 33}
1519+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 260, Col: 33}
15141520 }
15151521 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))
15161522 if templ_7745c5c3_Err != nil {
15171523 return templ_7745c5c3_Err
15181524 }
1519- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "</td><td class=\"tx chroma\">")
1525+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "</td><td class=\"tx chroma\">")
15201526 if templ_7745c5c3_Err != nil {
15211527 return templ_7745c5c3_Err
15221528 }
@@ -1524,12 +1530,12 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
15241530 if templ_7745c5c3_Err != nil {
15251531 return templ_7745c5c3_Err
15261532 }
1527- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "</td></tr>")
1533+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "</td></tr>")
15281534 if templ_7745c5c3_Err != nil {
15291535 return templ_7745c5c3_Err
15301536 }
15311537 if len(ln.Notes) > 0 || ln.Form != nil {
1532- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "<tr class=\"fnote\"><td colspan=\"3\"></td><td>")
1538+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "<tr class=\"fnote\"><td colspan=\"3\"></td><td>")
15331539 if templ_7745c5c3_Err != nil {
15341540 return templ_7745c5c3_Err
15351541 }
@@ -1537,19 +1543,19 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
15371543 if templ_7745c5c3_Err != nil {
15381544 return templ_7745c5c3_Err
15391545 }
1540- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "</td></tr>")
1546+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "</td></tr>")
15411547 if templ_7745c5c3_Err != nil {
15421548 return templ_7745c5c3_Err
15431549 }
15441550 }
15451551 }
1546- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "</tbody> ")
1552+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "</tbody> ")
15471553 if templ_7745c5c3_Err != nil {
15481554 return templ_7745c5c3_Err
15491555 }
15501556 }
15511557 if f.Tail != nil {
1552- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "<tbody>")
1558+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "<tbody>")
15531559 if templ_7745c5c3_Err != nil {
15541560 return templ_7745c5c3_Err
15551561 }
@@ -1557,36 +1563,36 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
15571563 if templ_7745c5c3_Err != nil {
15581564 return templ_7745c5c3_Err
15591565 }
1560- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "</tbody>")
1566+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "</tbody>")
15611567 if templ_7745c5c3_Err != nil {
15621568 return templ_7745c5c3_Err
15631569 }
15641570 }
1565- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "</table>")
1571+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "</table>")
15661572 if templ_7745c5c3_Err != nil {
15671573 return templ_7745c5c3_Err
15681574 }
15691575 }
15701576 if p.ShowSplit {
1571- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "<table class=\"dt spl\" aria-label=\"")
1577+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "<table class=\"dt spl\" aria-label=\"")
15721578 if templ_7745c5c3_Err != nil {
15731579 return templ_7745c5c3_Err
15741580 }
15751581 var templ_7745c5c3_Var80 string
15761582 templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path + ", split")
15771583 if templ_7745c5c3_Err != nil {
1578- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 276, Col: 58}
1584+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 280, Col: 58}
15791585 }
15801586 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)
15811587 if templ_7745c5c3_Err != nil {
15821588 return templ_7745c5c3_Err
15831589 }
1584- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "\"><colgroup><col class=\"c-ln\"><col class=\"c-m\"><col><col class=\"c-ln\"><col class=\"c-m\"><col></colgroup> ")
1590+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "\"><colgroup><col class=\"c-ln\"><col class=\"c-m\"><col><col class=\"c-ln\"><col class=\"c-m\"><col></colgroup> ")
15851591 if templ_7745c5c3_Err != nil {
15861592 return templ_7745c5c3_Err
15871593 }
15881594 for _, h := range f.Hunks {
1589- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "<tbody>")
1595+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<tbody>")
15901596 if templ_7745c5c3_Err != nil {
15911597 return templ_7745c5c3_Err
15921598 }
@@ -1596,25 +1602,25 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
15961602 return templ_7745c5c3_Err
15971603 }
15981604 }
1599- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<tr class=\"hunk\"><td colspan=\"6\">")
1605+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "<tr class=\"hunk\"><td colspan=\"6\">")
16001606 if templ_7745c5c3_Err != nil {
16011607 return templ_7745c5c3_Err
16021608 }
16031609 var templ_7745c5c3_Var81 string
16041610 templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinStringErrs(h.Header)
16051611 if templ_7745c5c3_Err != nil {
1606- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 283, Col: 51}
1612+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 287, Col: 51}
16071613 }
16081614 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))
16091615 if templ_7745c5c3_Err != nil {
16101616 return templ_7745c5c3_Err
16111617 }
1612- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "</td></tr>")
1618+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "</td></tr>")
16131619 if templ_7745c5c3_Err != nil {
16141620 return templ_7745c5c3_Err
16151621 }
16161622 for _, row := range h.Split {
1617- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "<tr>")
1623+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "<tr>")
16181624 if templ_7745c5c3_Err != nil {
16191625 return templ_7745c5c3_Err
16201626 }
@@ -1626,12 +1632,12 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
16261632 if templ_7745c5c3_Err != nil {
16271633 return templ_7745c5c3_Err
16281634 }
1629- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "</tr>")
1635+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "</tr>")
16301636 if templ_7745c5c3_Err != nil {
16311637 return templ_7745c5c3_Err
16321638 }
16331639 if notes, form := row.Notes(), row.Form(); len(notes) > 0 || form != nil {
1634- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "<tr class=\"fnote\"><td colspan=\"6\">")
1640+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "<tr class=\"fnote\"><td colspan=\"6\">")
16351641 if templ_7745c5c3_Err != nil {
16361642 return templ_7745c5c3_Err
16371643 }
@@ -1639,19 +1645,19 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
16391645 if templ_7745c5c3_Err != nil {
16401646 return templ_7745c5c3_Err
16411647 }
1642- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "</td></tr>")
1648+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "</td></tr>")
16431649 if templ_7745c5c3_Err != nil {
16441650 return templ_7745c5c3_Err
16451651 }
16461652 }
16471653 }
1648- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "</tbody> ")
1654+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "</tbody> ")
16491655 if templ_7745c5c3_Err != nil {
16501656 return templ_7745c5c3_Err
16511657 }
16521658 }
16531659 if f.Tail != nil {
1654- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "<tbody>")
1660+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "<tbody>")
16551661 if templ_7745c5c3_Err != nil {
16561662 return templ_7745c5c3_Err
16571663 }
@@ -1659,22 +1665,22 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
16591665 if templ_7745c5c3_Err != nil {
16601666 return templ_7745c5c3_Err
16611667 }
1662- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "</tbody>")
1668+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "</tbody>")
16631669 if templ_7745c5c3_Err != nil {
16641670 return templ_7745c5c3_Err
16651671 }
16661672 }
1667- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "</table>")
1673+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "</table>")
16681674 if templ_7745c5c3_Err != nil {
16691675 return templ_7745c5c3_Err
16701676 }
16711677 }
1672- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "</div>")
1678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "</div>")
16731679 if templ_7745c5c3_Err != nil {
16741680 return templ_7745c5c3_Err
16751681 }
16761682 } else {
1677- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "<p class=\"note pad\">")
1683+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "<p class=\"note pad\">")
16781684 if templ_7745c5c3_Err != nil {
16791685 return templ_7745c5c3_Err
16801686 }
@@ -1682,25 +1688,25 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
16821688 var templ_7745c5c3_Var82 string
16831689 templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.JoinStringErrs(f.Note)
16841690 if templ_7745c5c3_Err != nil {
1685- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 308, Col: 13}
1691+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 312, Col: 13}
16861692 }
16871693 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var82))
16881694 if templ_7745c5c3_Err != nil {
16891695 return templ_7745c5c3_Err
16901696 }
16911697 } else {
1692- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "no textual change.")
1698+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "no textual change.")
16931699 if templ_7745c5c3_Err != nil {
16941700 return templ_7745c5c3_Err
16951701 }
16961702 }
1697- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "</p>")
1703+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "</p>")
16981704 if templ_7745c5c3_Err != nil {
16991705 return templ_7745c5c3_Err
17001706 }
17011707 }
17021708 if len(f.Loose) > 0 {
1703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "<div class=\"dloose\">")
1709+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "<div class=\"dloose\">")
17041710 if templ_7745c5c3_Err != nil {
17051711 return templ_7745c5c3_Err
17061712 }
@@ -1710,12 +1716,12 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
17101716 return templ_7745c5c3_Err
17111717 }
17121718 }
1713- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "</div>")
1719+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "</div>")
17141720 if templ_7745c5c3_Err != nil {
17151721 return templ_7745c5c3_Err
17161722 }
17171723 }
1718- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "</details>")
1724+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "</details>")
17191725 if templ_7745c5c3_Err != nil {
17201726 return templ_7745c5c3_Err
17211727 }
@@ -1779,7 +1785,7 @@ func MRFilesMoved() templ.Component {
17791785 templ_7745c5c3_Var84 = templ.NopComponent
17801786 }
17811787 ctx = templ.ClearChildren(ctx)
1782- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "<p class=\"notice\" data-moved>this merge request changed since the page was loaded — <a href=\"\">reload</a></p>")
1788+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "<p class=\"notice\" data-moved>this merge request changed since the page was loaded — <a href=\"\">reload</a></p>")
17831789 if templ_7745c5c3_Err != nil {
17841790 return templ_7745c5c3_Err
17851791 }
@@ -1811,59 +1817,59 @@ func gapRow(g DiffGap, cols int) templ.Component {
18111817 templ_7745c5c3_Var85 = templ.NopComponent
18121818 }
18131819 ctx = templ.ClearChildren(ctx)
1814- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "<tr class=\"gap\" data-js data-gap=\"")
1820+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "<tr class=\"gap\" data-js data-gap=\"")
18151821 if templ_7745c5c3_Err != nil {
18161822 return templ_7745c5c3_Err
18171823 }
18181824 var templ_7745c5c3_Var86 string
18191825 templ_7745c5c3_Var86, templ_7745c5c3_Err = templ.ResolveAttributeValue(g.Key)
18201826 if templ_7745c5c3_Err != nil {
1821- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 342, Col: 41}
1827+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 346, Col: 41}
18221828 }
18231829 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var86)
18241830 if templ_7745c5c3_Err != nil {
18251831 return templ_7745c5c3_Err
18261832 }
1827- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "\"><td colspan=\"")
1833+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "\"><td colspan=\"")
18281834 if templ_7745c5c3_Err != nil {
18291835 return templ_7745c5c3_Err
18301836 }
18311837 var templ_7745c5c3_Var87 string
18321838 templ_7745c5c3_Var87, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(cols))
18331839 if templ_7745c5c3_Err != nil {
1834- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 343, Col: 26}
1840+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 347, Col: 26}
18351841 }
18361842 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var87)
18371843 if templ_7745c5c3_Err != nil {
18381844 return templ_7745c5c3_Err
18391845 }
1840- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "\"><button type=\"button\" data-src=\"")
1846+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\"><button type=\"button\" data-src=\"")
18411847 if templ_7745c5c3_Err != nil {
18421848 return templ_7745c5c3_Err
18431849 }
18441850 var templ_7745c5c3_Var88 string
18451851 templ_7745c5c3_Var88, templ_7745c5c3_Err = templ.ResolveAttributeValue(g.Src)
18461852 if templ_7745c5c3_Err != nil {
1847- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 344, Col: 41}
1853+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 348, Col: 41}
18481854 }
18491855 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var88)
18501856 if templ_7745c5c3_Err != nil {
18511857 return templ_7745c5c3_Err
18521858 }
1853- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\"><span aria-hidden=\"true\">⋯</span> ")
1859+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, "\"><span aria-hidden=\"true\">⋯</span> ")
18541860 if templ_7745c5c3_Err != nil {
18551861 return templ_7745c5c3_Err
18561862 }
18571863 var templ_7745c5c3_Var89 string
18581864 templ_7745c5c3_Var89, templ_7745c5c3_Err = templ.JoinStringErrs(g.Label())
18591865 if templ_7745c5c3_Err != nil {
1860- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 345, Col: 51}
1866+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 349, Col: 51}
18611867 }
18621868 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var89))
18631869 if templ_7745c5c3_Err != nil {
18641870 return templ_7745c5c3_Err
18651871 }
1866- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, "</button></td></tr>")
1872+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, "</button></td></tr>")
18671873 if templ_7745c5c3_Err != nil {
18681874 return templ_7745c5c3_Err
18691875 }
@@ -1894,51 +1900,51 @@ func DiffContext(c ContextRows) templ.Component {
18941900 templ_7745c5c3_Var90 = templ.NopComponent
18951901 }
18961902 ctx = templ.ClearChildren(ctx)
1897- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, "<table><tbody data-for=\"uni\">")
1903+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, "<table><tbody data-for=\"uni\">")
18981904 if templ_7745c5c3_Err != nil {
18991905 return templ_7745c5c3_Err
19001906 }
19011907 for _, ln := range c.Lines {
1902- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, "<tr class=\"ctx\"><td class=\"ln\">")
1908+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, "<tr class=\"ctx\"><td class=\"ln\">")
19031909 if templ_7745c5c3_Err != nil {
19041910 return templ_7745c5c3_Err
19051911 }
19061912 var templ_7745c5c3_Var91 string
19071913 templ_7745c5c3_Var91, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Old)
19081914 if templ_7745c5c3_Err != nil {
1909- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 358, Col: 28}
1915+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 362, Col: 28}
19101916 }
19111917 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var91))
19121918 if templ_7745c5c3_Err != nil {
19131919 return templ_7745c5c3_Err
19141920 }
1915- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, "</td><td class=\"ln\">")
1921+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, "</td><td class=\"ln\">")
19161922 if templ_7745c5c3_Err != nil {
19171923 return templ_7745c5c3_Err
19181924 }
19191925 var templ_7745c5c3_Var92 string
19201926 templ_7745c5c3_Var92, templ_7745c5c3_Err = templ.JoinStringErrs(ln.New)
19211927 if templ_7745c5c3_Err != nil {
1922- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 359, Col: 28}
1928+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 363, Col: 28}
19231929 }
19241930 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var92))
19251931 if templ_7745c5c3_Err != nil {
19261932 return templ_7745c5c3_Err
19271933 }
1928- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, "</td><td class=\"m\">")
1934+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "</td><td class=\"m\">")
19291935 if templ_7745c5c3_Err != nil {
19301936 return templ_7745c5c3_Err
19311937 }
19321938 var templ_7745c5c3_Var93 string
19331939 templ_7745c5c3_Var93, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)
19341940 if templ_7745c5c3_Err != nil {
1935- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 360, Col: 28}
1941+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 364, Col: 28}
19361942 }
19371943 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var93))
19381944 if templ_7745c5c3_Err != nil {
19391945 return templ_7745c5c3_Err
19401946 }
1941- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "</td><td class=\"tx chroma\">")
1947+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "</td><td class=\"tx chroma\">")
19421948 if templ_7745c5c3_Err != nil {
19431949 return templ_7745c5c3_Err
19441950 }
@@ -1946,7 +1952,7 @@ func DiffContext(c ContextRows) templ.Component {
19461952 if templ_7745c5c3_Err != nil {
19471953 return templ_7745c5c3_Err
19481954 }
1949- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "</td></tr>")
1955+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "</td></tr>")
19501956 if templ_7745c5c3_Err != nil {
19511957 return templ_7745c5c3_Err
19521958 }
@@ -1957,12 +1963,12 @@ func DiffContext(c ContextRows) templ.Component {
19571963 return templ_7745c5c3_Err
19581964 }
19591965 }
1960- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "</tbody> <tbody data-for=\"spl\">")
1966+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "</tbody> <tbody data-for=\"spl\">")
19611967 if templ_7745c5c3_Err != nil {
19621968 return templ_7745c5c3_Err
19631969 }
19641970 for i := range c.Lines {
1965- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "<tr>")
1971+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "<tr>")
19661972 if templ_7745c5c3_Err != nil {
19671973 return templ_7745c5c3_Err
19681974 }
@@ -1974,7 +1980,7 @@ func DiffContext(c ContextRows) templ.Component {
19741980 if templ_7745c5c3_Err != nil {
19751981 return templ_7745c5c3_Err
19761982 }
1977- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "</tr>")
1983+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "</tr>")
19781984 if templ_7745c5c3_Err != nil {
19791985 return templ_7745c5c3_Err
19801986 }
@@ -1985,7 +1991,7 @@ func DiffContext(c ContextRows) templ.Component {
19851991 return templ_7745c5c3_Err
19861992 }
19871993 }
1988- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "</tbody></table>")
1994+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "</tbody></table>")
19891995 if templ_7745c5c3_Err != nil {
19901996 return templ_7745c5c3_Err
19911997 }
@@ -2017,7 +2023,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
20172023 }
20182024 ctx = templ.ClearChildren(ctx)
20192025 if ln == nil {
2020- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "<td class=\"ln none\"></td><td class=\"m none\"></td><td class=\"tx none\"></td>")
2026+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "<td class=\"ln none\"></td><td class=\"m none\"></td><td class=\"tx none\"></td>")
20212027 if templ_7745c5c3_Err != nil {
20222028 return templ_7745c5c3_Err
20232029 }
@@ -2027,7 +2033,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
20272033 if templ_7745c5c3_Err != nil {
20282034 return templ_7745c5c3_Err
20292035 }
2030- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "<td class=\"")
2036+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "<td class=\"")
20312037 if templ_7745c5c3_Err != nil {
20322038 return templ_7745c5c3_Err
20332039 }
@@ -2040,7 +2046,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
20402046 if templ_7745c5c3_Err != nil {
20412047 return templ_7745c5c3_Err
20422048 }
2043- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "\">")
2049+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "\">")
20442050 if templ_7745c5c3_Err != nil {
20452051 return templ_7745c5c3_Err
20462052 }
@@ -2055,7 +2061,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
20552061 return templ_7745c5c3_Err
20562062 }
20572063 }
2058- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "</td>")
2064+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "</td>")
20592065 if templ_7745c5c3_Err != nil {
20602066 return templ_7745c5c3_Err
20612067 }
@@ -2064,7 +2070,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
20642070 if templ_7745c5c3_Err != nil {
20652071 return templ_7745c5c3_Err
20662072 }
2067- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "<td class=\"")
2073+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "<td class=\"")
20682074 if templ_7745c5c3_Err != nil {
20692075 return templ_7745c5c3_Err
20702076 }
@@ -2077,20 +2083,20 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
20772083 if templ_7745c5c3_Err != nil {
20782084 return templ_7745c5c3_Err
20792085 }
2080- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "\">")
2086+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "\">")
20812087 if templ_7745c5c3_Err != nil {
20822088 return templ_7745c5c3_Err
20832089 }
20842090 var templ_7745c5c3_Var99 string
20852091 templ_7745c5c3_Var99, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)
20862092 if templ_7745c5c3_Err != nil {
2087- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 397, Col: 68}
2093+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 401, Col: 68}
20882094 }
20892095 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var99))
20902096 if templ_7745c5c3_Err != nil {
20912097 return templ_7745c5c3_Err
20922098 }
2093- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "</td>")
2099+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "</td>")
20942100 if templ_7745c5c3_Err != nil {
20952101 return templ_7745c5c3_Err
20962102 }
@@ -2099,7 +2105,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
20992105 if templ_7745c5c3_Err != nil {
21002106 return templ_7745c5c3_Err
21012107 }
2102- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "<td class=\"")
2108+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "<td class=\"")
21032109 if templ_7745c5c3_Err != nil {
21042110 return templ_7745c5c3_Err
21052111 }
@@ -2112,7 +2118,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
21122118 if templ_7745c5c3_Err != nil {
21132119 return templ_7745c5c3_Err
21142120 }
2115- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "\">")
2121+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "\">")
21162122 if templ_7745c5c3_Err != nil {
21172123 return templ_7745c5c3_Err
21182124 }
@@ -2120,7 +2126,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
21202126 if templ_7745c5c3_Err != nil {
21212127 return templ_7745c5c3_Err
21222128 }
2123- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "</td>")
2129+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, "</td>")
21242130 if templ_7745c5c3_Err != nil {
21252131 return templ_7745c5c3_Err
21262132 }
@@ -2153,33 +2159,33 @@ func gutter(n, href string) templ.Component {
21532159 }
21542160 ctx = templ.ClearChildren(ctx)
21552161 if href != "" {
2156- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, "<a href=\"")
2162+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "<a href=\"")
21572163 if templ_7745c5c3_Err != nil {
21582164 return templ_7745c5c3_Err
21592165 }
21602166 var templ_7745c5c3_Var103 templ.SafeURL
21612167 templ_7745c5c3_Var103, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(href))
21622168 if templ_7745c5c3_Err != nil {
2163- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 406, Col: 31}
2169+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 410, Col: 31}
21642170 }
21652171 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var103))
21662172 if templ_7745c5c3_Err != nil {
21672173 return templ_7745c5c3_Err
21682174 }
2169- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "\" title=\"comment on this line\">")
2175+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, "\" title=\"comment on this line\">")
21702176 if templ_7745c5c3_Err != nil {
21712177 return templ_7745c5c3_Err
21722178 }
21732179 var templ_7745c5c3_Var104 string
21742180 templ_7745c5c3_Var104, templ_7745c5c3_Err = templ.JoinStringErrs(n)
21752181 if templ_7745c5c3_Err != nil {
2176- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 406, Col: 66}
2182+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 410, Col: 66}
21772183 }
21782184 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var104))
21792185 if templ_7745c5c3_Err != nil {
21802186 return templ_7745c5c3_Err
21812187 }
2182- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, "</a>")
2188+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 191, "</a>")
21832189 if templ_7745c5c3_Err != nil {
21842190 return templ_7745c5c3_Err
21852191 }
@@ -2187,7 +2193,7 @@ func gutter(n, href string) templ.Component {
21872193 var templ_7745c5c3_Var105 string
21882194 templ_7745c5c3_Var105, templ_7745c5c3_Err = templ.JoinStringErrs(n)
21892195 if templ_7745c5c3_Err != nil {
2190- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 408, Col: 5}
2196+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 412, Col: 5}
21912197 }
21922198 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var105))
21932199 if templ_7745c5c3_Err != nil {
@@ -530,14 +530,14 @@ func diffViewMenu(p DiffView) templ.Component {
530 return templ_7745c5c3_Err530 return templ_7745c5c3_Err
531 }531 }
532 if p.Both {532 if p.Both {
533- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<span hx-live=\"this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'\">")533+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<span hx-live=\"this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'\">")
534 if templ_7745c5c3_Err != nil {534 if templ_7745c5c3_Err != nil {
535 return templ_7745c5c3_Err535 return templ_7745c5c3_Err
536 }536 }
537 var templ_7745c5c3_Var22 string537 var templ_7745c5c3_Var22 string
538 templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(viewLabel(p.View))538 templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(viewLabel(p.View))
539 if templ_7745c5c3_Err != nil {539 if templ_7745c5c3_Err != nil {
540- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 120, Col: 122}540+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 120, Col: 168}
541 }541 }
542 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))542 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
543 if templ_7745c5c3_Err != nil {543 if templ_7745c5c3_Err != nil {
@@ -649,58 +649,64 @@ func viewLink(p DiffView, view, label, key, href string) templ.Component {
649 if templ_7745c5c3_Err != nil {649 if templ_7745c5c3_Err != nil {
650 return templ_7745c5c3_Err650 return templ_7745c5c3_Err
651 }651 }
652+ if view == "split" {
653+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " :aria-disabled=\"q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false\" :title=\"q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'\"")
654+ if templ_7745c5c3_Err != nil {
655+ return templ_7745c5c3_Err
656+ }
657+ }
652 if p.View == view {658 if p.View == view {
653- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " aria-current=\"true\"")659+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, " aria-current=\"true\"")
654 if templ_7745c5c3_Err != nil {660 if templ_7745c5c3_Err != nil {
655 return templ_7745c5c3_Err661 return templ_7745c5c3_Err
656 }662 }
657 }663 }
658 if p.Both {664 if p.Both {
659- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, " data-fire=\"")665+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, " data-fire=\"")
660 if templ_7745c5c3_Err != nil {666 if templ_7745c5c3_Err != nil {
661 return templ_7745c5c3_Err667 return templ_7745c5c3_Err
662 }668 }
663 var templ_7745c5c3_Var28 string669 var templ_7745c5c3_Var28 string
664 templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.ResolveAttributeValue(view)670 templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.ResolveAttributeValue(view)
665 if templ_7745c5c3_Err != nil {671 if templ_7745c5c3_Err != nil {
666- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 146, Col: 19}672+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 150, Col: 19}
667 }673 }
668 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var28)674 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var28)
669 if templ_7745c5c3_Err != nil {675 if templ_7745c5c3_Err != nil {
670 return templ_7745c5c3_Err676 return templ_7745c5c3_Err
671 }677 }
672- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "\" :aria-current=\"q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false\"")678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "\" :aria-current=\"(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false\"")
673 if templ_7745c5c3_Err != nil {679 if templ_7745c5c3_Err != nil {
674 return templ_7745c5c3_Err680 return templ_7745c5c3_Err
675 }681 }
676 }682 }
677- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, ">")683+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, ">")
678 if templ_7745c5c3_Err != nil {684 if templ_7745c5c3_Err != nil {
679 return templ_7745c5c3_Err685 return templ_7745c5c3_Err
680 }686 }
681 var templ_7745c5c3_Var29 string687 var templ_7745c5c3_Var29 string
682 templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(label)688 templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(label)
683 if templ_7745c5c3_Err != nil {689 if templ_7745c5c3_Err != nil {
684- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 149, Col: 9}690+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 153, Col: 9}
685 }691 }
686 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))692 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
687 if templ_7745c5c3_Err != nil {693 if templ_7745c5c3_Err != nil {
688 return templ_7745c5c3_Err694 return templ_7745c5c3_Err
689 }695 }
690- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<kbd aria-hidden=\"true\">")696+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "<kbd aria-hidden=\"true\">")
691 if templ_7745c5c3_Err != nil {697 if templ_7745c5c3_Err != nil {
692 return templ_7745c5c3_Err698 return templ_7745c5c3_Err
693 }699 }
694 var templ_7745c5c3_Var30 string700 var templ_7745c5c3_Var30 string
695 templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(key)701 templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(key)
696 if templ_7745c5c3_Err != nil {702 if templ_7745c5c3_Err != nil {
697- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 149, Col: 40}703+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 153, Col: 40}
698 }704 }
699 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))705 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
700 if templ_7745c5c3_Err != nil {706 if templ_7745c5c3_Err != nil {
701 return templ_7745c5c3_Err707 return templ_7745c5c3_Err
702 }708 }
703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "</kbd></a>")709+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</kbd></a>")
704 if templ_7745c5c3_Err != nil {710 if templ_7745c5c3_Err != nil {
705 return templ_7745c5c3_Err711 return templ_7745c5c3_Err
706 }712 }
@@ -731,7 +737,7 @@ func collapseButton() templ.Component {
731 templ_7745c5c3_Var31 = templ.NopComponent737 templ_7745c5c3_Var31 = templ.NopComponent
732 }738 }
733 ctx = templ.ClearChildren(ctx)739 ctx = templ.ClearChildren(ctx)
734- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "<button type=\"button\" aria-keyshortcuts=\"x\" data-js data-fire=\"collapse\" class=\"btn\"><span hx-live=\"this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'\">Collapse all</span><kbd aria-hidden=\"true\">x</kbd></button>")740+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<button type=\"button\" aria-keyshortcuts=\"x\" data-js data-fire=\"collapse\" class=\"btn\"><span hx-live=\"this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'\">Collapse all</span><kbd aria-hidden=\"true\">x</kbd></button>")
735 if templ_7745c5c3_Err != nil {741 if templ_7745c5c3_Err != nil {
736 return templ_7745c5c3_Err742 return templ_7745c5c3_Err
737 }743 }
@@ -763,13 +769,13 @@ func personView(pr Person) templ.Component {
763 var templ_7745c5c3_Var33 string769 var templ_7745c5c3_Var33 string
764 templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(pr.Name)770 templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(pr.Name)
765 if templ_7745c5c3_Err != nil {771 if templ_7745c5c3_Err != nil {
766- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 161, Col: 10}772+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 165, Col: 10}
767 }773 }
768 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))774 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
769 if templ_7745c5c3_Err != nil {775 if templ_7745c5c3_Err != nil {
770 return templ_7745c5c3_Err776 return templ_7745c5c3_Err
771 }777 }
772- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, " ")778+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, " ")
773 if templ_7745c5c3_Err != nil {779 if templ_7745c5c3_Err != nil {
774 return templ_7745c5c3_Err780 return templ_7745c5c3_Err
775 }781 }
@@ -777,59 +783,59 @@ func personView(pr Person) templ.Component {
777 var templ_7745c5c3_Var34 string783 var templ_7745c5c3_Var34 string
778 templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")784 templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
779 if templ_7745c5c3_Err != nil {785 if templ_7745c5c3_Err != nil {
780- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 10}786+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 10}
781 }787 }
782 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))788 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
783 if templ_7745c5c3_Err != nil {789 if templ_7745c5c3_Err != nil {
784 return templ_7745c5c3_Err790 return templ_7745c5c3_Err
785 }791 }
786- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "<time datetime=\"")792+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "<time datetime=\"")
787 if templ_7745c5c3_Err != nil {793 if templ_7745c5c3_Err != nil {
788 return templ_7745c5c3_Err794 return templ_7745c5c3_Err
789 }795 }
790 var templ_7745c5c3_Var35 string796 var templ_7745c5c3_Var35 string
791 templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.ResolveAttributeValue(pr.WhenAt)797 templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.ResolveAttributeValue(pr.WhenAt)
792 if templ_7745c5c3_Err != nil {798 if templ_7745c5c3_Err != nil {
793- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 38}799+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 38}
794 }800 }
795 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var35)801 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var35)
796 if templ_7745c5c3_Err != nil {802 if templ_7745c5c3_Err != nil {
797 return templ_7745c5c3_Err803 return templ_7745c5c3_Err
798 }804 }
799- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "\" title=\"")805+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" title=\"")
800 if templ_7745c5c3_Err != nil {806 if templ_7745c5c3_Err != nil {
801 return templ_7745c5c3_Err807 return templ_7745c5c3_Err
802 }808 }
803 var templ_7745c5c3_Var36 string809 var templ_7745c5c3_Var36 string
804 templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.ResolveAttributeValue(pr.Abs)810 templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.ResolveAttributeValue(pr.Abs)
805 if templ_7745c5c3_Err != nil {811 if templ_7745c5c3_Err != nil {
806- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 55}812+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 55}
807 }813 }
808 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var36)814 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var36)
809 if templ_7745c5c3_Err != nil {815 if templ_7745c5c3_Err != nil {
810 return templ_7745c5c3_Err816 return templ_7745c5c3_Err
811 }817 }
812- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\">")818+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "\">")
813 if templ_7745c5c3_Err != nil {819 if templ_7745c5c3_Err != nil {
814 return templ_7745c5c3_Err820 return templ_7745c5c3_Err
815 }821 }
816 var templ_7745c5c3_Var37 string822 var templ_7745c5c3_Var37 string
817 templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(pr.When)823 templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(pr.When)
818 if templ_7745c5c3_Err != nil {824 if templ_7745c5c3_Err != nil {
819- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 67}825+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 67}
820 }826 }
821 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))827 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
822 if templ_7745c5c3_Err != nil {828 if templ_7745c5c3_Err != nil {
823 return templ_7745c5c3_Err829 return templ_7745c5c3_Err
824 }830 }
825- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</time>")831+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</time>")
826 if templ_7745c5c3_Err != nil {832 if templ_7745c5c3_Err != nil {
827 return templ_7745c5c3_Err833 return templ_7745c5c3_Err
828 }834 }
829 var templ_7745c5c3_Var38 string835 var templ_7745c5c3_Var38 string
830 templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(" · " + pr.Abs)836 templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(" · " + pr.Abs)
831 if templ_7745c5c3_Err != nil {837 if templ_7745c5c3_Err != nil {
832- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 163, Col: 93}838+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 167, Col: 93}
833 }839 }
834 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))840 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
835 if templ_7745c5c3_Err != nil {841 if templ_7745c5c3_Err != nil {
@@ -861,20 +867,20 @@ func commitRail(p CommitPage) templ.Component {
861 templ_7745c5c3_Var39 = templ.NopComponent867 templ_7745c5c3_Var39 = templ.NopComponent
862 }868 }
863 ctx = templ.ClearChildren(ctx)869 ctx = templ.ClearChildren(ctx)
864- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")870+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
865 if templ_7745c5c3_Err != nil {871 if templ_7745c5c3_Err != nil {
866 return templ_7745c5c3_Err872 return templ_7745c5c3_Err
867 }873 }
868 var templ_7745c5c3_Var40 string874 var templ_7745c5c3_Var40 string
869 templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))875 templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
870 if templ_7745c5c3_Err != nil {876 if templ_7745c5c3_Err != nil {
871- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 169, Col: 65}877+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 173, Col: 65}
872 }878 }
873 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))879 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
874 if templ_7745c5c3_Err != nil {880 if templ_7745c5c3_Err != nil {
875 return templ_7745c5c3_Err881 return templ_7745c5c3_Err
876 }882 }
877- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "</span></h2>")883+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "</span></h2>")
878 if templ_7745c5c3_Err != nil {884 if templ_7745c5c3_Err != nil {
879 return templ_7745c5c3_Err885 return templ_7745c5c3_Err
880 }886 }
@@ -882,7 +888,7 @@ func commitRail(p CommitPage) templ.Component {
882 if templ_7745c5c3_Err != nil {888 if templ_7745c5c3_Err != nil {
883 return templ_7745c5c3_Err889 return templ_7745c5c3_Err
884 }890 }
885- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "</section>")891+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</section>")
886 if templ_7745c5c3_Err != nil {892 if templ_7745c5c3_Err != nil {
887 return templ_7745c5c3_Err893 return templ_7745c5c3_Err
888 }894 }
@@ -914,230 +920,230 @@ func FileList(files []DiffFile) templ.Component {
914 }920 }
915 ctx = templ.ClearChildren(ctx)921 ctx = templ.ClearChildren(ctx)
916 if len(files) > fileFilterMin {922 if len(files) > fileFilterMin {
917- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "<div class=\"ffilter\"><label for=\"files-filter\" class=\"sr\">filter the changed files</label> <input id=\"files-filter\" type=\"search\" placeholder=\"Filter files…\" autocomplete=\"off\" data-pick=\".files > li\" hx-on:input=\"ermite.filter(this)\"></div>")923+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<div class=\"ffilter\"><label for=\"files-filter\" class=\"sr\">filter the changed files</label> <input id=\"files-filter\" type=\"search\" placeholder=\"Filter files…\" autocomplete=\"off\" data-pick=\".files > li\" hx-on:input=\"ermite.filter(this)\"></div>")
918 if templ_7745c5c3_Err != nil {924 if templ_7745c5c3_Err != nil {
919 return templ_7745c5c3_Err925 return templ_7745c5c3_Err
920 }926 }
921 }927 }
922- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<ol class=\"files\" aria-label=\"Changed files\">")928+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<ol class=\"files\" aria-label=\"Changed files\">")
923 if templ_7745c5c3_Err != nil {929 if templ_7745c5c3_Err != nil {
924 return templ_7745c5c3_Err930 return templ_7745c5c3_Err
925 }931 }
926 for _, f := range files {932 for _, f := range files {
927- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<li><a href=\"")933+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "<li><a href=\"")
928 if templ_7745c5c3_Err != nil {934 if templ_7745c5c3_Err != nil {
929 return templ_7745c5c3_Err935 return templ_7745c5c3_Err
930 }936 }
931 var templ_7745c5c3_Var42 templ.SafeURL937 var templ_7745c5c3_Var42 templ.SafeURL
932 templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("#" + f.ID))938 templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("#" + f.ID))
933 if templ_7745c5c3_Err != nil {939 if templ_7745c5c3_Err != nil {
934- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 194, Col: 37}940+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 37}
935 }941 }
936 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))942 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
937 if templ_7745c5c3_Err != nil {943 if templ_7745c5c3_Err != nil {
938 return templ_7745c5c3_Err944 return templ_7745c5c3_Err
939 }945 }
940- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "\" title=\"")946+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "\" title=\"")
941 if templ_7745c5c3_Err != nil {947 if templ_7745c5c3_Err != nil {
942 return templ_7745c5c3_Err948 return templ_7745c5c3_Err
943 }949 }
944 var templ_7745c5c3_Var43 string950 var templ_7745c5c3_Var43 string
945 templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path)951 templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path)
946 if templ_7745c5c3_Err != nil {952 if templ_7745c5c3_Err != nil {
947- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 195, Col: 19}953+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 19}
948 }954 }
949 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var43)955 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var43)
950 if templ_7745c5c3_Err != nil {956 if templ_7745c5c3_Err != nil {
951 return templ_7745c5c3_Err957 return templ_7745c5c3_Err
952 }958 }
953- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "\" hx-on:click=\"(window.ermiteMR?.openFile || ermite.openFile)(this.hash.slice(1))\"><span class=\"st\" data-st=\"")959+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "\" hx-on:click=\"(window.ermiteMR?.openFile || ermite.openFile)(this.hash.slice(1))\"><span class=\"st\" data-st=\"")
954 if templ_7745c5c3_Err != nil {960 if templ_7745c5c3_Err != nil {
955 return templ_7745c5c3_Err961 return templ_7745c5c3_Err
956 }962 }
957 var templ_7745c5c3_Var44 string963 var templ_7745c5c3_Var44 string
958 templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Status)964 templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Status)
959 if templ_7745c5c3_Err != nil {965 if templ_7745c5c3_Err != nil {
960- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 40}966+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 202, Col: 40}
961 }967 }
962 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var44)968 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var44)
963 if templ_7745c5c3_Err != nil {969 if templ_7745c5c3_Err != nil {
964 return templ_7745c5c3_Err970 return templ_7745c5c3_Err
965 }971 }
966- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "\" title=\"")972+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "\" title=\"")
967 if templ_7745c5c3_Err != nil {973 if templ_7745c5c3_Err != nil {
968 return templ_7745c5c3_Err974 return templ_7745c5c3_Err
969 }975 }
970 var templ_7745c5c3_Var45 string976 var templ_7745c5c3_Var45 string
971 templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.ResolveAttributeValue(statusName(f.Status))977 templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.ResolveAttributeValue(statusName(f.Status))
972 if templ_7745c5c3_Err != nil {978 if templ_7745c5c3_Err != nil {
973- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 71}979+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 202, Col: 71}
974 }980 }
975 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var45)981 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var45)
976 if templ_7745c5c3_Err != nil {982 if templ_7745c5c3_Err != nil {
977 return templ_7745c5c3_Err983 return templ_7745c5c3_Err
978 }984 }
979- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "\">")985+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\">")
980 if templ_7745c5c3_Err != nil {986 if templ_7745c5c3_Err != nil {
981 return templ_7745c5c3_Err987 return templ_7745c5c3_Err
982 }988 }
983 var templ_7745c5c3_Var46 string989 var templ_7745c5c3_Var46 string
984 templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(f.Status)990 templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(f.Status)
985 if templ_7745c5c3_Err != nil {991 if templ_7745c5c3_Err != nil {
986- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 198, Col: 84}992+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 202, Col: 84}
987 }993 }
988 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))994 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
989 if templ_7745c5c3_Err != nil {995 if templ_7745c5c3_Err != nil {
990 return templ_7745c5c3_Err996 return templ_7745c5c3_Err
991 }997 }
992- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "</span> <span class=\"nm\"><span class=\"p\">")998+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</span> <span class=\"nm\"><span class=\"p\">")
993 if templ_7745c5c3_Err != nil {999 if templ_7745c5c3_Err != nil {
994 return templ_7745c5c3_Err1000 return templ_7745c5c3_Err
995 }1001 }
996 var templ_7745c5c3_Var47 string1002 var templ_7745c5c3_Var47 string
997 templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(f.Name)1003 templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(f.Name)
998 if templ_7745c5c3_Err != nil {1004 if templ_7745c5c3_Err != nil {
999- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 46}1005+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 46}
1000 }1006 }
1001 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))1007 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
1002 if templ_7745c5c3_Err != nil {1008 if templ_7745c5c3_Err != nil {
1003 return templ_7745c5c3_Err1009 return templ_7745c5c3_Err
1004 }1010 }
1005- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</span>")1011+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</span>")
1006 if templ_7745c5c3_Err != nil {1012 if templ_7745c5c3_Err != nil {
1007 return templ_7745c5c3_Err1013 return templ_7745c5c3_Err
1008 }1014 }
1009 var templ_7745c5c3_Var48 string1015 var templ_7745c5c3_Var48 string
1010 templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1016 templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1011 if templ_7745c5c3_Err != nil {1017 if templ_7745c5c3_Err != nil {
1012- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 60}1018+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 60}
1013 }1019 }
1014 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))1020 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
1015 if templ_7745c5c3_Err != nil {1021 if templ_7745c5c3_Err != nil {
1016 return templ_7745c5c3_Err1022 return templ_7745c5c3_Err
1017 }1023 }
1018- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "<span class=\"d\"><bdi>")1024+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "<span class=\"d\"><bdi>")
1019 if templ_7745c5c3_Err != nil {1025 if templ_7745c5c3_Err != nil {
1020 return templ_7745c5c3_Err1026 return templ_7745c5c3_Err
1021 }1027 }
1022 var templ_7745c5c3_Var49 string1028 var templ_7745c5c3_Var49 string
1023 templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(f.Dir)1029 templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(f.Dir)
1024 if templ_7745c5c3_Err != nil {1030 if templ_7745c5c3_Err != nil {
1025- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 199, Col: 90}1031+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 90}
1026 }1032 }
1027 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))1033 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
1028 if templ_7745c5c3_Err != nil {1034 if templ_7745c5c3_Err != nil {
1029 return templ_7745c5c3_Err1035 return templ_7745c5c3_Err
1030 }1036 }
1031- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</bdi></span></span> ")1037+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "</bdi></span></span> ")
1032 if templ_7745c5c3_Err != nil {1038 if templ_7745c5c3_Err != nil {
1033 return templ_7745c5c3_Err1039 return templ_7745c5c3_Err
1034 }1040 }
1035 if f.OpenNotes > 0 {1041 if f.OpenNotes > 0 {
1036- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<span class=\"cn\" title=\"")1042+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "<span class=\"cn\" title=\"")
1037 if templ_7745c5c3_Err != nil {1043 if templ_7745c5c3_Err != nil {
1038 return templ_7745c5c3_Err1044 return templ_7745c5c3_Err
1039 }1045 }
1040 var templ_7745c5c3_Var50 string1046 var templ_7745c5c3_Var50 string
1041 templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.ResolveAttributeValue(plural(f.OpenNotes, "open comment", "open comments"))1047 templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.ResolveAttributeValue(plural(f.OpenNotes, "open comment", "open comments"))
1042 if templ_7745c5c3_Err != nil {1048 if templ_7745c5c3_Err != nil {
1043- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 201, Col: 83}1049+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 205, Col: 83}
1044 }1050 }
1045 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var50)1051 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var50)
1046 if templ_7745c5c3_Err != nil {1052 if templ_7745c5c3_Err != nil {
1047 return templ_7745c5c3_Err1053 return templ_7745c5c3_Err
1048 }1054 }
1049- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "\">")1055+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "\">")
1050 if templ_7745c5c3_Err != nil {1056 if templ_7745c5c3_Err != nil {
1051 return templ_7745c5c3_Err1057 return templ_7745c5c3_Err
1052 }1058 }
1053 var templ_7745c5c3_Var51 string1059 var templ_7745c5c3_Var51 string
1054 templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.OpenNotes))1060 templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.OpenNotes))
1055 if templ_7745c5c3_Err != nil {1061 if templ_7745c5c3_Err != nil {
1056- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 201, Col: 105}1062+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 205, Col: 105}
1057 }1063 }
1058 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51))1064 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51))
1059 if templ_7745c5c3_Err != nil {1065 if templ_7745c5c3_Err != nil {
1060 return templ_7745c5c3_Err1066 return templ_7745c5c3_Err
1061 }1067 }
1062- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</span> ")1068+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</span> ")
1063 if templ_7745c5c3_Err != nil {1069 if templ_7745c5c3_Err != nil {
1064 return templ_7745c5c3_Err1070 return templ_7745c5c3_Err
1065 }1071 }
1066 } else if f.Notes > 0 {1072 } else if f.Notes > 0 {
1067- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "<span class=\"cn done\" title=\"")1073+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<span class=\"cn done\" title=\"")
1068 if templ_7745c5c3_Err != nil {1074 if templ_7745c5c3_Err != nil {
1069 return templ_7745c5c3_Err1075 return templ_7745c5c3_Err
1070 }1076 }
1071 var templ_7745c5c3_Var52 string1077 var templ_7745c5c3_Var52 string
1072 templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.ResolveAttributeValue(plural(f.Notes, "resolved comment", "resolved comments"))1078 templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.ResolveAttributeValue(plural(f.Notes, "resolved comment", "resolved comments"))
1073 if templ_7745c5c3_Err != nil {1079 if templ_7745c5c3_Err != nil {
1074- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 92}1080+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 207, Col: 92}
1075 }1081 }
1076 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var52)1082 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var52)
1077 if templ_7745c5c3_Err != nil {1083 if templ_7745c5c3_Err != nil {
1078 return templ_7745c5c3_Err1084 return templ_7745c5c3_Err
1079 }1085 }
1080- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "\">")1086+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\">")
1081 if templ_7745c5c3_Err != nil {1087 if templ_7745c5c3_Err != nil {
1082 return templ_7745c5c3_Err1088 return templ_7745c5c3_Err
1083 }1089 }
1084 var templ_7745c5c3_Var53 string1090 var templ_7745c5c3_Var53 string
1085 templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Notes))1091 templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Notes))
1086 if templ_7745c5c3_Err != nil {1092 if templ_7745c5c3_Err != nil {
1087- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 203, Col: 110}1093+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 207, Col: 110}
1088 }1094 }
1089 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))1095 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
1090 if templ_7745c5c3_Err != nil {1096 if templ_7745c5c3_Err != nil {
1091 return templ_7745c5c3_Err1097 return templ_7745c5c3_Err
1092 }1098 }
1093- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "</span> ")1099+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "</span> ")
1094 if templ_7745c5c3_Err != nil {1100 if templ_7745c5c3_Err != nil {
1095 return templ_7745c5c3_Err1101 return templ_7745c5c3_Err
1096 }1102 }
1097 }1103 }
1098 if f.Bin {1104 if f.Bin {
1099- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<span class=\"n mute\">bin</span>")1105+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<span class=\"n mute\">bin</span>")
1100 if templ_7745c5c3_Err != nil {1106 if templ_7745c5c3_Err != nil {
1101 return templ_7745c5c3_Err1107 return templ_7745c5c3_Err
1102 }1108 }
1103 } else {1109 } else {
1104- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<span class=\"n\"><span class=\"plus\">+")1110+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<span class=\"n\"><span class=\"plus\">+")
1105 if templ_7745c5c3_Err != nil {1111 if templ_7745c5c3_Err != nil {
1106 return templ_7745c5c3_Err1112 return templ_7745c5c3_Err
1107 }1113 }
1108 var templ_7745c5c3_Var54 string1114 var templ_7745c5c3_Var54 string
1109 templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Add))1115 templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Add))
1110 if templ_7745c5c3_Err != nil {1116 if templ_7745c5c3_Err != nil {
1111- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 208, Col: 55}1117+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 212, Col: 55}
1112 }1118 }
1113 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))1119 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
1114 if templ_7745c5c3_Err != nil {1120 if templ_7745c5c3_Err != nil {
1115 return templ_7745c5c3_Err1121 return templ_7745c5c3_Err
1116 }1122 }
1117- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "</span> <span class=\"minus\">-")1123+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "</span> <span class=\"minus\">-")
1118 if templ_7745c5c3_Err != nil {1124 if templ_7745c5c3_Err != nil {
1119 return templ_7745c5c3_Err1125 return templ_7745c5c3_Err
1120 }1126 }
1121 var templ_7745c5c3_Var55 string1127 var templ_7745c5c3_Var55 string
1122 templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Del))1128 templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Del))
1123 if templ_7745c5c3_Err != nil {1129 if templ_7745c5c3_Err != nil {
1124- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 208, Col: 99}1130+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 212, Col: 99}
1125 }1131 }
1126 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))1132 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
1127 if templ_7745c5c3_Err != nil {1133 if templ_7745c5c3_Err != nil {
1128 return templ_7745c5c3_Err1134 return templ_7745c5c3_Err
1129 }1135 }
1130- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "</span></span>")1136+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</span></span>")
1131 if templ_7745c5c3_Err != nil {1137 if templ_7745c5c3_Err != nil {
1132 return templ_7745c5c3_Err1138 return templ_7745c5c3_Err
1133 }1139 }
1134 }1140 }
1135- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</a></li>")1141+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</a></li>")
1136 if templ_7745c5c3_Err != nil {1142 if templ_7745c5c3_Err != nil {
1137 return templ_7745c5c3_Err1143 return templ_7745c5c3_Err
1138 }1144 }
1139 }1145 }
1140- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</ol>")1146+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "</ol>")
1141 if templ_7745c5c3_Err != nil {1147 if templ_7745c5c3_Err != nil {
1142 return templ_7745c5c3_Err1148 return templ_7745c5c3_Err
1143 }1149 }
@@ -1175,7 +1181,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1175 if templ_7745c5c3_Err != nil {1181 if templ_7745c5c3_Err != nil {
1176 return templ_7745c5c3_Err1182 return templ_7745c5c3_Err
1177 }1183 }
1178- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "<details class=\"")1184+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "<details class=\"")
1179 if templ_7745c5c3_Err != nil {1185 if templ_7745c5c3_Err != nil {
1180 return templ_7745c5c3_Err1186 return templ_7745c5c3_Err
1181 }1187 }
@@ -1188,134 +1194,134 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1188 if templ_7745c5c3_Err != nil {1194 if templ_7745c5c3_Err != nil {
1189 return templ_7745c5c3_Err1195 return templ_7745c5c3_Err
1190 }1196 }
1191- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "\" id=\"")1197+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\" id=\"")
1192 if templ_7745c5c3_Err != nil {1198 if templ_7745c5c3_Err != nil {
1193 return templ_7745c5c3_Err1199 return templ_7745c5c3_Err
1194 }1200 }
1195 var templ_7745c5c3_Var59 string1201 var templ_7745c5c3_Var59 string
1196 templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID)1202 templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID)
1197 if templ_7745c5c3_Err != nil {1203 if templ_7745c5c3_Err != nil {
1198- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 223, Col: 11}1204+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 227, Col: 11}
1199 }1205 }
1200 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var59)1206 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var59)
1201 if templ_7745c5c3_Err != nil {1207 if templ_7745c5c3_Err != nil {
1202 return templ_7745c5c3_Err1208 return templ_7745c5c3_Err
1203 }1209 }
1204- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\" data-file=\"")1210+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "\" data-file=\"")
1205 if templ_7745c5c3_Err != nil {1211 if templ_7745c5c3_Err != nil {
1206 return templ_7745c5c3_Err1212 return templ_7745c5c3_Err
1207 }1213 }
1208 var templ_7745c5c3_Var60 string1214 var templ_7745c5c3_Var60 string
1209 templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Key)1215 templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Key)
1210 if templ_7745c5c3_Err != nil {1216 if templ_7745c5c3_Err != nil {
1211- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 224, Col: 19}1217+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 228, Col: 19}
1212 }1218 }
1213 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var60)1219 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var60)
1214 if templ_7745c5c3_Err != nil {1220 if templ_7745c5c3_Err != nil {
1215 return templ_7745c5c3_Err1221 return templ_7745c5c3_Err
1216 }1222 }
1217- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "\"")1223+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"")
1218 if templ_7745c5c3_Err != nil {1224 if templ_7745c5c3_Err != nil {
1219 return templ_7745c5c3_Err1225 return templ_7745c5c3_Err
1220 }1226 }
1221 if f.Open {1227 if f.Open {
1222- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, " open")1228+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, " open")
1223 if templ_7745c5c3_Err != nil {1229 if templ_7745c5c3_Err != nil {
1224 return templ_7745c5c3_Err1230 return templ_7745c5c3_Err
1225 }1231 }
1226 }1232 }
1227- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "><summary><span class=\"st\">")1233+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "><summary><span class=\"st\">")
1228 if templ_7745c5c3_Err != nil {1234 if templ_7745c5c3_Err != nil {
1229 return templ_7745c5c3_Err1235 return templ_7745c5c3_Err
1230 }1236 }
1231 var templ_7745c5c3_Var61 string1237 var templ_7745c5c3_Var61 string
1232 templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(f.Status)1238 templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(f.Status)
1233 if templ_7745c5c3_Err != nil {1239 if templ_7745c5c3_Err != nil {
1234- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 30}1240+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 30}
1235 }1241 }
1236 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))1242 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61))
1237 if templ_7745c5c3_Err != nil {1243 if templ_7745c5c3_Err != nil {
1238 return templ_7745c5c3_Err1244 return templ_7745c5c3_Err
1239 }1245 }
1240- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</span>")1246+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "</span>")
1241 if templ_7745c5c3_Err != nil {1247 if templ_7745c5c3_Err != nil {
1242 return templ_7745c5c3_Err1248 return templ_7745c5c3_Err
1243 }1249 }
1244 var templ_7745c5c3_Var62 string1250 var templ_7745c5c3_Var62 string
1245 templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1251 templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1246 if templ_7745c5c3_Err != nil {1252 if templ_7745c5c3_Err != nil {
1247- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 44}1253+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 44}
1248 }1254 }
1249 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))1255 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62))
1250 if templ_7745c5c3_Err != nil {1256 if templ_7745c5c3_Err != nil {
1251 return templ_7745c5c3_Err1257 return templ_7745c5c3_Err
1252 }1258 }
1253- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "<span class=\"p\">")1259+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "<span class=\"p\">")
1254 if templ_7745c5c3_Err != nil {1260 if templ_7745c5c3_Err != nil {
1255 return templ_7745c5c3_Err1261 return templ_7745c5c3_Err
1256 }1262 }
1257 var templ_7745c5c3_Var63 string1263 var templ_7745c5c3_Var63 string
1258 templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(f.Path)1264 templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(f.Path)
1259 if templ_7745c5c3_Err != nil {1265 if templ_7745c5c3_Err != nil {
1260- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 70}1266+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 70}
1261 }1267 }
1262 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63))1268 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63))
1263 if templ_7745c5c3_Err != nil {1269 if templ_7745c5c3_Err != nil {
1264 return templ_7745c5c3_Err1270 return templ_7745c5c3_Err
1265 }1271 }
1266- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "</span>")1272+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "</span>")
1267 if templ_7745c5c3_Err != nil {1273 if templ_7745c5c3_Err != nil {
1268 return templ_7745c5c3_Err1274 return templ_7745c5c3_Err
1269 }1275 }
1270 var templ_7745c5c3_Var64 string1276 var templ_7745c5c3_Var64 string
1271 templ_7745c5c3_Var64, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1277 templ_7745c5c3_Var64, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1272 if templ_7745c5c3_Err != nil {1278 if templ_7745c5c3_Err != nil {
1273- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 84}1279+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 84}
1274 }1280 }
1275 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var64))1281 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var64))
1276 if templ_7745c5c3_Err != nil {1282 if templ_7745c5c3_Err != nil {
1277 return templ_7745c5c3_Err1283 return templ_7745c5c3_Err
1278 }1284 }
1279- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "<span class=\"plus\">+")1285+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "<span class=\"plus\">+")
1280 if templ_7745c5c3_Err != nil {1286 if templ_7745c5c3_Err != nil {
1281 return templ_7745c5c3_Err1287 return templ_7745c5c3_Err
1282 }1288 }
1283 var templ_7745c5c3_Var65 string1289 var templ_7745c5c3_Var65 string
1284 templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Add))1290 templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Add))
1285 if templ_7745c5c3_Err != nil {1291 if templ_7745c5c3_Err != nil {
1286- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 119}1292+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 119}
1287 }1293 }
1288 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))1294 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))
1289 if templ_7745c5c3_Err != nil {1295 if templ_7745c5c3_Err != nil {
1290 return templ_7745c5c3_Err1296 return templ_7745c5c3_Err
1291 }1297 }
1292- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "</span>")1298+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "</span>")
1293 if templ_7745c5c3_Err != nil {1299 if templ_7745c5c3_Err != nil {
1294 return templ_7745c5c3_Err1300 return templ_7745c5c3_Err
1295 }1301 }
1296 var templ_7745c5c3_Var66 string1302 var templ_7745c5c3_Var66 string
1297 templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1303 templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1298 if templ_7745c5c3_Err != nil {1304 if templ_7745c5c3_Err != nil {
1299- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 133}1305+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 133}
1300 }1306 }
1301 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))1307 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66))
1302 if templ_7745c5c3_Err != nil {1308 if templ_7745c5c3_Err != nil {
1303 return templ_7745c5c3_Err1309 return templ_7745c5c3_Err
1304 }1310 }
1305- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "<span class=\"minus\">-")1311+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "<span class=\"minus\">-")
1306 if templ_7745c5c3_Err != nil {1312 if templ_7745c5c3_Err != nil {
1307 return templ_7745c5c3_Err1313 return templ_7745c5c3_Err
1308 }1314 }
1309 var templ_7745c5c3_Var67 string1315 var templ_7745c5c3_Var67 string
1310 templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Del))1316 templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(f.Del))
1311 if templ_7745c5c3_Err != nil {1317 if templ_7745c5c3_Err != nil {
1312- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 230, Col: 169}1318+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 234, Col: 169}
1313 }1319 }
1314 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var67))1320 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var67))
1315 if templ_7745c5c3_Err != nil {1321 if templ_7745c5c3_Err != nil {
1316 return templ_7745c5c3_Err1322 return templ_7745c5c3_Err
1317 }1323 }
1318- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "</span> ")1324+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "</span> ")
1319 if templ_7745c5c3_Err != nil {1325 if templ_7745c5c3_Err != nil {
1320 return templ_7745c5c3_Err1326 return templ_7745c5c3_Err
1321 }1327 }
@@ -1323,36 +1329,36 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1323 var templ_7745c5c3_Var68 string1329 var templ_7745c5c3_Var68 string
1324 templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1330 templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1325 if templ_7745c5c3_Err != nil {1331 if templ_7745c5c3_Err != nil {
1326- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 232, Col: 9}1332+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 236, Col: 9}
1327 }1333 }
1328 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))1334 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))
1329 if templ_7745c5c3_Err != nil {1335 if templ_7745c5c3_Err != nil {
1330 return templ_7745c5c3_Err1336 return templ_7745c5c3_Err
1331 }1337 }
1332- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "<span class=\"note\">")1338+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "<span class=\"note\">")
1333 if templ_7745c5c3_Err != nil {1339 if templ_7745c5c3_Err != nil {
1334 return templ_7745c5c3_Err1340 return templ_7745c5c3_Err
1335 }1341 }
1336 var templ_7745c5c3_Var69 string1342 var templ_7745c5c3_Var69 string
1337 templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(f.Note)1343 templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(f.Note)
1338 if templ_7745c5c3_Err != nil {1344 if templ_7745c5c3_Err != nil {
1339- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 232, Col: 38}1345+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 236, Col: 38}
1340 }1346 }
1341 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))1347 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))
1342 if templ_7745c5c3_Err != nil {1348 if templ_7745c5c3_Err != nil {
1343 return templ_7745c5c3_Err1349 return templ_7745c5c3_Err
1344 }1350 }
1345- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "</span>")1351+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</span>")
1346 if templ_7745c5c3_Err != nil {1352 if templ_7745c5c3_Err != nil {
1347 return templ_7745c5c3_Err1353 return templ_7745c5c3_Err
1348 }1354 }
1349 }1355 }
1350- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</summary> ")1356+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "</summary> ")
1351 if templ_7745c5c3_Err != nil {1357 if templ_7745c5c3_Err != nil {
1352 return templ_7745c5c3_Err1358 return templ_7745c5c3_Err
1353 }1359 }
1354 if f.Lazy {1360 if f.Lazy {
1355- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, " ")1361+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, " ")
1356 if templ_7745c5c3_Err != nil {1362 if templ_7745c5c3_Err != nil {
1357 return templ_7745c5c3_Err1363 return templ_7745c5c3_Err
1358 }1364 }
@@ -1361,7 +1367,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1361 if templ_7745c5c3_Err != nil {1367 if templ_7745c5c3_Err != nil {
1362 return templ_7745c5c3_Err1368 return templ_7745c5c3_Err
1363 }1369 }
1364- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<div class=\"")1370+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "<div class=\"")
1365 if templ_7745c5c3_Err != nil {1371 if templ_7745c5c3_Err != nil {
1366 return templ_7745c5c3_Err1372 return templ_7745c5c3_Err
1367 }1373 }
@@ -1374,74 +1380,74 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1374 if templ_7745c5c3_Err != nil {1380 if templ_7745c5c3_Err != nil {
1375 return templ_7745c5c3_Err1381 return templ_7745c5c3_Err
1376 }1382 }
1377- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-src=\"")1383+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\" data-src=\"")
1378 if templ_7745c5c3_Err != nil {1384 if templ_7745c5c3_Err != nil {
1379 return templ_7745c5c3_Err1385 return templ_7745c5c3_Err
1380 }1386 }
1381 var templ_7745c5c3_Var72 string1387 var templ_7745c5c3_Var72 string
1382 templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Src)1388 templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Src)
1383 if templ_7745c5c3_Err != nil {1389 if templ_7745c5c3_Err != nil {
1384- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 239, Col: 69}1390+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 243, Col: 69}
1385 }1391 }
1386 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var72)1392 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var72)
1387 if templ_7745c5c3_Err != nil {1393 if templ_7745c5c3_Err != nil {
1388 return templ_7745c5c3_Err1394 return templ_7745c5c3_Err
1389 }1395 }
1390- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\" data-notes=\"")1396+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\" data-notes=\"")
1391 if templ_7745c5c3_Err != nil {1397 if templ_7745c5c3_Err != nil {
1392 return templ_7745c5c3_Err1398 return templ_7745c5c3_Err
1393 }1399 }
1394 var templ_7745c5c3_Var73 string1400 var templ_7745c5c3_Var73 string
1395 templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Comments)1401 templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Comments)
1396 if templ_7745c5c3_Err != nil {1402 if templ_7745c5c3_Err != nil {
1397- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 239, Col: 95}1403+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 243, Col: 95}
1398 }1404 }
1399 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var73)1405 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var73)
1400 if templ_7745c5c3_Err != nil {1406 if templ_7745c5c3_Err != nil {
1401 return templ_7745c5c3_Err1407 return templ_7745c5c3_Err
1402 }1408 }
1403- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\"><a href=\"")1409+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "\"><a href=\"")
1404 if templ_7745c5c3_Err != nil {1410 if templ_7745c5c3_Err != nil {
1405 return templ_7745c5c3_Err1411 return templ_7745c5c3_Err
1406 }1412 }
1407 var templ_7745c5c3_Var74 templ.SafeURL1413 var templ_7745c5c3_Var74 templ.SafeURL
1408 templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("?from=" + itoa(f.From) + "#" + f.ID))1414 templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("?from=" + itoa(f.From) + "#" + f.ID))
1409 if templ_7745c5c3_Err != nil {1415 if templ_7745c5c3_Err != nil {
1410- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 240, Col: 65}1416+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 244, Col: 65}
1411 }1417 }
1412 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))1418 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))
1413 if templ_7745c5c3_Err != nil {1419 if templ_7745c5c3_Err != nil {
1414 return templ_7745c5c3_Err1420 return templ_7745c5c3_Err
1415 }1421 }
1416- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "\">show this file</a></div>")1422+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "\">show this file</a></div>")
1417 if templ_7745c5c3_Err != nil {1423 if templ_7745c5c3_Err != nil {
1418 return templ_7745c5c3_Err1424 return templ_7745c5c3_Err
1419 }1425 }
1420 } else if len(f.Hunks) > 0 {1426 } else if len(f.Hunks) > 0 {
1421- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "<div class=\"dscroll\">")1427+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "<div class=\"dscroll\">")
1422 if templ_7745c5c3_Err != nil {1428 if templ_7745c5c3_Err != nil {
1423 return templ_7745c5c3_Err1429 return templ_7745c5c3_Err
1424 }1430 }
1425 if p.ShowUnified {1431 if p.ShowUnified {
1426- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "<table class=\"dt uni\" aria-label=\"")1432+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "<table class=\"dt uni\" aria-label=\"")
1427 if templ_7745c5c3_Err != nil {1433 if templ_7745c5c3_Err != nil {
1428 return templ_7745c5c3_Err1434 return templ_7745c5c3_Err
1429 }1435 }
1430 var templ_7745c5c3_Var75 string1436 var templ_7745c5c3_Var75 string
1431 templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path + ", unified")1437 templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path + ", unified")
1432 if templ_7745c5c3_Err != nil {1438 if templ_7745c5c3_Err != nil {
1433- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 245, Col: 60}1439+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 249, Col: 60}
1434 }1440 }
1435 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)1441 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)
1436 if templ_7745c5c3_Err != nil {1442 if templ_7745c5c3_Err != nil {
1437 return templ_7745c5c3_Err1443 return templ_7745c5c3_Err
1438 }1444 }
1439- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "\">")1445+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "\">")
1440 if templ_7745c5c3_Err != nil {1446 if templ_7745c5c3_Err != nil {
1441 return templ_7745c5c3_Err1447 return templ_7745c5c3_Err
1442 }1448 }
1443 for _, h := range f.Hunks {1449 for _, h := range f.Hunks {
1444- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "<tbody>")1450+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<tbody>")
1445 if templ_7745c5c3_Err != nil {1451 if templ_7745c5c3_Err != nil {
1446 return templ_7745c5c3_Err1452 return templ_7745c5c3_Err
1447 }1453 }
@@ -1451,20 +1457,20 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1451 return templ_7745c5c3_Err1457 return templ_7745c5c3_Err
1452 }1458 }
1453 }1459 }
1454- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<tr class=\"hunk\"><td colspan=\"4\">")1460+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "<tr class=\"hunk\"><td colspan=\"4\">")
1455 if templ_7745c5c3_Err != nil {1461 if templ_7745c5c3_Err != nil {
1456 return templ_7745c5c3_Err1462 return templ_7745c5c3_Err
1457 }1463 }
1458 var templ_7745c5c3_Var76 string1464 var templ_7745c5c3_Var76 string
1459 templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(h.Header)1465 templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(h.Header)
1460 if templ_7745c5c3_Err != nil {1466 if templ_7745c5c3_Err != nil {
1461- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 251, Col: 51}1467+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 255, Col: 51}
1462 }1468 }
1463 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))1469 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))
1464 if templ_7745c5c3_Err != nil {1470 if templ_7745c5c3_Err != nil {
1465 return templ_7745c5c3_Err1471 return templ_7745c5c3_Err
1466 }1472 }
1467- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "</td></tr>")1473+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "</td></tr>")
1468 if templ_7745c5c3_Err != nil {1474 if templ_7745c5c3_Err != nil {
1469 return templ_7745c5c3_Err1475 return templ_7745c5c3_Err
1470 }1476 }
@@ -1474,7 +1480,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1474 if templ_7745c5c3_Err != nil {1480 if templ_7745c5c3_Err != nil {
1475 return templ_7745c5c3_Err1481 return templ_7745c5c3_Err
1476 }1482 }
1477- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "<tr class=\"")1483+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "<tr class=\"")
1478 if templ_7745c5c3_Err != nil {1484 if templ_7745c5c3_Err != nil {
1479 return templ_7745c5c3_Err1485 return templ_7745c5c3_Err
1480 }1486 }
@@ -1487,7 +1493,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1487 if templ_7745c5c3_Err != nil {1493 if templ_7745c5c3_Err != nil {
1488 return templ_7745c5c3_Err1494 return templ_7745c5c3_Err
1489 }1495 }
1490- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "\"><td class=\"ln\">")1496+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "\"><td class=\"ln\">")
1491 if templ_7745c5c3_Err != nil {1497 if templ_7745c5c3_Err != nil {
1492 return templ_7745c5c3_Err1498 return templ_7745c5c3_Err
1493 }1499 }
@@ -1495,7 +1501,7 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1495 if templ_7745c5c3_Err != nil {1501 if templ_7745c5c3_Err != nil {
1496 return templ_7745c5c3_Err1502 return templ_7745c5c3_Err
1497 }1503 }
1498- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "</td><td class=\"ln\">")1504+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</td><td class=\"ln\">")
1499 if templ_7745c5c3_Err != nil {1505 if templ_7745c5c3_Err != nil {
1500 return templ_7745c5c3_Err1506 return templ_7745c5c3_Err
1501 }1507 }
@@ -1503,20 +1509,20 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1503 if templ_7745c5c3_Err != nil {1509 if templ_7745c5c3_Err != nil {
1504 return templ_7745c5c3_Err1510 return templ_7745c5c3_Err
1505 }1511 }
1506- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</td><td class=\"m\">")1512+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "</td><td class=\"m\">")
1507 if templ_7745c5c3_Err != nil {1513 if templ_7745c5c3_Err != nil {
1508 return templ_7745c5c3_Err1514 return templ_7745c5c3_Err
1509 }1515 }
1510 var templ_7745c5c3_Var79 string1516 var templ_7745c5c3_Var79 string
1511 templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)1517 templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)
1512 if templ_7745c5c3_Err != nil {1518 if templ_7745c5c3_Err != nil {
1513- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 256, Col: 33}1519+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 260, Col: 33}
1514 }1520 }
1515 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))1521 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))
1516 if templ_7745c5c3_Err != nil {1522 if templ_7745c5c3_Err != nil {
1517 return templ_7745c5c3_Err1523 return templ_7745c5c3_Err
1518 }1524 }
1519- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "</td><td class=\"tx chroma\">")1525+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "</td><td class=\"tx chroma\">")
1520 if templ_7745c5c3_Err != nil {1526 if templ_7745c5c3_Err != nil {
1521 return templ_7745c5c3_Err1527 return templ_7745c5c3_Err
1522 }1528 }
@@ -1524,12 +1530,12 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1524 if templ_7745c5c3_Err != nil {1530 if templ_7745c5c3_Err != nil {
1525 return templ_7745c5c3_Err1531 return templ_7745c5c3_Err
1526 }1532 }
1527- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "</td></tr>")1533+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "</td></tr>")
1528 if templ_7745c5c3_Err != nil {1534 if templ_7745c5c3_Err != nil {
1529 return templ_7745c5c3_Err1535 return templ_7745c5c3_Err
1530 }1536 }
1531 if len(ln.Notes) > 0 || ln.Form != nil {1537 if len(ln.Notes) > 0 || ln.Form != nil {
1532- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "<tr class=\"fnote\"><td colspan=\"3\"></td><td>")1538+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "<tr class=\"fnote\"><td colspan=\"3\"></td><td>")
1533 if templ_7745c5c3_Err != nil {1539 if templ_7745c5c3_Err != nil {
1534 return templ_7745c5c3_Err1540 return templ_7745c5c3_Err
1535 }1541 }
@@ -1537,19 +1543,19 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1537 if templ_7745c5c3_Err != nil {1543 if templ_7745c5c3_Err != nil {
1538 return templ_7745c5c3_Err1544 return templ_7745c5c3_Err
1539 }1545 }
1540- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "</td></tr>")1546+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "</td></tr>")
1541 if templ_7745c5c3_Err != nil {1547 if templ_7745c5c3_Err != nil {
1542 return templ_7745c5c3_Err1548 return templ_7745c5c3_Err
1543 }1549 }
1544 }1550 }
1545 }1551 }
1546- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "</tbody> ")1552+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "</tbody> ")
1547 if templ_7745c5c3_Err != nil {1553 if templ_7745c5c3_Err != nil {
1548 return templ_7745c5c3_Err1554 return templ_7745c5c3_Err
1549 }1555 }
1550 }1556 }
1551 if f.Tail != nil {1557 if f.Tail != nil {
1552- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "<tbody>")1558+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "<tbody>")
1553 if templ_7745c5c3_Err != nil {1559 if templ_7745c5c3_Err != nil {
1554 return templ_7745c5c3_Err1560 return templ_7745c5c3_Err
1555 }1561 }
@@ -1557,36 +1563,36 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1557 if templ_7745c5c3_Err != nil {1563 if templ_7745c5c3_Err != nil {
1558 return templ_7745c5c3_Err1564 return templ_7745c5c3_Err
1559 }1565 }
1560- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "</tbody>")1566+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "</tbody>")
1561 if templ_7745c5c3_Err != nil {1567 if templ_7745c5c3_Err != nil {
1562 return templ_7745c5c3_Err1568 return templ_7745c5c3_Err
1563 }1569 }
1564 }1570 }
1565- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "</table>")1571+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "</table>")
1566 if templ_7745c5c3_Err != nil {1572 if templ_7745c5c3_Err != nil {
1567 return templ_7745c5c3_Err1573 return templ_7745c5c3_Err
1568 }1574 }
1569 }1575 }
1570 if p.ShowSplit {1576 if p.ShowSplit {
1571- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "<table class=\"dt spl\" aria-label=\"")1577+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "<table class=\"dt spl\" aria-label=\"")
1572 if templ_7745c5c3_Err != nil {1578 if templ_7745c5c3_Err != nil {
1573 return templ_7745c5c3_Err1579 return templ_7745c5c3_Err
1574 }1580 }
1575 var templ_7745c5c3_Var80 string1581 var templ_7745c5c3_Var80 string
1576 templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path + ", split")1582 templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path + ", split")
1577 if templ_7745c5c3_Err != nil {1583 if templ_7745c5c3_Err != nil {
1578- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 276, Col: 58}1584+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 280, Col: 58}
1579 }1585 }
1580 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)1586 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)
1581 if templ_7745c5c3_Err != nil {1587 if templ_7745c5c3_Err != nil {
1582 return templ_7745c5c3_Err1588 return templ_7745c5c3_Err
1583 }1589 }
1584- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "\"><colgroup><col class=\"c-ln\"><col class=\"c-m\"><col><col class=\"c-ln\"><col class=\"c-m\"><col></colgroup> ")1590+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "\"><colgroup><col class=\"c-ln\"><col class=\"c-m\"><col><col class=\"c-ln\"><col class=\"c-m\"><col></colgroup> ")
1585 if templ_7745c5c3_Err != nil {1591 if templ_7745c5c3_Err != nil {
1586 return templ_7745c5c3_Err1592 return templ_7745c5c3_Err
1587 }1593 }
1588 for _, h := range f.Hunks {1594 for _, h := range f.Hunks {
1589- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "<tbody>")1595+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<tbody>")
1590 if templ_7745c5c3_Err != nil {1596 if templ_7745c5c3_Err != nil {
1591 return templ_7745c5c3_Err1597 return templ_7745c5c3_Err
1592 }1598 }
@@ -1596,25 +1602,25 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1596 return templ_7745c5c3_Err1602 return templ_7745c5c3_Err
1597 }1603 }
1598 }1604 }
1599- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<tr class=\"hunk\"><td colspan=\"6\">")1605+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "<tr class=\"hunk\"><td colspan=\"6\">")
1600 if templ_7745c5c3_Err != nil {1606 if templ_7745c5c3_Err != nil {
1601 return templ_7745c5c3_Err1607 return templ_7745c5c3_Err
1602 }1608 }
1603 var templ_7745c5c3_Var81 string1609 var templ_7745c5c3_Var81 string
1604 templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinStringErrs(h.Header)1610 templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinStringErrs(h.Header)
1605 if templ_7745c5c3_Err != nil {1611 if templ_7745c5c3_Err != nil {
1606- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 283, Col: 51}1612+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 287, Col: 51}
1607 }1613 }
1608 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))1614 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))
1609 if templ_7745c5c3_Err != nil {1615 if templ_7745c5c3_Err != nil {
1610 return templ_7745c5c3_Err1616 return templ_7745c5c3_Err
1611 }1617 }
1612- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "</td></tr>")1618+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "</td></tr>")
1613 if templ_7745c5c3_Err != nil {1619 if templ_7745c5c3_Err != nil {
1614 return templ_7745c5c3_Err1620 return templ_7745c5c3_Err
1615 }1621 }
1616 for _, row := range h.Split {1622 for _, row := range h.Split {
1617- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "<tr>")1623+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "<tr>")
1618 if templ_7745c5c3_Err != nil {1624 if templ_7745c5c3_Err != nil {
1619 return templ_7745c5c3_Err1625 return templ_7745c5c3_Err
1620 }1626 }
@@ -1626,12 +1632,12 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1626 if templ_7745c5c3_Err != nil {1632 if templ_7745c5c3_Err != nil {
1627 return templ_7745c5c3_Err1633 return templ_7745c5c3_Err
1628 }1634 }
1629- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "</tr>")1635+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "</tr>")
1630 if templ_7745c5c3_Err != nil {1636 if templ_7745c5c3_Err != nil {
1631 return templ_7745c5c3_Err1637 return templ_7745c5c3_Err
1632 }1638 }
1633 if notes, form := row.Notes(), row.Form(); len(notes) > 0 || form != nil {1639 if notes, form := row.Notes(), row.Form(); len(notes) > 0 || form != nil {
1634- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "<tr class=\"fnote\"><td colspan=\"6\">")1640+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "<tr class=\"fnote\"><td colspan=\"6\">")
1635 if templ_7745c5c3_Err != nil {1641 if templ_7745c5c3_Err != nil {
1636 return templ_7745c5c3_Err1642 return templ_7745c5c3_Err
1637 }1643 }
@@ -1639,19 +1645,19 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1639 if templ_7745c5c3_Err != nil {1645 if templ_7745c5c3_Err != nil {
1640 return templ_7745c5c3_Err1646 return templ_7745c5c3_Err
1641 }1647 }
1642- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "</td></tr>")1648+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "</td></tr>")
1643 if templ_7745c5c3_Err != nil {1649 if templ_7745c5c3_Err != nil {
1644 return templ_7745c5c3_Err1650 return templ_7745c5c3_Err
1645 }1651 }
1646 }1652 }
1647 }1653 }
1648- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "</tbody> ")1654+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "</tbody> ")
1649 if templ_7745c5c3_Err != nil {1655 if templ_7745c5c3_Err != nil {
1650 return templ_7745c5c3_Err1656 return templ_7745c5c3_Err
1651 }1657 }
1652 }1658 }
1653 if f.Tail != nil {1659 if f.Tail != nil {
1654- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "<tbody>")1660+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "<tbody>")
1655 if templ_7745c5c3_Err != nil {1661 if templ_7745c5c3_Err != nil {
1656 return templ_7745c5c3_Err1662 return templ_7745c5c3_Err
1657 }1663 }
@@ -1659,22 +1665,22 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1659 if templ_7745c5c3_Err != nil {1665 if templ_7745c5c3_Err != nil {
1660 return templ_7745c5c3_Err1666 return templ_7745c5c3_Err
1661 }1667 }
1662- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "</tbody>")1668+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "</tbody>")
1663 if templ_7745c5c3_Err != nil {1669 if templ_7745c5c3_Err != nil {
1664 return templ_7745c5c3_Err1670 return templ_7745c5c3_Err
1665 }1671 }
1666 }1672 }
1667- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "</table>")1673+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "</table>")
1668 if templ_7745c5c3_Err != nil {1674 if templ_7745c5c3_Err != nil {
1669 return templ_7745c5c3_Err1675 return templ_7745c5c3_Err
1670 }1676 }
1671 }1677 }
1672- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "</div>")1678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "</div>")
1673 if templ_7745c5c3_Err != nil {1679 if templ_7745c5c3_Err != nil {
1674 return templ_7745c5c3_Err1680 return templ_7745c5c3_Err
1675 }1681 }
1676 } else {1682 } else {
1677- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "<p class=\"note pad\">")1683+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "<p class=\"note pad\">")
1678 if templ_7745c5c3_Err != nil {1684 if templ_7745c5c3_Err != nil {
1679 return templ_7745c5c3_Err1685 return templ_7745c5c3_Err
1680 }1686 }
@@ -1682,25 +1688,25 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1682 var templ_7745c5c3_Var82 string1688 var templ_7745c5c3_Var82 string
1683 templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.JoinStringErrs(f.Note)1689 templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.JoinStringErrs(f.Note)
1684 if templ_7745c5c3_Err != nil {1690 if templ_7745c5c3_Err != nil {
1685- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 308, Col: 13}1691+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 312, Col: 13}
1686 }1692 }
1687 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var82))1693 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var82))
1688 if templ_7745c5c3_Err != nil {1694 if templ_7745c5c3_Err != nil {
1689 return templ_7745c5c3_Err1695 return templ_7745c5c3_Err
1690 }1696 }
1691 } else {1697 } else {
1692- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "no textual change.")1698+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "no textual change.")
1693 if templ_7745c5c3_Err != nil {1699 if templ_7745c5c3_Err != nil {
1694 return templ_7745c5c3_Err1700 return templ_7745c5c3_Err
1695 }1701 }
1696 }1702 }
1697- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "</p>")1703+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "</p>")
1698 if templ_7745c5c3_Err != nil {1704 if templ_7745c5c3_Err != nil {
1699 return templ_7745c5c3_Err1705 return templ_7745c5c3_Err
1700 }1706 }
1701 }1707 }
1702 if len(f.Loose) > 0 {1708 if len(f.Loose) > 0 {
1703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "<div class=\"dloose\">")1709+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "<div class=\"dloose\">")
1704 if templ_7745c5c3_Err != nil {1710 if templ_7745c5c3_Err != nil {
1705 return templ_7745c5c3_Err1711 return templ_7745c5c3_Err
1706 }1712 }
@@ -1710,12 +1716,12 @@ func DiffFileView(f DiffFile, p DiffView) templ.Component {
1710 return templ_7745c5c3_Err1716 return templ_7745c5c3_Err
1711 }1717 }
1712 }1718 }
1713- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "</div>")1719+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "</div>")
1714 if templ_7745c5c3_Err != nil {1720 if templ_7745c5c3_Err != nil {
1715 return templ_7745c5c3_Err1721 return templ_7745c5c3_Err
1716 }1722 }
1717 }1723 }
1718- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "</details>")1724+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "</details>")
1719 if templ_7745c5c3_Err != nil {1725 if templ_7745c5c3_Err != nil {
1720 return templ_7745c5c3_Err1726 return templ_7745c5c3_Err
1721 }1727 }
@@ -1779,7 +1785,7 @@ func MRFilesMoved() templ.Component {
1779 templ_7745c5c3_Var84 = templ.NopComponent1785 templ_7745c5c3_Var84 = templ.NopComponent
1780 }1786 }
1781 ctx = templ.ClearChildren(ctx)1787 ctx = templ.ClearChildren(ctx)
1782- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "<p class=\"notice\" data-moved>this merge request changed since the page was loaded — <a href=\"\">reload</a></p>")1788+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "<p class=\"notice\" data-moved>this merge request changed since the page was loaded — <a href=\"\">reload</a></p>")
1783 if templ_7745c5c3_Err != nil {1789 if templ_7745c5c3_Err != nil {
1784 return templ_7745c5c3_Err1790 return templ_7745c5c3_Err
1785 }1791 }
@@ -1811,59 +1817,59 @@ func gapRow(g DiffGap, cols int) templ.Component {
1811 templ_7745c5c3_Var85 = templ.NopComponent1817 templ_7745c5c3_Var85 = templ.NopComponent
1812 }1818 }
1813 ctx = templ.ClearChildren(ctx)1819 ctx = templ.ClearChildren(ctx)
1814- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "<tr class=\"gap\" data-js data-gap=\"")1820+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "<tr class=\"gap\" data-js data-gap=\"")
1815 if templ_7745c5c3_Err != nil {1821 if templ_7745c5c3_Err != nil {
1816 return templ_7745c5c3_Err1822 return templ_7745c5c3_Err
1817 }1823 }
1818 var templ_7745c5c3_Var86 string1824 var templ_7745c5c3_Var86 string
1819 templ_7745c5c3_Var86, templ_7745c5c3_Err = templ.ResolveAttributeValue(g.Key)1825 templ_7745c5c3_Var86, templ_7745c5c3_Err = templ.ResolveAttributeValue(g.Key)
1820 if templ_7745c5c3_Err != nil {1826 if templ_7745c5c3_Err != nil {
1821- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 342, Col: 41}1827+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 346, Col: 41}
1822 }1828 }
1823 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var86)1829 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var86)
1824 if templ_7745c5c3_Err != nil {1830 if templ_7745c5c3_Err != nil {
1825 return templ_7745c5c3_Err1831 return templ_7745c5c3_Err
1826 }1832 }
1827- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "\"><td colspan=\"")1833+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "\"><td colspan=\"")
1828 if templ_7745c5c3_Err != nil {1834 if templ_7745c5c3_Err != nil {
1829 return templ_7745c5c3_Err1835 return templ_7745c5c3_Err
1830 }1836 }
1831 var templ_7745c5c3_Var87 string1837 var templ_7745c5c3_Var87 string
1832 templ_7745c5c3_Var87, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(cols))1838 templ_7745c5c3_Var87, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(cols))
1833 if templ_7745c5c3_Err != nil {1839 if templ_7745c5c3_Err != nil {
1834- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 343, Col: 26}1840+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 347, Col: 26}
1835 }1841 }
1836 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var87)1842 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var87)
1837 if templ_7745c5c3_Err != nil {1843 if templ_7745c5c3_Err != nil {
1838 return templ_7745c5c3_Err1844 return templ_7745c5c3_Err
1839 }1845 }
1840- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "\"><button type=\"button\" data-src=\"")1846+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\"><button type=\"button\" data-src=\"")
1841 if templ_7745c5c3_Err != nil {1847 if templ_7745c5c3_Err != nil {
1842 return templ_7745c5c3_Err1848 return templ_7745c5c3_Err
1843 }1849 }
1844 var templ_7745c5c3_Var88 string1850 var templ_7745c5c3_Var88 string
1845 templ_7745c5c3_Var88, templ_7745c5c3_Err = templ.ResolveAttributeValue(g.Src)1851 templ_7745c5c3_Var88, templ_7745c5c3_Err = templ.ResolveAttributeValue(g.Src)
1846 if templ_7745c5c3_Err != nil {1852 if templ_7745c5c3_Err != nil {
1847- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 344, Col: 41}1853+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 348, Col: 41}
1848 }1854 }
1849 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var88)1855 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var88)
1850 if templ_7745c5c3_Err != nil {1856 if templ_7745c5c3_Err != nil {
1851 return templ_7745c5c3_Err1857 return templ_7745c5c3_Err
1852 }1858 }
1853- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\"><span aria-hidden=\"true\">⋯</span> ")1859+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, "\"><span aria-hidden=\"true\">⋯</span> ")
1854 if templ_7745c5c3_Err != nil {1860 if templ_7745c5c3_Err != nil {
1855 return templ_7745c5c3_Err1861 return templ_7745c5c3_Err
1856 }1862 }
1857 var templ_7745c5c3_Var89 string1863 var templ_7745c5c3_Var89 string
1858 templ_7745c5c3_Var89, templ_7745c5c3_Err = templ.JoinStringErrs(g.Label())1864 templ_7745c5c3_Var89, templ_7745c5c3_Err = templ.JoinStringErrs(g.Label())
1859 if templ_7745c5c3_Err != nil {1865 if templ_7745c5c3_Err != nil {
1860- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 345, Col: 51}1866+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 349, Col: 51}
1861 }1867 }
1862 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var89))1868 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var89))
1863 if templ_7745c5c3_Err != nil {1869 if templ_7745c5c3_Err != nil {
1864 return templ_7745c5c3_Err1870 return templ_7745c5c3_Err
1865 }1871 }
1866- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, "</button></td></tr>")1872+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, "</button></td></tr>")
1867 if templ_7745c5c3_Err != nil {1873 if templ_7745c5c3_Err != nil {
1868 return templ_7745c5c3_Err1874 return templ_7745c5c3_Err
1869 }1875 }
@@ -1894,51 +1900,51 @@ func DiffContext(c ContextRows) templ.Component {
1894 templ_7745c5c3_Var90 = templ.NopComponent1900 templ_7745c5c3_Var90 = templ.NopComponent
1895 }1901 }
1896 ctx = templ.ClearChildren(ctx)1902 ctx = templ.ClearChildren(ctx)
1897- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, "<table><tbody data-for=\"uni\">")1903+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, "<table><tbody data-for=\"uni\">")
1898 if templ_7745c5c3_Err != nil {1904 if templ_7745c5c3_Err != nil {
1899 return templ_7745c5c3_Err1905 return templ_7745c5c3_Err
1900 }1906 }
1901 for _, ln := range c.Lines {1907 for _, ln := range c.Lines {
1902- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, "<tr class=\"ctx\"><td class=\"ln\">")1908+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, "<tr class=\"ctx\"><td class=\"ln\">")
1903 if templ_7745c5c3_Err != nil {1909 if templ_7745c5c3_Err != nil {
1904 return templ_7745c5c3_Err1910 return templ_7745c5c3_Err
1905 }1911 }
1906 var templ_7745c5c3_Var91 string1912 var templ_7745c5c3_Var91 string
1907 templ_7745c5c3_Var91, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Old)1913 templ_7745c5c3_Var91, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Old)
1908 if templ_7745c5c3_Err != nil {1914 if templ_7745c5c3_Err != nil {
1909- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 358, Col: 28}1915+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 362, Col: 28}
1910 }1916 }
1911 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var91))1917 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var91))
1912 if templ_7745c5c3_Err != nil {1918 if templ_7745c5c3_Err != nil {
1913 return templ_7745c5c3_Err1919 return templ_7745c5c3_Err
1914 }1920 }
1915- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, "</td><td class=\"ln\">")1921+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, "</td><td class=\"ln\">")
1916 if templ_7745c5c3_Err != nil {1922 if templ_7745c5c3_Err != nil {
1917 return templ_7745c5c3_Err1923 return templ_7745c5c3_Err
1918 }1924 }
1919 var templ_7745c5c3_Var92 string1925 var templ_7745c5c3_Var92 string
1920 templ_7745c5c3_Var92, templ_7745c5c3_Err = templ.JoinStringErrs(ln.New)1926 templ_7745c5c3_Var92, templ_7745c5c3_Err = templ.JoinStringErrs(ln.New)
1921 if templ_7745c5c3_Err != nil {1927 if templ_7745c5c3_Err != nil {
1922- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 359, Col: 28}1928+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 363, Col: 28}
1923 }1929 }
1924 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var92))1930 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var92))
1925 if templ_7745c5c3_Err != nil {1931 if templ_7745c5c3_Err != nil {
1926 return templ_7745c5c3_Err1932 return templ_7745c5c3_Err
1927 }1933 }
1928- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, "</td><td class=\"m\">")1934+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "</td><td class=\"m\">")
1929 if templ_7745c5c3_Err != nil {1935 if templ_7745c5c3_Err != nil {
1930 return templ_7745c5c3_Err1936 return templ_7745c5c3_Err
1931 }1937 }
1932 var templ_7745c5c3_Var93 string1938 var templ_7745c5c3_Var93 string
1933 templ_7745c5c3_Var93, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)1939 templ_7745c5c3_Var93, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)
1934 if templ_7745c5c3_Err != nil {1940 if templ_7745c5c3_Err != nil {
1935- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 360, Col: 28}1941+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 364, Col: 28}
1936 }1942 }
1937 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var93))1943 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var93))
1938 if templ_7745c5c3_Err != nil {1944 if templ_7745c5c3_Err != nil {
1939 return templ_7745c5c3_Err1945 return templ_7745c5c3_Err
1940 }1946 }
1941- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "</td><td class=\"tx chroma\">")1947+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "</td><td class=\"tx chroma\">")
1942 if templ_7745c5c3_Err != nil {1948 if templ_7745c5c3_Err != nil {
1943 return templ_7745c5c3_Err1949 return templ_7745c5c3_Err
1944 }1950 }
@@ -1946,7 +1952,7 @@ func DiffContext(c ContextRows) templ.Component {
1946 if templ_7745c5c3_Err != nil {1952 if templ_7745c5c3_Err != nil {
1947 return templ_7745c5c3_Err1953 return templ_7745c5c3_Err
1948 }1954 }
1949- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "</td></tr>")1955+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "</td></tr>")
1950 if templ_7745c5c3_Err != nil {1956 if templ_7745c5c3_Err != nil {
1951 return templ_7745c5c3_Err1957 return templ_7745c5c3_Err
1952 }1958 }
@@ -1957,12 +1963,12 @@ func DiffContext(c ContextRows) templ.Component {
1957 return templ_7745c5c3_Err1963 return templ_7745c5c3_Err
1958 }1964 }
1959 }1965 }
1960- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "</tbody> <tbody data-for=\"spl\">")1966+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "</tbody> <tbody data-for=\"spl\">")
1961 if templ_7745c5c3_Err != nil {1967 if templ_7745c5c3_Err != nil {
1962 return templ_7745c5c3_Err1968 return templ_7745c5c3_Err
1963 }1969 }
1964 for i := range c.Lines {1970 for i := range c.Lines {
1965- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "<tr>")1971+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "<tr>")
1966 if templ_7745c5c3_Err != nil {1972 if templ_7745c5c3_Err != nil {
1967 return templ_7745c5c3_Err1973 return templ_7745c5c3_Err
1968 }1974 }
@@ -1974,7 +1980,7 @@ func DiffContext(c ContextRows) templ.Component {
1974 if templ_7745c5c3_Err != nil {1980 if templ_7745c5c3_Err != nil {
1975 return templ_7745c5c3_Err1981 return templ_7745c5c3_Err
1976 }1982 }
1977- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "</tr>")1983+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "</tr>")
1978 if templ_7745c5c3_Err != nil {1984 if templ_7745c5c3_Err != nil {
1979 return templ_7745c5c3_Err1985 return templ_7745c5c3_Err
1980 }1986 }
@@ -1985,7 +1991,7 @@ func DiffContext(c ContextRows) templ.Component {
1985 return templ_7745c5c3_Err1991 return templ_7745c5c3_Err
1986 }1992 }
1987 }1993 }
1988- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "</tbody></table>")1994+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "</tbody></table>")
1989 if templ_7745c5c3_Err != nil {1995 if templ_7745c5c3_Err != nil {
1990 return templ_7745c5c3_Err1996 return templ_7745c5c3_Err
1991 }1997 }
@@ -2017,7 +2023,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2017 }2023 }
2018 ctx = templ.ClearChildren(ctx)2024 ctx = templ.ClearChildren(ctx)
2019 if ln == nil {2025 if ln == nil {
2020- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "<td class=\"ln none\"></td><td class=\"m none\"></td><td class=\"tx none\"></td>")2026+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "<td class=\"ln none\"></td><td class=\"m none\"></td><td class=\"tx none\"></td>")
2021 if templ_7745c5c3_Err != nil {2027 if templ_7745c5c3_Err != nil {
2022 return templ_7745c5c3_Err2028 return templ_7745c5c3_Err
2023 }2029 }
@@ -2027,7 +2033,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2027 if templ_7745c5c3_Err != nil {2033 if templ_7745c5c3_Err != nil {
2028 return templ_7745c5c3_Err2034 return templ_7745c5c3_Err
2029 }2035 }
2030- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "<td class=\"")2036+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "<td class=\"")
2031 if templ_7745c5c3_Err != nil {2037 if templ_7745c5c3_Err != nil {
2032 return templ_7745c5c3_Err2038 return templ_7745c5c3_Err
2033 }2039 }
@@ -2040,7 +2046,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2040 if templ_7745c5c3_Err != nil {2046 if templ_7745c5c3_Err != nil {
2041 return templ_7745c5c3_Err2047 return templ_7745c5c3_Err
2042 }2048 }
2043- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "\">")2049+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "\">")
2044 if templ_7745c5c3_Err != nil {2050 if templ_7745c5c3_Err != nil {
2045 return templ_7745c5c3_Err2051 return templ_7745c5c3_Err
2046 }2052 }
@@ -2055,7 +2061,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2055 return templ_7745c5c3_Err2061 return templ_7745c5c3_Err
2056 }2062 }
2057 }2063 }
2058- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "</td>")2064+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "</td>")
2059 if templ_7745c5c3_Err != nil {2065 if templ_7745c5c3_Err != nil {
2060 return templ_7745c5c3_Err2066 return templ_7745c5c3_Err
2061 }2067 }
@@ -2064,7 +2070,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2064 if templ_7745c5c3_Err != nil {2070 if templ_7745c5c3_Err != nil {
2065 return templ_7745c5c3_Err2071 return templ_7745c5c3_Err
2066 }2072 }
2067- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "<td class=\"")2073+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "<td class=\"")
2068 if templ_7745c5c3_Err != nil {2074 if templ_7745c5c3_Err != nil {
2069 return templ_7745c5c3_Err2075 return templ_7745c5c3_Err
2070 }2076 }
@@ -2077,20 +2083,20 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2077 if templ_7745c5c3_Err != nil {2083 if templ_7745c5c3_Err != nil {
2078 return templ_7745c5c3_Err2084 return templ_7745c5c3_Err
2079 }2085 }
2080- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "\">")2086+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "\">")
2081 if templ_7745c5c3_Err != nil {2087 if templ_7745c5c3_Err != nil {
2082 return templ_7745c5c3_Err2088 return templ_7745c5c3_Err
2083 }2089 }
2084 var templ_7745c5c3_Var99 string2090 var templ_7745c5c3_Var99 string
2085 templ_7745c5c3_Var99, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)2091 templ_7745c5c3_Var99, templ_7745c5c3_Err = templ.JoinStringErrs(ln.Mark)
2086 if templ_7745c5c3_Err != nil {2092 if templ_7745c5c3_Err != nil {
2087- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 397, Col: 68}2093+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 401, Col: 68}
2088 }2094 }
2089 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var99))2095 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var99))
2090 if templ_7745c5c3_Err != nil {2096 if templ_7745c5c3_Err != nil {
2091 return templ_7745c5c3_Err2097 return templ_7745c5c3_Err
2092 }2098 }
2093- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "</td>")2099+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "</td>")
2094 if templ_7745c5c3_Err != nil {2100 if templ_7745c5c3_Err != nil {
2095 return templ_7745c5c3_Err2101 return templ_7745c5c3_Err
2096 }2102 }
@@ -2099,7 +2105,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2099 if templ_7745c5c3_Err != nil {2105 if templ_7745c5c3_Err != nil {
2100 return templ_7745c5c3_Err2106 return templ_7745c5c3_Err
2101 }2107 }
2102- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "<td class=\"")2108+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "<td class=\"")
2103 if templ_7745c5c3_Err != nil {2109 if templ_7745c5c3_Err != nil {
2104 return templ_7745c5c3_Err2110 return templ_7745c5c3_Err
2105 }2111 }
@@ -2112,7 +2118,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2112 if templ_7745c5c3_Err != nil {2118 if templ_7745c5c3_Err != nil {
2113 return templ_7745c5c3_Err2119 return templ_7745c5c3_Err
2114 }2120 }
2115- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "\">")2121+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "\">")
2116 if templ_7745c5c3_Err != nil {2122 if templ_7745c5c3_Err != nil {
2117 return templ_7745c5c3_Err2123 return templ_7745c5c3_Err
2118 }2124 }
@@ -2120,7 +2126,7 @@ func splitSide(ln *DiffLine, old bool) templ.Component {
2120 if templ_7745c5c3_Err != nil {2126 if templ_7745c5c3_Err != nil {
2121 return templ_7745c5c3_Err2127 return templ_7745c5c3_Err
2122 }2128 }
2123- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "</td>")2129+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, "</td>")
2124 if templ_7745c5c3_Err != nil {2130 if templ_7745c5c3_Err != nil {
2125 return templ_7745c5c3_Err2131 return templ_7745c5c3_Err
2126 }2132 }
@@ -2153,33 +2159,33 @@ func gutter(n, href string) templ.Component {
2153 }2159 }
2154 ctx = templ.ClearChildren(ctx)2160 ctx = templ.ClearChildren(ctx)
2155 if href != "" {2161 if href != "" {
2156- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, "<a href=\"")2162+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "<a href=\"")
2157 if templ_7745c5c3_Err != nil {2163 if templ_7745c5c3_Err != nil {
2158 return templ_7745c5c3_Err2164 return templ_7745c5c3_Err
2159 }2165 }
2160 var templ_7745c5c3_Var103 templ.SafeURL2166 var templ_7745c5c3_Var103 templ.SafeURL
2161 templ_7745c5c3_Var103, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(href))2167 templ_7745c5c3_Var103, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(href))
2162 if templ_7745c5c3_Err != nil {2168 if templ_7745c5c3_Err != nil {
2163- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 406, Col: 31}2169+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 410, Col: 31}
2164 }2170 }
2165 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var103))2171 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var103))
2166 if templ_7745c5c3_Err != nil {2172 if templ_7745c5c3_Err != nil {
2167 return templ_7745c5c3_Err2173 return templ_7745c5c3_Err
2168 }2174 }
2169- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "\" title=\"comment on this line\">")2175+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, "\" title=\"comment on this line\">")
2170 if templ_7745c5c3_Err != nil {2176 if templ_7745c5c3_Err != nil {
2171 return templ_7745c5c3_Err2177 return templ_7745c5c3_Err
2172 }2178 }
2173 var templ_7745c5c3_Var104 string2179 var templ_7745c5c3_Var104 string
2174 templ_7745c5c3_Var104, templ_7745c5c3_Err = templ.JoinStringErrs(n)2180 templ_7745c5c3_Var104, templ_7745c5c3_Err = templ.JoinStringErrs(n)
2175 if templ_7745c5c3_Err != nil {2181 if templ_7745c5c3_Err != nil {
2176- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 406, Col: 66}2182+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 410, Col: 66}
2177 }2183 }
2178 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var104))2184 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var104))
2179 if templ_7745c5c3_Err != nil {2185 if templ_7745c5c3_Err != nil {
2180 return templ_7745c5c3_Err2186 return templ_7745c5c3_Err
2181 }2187 }
2182- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, "</a>")2188+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 191, "</a>")
2183 if templ_7745c5c3_Err != nil {2189 if templ_7745c5c3_Err != nil {
2184 return templ_7745c5c3_Err2190 return templ_7745c5c3_Err
2185 }2191 }
@@ -2187,7 +2193,7 @@ func gutter(n, href string) templ.Component {
2187 var templ_7745c5c3_Var105 string2193 var templ_7745c5c3_Var105 string
2188 templ_7745c5c3_Var105, templ_7745c5c3_Err = templ.JoinStringErrs(n)2194 templ_7745c5c3_Var105, templ_7745c5c3_Err = templ.JoinStringErrs(n)
2189 if templ_7745c5c3_Err != nil {2195 if templ_7745c5c3_Err != nil {
2190- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 408, Col: 5}2196+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/diff.templ`, Line: 412, Col: 5}
2191 }2197 }
2192 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var105))2198 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var105))
2193 if templ_7745c5c3_Err != nil {2199 if templ_7745c5c3_Err != nil {
M internal/adapters/web/jstest/a11y.test.mjs +23 -0
@@ -358,3 +358,26 @@ test('activity moves a home row up only in newest activity order, preserving foc
358358 assert.ok(fresh.hasAttribute('data-cursor'));
359359 }
360360 });
361+
362+test('mobile MR layout shortcuts preserve the saved preference until back on desktop', () => {
363+ const diffs = el('div', { id: 'diffs', attrs: { 'data-mr': '', 'data-diff': 'split', 'data-mobile': 'true' } });
364+ dom.body.replaceChildren(diffs);
365+ const oldQuery = doc.querySelector;
366+ doc.querySelector = query.one;
367+ const previous = globalThis.sessionStorage;
368+ const writes = [];
369+ globalThis.sessionStorage = { setItem: (...args) => writes.push(args) };
370+ try {
371+ window.ermite.layout('unified');
372+ window.ermite.layout('split');
373+ assert.equal(diffs.dataset.diff, 'split');
374+ assert.deepEqual(writes, []);
375+ diffs.dataset.mobile = 'false';
376+ window.ermite.layout('unified');
377+ assert.equal(diffs.dataset.diff, 'unified');
378+ assert.deepEqual(writes, [['diff', 'unified']]);
379+ } finally {
380+ globalThis.sessionStorage = previous;
381+ doc.querySelector = oldQuery;
382+ }
383+});
@@ -358,3 +358,26 @@ test('activity moves a home row up only in newest activity order, preserving foc
358 assert.ok(fresh.hasAttribute('data-cursor'));358 assert.ok(fresh.hasAttribute('data-cursor'));
359 }359 }
360 });360 });
361+
362+test('mobile MR layout shortcuts preserve the saved preference until back on desktop', () => {
363+ const diffs = el('div', { id: 'diffs', attrs: { 'data-mr': '', 'data-diff': 'split', 'data-mobile': 'true' } });
364+ dom.body.replaceChildren(diffs);
365+ const oldQuery = doc.querySelector;
366+ doc.querySelector = query.one;
367+ const previous = globalThis.sessionStorage;
368+ const writes = [];
369+ globalThis.sessionStorage = { setItem: (...args) => writes.push(args) };
370+ try {
371+ window.ermite.layout('unified');
372+ window.ermite.layout('split');
373+ assert.equal(diffs.dataset.diff, 'split');
374+ assert.deepEqual(writes, []);
375+ diffs.dataset.mobile = 'false';
376+ window.ermite.layout('unified');
377+ assert.equal(diffs.dataset.diff, 'unified');
378+ assert.deepEqual(writes, [['diff', 'unified']]);
379+ } finally {
380+ globalThis.sessionStorage = previous;
381+ doc.querySelector = oldQuery;
382+ }
383+});
M internal/adapters/web/jstest/mr.test.mjs +106 -0
@@ -92,3 +92,109 @@ for (const dataset of [{diff:'split'}, {view:'split'}]) test(`reveal selects the
9292 globalThis.requestAnimationFrame=savedRAF;
9393 }
9494 });
95+
96+test('touch range: first tap anchors, second tap opens the sorted range', () => {
97+ const base = 'https://forge.test/demo/merge-requests/1';
98+ const first = base + '?on=new:24:a.go#f1';
99+ const last = base + '?on=new:10:a.go#f1';
100+ assert.deepEqual(C.touchRange(null, first, base), { start: first, url: null });
101+ const result = C.touchRange(first, last, base);
102+ assert.equal(result.start, null);
103+ assert.equal(new URL(result.url).searchParams.get('on'), 'new:10-24:a.go');
104+ assert.deepEqual(C.touchRange(first, first, base), { start: null, url: first });
105+});
106+
107+test('touch range: a different file, side or request becomes a new anchor', () => {
108+ const base = 'https://forge.test/demo/merge-requests/1';
109+ const first = base + '?on=new:24:a.go#f1';
110+ for (const next of [first.replace('new:', 'old:'), first.replace('a.go', 'b.go'), first.replace('/1?', '/2?')]) {
111+ assert.deepEqual(C.touchRange(first, next, base), { start: next, url: null });
112+ }
113+});
114+
115+test('mobile unified fallback only redirects single-layout split pages and preserves query/hash', () => {
116+ const href = 'https://forge.test/demo/merge-requests/1?view=split&from=25&on=new:3:a.go#f26';
117+ assert.equal(C.mobileURL(href, 'split', false), null);
118+ assert.equal(C.mobileURL(href, undefined, true), null, 'both layouts are switched by CSS');
119+ assert.equal(C.mobileURL(href, 'unified', true), null, 'no redirect loop');
120+ const url = new URL(C.mobileURL(href, 'split', true));
121+ assert.equal(url.searchParams.get('view'), 'unified');
122+ assert.equal(url.searchParams.get('from'), '25');
123+ assert.equal(url.searchParams.get('on'), 'new:3:a.go');
124+ assert.equal(url.hash, '#f26');
125+});
126+
127+test('touch control: lazy links enable toolbar; ordinary taps pass through; ranges navigate and cancel', async () => {
128+ const saved = Object.fromEntries(['document', 'location', 'addEventListener', 'localStorage', 'sessionStorage', 'fetch', 'matchMedia'].map((k) => [k, globalThis[k]]));
129+ const make = () => ({
130+ attrs: {}, events: {}, children: [], textContent: '',
131+ setAttribute(k, v) { this.attrs[k] = v; },
132+ removeAttribute(k) { delete this.attrs[k]; },
133+ addEventListener(k, fn) { this.events[k] = fn; },
134+ append(...nodes) { this.children.push(...nodes); },
135+ prepend(node) { this.children.unshift(node); },
136+ querySelector() { return null; }, querySelectorAll() { return []; },
137+ });
138+ const diffs = make();
139+ diffs.dataset = { diff: 'split' };
140+ const base = 'https://forge.test/demo/merge-requests/1';
141+ const line = (n) => Object.assign(make(), { href: `${base}?on=new:${n}:a.go#f1`, textContent: String(n) });
142+ const a = line(20), b = line(10);
143+ let loaded = false;
144+ diffs.querySelector = () => loaded ? a : null;
145+ let assigned = null;
146+ globalThis.document = {
147+ querySelector: (sel) => sel === '#diffs[data-mr]' || sel === '#diffs' ? diffs : null,
148+ querySelectorAll: () => [], createElement: (tag) => tag === 'template' ? { content: { querySelectorAll: () => [] } } : make(),
149+ };
150+ globalThis.location = { href: base, pathname: '/demo/merge-requests/1', hash: '', assign(url) { assigned = url; } };
151+ globalThis.addEventListener = () => {};
152+ let resize;
153+ const media = { matches: true, addEventListener(type, fn) { resize = fn; } };
154+ globalThis.matchMedia = () => media;
155+ globalThis.fetch = async () => { loaded = true; return { ok: true, status: 200, text: async () => '' }; };
156+ globalThis.localStorage = globalThis.sessionStorage = { getItem: () => null };
157+ const click = (link, modifiers = {}) => {
158+ const e = { target: { closest: () => link }, prevented: false, stopped: false,
159+ preventDefault() { this.prevented = true; }, stopPropagation() { this.stopped = true; }, ...modifiers };
160+ diffs.events.click(e);
161+ return e;
162+ };
163+ try {
164+ window.ermiteMR.start();
165+ const bar = diffs.children[0];
166+ const [button, status] = bar.children;
167+ assert.equal(bar.hidden, true, 'no commentable links in the initial window');
168+ assert.equal(typeof diffs.events.click, 'function', 'delegation installed before lazy load');
169+ await window.ermiteMR.load({ dataset: { src: '/files?from=25' } });
170+ assert.equal(bar.hidden, false, 'lazy window refresh reveals range control');
171+ assert.equal(diffs.dataset.mobile, 'true');
172+ assert.equal(diffs.dataset.diff, 'split', 'preferred layout is retained');
173+ media.matches = false;
174+ resize();
175+ assert.equal(diffs.dataset.mobile, 'false', 'desktop menu returns to preferred layout');
176+ assert.equal(diffs.dataset.diff, 'split');
177+ assert.equal(click(a).prevented, false, 'normal single-line navigation is untouched');
178+ button.events.click();
179+ assert.equal(button.attrs['aria-pressed'], 'true');
180+ assert.equal(click(a, { shiftKey: true }).prevented, false, 'desktop range selection is untouched');
181+ const event = click(a);
182+ assert.equal(event.prevented, true);
183+ assert.equal(event.stopped, true);
184+ assert.ok('data-range-start' in a.attrs);
185+ assert.match(status.textContent, /20/);
186+ click(b);
187+ assert.equal(new URL(assigned).searchParams.get('on'), 'new:10-20:a.go');
188+ assert.equal('data-range-start' in a.attrs, false);
189+ click(a);
190+ button.events.click();
191+ assert.equal(button.attrs['aria-pressed'], 'false');
192+ assert.equal(status.textContent, '');
193+ assert.equal('data-range-start' in a.attrs, false);
194+ assert.equal(click(b).prevented, false);
195+ } finally {
196+ for (const [k, v] of Object.entries(saved)) {
197+ if (v === undefined) delete globalThis[k]; else globalThis[k] = v;
198+ }
199+ }
200+});
@@ -92,3 +92,109 @@ for (const dataset of [{diff:'split'}, {view:'split'}]) test(`reveal selects the
92 globalThis.requestAnimationFrame=savedRAF;92 globalThis.requestAnimationFrame=savedRAF;
93 }93 }
94 });94 });
95+
96+test('touch range: first tap anchors, second tap opens the sorted range', () => {
97+ const base = 'https://forge.test/demo/merge-requests/1';
98+ const first = base + '?on=new:24:a.go#f1';
99+ const last = base + '?on=new:10:a.go#f1';
100+ assert.deepEqual(C.touchRange(null, first, base), { start: first, url: null });
101+ const result = C.touchRange(first, last, base);
102+ assert.equal(result.start, null);
103+ assert.equal(new URL(result.url).searchParams.get('on'), 'new:10-24:a.go');
104+ assert.deepEqual(C.touchRange(first, first, base), { start: null, url: first });
105+});
106+
107+test('touch range: a different file, side or request becomes a new anchor', () => {
108+ const base = 'https://forge.test/demo/merge-requests/1';
109+ const first = base + '?on=new:24:a.go#f1';
110+ for (const next of [first.replace('new:', 'old:'), first.replace('a.go', 'b.go'), first.replace('/1?', '/2?')]) {
111+ assert.deepEqual(C.touchRange(first, next, base), { start: next, url: null });
112+ }
113+});
114+
115+test('mobile unified fallback only redirects single-layout split pages and preserves query/hash', () => {
116+ const href = 'https://forge.test/demo/merge-requests/1?view=split&from=25&on=new:3:a.go#f26';
117+ assert.equal(C.mobileURL(href, 'split', false), null);
118+ assert.equal(C.mobileURL(href, undefined, true), null, 'both layouts are switched by CSS');
119+ assert.equal(C.mobileURL(href, 'unified', true), null, 'no redirect loop');
120+ const url = new URL(C.mobileURL(href, 'split', true));
121+ assert.equal(url.searchParams.get('view'), 'unified');
122+ assert.equal(url.searchParams.get('from'), '25');
123+ assert.equal(url.searchParams.get('on'), 'new:3:a.go');
124+ assert.equal(url.hash, '#f26');
125+});
126+
127+test('touch control: lazy links enable toolbar; ordinary taps pass through; ranges navigate and cancel', async () => {
128+ const saved = Object.fromEntries(['document', 'location', 'addEventListener', 'localStorage', 'sessionStorage', 'fetch', 'matchMedia'].map((k) => [k, globalThis[k]]));
129+ const make = () => ({
130+ attrs: {}, events: {}, children: [], textContent: '',
131+ setAttribute(k, v) { this.attrs[k] = v; },
132+ removeAttribute(k) { delete this.attrs[k]; },
133+ addEventListener(k, fn) { this.events[k] = fn; },
134+ append(...nodes) { this.children.push(...nodes); },
135+ prepend(node) { this.children.unshift(node); },
136+ querySelector() { return null; }, querySelectorAll() { return []; },
137+ });
138+ const diffs = make();
139+ diffs.dataset = { diff: 'split' };
140+ const base = 'https://forge.test/demo/merge-requests/1';
141+ const line = (n) => Object.assign(make(), { href: `${base}?on=new:${n}:a.go#f1`, textContent: String(n) });
142+ const a = line(20), b = line(10);
143+ let loaded = false;
144+ diffs.querySelector = () => loaded ? a : null;
145+ let assigned = null;
146+ globalThis.document = {
147+ querySelector: (sel) => sel === '#diffs[data-mr]' || sel === '#diffs' ? diffs : null,
148+ querySelectorAll: () => [], createElement: (tag) => tag === 'template' ? { content: { querySelectorAll: () => [] } } : make(),
149+ };
150+ globalThis.location = { href: base, pathname: '/demo/merge-requests/1', hash: '', assign(url) { assigned = url; } };
151+ globalThis.addEventListener = () => {};
152+ let resize;
153+ const media = { matches: true, addEventListener(type, fn) { resize = fn; } };
154+ globalThis.matchMedia = () => media;
155+ globalThis.fetch = async () => { loaded = true; return { ok: true, status: 200, text: async () => '' }; };
156+ globalThis.localStorage = globalThis.sessionStorage = { getItem: () => null };
157+ const click = (link, modifiers = {}) => {
158+ const e = { target: { closest: () => link }, prevented: false, stopped: false,
159+ preventDefault() { this.prevented = true; }, stopPropagation() { this.stopped = true; }, ...modifiers };
160+ diffs.events.click(e);
161+ return e;
162+ };
163+ try {
164+ window.ermiteMR.start();
165+ const bar = diffs.children[0];
166+ const [button, status] = bar.children;
167+ assert.equal(bar.hidden, true, 'no commentable links in the initial window');
168+ assert.equal(typeof diffs.events.click, 'function', 'delegation installed before lazy load');
169+ await window.ermiteMR.load({ dataset: { src: '/files?from=25' } });
170+ assert.equal(bar.hidden, false, 'lazy window refresh reveals range control');
171+ assert.equal(diffs.dataset.mobile, 'true');
172+ assert.equal(diffs.dataset.diff, 'split', 'preferred layout is retained');
173+ media.matches = false;
174+ resize();
175+ assert.equal(diffs.dataset.mobile, 'false', 'desktop menu returns to preferred layout');
176+ assert.equal(diffs.dataset.diff, 'split');
177+ assert.equal(click(a).prevented, false, 'normal single-line navigation is untouched');
178+ button.events.click();
179+ assert.equal(button.attrs['aria-pressed'], 'true');
180+ assert.equal(click(a, { shiftKey: true }).prevented, false, 'desktop range selection is untouched');
181+ const event = click(a);
182+ assert.equal(event.prevented, true);
183+ assert.equal(event.stopped, true);
184+ assert.ok('data-range-start' in a.attrs);
185+ assert.match(status.textContent, /20/);
186+ click(b);
187+ assert.equal(new URL(assigned).searchParams.get('on'), 'new:10-20:a.go');
188+ assert.equal('data-range-start' in a.attrs, false);
189+ click(a);
190+ button.events.click();
191+ assert.equal(button.attrs['aria-pressed'], 'false');
192+ assert.equal(status.textContent, '');
193+ assert.equal('data-range-start' in a.attrs, false);
194+ assert.equal(click(b).prevented, false);
195+ } finally {
196+ for (const [k, v] of Object.entries(saved)) {
197+ if (v === undefined) delete globalThis[k]; else globalThis[k] = v;
198+ }
199+ }
200+});
A internal/adapters/web/static/css/85-mobile.css +51 -0
@@ -0,0 +1,51 @@
1+@layer components {
2+ .mr-touch-range { display: none; }
3+
4+ /* MR only: retain the shell's desktop layout and other pages' spacing. */
5+ @media (max-width: 720px) {
6+ body:has(#diffs[data-mr]) {
7+ --pad: 0px;
8+ --hdr-h: 97px;
9+ overflow-x: clip;
10+ }
11+ body:has(#diffs[data-mr]) .work { padding-inline: 0; margin-inline: 0; gap: var(--s3); }
12+ body:has(#diffs[data-mr]) main { min-width: 0; padding-inline: 0; }
13+ body:has(#diffs[data-mr]) :is(.card, .mr-card, .mr-desc, .dfile, .dscroll, .code, .rail section) {
14+ margin-inline: 0; border-inline: 0; border-radius: 0; min-width: 0; max-width: 100%;
15+ }
16+ body:has(#diffs[data-mr]) :is(.mr-h, .mr-desc.prose, .card-h) { padding-inline: 4px; }
17+ body:has(#diffs[data-mr]) .mr-desc.prose > pre { margin-inline: -4px; padding-inline: 0; max-width: calc(100% + 8px); }
18+ #diffs[data-mr] .dfile > summary { padding-inline: 0; border-inline: 0; border-radius: 0; }
19+ #diffs[data-mr] :is(.dscroll, .code) { overflow-x: auto; overscroll-behavior-x: contain; padding-inline: 0; }
20+ #diffs[data-mr] .dt .ln { width: calc(var(--lnw) + .5ch); min-width: calc(var(--lnw) + .5ch); padding-inline: .25ch; }
21+ #diffs[data-mr] .dt .m { width: 1ch; }
22+ #diffs[data-mr][data-diff] .uni { display: table; }
23+ #diffs[data-mr][data-diff] .spl { display: none; }
24+ #diffs[data-mr] .fnote td { padding-inline: 0; }
25+ #diffs[data-mr] :is(.cform, .cmt) { width: min(65ch, calc(100vw - 5rem)); max-width: calc(100vw - 5rem); overflow-wrap: anywhere; }
26+ body:has(#diffs[data-mr]) :is(input, textarea, select) { font-size: 16px; }
27+ body:has(#diffs[data-mr]) .f-btns { flex-wrap: wrap; }
28+ body:has(#diffs[data-mr]) .menu .menu-pop {
29+ position: fixed; inset: auto 0 0; width: auto; max-width: 100%;
30+ max-height: 75dvh; overflow-y: auto; border-radius: var(--r) var(--r) 0 0;
31+ padding-bottom: max(var(--s4), env(safe-area-inset-bottom));
32+ }
33+ body:has(#diffs[data-mr]) .mr-bar { position: static; }
34+ /* A wrapping toolbar has no reliable fixed sticky height. */
35+ body:has(#diffs[data-mr]) { --bar-h: 0px; }
36+ }
37+
38+ @media (pointer: coarse), (hover: none) {
39+ .mr-touch-range { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
40+ /* Real, disjoint cells: never expand invisible targets into other lines
41+ or into the neighbouring old/new gutter. */
42+ #diffs[data-mr] .dt { line-height: max(var(--lh-code), 40px); }
43+ #diffs[data-mr] .dt .ln { width: max(calc(var(--lnw) + .5ch), 40px); min-width: 40px; padding: 0; }
44+ #diffs[data-mr] .spl .c-ln { width: max(calc(var(--lnw) + .5ch), 40px); }
45+ #diffs[data-mr] .ln a { display: block; width: 100%; min-height: 40px; text-align: center; text-decoration: underline; }
46+ .mr-touch-range[hidden] { display: none; }
47+ #diffs[data-mr] .ln a[data-range-start] { outline: 2px solid var(--focus); background: var(--sel); }
48+ body:has(#diffs[data-mr]) :is(.cform .btn, .menu .btn, .mr-touch-range .btn, .c-act button) { min-height: 40px; height: auto; padding-block: var(--s2); }
49+ #diffs[data-mr] .cform { scroll-margin-block: calc(var(--hdr-h) + 12px); }
50+ }
51+}
@@ -0,0 +1,51 @@
1+@layer components {
2+ .mr-touch-range { display: none; }
3+
4+ /* MR only: retain the shell's desktop layout and other pages' spacing. */
5+ @media (max-width: 720px) {
6+ body:has(#diffs[data-mr]) {
7+ --pad: 0px;
8+ --hdr-h: 97px;
9+ overflow-x: clip;
10+ }
11+ body:has(#diffs[data-mr]) .work { padding-inline: 0; margin-inline: 0; gap: var(--s3); }
12+ body:has(#diffs[data-mr]) main { min-width: 0; padding-inline: 0; }
13+ body:has(#diffs[data-mr]) :is(.card, .mr-card, .mr-desc, .dfile, .dscroll, .code, .rail section) {
14+ margin-inline: 0; border-inline: 0; border-radius: 0; min-width: 0; max-width: 100%;
15+ }
16+ body:has(#diffs[data-mr]) :is(.mr-h, .mr-desc.prose, .card-h) { padding-inline: 4px; }
17+ body:has(#diffs[data-mr]) .mr-desc.prose > pre { margin-inline: -4px; padding-inline: 0; max-width: calc(100% + 8px); }
18+ #diffs[data-mr] .dfile > summary { padding-inline: 0; border-inline: 0; border-radius: 0; }
19+ #diffs[data-mr] :is(.dscroll, .code) { overflow-x: auto; overscroll-behavior-x: contain; padding-inline: 0; }
20+ #diffs[data-mr] .dt .ln { width: calc(var(--lnw) + .5ch); min-width: calc(var(--lnw) + .5ch); padding-inline: .25ch; }
21+ #diffs[data-mr] .dt .m { width: 1ch; }
22+ #diffs[data-mr][data-diff] .uni { display: table; }
23+ #diffs[data-mr][data-diff] .spl { display: none; }
24+ #diffs[data-mr] .fnote td { padding-inline: 0; }
25+ #diffs[data-mr] :is(.cform, .cmt) { width: min(65ch, calc(100vw - 5rem)); max-width: calc(100vw - 5rem); overflow-wrap: anywhere; }
26+ body:has(#diffs[data-mr]) :is(input, textarea, select) { font-size: 16px; }
27+ body:has(#diffs[data-mr]) .f-btns { flex-wrap: wrap; }
28+ body:has(#diffs[data-mr]) .menu .menu-pop {
29+ position: fixed; inset: auto 0 0; width: auto; max-width: 100%;
30+ max-height: 75dvh; overflow-y: auto; border-radius: var(--r) var(--r) 0 0;
31+ padding-bottom: max(var(--s4), env(safe-area-inset-bottom));
32+ }
33+ body:has(#diffs[data-mr]) .mr-bar { position: static; }
34+ /* A wrapping toolbar has no reliable fixed sticky height. */
35+ body:has(#diffs[data-mr]) { --bar-h: 0px; }
36+ }
37+
38+ @media (pointer: coarse), (hover: none) {
39+ .mr-touch-range { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
40+ /* Real, disjoint cells: never expand invisible targets into other lines
41+ or into the neighbouring old/new gutter. */
42+ #diffs[data-mr] .dt { line-height: max(var(--lh-code), 40px); }
43+ #diffs[data-mr] .dt .ln { width: max(calc(var(--lnw) + .5ch), 40px); min-width: 40px; padding: 0; }
44+ #diffs[data-mr] .spl .c-ln { width: max(calc(var(--lnw) + .5ch), 40px); }
45+ #diffs[data-mr] .ln a { display: block; width: 100%; min-height: 40px; text-align: center; text-decoration: underline; }
46+ .mr-touch-range[hidden] { display: none; }
47+ #diffs[data-mr] .ln a[data-range-start] { outline: 2px solid var(--focus); background: var(--sel); }
48+ body:has(#diffs[data-mr]) :is(.cform .btn, .menu .btn, .mr-touch-range .btn, .c-act button) { min-height: 40px; height: auto; padding-block: var(--s2); }
49+ #diffs[data-mr] .cform { scroll-margin-block: calc(var(--hdr-h) + 12px); }
50+ }
51+}
M internal/adapters/web/static/js/ermite.js +1 -0
@@ -183,6 +183,7 @@
183183 layout(mode) {
184184 const el = $('[data-diff]');
185185 if (!el) return;
186+ if (el.hasAttribute('data-mr') && el.dataset.mobile === 'true') return;
186187 el.dataset.diff = mode;
187188 try { sessionStorage.setItem('diff', mode); } catch { /* storage refused: the layout holds for this page */ }
188189 for (const d of $$('[data-file]')) if ($('.dt', d)) d.open = true;
@@ -183,6 +183,7 @@
183 layout(mode) {183 layout(mode) {
184 const el = $('[data-diff]');184 const el = $('[data-diff]');
185 if (!el) return;185 if (!el) return;
186+ if (el.hasAttribute('data-mr') && el.dataset.mobile === 'true') return;
186 el.dataset.diff = mode;187 el.dataset.diff = mode;
187 try { sessionStorage.setItem('diff', mode); } catch { /* storage refused: the layout holds for this page */ }188 try { sessionStorage.setItem('diff', mode); } catch { /* storage refused: the layout holds for this page */ }
188 for (const d of $$('[data-file]')) if ($('.dt', d)) d.open = true;189 for (const d of $$('[data-file]')) if ($('.dt', d)) d.open = true;
M internal/adapters/web/static/js/mr.js +79 -1
@@ -27,6 +27,20 @@ window.ermiteMR = (() => {
2727 b.searchParams.set('on', `${y[1]}:${nums[0]}-${nums[1]}:${y[3]}`);
2828 return b.href;
2929 },
30+ // Range mode is explicit: ordinary taps still open single-line forms.
31+ touchRange(previous, current, base) {
32+ if (!previous) return { start: current, url: null };
33+ const url = core.rangeURL(previous, current, base);
34+ if (url) return { start: null, url };
35+ if (previous === current) return { start: null, url: current };
36+ return { start: current, url: null }; // another file/side starts afresh
37+ },
38+ mobileURL(href, view, narrow) {
39+ if (!narrow || view !== 'split') return null;
40+ const url = new URL(href);
41+ url.searchParams.set('view', 'unified');
42+ return url.href;
43+ },
3044 quote(button) {
3145 const thread = button.closest('.cmt').closest('[data-thread]');
3246 const details = thread?.querySelector(':scope > details[data-reply]');
@@ -60,6 +74,7 @@ window.ermiteMR = (() => {
6074 const $ = (sel, root = document) => root.querySelector(sel);
6175 const $$ = (sel, root = document) => [...root.querySelectorAll(sel)];
6276 const loading = new Map(); // src -> promise of the swap
77+ let refreshTouchComments = () => {};
6378 let moved = false;
6479 let lazyIO = null; // the observer of the placeholders (watch)
6580 let revealGen = 0; // the last reveal wins the scroll
@@ -108,6 +123,7 @@ window.ermiteMR = (() => {
108123 window.htmx?.process(f);
109124 window.ermite?.watchFile?.(f, old);
110125 }
126+ refreshTouchComments();
111127 }
112128
113129 // stale: the diff changed under the page. The placeholders say so; no file
@@ -130,7 +146,7 @@ window.ermiteMR = (() => {
130146 // A page with both layouts says which shows in data-diff; a large diff
131147 // rendered in one layout only says it in data-view.
132148 const diffs = $('#diffs')?.dataset;
133- if (/^c\d+$/.test(id) && (diffs?.diff || diffs?.view) === 'split') {
149+ if (/^c\d+$/.test(id) && !window.matchMedia?.('(max-width: 720px)').matches && (diffs?.diff || diffs?.view) === 'split') {
134150 const split = document.getElementById(id + '-s');
135151 if (split) return split;
136152 }
@@ -285,8 +301,70 @@ window.ermiteMR = (() => {
285301 reveal(id);
286302 }
287303
304+ function touchComments() {
305+ const diffs = $('#diffs');
306+ const bar = document.createElement('div');
307+ bar.className = 'mr-touch-range';
308+ const button = document.createElement('button');
309+ button.type = 'button';
310+ button.className = 'btn';
311+ button.textContent = 'Select line range';
312+ button.setAttribute('aria-pressed', 'false');
313+ const status = document.createElement('span');
314+ status.setAttribute('role', 'status');
315+ bar.append(button, status);
316+ diffs.prepend(bar);
317+ refreshTouchComments = () => { bar.hidden = !$('.ln a[href*="on="]', diffs); };
318+ refreshTouchComments();
319+ let enabled = false, start = null, marker = null;
320+ const clear = () => { marker?.removeAttribute('data-range-start'); marker = null; start = null; };
321+ button.addEventListener('click', () => {
322+ enabled = !enabled;
323+ clear();
324+ button.setAttribute('aria-pressed', String(enabled));
325+ status.textContent = enabled ? 'Tap the first line number, then the last. Tap the same line for one line.' : '';
326+ });
327+ diffs.addEventListener('click', (e) => {
328+ const link = e.target.closest?.('.ln a[href*="on="]');
329+ if (!enabled || !link || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;
330+ e.preventDefault();
331+ e.stopPropagation(); // do not alter the desktop shift-click anchor
332+ const next = core.touchRange(start, link.href, location.href);
333+ clear();
334+ if (next.url) { location.assign(next.url); return; }
335+ start = next.start;
336+ marker = link;
337+ marker.setAttribute('data-range-start', '');
338+ status.textContent = `Range starts at line ${link.textContent.trim()}. Tap the last line number (same file and side).`;
339+ });
340+ // The server opens the line form. Scroll after layout without stealing
341+ // focus or forcing a mobile keyboard to appear.
342+ if (new URL(location.href).searchParams.has('on')) requestAnimationFrame(() => {
343+ const form = $$('.fnote .cform', diffs).find((f) => f.getClientRects().length);
344+ form?.scrollIntoView({ block: 'center' });
345+ });
346+ }
347+
288348 function start() {
289349 if (!$('#diffs[data-mr]')) return;
350+ // Large diffs may contain only the split table. Ask the existing server
351+ // route for unified rather than writing the saved session preference.
352+ const narrow = window.matchMedia?.('(max-width: 720px)');
353+ const unify = () => {
354+ $('#diffs').dataset.mobile = String(!!narrow?.matches);
355+ const url = core.mobileURL(location.href, $('#diffs')?.dataset.view, narrow?.matches);
356+ if (url) { location.replace(url); return true; }
357+ return false;
358+ };
359+ if (unify()) return;
360+ narrow?.addEventListener('change', unify);
361+ addEventListener('click', (e) => {
362+ if (narrow?.matches && e.target.closest?.('.vbtn[data-view="split"]')) {
363+ e.preventDefault();
364+ e.stopImmediatePropagation();
365+ }
366+ }, true);
367+ touchComments();
290368 let folded = false;
291369 try { folded = localStorage.getItem('mr-files-folded') === '1'; } catch { /* no storage: open */ }
292370 if (folded) foldFiles(true);
@@ -27,6 +27,20 @@ window.ermiteMR = (() => {
27 b.searchParams.set('on', `${y[1]}:${nums[0]}-${nums[1]}:${y[3]}`);27 b.searchParams.set('on', `${y[1]}:${nums[0]}-${nums[1]}:${y[3]}`);
28 return b.href;28 return b.href;
29 },29 },
30+ // Range mode is explicit: ordinary taps still open single-line forms.
31+ touchRange(previous, current, base) {
32+ if (!previous) return { start: current, url: null };
33+ const url = core.rangeURL(previous, current, base);
34+ if (url) return { start: null, url };
35+ if (previous === current) return { start: null, url: current };
36+ return { start: current, url: null }; // another file/side starts afresh
37+ },
38+ mobileURL(href, view, narrow) {
39+ if (!narrow || view !== 'split') return null;
40+ const url = new URL(href);
41+ url.searchParams.set('view', 'unified');
42+ return url.href;
43+ },
30 quote(button) {44 quote(button) {
31 const thread = button.closest('.cmt').closest('[data-thread]');45 const thread = button.closest('.cmt').closest('[data-thread]');
32 const details = thread?.querySelector(':scope > details[data-reply]');46 const details = thread?.querySelector(':scope > details[data-reply]');
@@ -60,6 +74,7 @@ window.ermiteMR = (() => {
60 const $ = (sel, root = document) => root.querySelector(sel);74 const $ = (sel, root = document) => root.querySelector(sel);
61 const $$ = (sel, root = document) => [...root.querySelectorAll(sel)];75 const $$ = (sel, root = document) => [...root.querySelectorAll(sel)];
62 const loading = new Map(); // src -> promise of the swap76 const loading = new Map(); // src -> promise of the swap
77+ let refreshTouchComments = () => {};
63 let moved = false;78 let moved = false;
64 let lazyIO = null; // the observer of the placeholders (watch)79 let lazyIO = null; // the observer of the placeholders (watch)
65 let revealGen = 0; // the last reveal wins the scroll80 let revealGen = 0; // the last reveal wins the scroll
@@ -108,6 +123,7 @@ window.ermiteMR = (() => {
108 window.htmx?.process(f);123 window.htmx?.process(f);
109 window.ermite?.watchFile?.(f, old);124 window.ermite?.watchFile?.(f, old);
110 }125 }
126+ refreshTouchComments();
111 }127 }
112 128
113 // stale: the diff changed under the page. The placeholders say so; no file129 // stale: the diff changed under the page. The placeholders say so; no file
@@ -130,7 +146,7 @@ window.ermiteMR = (() => {
130 // A page with both layouts says which shows in data-diff; a large diff146 // A page with both layouts says which shows in data-diff; a large diff
131 // rendered in one layout only says it in data-view.147 // rendered in one layout only says it in data-view.
132 const diffs = $('#diffs')?.dataset;148 const diffs = $('#diffs')?.dataset;
133- if (/^c\d+$/.test(id) && (diffs?.diff || diffs?.view) === 'split') {149+ if (/^c\d+$/.test(id) && !window.matchMedia?.('(max-width: 720px)').matches && (diffs?.diff || diffs?.view) === 'split') {
134 const split = document.getElementById(id + '-s');150 const split = document.getElementById(id + '-s');
135 if (split) return split;151 if (split) return split;
136 }152 }
@@ -285,8 +301,70 @@ window.ermiteMR = (() => {
285 reveal(id);301 reveal(id);
286 }302 }
287 303
304+ function touchComments() {
305+ const diffs = $('#diffs');
306+ const bar = document.createElement('div');
307+ bar.className = 'mr-touch-range';
308+ const button = document.createElement('button');
309+ button.type = 'button';
310+ button.className = 'btn';
311+ button.textContent = 'Select line range';
312+ button.setAttribute('aria-pressed', 'false');
313+ const status = document.createElement('span');
314+ status.setAttribute('role', 'status');
315+ bar.append(button, status);
316+ diffs.prepend(bar);
317+ refreshTouchComments = () => { bar.hidden = !$('.ln a[href*="on="]', diffs); };
318+ refreshTouchComments();
319+ let enabled = false, start = null, marker = null;
320+ const clear = () => { marker?.removeAttribute('data-range-start'); marker = null; start = null; };
321+ button.addEventListener('click', () => {
322+ enabled = !enabled;
323+ clear();
324+ button.setAttribute('aria-pressed', String(enabled));
325+ status.textContent = enabled ? 'Tap the first line number, then the last. Tap the same line for one line.' : '';
326+ });
327+ diffs.addEventListener('click', (e) => {
328+ const link = e.target.closest?.('.ln a[href*="on="]');
329+ if (!enabled || !link || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;
330+ e.preventDefault();
331+ e.stopPropagation(); // do not alter the desktop shift-click anchor
332+ const next = core.touchRange(start, link.href, location.href);
333+ clear();
334+ if (next.url) { location.assign(next.url); return; }
335+ start = next.start;
336+ marker = link;
337+ marker.setAttribute('data-range-start', '');
338+ status.textContent = `Range starts at line ${link.textContent.trim()}. Tap the last line number (same file and side).`;
339+ });
340+ // The server opens the line form. Scroll after layout without stealing
341+ // focus or forcing a mobile keyboard to appear.
342+ if (new URL(location.href).searchParams.has('on')) requestAnimationFrame(() => {
343+ const form = $$('.fnote .cform', diffs).find((f) => f.getClientRects().length);
344+ form?.scrollIntoView({ block: 'center' });
345+ });
346+ }
347+
288 function start() {348 function start() {
289 if (!$('#diffs[data-mr]')) return;349 if (!$('#diffs[data-mr]')) return;
350+ // Large diffs may contain only the split table. Ask the existing server
351+ // route for unified rather than writing the saved session preference.
352+ const narrow = window.matchMedia?.('(max-width: 720px)');
353+ const unify = () => {
354+ $('#diffs').dataset.mobile = String(!!narrow?.matches);
355+ const url = core.mobileURL(location.href, $('#diffs')?.dataset.view, narrow?.matches);
356+ if (url) { location.replace(url); return true; }
357+ return false;
358+ };
359+ if (unify()) return;
360+ narrow?.addEventListener('change', unify);
361+ addEventListener('click', (e) => {
362+ if (narrow?.matches && e.target.closest?.('.vbtn[data-view="split"]')) {
363+ e.preventDefault();
364+ e.stopImmediatePropagation();
365+ }
366+ }, true);
367+ touchComments();
290 let folded = false;368 let folded = false;
291 try { folded = localStorage.getItem('mr-files-folded') === '1'; } catch { /* no storage: open */ }369 try { folded = localStorage.getItem('mr-files-folded') === '1'; } catch { /* no storage: open */ }
292 if (folded) foldFiles(true);370 if (folded) foldFiles(true);
M internal/app/testdata/web/commit-big.html +3 -3
@@ -127,12 +127,12 @@
127127 </span>
128128 <details class="menu vmenu">
129129 <summary class="btn" aria-label="Diff view">
130-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
130+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
131131 </summary>
132132 <div class="menu-pop" role="group" aria-label="Diff view">
133-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
133+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
134134 </a>
135-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
135+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
136136 </a>
137137 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
138138 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -127,12 +127,12 @@
127 </span>127 </span>
128 <details class="menu vmenu">128 <details class="menu vmenu">
129 <summary class="btn" aria-label="Diff view">129 <summary class="btn" aria-label="Diff view">
130-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>130+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
131 </summary>131 </summary>
132 <div class="menu-pop" role="group" aria-label="Diff view">132 <div class="menu-pop" role="group" aria-label="Diff view">
133-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>133+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
134 </a>134 </a>
135-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>135+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
136 </a>136 </a>
137 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">137 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
138 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>138 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
M internal/app/testdata/web/commit-binary.html +3 -3
@@ -123,12 +123,12 @@
123123 </span>
124124 <details class="menu vmenu">
125125 <summary class="btn" aria-label="Diff view">
126-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
126+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
127127 </summary>
128128 <div class="menu-pop" role="group" aria-label="Diff view">
129-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
129+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
130130 </a>
131-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
131+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
132132 </a>
133133 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
134134 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -123,12 +123,12 @@
123 </span>123 </span>
124 <details class="menu vmenu">124 <details class="menu vmenu">
125 <summary class="btn" aria-label="Diff view">125 <summary class="btn" aria-label="Diff view">
126-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>126+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
127 </summary>127 </summary>
128 <div class="menu-pop" role="group" aria-label="Diff view">128 <div class="menu-pop" role="group" aria-label="Diff view">
129-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>129+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
130 </a>130 </a>
131-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>131+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
132 </a>132 </a>
133 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">133 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
134 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>134 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
M internal/app/testdata/web/commit-merge.html +3 -3
@@ -122,12 +122,12 @@
122122 </span>
123123 <details class="menu vmenu">
124124 <summary class="btn" aria-label="Diff view">
125-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
125+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
126126 </summary>
127127 <div class="menu-pop" role="group" aria-label="Diff view">
128-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
128+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
129129 </a>
130-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
130+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
131131 </a>
132132 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
133133 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -122,12 +122,12 @@
122 </span>122 </span>
123 <details class="menu vmenu">123 <details class="menu vmenu">
124 <summary class="btn" aria-label="Diff view">124 <summary class="btn" aria-label="Diff view">
125-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>125+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
126 </summary>126 </summary>
127 <div class="menu-pop" role="group" aria-label="Diff view">127 <div class="menu-pop" role="group" aria-label="Diff view">
128-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>128+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
129 </a>129 </a>
130-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>130+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
131 </a>131 </a>
132 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">132 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
133 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>133 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
M internal/app/testdata/web/commit-modify-split.html +3 -3
@@ -129,12 +129,12 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
129129 </span>
130130 <details class="menu vmenu">
131131 <summary class="btn" aria-label="Diff view">
132-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Split</span>
132+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Split</span>
133133 </summary>
134134 <div class="menu-pop" role="group" aria-label="Diff view">
135-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
135+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
136136 </a>
137-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" aria-current="true" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
137+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" aria-current="true" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
138138 </a>
139139 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
140140 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -129,12 +129,12 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
129 </span>129 </span>
130 <details class="menu vmenu">130 <details class="menu vmenu">
131 <summary class="btn" aria-label="Diff view">131 <summary class="btn" aria-label="Diff view">
132-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Split</span>132+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Split</span>
133 </summary>133 </summary>
134 <div class="menu-pop" role="group" aria-label="Diff view">134 <div class="menu-pop" role="group" aria-label="Diff view">
135-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>135+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
136 </a>136 </a>
137-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" aria-current="true" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>137+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" aria-current="true" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
138 </a>138 </a>
139 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">139 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
140 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>140 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
M internal/app/testdata/web/commit-modify.html +3 -3
@@ -129,12 +129,12 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
129129 </span>
130130 <details class="menu vmenu">
131131 <summary class="btn" aria-label="Diff view">
132-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
132+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
133133 </summary>
134134 <div class="menu-pop" role="group" aria-label="Diff view">
135-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
135+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
136136 </a>
137-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
137+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
138138 </a>
139139 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
140140 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -129,12 +129,12 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
129 </span>129 </span>
130 <details class="menu vmenu">130 <details class="menu vmenu">
131 <summary class="btn" aria-label="Diff view">131 <summary class="btn" aria-label="Diff view">
132-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>132+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
133 </summary>133 </summary>
134 <div class="menu-pop" role="group" aria-label="Diff view">134 <div class="menu-pop" role="group" aria-label="Diff view">
135-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>135+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
136 </a>136 </a>
137-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>137+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
138 </a>138 </a>
139 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">139 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
140 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>140 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
M internal/app/testdata/web/commit-rename.html +3 -3
@@ -123,12 +123,12 @@
123123 </span>
124124 <details class="menu vmenu">
125125 <summary class="btn" aria-label="Diff view">
126-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
126+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
127127 </summary>
128128 <div class="menu-pop" role="group" aria-label="Diff view">
129-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
129+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
130130 </a>
131-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
131+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
132132 </a>
133133 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
134134 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -123,12 +123,12 @@
123 </span>123 </span>
124 <details class="menu vmenu">124 <details class="menu vmenu">
125 <summary class="btn" aria-label="Diff view">125 <summary class="btn" aria-label="Diff view">
126-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>126+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
127 </summary>127 </summary>
128 <div class="menu-pop" role="group" aria-label="Diff view">128 <div class="menu-pop" role="group" aria-label="Diff view">
129-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>129+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
130 </a>130 </a>
131-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>131+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
132 </a>132 </a>
133 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">133 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
134 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>134 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
M internal/app/testdata/web/commit-root.html +3 -3
@@ -121,12 +121,12 @@
121121 </span>
122122 <details class="menu vmenu">
123123 <summary class="btn" aria-label="Diff view">
124-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
124+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
125125 </summary>
126126 <div class="menu-pop" role="group" aria-label="Diff view">
127-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
127+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
128128 </a>
129-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
129+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
130130 </a>
131131 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
132132 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -121,12 +121,12 @@
121 </span>121 </span>
122 <details class="menu vmenu">122 <details class="menu vmenu">
123 <summary class="btn" aria-label="Diff view">123 <summary class="btn" aria-label="Diff view">
124-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>124+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
125 </summary>125 </summary>
126 <div class="menu-pop" role="group" aria-label="Diff view">126 <div class="menu-pop" role="group" aria-label="Diff view">
127-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>127+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
128 </a>128 </a>
129-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>129+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
130 </a>130 </a>
131 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">131 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
132 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>132 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
M internal/app/testdata/web/commit-trojan.html +3 -3
@@ -124,12 +124,12 @@
124124 </span>
125125 <details class="menu vmenu">
126126 <summary class="btn" aria-label="Diff view">
127-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
127+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
128128 </summary>
129129 <div class="menu-pop" role="group" aria-label="Diff view">
130-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
130+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
131131 </a>
132-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
132+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
133133 </a>
134134 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
135135 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>
@@ -124,12 +124,12 @@
124 </span>124 </span>
125 <details class="menu vmenu">125 <details class="menu vmenu">
126 <summary class="btn" aria-label="Diff view">126 <summary class="btn" aria-label="Diff view">
127-<span hx-live="this.textContent = q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>127+<span hx-live="this.textContent = q('#diffs').attr['data-mobile'] !== 'true' && q('#diffs').attr['data-diff'] === 'split' ? 'Split' : 'Unified'">Unified</span>
128 </summary>128 </summary>
129 <div class="menu-pop" role="group" aria-label="Diff view">129 <div class="menu-pop" role="group" aria-label="Diff view">
130-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>130+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" data-fire="unified" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Unified<kbd aria-hidden="true">u</kbd>
131 </a>131 </a>
132-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" data-fire="split" :aria-current="q('#diffs').attr['data-diff'] === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>132+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" :aria-disabled="q('#diffs').attr['data-mobile'] === 'true' ? 'true' : false" :title="q('#diffs').attr['data-mobile'] === 'true' ? 'Split view requires a wider screen' : 'Split view'" data-fire="split" :aria-current="(q('#diffs').attr['data-mobile'] === 'true' ? 'unified' : q('#diffs').attr['data-diff']) === this.dataset.view ? 'true' : false">Split<kbd aria-hidden="true">d</kbd>
133 </a>133 </a>
134 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">134 <button type="button" aria-keyshortcuts="x" data-js data-fire="collapse" class="btn">
135 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>135 <span hx-live="this.textContent = q('[data-file][open]').count || !q('[data-file]').count ? 'Collapse all' : 'Expand all'">Collapse all</span>

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 3

Tags 43

↑↓ moveenter openesc close