detached e97c08e

feat(web): refresh the MR view in place when its source branch moves

A push to the source branch sends an mr-head event instead of the reload
banner. The page fetches itself, swaps the head-dependent regions, keeps
the reader's line, folds, tab and focus, and waits for unsent comments.
commit
e97c08ee5c24b3c1e3d6931238d9bd485833c889
author
brice · · 2026-10-20 05:43 UTC
parent
b46e8c1
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
19 files · +899 -450
M docs/merge-requests.md +14 -0
@@ -118,3 +118,17 @@ The rail keeps Files (including its `g f` shortcut) and Verdicts. Merge settings
118118 are read-only information in the More (⋯) menu, available to every viewer.
119119 Signing-key information is also there when a merge box offers signed modes;
120120 merge actions remain restricted to their existing permissions.
121+
122+## Live source-branch updates
123+
124+A push to the source branch refreshes the web review in place: the diff, files
125+rail, commits/checks footer, diff range and merge controls follow the new head.
126+The review keeps its visible file/line, folded files and selected footer tab.
127+The page request still reads only one 25-file window of hunks; the visible
128+anchor's window is fetched too if needed, and other windows remain lazy.
129+
130+While a comment is focused or has unsent edits, the refresh waits. A small
131+“branch updated” status offers **refresh now**, which also refreshes in place
132+and keeps unsent forms (including a comment whose old line disappeared).
133+Emptying or cancelling the draft lets the pending refresh proceed. Submitting
134+an ordinary comment navigates to the server's current review as usual.
@@ -118,3 +118,17 @@ The rail keeps Files (including its `g f` shortcut) and Verdicts. Merge settings
118 are read-only information in the More (⋯) menu, available to every viewer.118 are read-only information in the More (⋯) menu, available to every viewer.
119 Signing-key information is also there when a merge box offers signed modes;119 Signing-key information is also there when a merge box offers signed modes;
120 merge actions remain restricted to their existing permissions.120 merge actions remain restricted to their existing permissions.
121+
122+## Live source-branch updates
123+
124+A push to the source branch refreshes the web review in place: the diff, files
125+rail, commits/checks footer, diff range and merge controls follow the new head.
126+The review keeps its visible file/line, folded files and selected footer tab.
127+The page request still reads only one 25-file window of hunks; the visible
128+anchor's window is fetched too if needed, and other windows remain lazy.
129+
130+While a comment is focused or has unsent edits, the refresh waits. A small
131+“branch updated” status offers **refresh now**, which also refreshes in place
132+and keeps unsent forms (including a comment whose old line disappeared).
133+Emptying or cancelling the draft lets the pending refresh proceed. Submitting
134+an ordinary comment navigates to the server's current review as usual.
M internal/adapters/web/events.go +5 -1
@@ -31,7 +31,7 @@ import (
3131 // GET /-/events?topic=repo:<name>&view=summary|refs
3232 // GET /-/events?topic=repo:<name>&view=commits&ref=<branch>&head=<sha>
3333 // GET /-/events?topic=repo:<name>&view=mrs
34-// GET /-/events?topic=repo:<name>&view=mr&n=<number>&ref=<source branch>&target=<target branch>
34+// GET /-/events?topic=repo:<name>&view=mr&n=<number>&ref=<source branch>&head=<sha>&target=<target branch>
3535 // GET /-/events?topic=repo:<name>&view=issues
3636 // GET /-/events?topic=repo:<name>&view=issue&n=<number>
3737 // GET /-/events?topic=repo:<name>&view=actions
@@ -60,6 +60,10 @@ import (
6060 // the badge of the merge box (a slot like mr-notice), when the
6161 // mergeability of the request shown settles or a push moves its
6262 // source or target
63+// mr-head data: <div id="mr-head"></div>; the source branch moved.
64+// ermiteMR fetches the current page and refreshes its head-dependent
65+// regions in place, preserving the reader's position and drafts.
66+// The replacement stream uses the new head for CI filtering.
6367 // mr-notice data: <div id="mr-notice">…</div>, on the merge request and issue pages:
6468 // something changed, with the link that reloads the page
6569 // ci-run data: <tr id="run-<id>">…</tr> (the list of runs),
@@ -31,7 +31,7 @@ import (
31 // GET /-/events?topic=repo:<name>&view=summary|refs31 // GET /-/events?topic=repo:<name>&view=summary|refs
32 // GET /-/events?topic=repo:<name>&view=commits&ref=<branch>&head=<sha>32 // GET /-/events?topic=repo:<name>&view=commits&ref=<branch>&head=<sha>
33 // GET /-/events?topic=repo:<name>&view=mrs33 // GET /-/events?topic=repo:<name>&view=mrs
34-// GET /-/events?topic=repo:<name>&view=mr&n=<number>&ref=<source branch>&target=<target branch>34+// GET /-/events?topic=repo:<name>&view=mr&n=<number>&ref=<source branch>&head=<sha>&target=<target branch>
35 // GET /-/events?topic=repo:<name>&view=issues35 // GET /-/events?topic=repo:<name>&view=issues
36 // GET /-/events?topic=repo:<name>&view=issue&n=<number>36 // GET /-/events?topic=repo:<name>&view=issue&n=<number>
37 // GET /-/events?topic=repo:<name>&view=actions37 // GET /-/events?topic=repo:<name>&view=actions
@@ -60,6 +60,10 @@ import (
60 // the badge of the merge box (a slot like mr-notice), when the60 // the badge of the merge box (a slot like mr-notice), when the
61 // mergeability of the request shown settles or a push moves its61 // mergeability of the request shown settles or a push moves its
62 // source or target62 // source or target
63+// mr-head data: <div id="mr-head"></div>; the source branch moved.
64+// ermiteMR fetches the current page and refreshes its head-dependent
65+// regions in place, preserving the reader's position and drafts.
66+// The replacement stream uses the new head for CI filtering.
63 // mr-notice data: <div id="mr-notice">…</div>, on the merge request and issue pages:67 // mr-notice data: <div id="mr-notice">…</div>, on the merge request and issue pages:
64 // something changed, with the link that reloads the page68 // something changed, with the link that reloads the page
65 // ci-run data: <tr id="run-<id>">…</tr> (the list of runs),69 // ci-run data: <tr id="run-<id>">…</tr> (the list of runs),
M internal/adapters/web/events_test.go +24 -0
@@ -478,3 +478,27 @@ func TestCommitsBannerWithoutMergeRequests(t *testing.T) {
478478 require.Len(t, got, 1)
479479 assert.Contains(t, got[0].html, "the branch moved — reload")
480480 }
481+
482+func TestMRPushEventsKeepMergeability(t *testing.T) {
483+ t.Parallel()
484+ svc := mocks.NewMergeRequestService(t)
485+ svc.EXPECT().Mergeability(mock.Anything, mock.Anything, mock.Anything, int64(1)).
486+ Return(domain.Mergeability{State: domain.MergeabilityUpToDate}, nil).Twice()
487+ l := liveStream{s: &Server{cfg: Config{MergeRequests: svc}}, repo: "demo", view: "mr", n: "1", ref: "feature", target: "main"}
488+ ctx := context.WithValue(t.Context(), signedInKey{}, struct{}{})
489+ for _, ref := range []string{"feature", "main"} {
490+ fs, err := l.mrPushed(ctx, domain.PushEvent{Updates: []domain.RefUpdate{{Ref: "refs/heads/" + ref}}})
491+ require.NoError(t, err)
492+ if ref == "feature" {
493+ require.Len(t, fs, 2)
494+ assert.Equal(t, "mr-head", fs[0].event)
495+ assert.Equal(t, "event: mr-head\nid: b-1\ndata: <div id=\"mr-head\"></div>\n\n", formatEvent("b-1", fs[0].event, fs[0].html, true))
496+ } else {
497+ require.Len(t, fs, 1)
498+ }
499+ assert.Equal(t, "mr-mergeability", fs[len(fs)-1].event)
500+ for _, f := range fs {
501+ assert.NotEqual(t, "mr-notice", f.event)
502+ }
503+ }
504+}
@@ -478,3 +478,27 @@ func TestCommitsBannerWithoutMergeRequests(t *testing.T) {
478 require.Len(t, got, 1)478 require.Len(t, got, 1)
479 assert.Contains(t, got[0].html, "the branch moved — reload")479 assert.Contains(t, got[0].html, "the branch moved — reload")
480 }480 }
481+
482+func TestMRPushEventsKeepMergeability(t *testing.T) {
483+ t.Parallel()
484+ svc := mocks.NewMergeRequestService(t)
485+ svc.EXPECT().Mergeability(mock.Anything, mock.Anything, mock.Anything, int64(1)).
486+ Return(domain.Mergeability{State: domain.MergeabilityUpToDate}, nil).Twice()
487+ l := liveStream{s: &Server{cfg: Config{MergeRequests: svc}}, repo: "demo", view: "mr", n: "1", ref: "feature", target: "main"}
488+ ctx := context.WithValue(t.Context(), signedInKey{}, struct{}{})
489+ for _, ref := range []string{"feature", "main"} {
490+ fs, err := l.mrPushed(ctx, domain.PushEvent{Updates: []domain.RefUpdate{{Ref: "refs/heads/" + ref}}})
491+ require.NoError(t, err)
492+ if ref == "feature" {
493+ require.Len(t, fs, 2)
494+ assert.Equal(t, "mr-head", fs[0].event)
495+ assert.Equal(t, "event: mr-head\nid: b-1\ndata: <div id=\"mr-head\"></div>\n\n", formatEvent("b-1", fs[0].event, fs[0].html, true))
496+ } else {
497+ require.Len(t, fs, 1)
498+ }
499+ assert.Equal(t, "mr-mergeability", fs[len(fs)-1].event)
500+ for _, f := range fs {
501+ assert.NotEqual(t, "mr-notice", f.event)
502+ }
503+ }
504+}
M internal/adapters/web/fragments.go +2 -7
@@ -474,8 +474,7 @@ func (l *liveStream) issueNotice(ctx context.Context, number int64, text string)
474474 // mrPushed announces a push to the source branch of the merge request shown,
475475 // and has the badge follow a push to its source or its target.
476476 func (l *liveStream) mrPushed(ctx context.Context, p domain.PushEvent) ([]fragment, error) {
477- n, err := strconv.ParseInt(l.n, 10, 64)
478- if err != nil {
477+ if _, err := strconv.ParseInt(l.n, 10, 64); err != nil {
479478 return nil, nil
480479 }
481480 var out []fragment
@@ -483,11 +482,7 @@ func (l *liveStream) mrPushed(ctx context.Context, p domain.PushEvent) ([]fragme
483482 for _, u := range p.Updates {
484483 switch {
485484 case l.ref != "" && u.Ref == "refs/heads/"+l.ref:
486- notice, err := l.notice(ctx, "the branch changed — reload", mrHref(l.repo, n))
487- if err != nil {
488- return nil, err
489- }
490- out = append(out, notice...)
485+ out = append(out, fragment{event: "mr-head", html: `<div id="mr-head"></div>`})
491486 moved = true
492487 case l.target != "" && u.Ref == "refs/heads/"+l.target:
493488 moved = true
@@ -474,8 +474,7 @@ func (l *liveStream) issueNotice(ctx context.Context, number int64, text string)
474 // mrPushed announces a push to the source branch of the merge request shown,474 // mrPushed announces a push to the source branch of the merge request shown,
475 // and has the badge follow a push to its source or its target.475 // and has the badge follow a push to its source or its target.
476 func (l *liveStream) mrPushed(ctx context.Context, p domain.PushEvent) ([]fragment, error) {476 func (l *liveStream) mrPushed(ctx context.Context, p domain.PushEvent) ([]fragment, error) {
477- n, err := strconv.ParseInt(l.n, 10, 64)477+ if _, err := strconv.ParseInt(l.n, 10, 64); err != nil {
478- if err != nil {
479 return nil, nil478 return nil, nil
480 }479 }
481 var out []fragment480 var out []fragment
@@ -483,11 +482,7 @@ func (l *liveStream) mrPushed(ctx context.Context, p domain.PushEvent) ([]fragme
483 for _, u := range p.Updates {482 for _, u := range p.Updates {
484 switch {483 switch {
485 case l.ref != "" && u.Ref == "refs/heads/"+l.ref:484 case l.ref != "" && u.Ref == "refs/heads/"+l.ref:
486- notice, err := l.notice(ctx, "the branch changed — reload", mrHref(l.repo, n))485+ out = append(out, fragment{event: "mr-head", html: `<div id="mr-head"></div>`})
487- if err != nil {
488- return nil, err
489- }
490- out = append(out, notice...)
491 moved = true486 moved = true
492 case l.target != "" && u.Ref == "refs/heads/"+l.target:487 case l.target != "" && u.Ref == "refs/heads/"+l.target:
493 moved = true488 moved = true
M internal/adapters/web/fragments.templ +1 -0
@@ -103,6 +103,7 @@ templ Live(l Layout) {
103103 htmx:sse:error -> ermiteLive.error(event.detail.status);
104104 htmx:sse:before:connection -> ermiteLive.gate(event);
105105 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
106+ mr-head -> ermiteMR.headChanged();
106107 gap -> ermiteLive.reload()"
107108 ></span>
108109 }
@@ -103,6 +103,7 @@ templ Live(l Layout) {
103 htmx:sse:error -> ermiteLive.error(event.detail.status);103 htmx:sse:error -> ermiteLive.error(event.detail.status);
104 htmx:sse:before:connection -> ermiteLive.gate(event);104 htmx:sse:before:connection -> ermiteLive.gate(event);
105 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);105 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
106+ mr-head -> ermiteMR.headChanged();
106 gap -> ermiteLive.reload()"107 gap -> ermiteLive.reload()"
107 ></span>108 ></span>
108 }109 }
M internal/adapters/web/fragments_templ.go +1 -1 generated file: collapsed
M internal/adapters/web/fragments_test.go +22 -0
@@ -7,6 +7,8 @@ import (
77 "strings"
88 "testing"
99
10+ "bnema.dev/ermite/internal/domain"
11+
1012 "github.com/a-h/templ"
1113 "github.com/stretchr/testify/assert"
1214 "github.com/stretchr/testify/require"
@@ -77,3 +79,23 @@ func TestDiffControlsPassDataThroughAttributes(t *testing.T) {
7779 assert.Contains(t, link, `this.dataset.view`)
7880 assert.NotContains(t, link, "=== 'split'")
7981 }
82+
83+// The push signal is intentionally constant-sized: diff work belongs to the
84+// subsequent windowed page request, not to each subscriber's event handler.
85+func TestMRPushedHeadSignal(t *testing.T) {
86+ t.Parallel()
87+ l := liveStream{s: &Server{}, repo: "demo", view: "mr", n: "1", ref: "feature", target: "main"}
88+ for _, tt := range []struct {
89+ ref string
90+ want int
91+ }{{"refs/heads/feature", 1}, {"refs/heads/main", 0}, {"refs/heads/other", 0}} {
92+ fs, err := l.mrPushed(t.Context(), domain.PushEvent{Updates: []domain.RefUpdate{{Ref: tt.ref}}})
93+ require.NoError(t, err)
94+ require.Len(t, fs, tt.want)
95+ if tt.want > 0 {
96+ assert.Equal(t, "mr-head", fs[0].event)
97+ assert.Equal(t, `<div id="mr-head"></div>`, fs[0].html)
98+ assert.NotContains(t, fs[0].html, "the branch changed")
99+ }
100+ }
101+}
@@ -7,6 +7,8 @@ import (
7 "strings"7 "strings"
8 "testing"8 "testing"
9 9
10+ "bnema.dev/ermite/internal/domain"
11+
10 "github.com/a-h/templ"12 "github.com/a-h/templ"
11 "github.com/stretchr/testify/assert"13 "github.com/stretchr/testify/assert"
12 "github.com/stretchr/testify/require"14 "github.com/stretchr/testify/require"
@@ -77,3 +79,23 @@ func TestDiffControlsPassDataThroughAttributes(t *testing.T) {
77 assert.Contains(t, link, `this.dataset.view`)79 assert.Contains(t, link, `this.dataset.view`)
78 assert.NotContains(t, link, "=== 'split'")80 assert.NotContains(t, link, "=== 'split'")
79 }81 }
82+
83+// The push signal is intentionally constant-sized: diff work belongs to the
84+// subsequent windowed page request, not to each subscriber's event handler.
85+func TestMRPushedHeadSignal(t *testing.T) {
86+ t.Parallel()
87+ l := liveStream{s: &Server{}, repo: "demo", view: "mr", n: "1", ref: "feature", target: "main"}
88+ for _, tt := range []struct {
89+ ref string
90+ want int
91+ }{{"refs/heads/feature", 1}, {"refs/heads/main", 0}, {"refs/heads/other", 0}} {
92+ fs, err := l.mrPushed(t.Context(), domain.PushEvent{Updates: []domain.RefUpdate{{Ref: tt.ref}}})
93+ require.NoError(t, err)
94+ require.Len(t, fs, tt.want)
95+ if tt.want > 0 {
96+ assert.Equal(t, "mr-head", fs[0].event)
97+ assert.Equal(t, `<div id="mr-head"></div>`, fs[0].html)
98+ assert.NotContains(t, fs[0].html, "the branch changed")
99+ }
100+ }
101+}
M internal/adapters/web/jstest/mr.test.mjs +108 -0
@@ -300,3 +300,111 @@ test('touch control: lazy links enable toolbar; ordinary taps pass through; rang
300300 }
301301 }
302302 });
303+
304+// Deterministic timers: no sleeps, and each test restores every mocked global.
305+function clock() {
306+ const saved = { setTimeout: globalThis.setTimeout, clearTimeout: globalThis.clearTimeout };
307+ const tasks = new Map(); let n = 0;
308+ globalThis.setTimeout = (fn) => { tasks.set(++n, fn); return n; };
309+ globalThis.clearTimeout = (id) => tasks.delete(id);
310+ return { async tick() { const batch = [...tasks.values()]; tasks.clear(); for (const fn of batch) await fn(); },
311+ size: () => tasks.size, restore() { Object.assign(globalThis, saved); } };
312+}
313+
314+test('head refresh defers a real textarea draft, resumes after emptying and blurring', async () => {
315+ const saved = globalThis.document, c = clock();
316+ const text = { value: 'unsent', defaultValue: '' };
317+ let fetched = 0, applied = 0; const notices = [];
318+ globalThis.document = { activeElement: text, querySelectorAll: () => [text] };
319+ const r = window.ermiteMR.refresher({ blocked: window.ermiteMR.hasDraft,
320+ fetchPage: async () => { fetched++; return 'page'; }, apply: () => applied++,
321+ notice: (v) => notices.push(v), failed: () => assert.fail('unexpected fallback') });
322+ try {
323+ r.request(); await c.tick();
324+ assert.equal(fetched, 0); assert.deepEqual(notices, [true]);
325+ text.value = ''; r.resume(); await c.tick();
326+ assert.equal(fetched, 0, 'focus still protects an empty draft');
327+ document.activeElement = null; r.resume(); await c.tick();
328+ assert.equal(fetched, 1); assert.equal(applied, 1); assert.equal(r.pending(), false);
329+ } finally { globalThis.document = saved; c.restore(); }
330+});
331+
332+test('head refresh debounces bursts, serializes requests, and reruns after an in-flight push', async () => {
333+ const c = clock(); let fetched = 0, applied = 0, resolve;
334+ const r = window.ermiteMR.refresher({ blocked: () => false,
335+ fetchPage: () => { fetched++; return new Promise((r) => { resolve = r; }); },
336+ apply: () => applied++, notice() {}, failed: () => assert.fail('unexpected failure') });
337+ try {
338+ r.request(); r.request(); r.request(); assert.equal(c.size(), 1);
339+ const first = c.tick(); assert.equal(fetched, 1);
340+ r.request(); await c.tick(); assert.equal(fetched, 1, 'one fetch in flight');
341+ resolve('one'); await first; assert.equal(applied, 1); assert.equal(c.size(), 1);
342+ const second = c.tick(); assert.equal(fetched, 2); resolve('two'); await second;
343+ assert.equal(applied, 2); assert.equal(c.size(), 0);
344+ } finally { c.restore(); }
345+});
346+
347+test('typing during fetch defers the swap; manual refresh bypasses deferral', async () => {
348+ const c = clock(); let blocked = false, applied = 0, resolve; const notices = [];
349+ const r = window.ermiteMR.refresher({ blocked: () => blocked,
350+ fetchPage: () => new Promise((r) => { resolve = r; }), apply: (_page, manual) => { applied++; assert.equal(manual, true); },
351+ notice: (v) => notices.push(v), failed: () => assert.fail('unexpected failure') });
352+ try {
353+ r.request(); const first = c.tick(); blocked = true; resolve('page'); await first;
354+ assert.equal(applied, 0); assert.deepEqual(notices, [true]);
355+ r.request(true); const second = c.tick(); resolve('new page'); await second;
356+ assert.equal(applied, 1); assert.equal(notices.at(-1), false);
357+ } finally { c.restore(); }
358+});
359+
360+test('fetch failures and non-MR responses take the fallback, never apply', async () => {
361+ const saved = { fetch: globalThis.fetch, location: globalThis.location, DOMParser: globalThis.DOMParser };
362+ const c = clock(); let fallback = 0;
363+ globalThis.location = { href: 'https://forge.test/demo/merge-requests/1?view=split&from=25' };
364+ const r = window.ermiteMR.refresher({ blocked: () => false, fetchPage: window.ermiteMR.fetchPage,
365+ apply: () => assert.fail('must not swap'), notice() {}, failed: () => fallback++ });
366+ try {
367+ for (const result of ['network', { ok: false }, { ok: true, redirected: true }, { ok: true, text: async () => '<html>login</html>' }]) {
368+ globalThis.fetch = async (url, opts) => {
369+ assert.equal(url, location.href); assert.equal(opts.credentials, 'same-origin');
370+ if (result === 'network') throw new Error('offline'); return result;
371+ };
372+ globalThis.DOMParser = class { parseFromString() { return { querySelector: () => null }; } };
373+ r.request(); await c.tick();
374+ }
375+ assert.equal(fallback, 4);
376+ } finally {
377+ for (const [k,v] of Object.entries(saved)) { if (v === undefined) delete globalThis[k]; else globalThis[k] = v; }
378+ c.restore();
379+ }
380+});
381+
382+test('viewport probe finds a stable path/side/line and restores its offset without line scans', () => {
383+ const names = ['document', 'location', 'innerHeight', 'innerWidth', 'scrollY', 'scrollBy', 'scrollTo', 'CSS', 'matchMedia'];
384+ const saved = Object.fromEntries(names.map((k) => [k, globalThis[k]]));
385+ const rect = (top, bottom = top + 20) => ({ top, bottom, left: 0, width: 900 });
386+ let lineTop = 160, headerTop = -200, found = true; const calls = [];
387+ const header = { getBoundingClientRect: () => rect(headerTop) };
388+ const row = { getBoundingClientRect: () => rect(lineTop), querySelector: () => link };
389+ const link = { href: 'https://forge.test/demo/merge-requests/1?on=new:42:a.go#f2', closest: () => row };
390+ const file = { id: 'f2', dataset: { file: 'a.go' }, querySelector: (s) => s.includes('summary') ? header : s.includes('href$') ? (assert.ok(s.includes('on=new:42:a.go#f3')), found ? link : null) : null };
391+ const hit = { closest: (s) => s === 'tr' ? row : file };
392+ const diffs = { dataset: { diff: 'unified' }, getBoundingClientRect: () => rect(120), contains: () => true };
393+ globalThis.document = {
394+ querySelector: (s) => s === '#diffs' ? diffs : s === '.hdr' ? { getBoundingClientRect: () => rect(0, 100) } : null,
395+ querySelectorAll: (s) => { assert.equal(s, '#diffs details.dfile', 'only files, never every line'); return found === 'gone' ? [] : [file]; },
396+ elementFromPoint: () => hit, documentElement: { scrollHeight: 10000 },
397+ };
398+ Object.assign(globalThis, { location: { href: link.href }, innerHeight: 800, innerWidth: 1200, scrollY: 2500,
399+ scrollBy: (arg) => calls.push(['by', arg]), scrollTo: (arg) => calls.push(['to', arg]), CSS: { escape: (s) => s }, matchMedia: () => ({ matches: false }) });
400+ try {
401+ const a = window.ermiteMR.scrollAnchor();
402+ assert.equal(a.file, 'a.go'); assert.equal(a.on, 'new:42:a.go'); assert.equal(a.offset, 160);
403+ file.id = 'f3'; lineTop = 260; window.ermiteMR.restoreAnchor(a);
404+ assert.deepEqual(calls.pop(), ['by', { top: 100, behavior: 'instant' }]);
405+ found = false; headerTop = -100; window.ermiteMR.restoreAnchor(a);
406+ assert.deepEqual(calls.pop(), ['by', { top: 100, behavior: 'instant' }]);
407+ found = 'gone'; window.ermiteMR.restoreAnchor({ ...a, y: 20000 });
408+ assert.deepEqual(calls.pop(), ['to', { top: 9200, behavior: 'instant' }]);
409+ } finally { for (const [k,v] of Object.entries(saved)) { if (v === undefined) delete globalThis[k]; else globalThis[k] = v; } }
410+});
@@ -300,3 +300,111 @@ test('touch control: lazy links enable toolbar; ordinary taps pass through; rang
300 }300 }
301 }301 }
302 });302 });
303+
304+// Deterministic timers: no sleeps, and each test restores every mocked global.
305+function clock() {
306+ const saved = { setTimeout: globalThis.setTimeout, clearTimeout: globalThis.clearTimeout };
307+ const tasks = new Map(); let n = 0;
308+ globalThis.setTimeout = (fn) => { tasks.set(++n, fn); return n; };
309+ globalThis.clearTimeout = (id) => tasks.delete(id);
310+ return { async tick() { const batch = [...tasks.values()]; tasks.clear(); for (const fn of batch) await fn(); },
311+ size: () => tasks.size, restore() { Object.assign(globalThis, saved); } };
312+}
313+
314+test('head refresh defers a real textarea draft, resumes after emptying and blurring', async () => {
315+ const saved = globalThis.document, c = clock();
316+ const text = { value: 'unsent', defaultValue: '' };
317+ let fetched = 0, applied = 0; const notices = [];
318+ globalThis.document = { activeElement: text, querySelectorAll: () => [text] };
319+ const r = window.ermiteMR.refresher({ blocked: window.ermiteMR.hasDraft,
320+ fetchPage: async () => { fetched++; return 'page'; }, apply: () => applied++,
321+ notice: (v) => notices.push(v), failed: () => assert.fail('unexpected fallback') });
322+ try {
323+ r.request(); await c.tick();
324+ assert.equal(fetched, 0); assert.deepEqual(notices, [true]);
325+ text.value = ''; r.resume(); await c.tick();
326+ assert.equal(fetched, 0, 'focus still protects an empty draft');
327+ document.activeElement = null; r.resume(); await c.tick();
328+ assert.equal(fetched, 1); assert.equal(applied, 1); assert.equal(r.pending(), false);
329+ } finally { globalThis.document = saved; c.restore(); }
330+});
331+
332+test('head refresh debounces bursts, serializes requests, and reruns after an in-flight push', async () => {
333+ const c = clock(); let fetched = 0, applied = 0, resolve;
334+ const r = window.ermiteMR.refresher({ blocked: () => false,
335+ fetchPage: () => { fetched++; return new Promise((r) => { resolve = r; }); },
336+ apply: () => applied++, notice() {}, failed: () => assert.fail('unexpected failure') });
337+ try {
338+ r.request(); r.request(); r.request(); assert.equal(c.size(), 1);
339+ const first = c.tick(); assert.equal(fetched, 1);
340+ r.request(); await c.tick(); assert.equal(fetched, 1, 'one fetch in flight');
341+ resolve('one'); await first; assert.equal(applied, 1); assert.equal(c.size(), 1);
342+ const second = c.tick(); assert.equal(fetched, 2); resolve('two'); await second;
343+ assert.equal(applied, 2); assert.equal(c.size(), 0);
344+ } finally { c.restore(); }
345+});
346+
347+test('typing during fetch defers the swap; manual refresh bypasses deferral', async () => {
348+ const c = clock(); let blocked = false, applied = 0, resolve; const notices = [];
349+ const r = window.ermiteMR.refresher({ blocked: () => blocked,
350+ fetchPage: () => new Promise((r) => { resolve = r; }), apply: (_page, manual) => { applied++; assert.equal(manual, true); },
351+ notice: (v) => notices.push(v), failed: () => assert.fail('unexpected failure') });
352+ try {
353+ r.request(); const first = c.tick(); blocked = true; resolve('page'); await first;
354+ assert.equal(applied, 0); assert.deepEqual(notices, [true]);
355+ r.request(true); const second = c.tick(); resolve('new page'); await second;
356+ assert.equal(applied, 1); assert.equal(notices.at(-1), false);
357+ } finally { c.restore(); }
358+});
359+
360+test('fetch failures and non-MR responses take the fallback, never apply', async () => {
361+ const saved = { fetch: globalThis.fetch, location: globalThis.location, DOMParser: globalThis.DOMParser };
362+ const c = clock(); let fallback = 0;
363+ globalThis.location = { href: 'https://forge.test/demo/merge-requests/1?view=split&from=25' };
364+ const r = window.ermiteMR.refresher({ blocked: () => false, fetchPage: window.ermiteMR.fetchPage,
365+ apply: () => assert.fail('must not swap'), notice() {}, failed: () => fallback++ });
366+ try {
367+ for (const result of ['network', { ok: false }, { ok: true, redirected: true }, { ok: true, text: async () => '<html>login</html>' }]) {
368+ globalThis.fetch = async (url, opts) => {
369+ assert.equal(url, location.href); assert.equal(opts.credentials, 'same-origin');
370+ if (result === 'network') throw new Error('offline'); return result;
371+ };
372+ globalThis.DOMParser = class { parseFromString() { return { querySelector: () => null }; } };
373+ r.request(); await c.tick();
374+ }
375+ assert.equal(fallback, 4);
376+ } finally {
377+ for (const [k,v] of Object.entries(saved)) { if (v === undefined) delete globalThis[k]; else globalThis[k] = v; }
378+ c.restore();
379+ }
380+});
381+
382+test('viewport probe finds a stable path/side/line and restores its offset without line scans', () => {
383+ const names = ['document', 'location', 'innerHeight', 'innerWidth', 'scrollY', 'scrollBy', 'scrollTo', 'CSS', 'matchMedia'];
384+ const saved = Object.fromEntries(names.map((k) => [k, globalThis[k]]));
385+ const rect = (top, bottom = top + 20) => ({ top, bottom, left: 0, width: 900 });
386+ let lineTop = 160, headerTop = -200, found = true; const calls = [];
387+ const header = { getBoundingClientRect: () => rect(headerTop) };
388+ const row = { getBoundingClientRect: () => rect(lineTop), querySelector: () => link };
389+ const link = { href: 'https://forge.test/demo/merge-requests/1?on=new:42:a.go#f2', closest: () => row };
390+ const file = { id: 'f2', dataset: { file: 'a.go' }, querySelector: (s) => s.includes('summary') ? header : s.includes('href$') ? (assert.ok(s.includes('on=new:42:a.go#f3')), found ? link : null) : null };
391+ const hit = { closest: (s) => s === 'tr' ? row : file };
392+ const diffs = { dataset: { diff: 'unified' }, getBoundingClientRect: () => rect(120), contains: () => true };
393+ globalThis.document = {
394+ querySelector: (s) => s === '#diffs' ? diffs : s === '.hdr' ? { getBoundingClientRect: () => rect(0, 100) } : null,
395+ querySelectorAll: (s) => { assert.equal(s, '#diffs details.dfile', 'only files, never every line'); return found === 'gone' ? [] : [file]; },
396+ elementFromPoint: () => hit, documentElement: { scrollHeight: 10000 },
397+ };
398+ Object.assign(globalThis, { location: { href: link.href }, innerHeight: 800, innerWidth: 1200, scrollY: 2500,
399+ scrollBy: (arg) => calls.push(['by', arg]), scrollTo: (arg) => calls.push(['to', arg]), CSS: { escape: (s) => s }, matchMedia: () => ({ matches: false }) });
400+ try {
401+ const a = window.ermiteMR.scrollAnchor();
402+ assert.equal(a.file, 'a.go'); assert.equal(a.on, 'new:42:a.go'); assert.equal(a.offset, 160);
403+ file.id = 'f3'; lineTop = 260; window.ermiteMR.restoreAnchor(a);
404+ assert.deepEqual(calls.pop(), ['by', { top: 100, behavior: 'instant' }]);
405+ found = false; headerTop = -100; window.ermiteMR.restoreAnchor(a);
406+ assert.deepEqual(calls.pop(), ['by', { top: 100, behavior: 'instant' }]);
407+ found = 'gone'; window.ermiteMR.restoreAnchor({ ...a, y: 20000 });
408+ assert.deepEqual(calls.pop(), ['to', { top: 9200, behavior: 'instant' }]);
409+ } finally { for (const [k,v] of Object.entries(saved)) { if (v === undefined) delete globalThis[k]; else globalThis[k] = v; } }
410+});
M internal/adapters/web/mr.templ +32 -28
@@ -157,35 +157,39 @@ templ MergeRequest(l Layout, p MRPage) {
157157 <p class="d-err" role="alert">{ p.MergeError }</p>
158158 }
159159 @LiveSlot("mr-notice")
160- if p.Since != nil {
161- <nav class="since" aria-label="Diff range">
162- <a
163- href={ templ.SafeURL(p.Since.AllHref) }
164- if !p.Since.Current {
165- aria-current="page"
166- }
167- >all changes <span class="mute">vs { p.Target }</span></a>
168- <a
169- href={ templ.SafeURL(p.Since.SinceHref) }
170- if p.Since.Current {
171- aria-current="page"
172- }
173- >since your last read <span class="mute">{ p.Since.ReadShort } → { p.Since.HeadShort }</span></a>
174- </nav>
175- }
176- if p.SinceNote != "" {
177- <p class="notice">{ p.SinceNote }</p>
178- }
160+ <div id="mr-range" hidden?={ p.Since == nil && p.SinceNote == "" }>
161+ if p.Since != nil {
162+ <nav class="since" aria-label="Diff range">
163+ <a
164+ href={ templ.SafeURL(p.Since.AllHref) }
165+ if !p.Since.Current {
166+ aria-current="page"
167+ }
168+ >all changes <span class="mute">vs { p.Target }</span></a>
169+ <a
170+ href={ templ.SafeURL(p.Since.SinceHref) }
171+ if p.Since.Current {
172+ aria-current="page"
173+ }
174+ >since your last read <span class="mute">{ p.Since.ReadShort } → { p.Since.HeadShort }</span></a>
175+ </nav>
176+ }
177+ if p.SinceNote != "" {
178+ <p class="notice">{ p.SinceNote }</p>
179+ }
180+ </div>
179181 @mrBar(p)
180- if p.Invisible {
181- <p class="notice">
182- this diff holds invisible characters (direction controls, zero-width characters). They are shown as
183- <span class="inv">&lt;U+XXXX&gt;</span> markers, never applied.
184- </p>
185- }
186- if p.Note != "" {
187- <p class="notice">{ p.Note }</p>
188- }
182+ <div id="mr-diff-notices" hidden?={ !p.Invisible && p.Note == "" }>
183+ if p.Invisible {
184+ <p class="notice">
185+ this diff holds invisible characters (direction controls, zero-width characters). They are shown as
186+ <span class="inv">&lt;U+XXXX&gt;</span> markers, never applied.
187+ </p>
188+ }
189+ if p.Note != "" {
190+ <p class="notice">{ p.Note }</p>
191+ }
192+ </div>
189193 <div
190194 id="diffs"
191195 data-mr
@@ -157,35 +157,39 @@ templ MergeRequest(l Layout, p MRPage) {
157 <p class="d-err" role="alert">{ p.MergeError }</p>157 <p class="d-err" role="alert">{ p.MergeError }</p>
158 }158 }
159 @LiveSlot("mr-notice")159 @LiveSlot("mr-notice")
160- if p.Since != nil {160+ <div id="mr-range" hidden?={ p.Since == nil && p.SinceNote == "" }>
161- <nav class="since" aria-label="Diff range">161+ if p.Since != nil {
162- <a162+ <nav class="since" aria-label="Diff range">
163- href={ templ.SafeURL(p.Since.AllHref) }163+ <a
164- if !p.Since.Current {164+ href={ templ.SafeURL(p.Since.AllHref) }
165- aria-current="page"165+ if !p.Since.Current {
166- }166+ aria-current="page"
167- >all changes <span class="mute">vs { p.Target }</span></a>167+ }
168- <a168+ >all changes <span class="mute">vs { p.Target }</span></a>
169- href={ templ.SafeURL(p.Since.SinceHref) }169+ <a
170- if p.Since.Current {170+ href={ templ.SafeURL(p.Since.SinceHref) }
171- aria-current="page"171+ if p.Since.Current {
172- }172+ aria-current="page"
173- >since your last read <span class="mute">{ p.Since.ReadShort } → { p.Since.HeadShort }</span></a>173+ }
174- </nav>174+ >since your last read <span class="mute">{ p.Since.ReadShort } → { p.Since.HeadShort }</span></a>
175- }175+ </nav>
176- if p.SinceNote != "" {176+ }
177- <p class="notice">{ p.SinceNote }</p>177+ if p.SinceNote != "" {
178- }178+ <p class="notice">{ p.SinceNote }</p>
179+ }
180+ </div>
179 @mrBar(p)181 @mrBar(p)
180- if p.Invisible {182+ <div id="mr-diff-notices" hidden?={ !p.Invisible && p.Note == "" }>
181- <p class="notice">183+ if p.Invisible {
182- this diff holds invisible characters (direction controls, zero-width characters). They are shown as184+ <p class="notice">
183- <span class="inv">&lt;U+XXXX&gt;</span> markers, never applied.185+ this diff holds invisible characters (direction controls, zero-width characters). They are shown as
184- </p>186+ <span class="inv">&lt;U+XXXX&gt;</span> markers, never applied.
185- }187+ </p>
186- if p.Note != "" {188+ }
187- <p class="notice">{ p.Note }</p>189+ if p.Note != "" {
188- }190+ <p class="notice">{ p.Note }</p>
191+ }
192+ </div>
189 <div193 <div
190 id="diffs"194 id="diffs"
191 data-mr195 data-mr
M internal/adapters/web/mr_templ.go +414 -402
@@ -867,125 +867,131 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
867867 if templ_7745c5c3_Err != nil {
868868 return templ_7745c5c3_Err
869869 }
870- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, " ")
870+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, " <div id=\"mr-range\"")
871+ if templ_7745c5c3_Err != nil {
872+ return templ_7745c5c3_Err
873+ }
874+ if p.Since == nil && p.SinceNote == "" {
875+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, " hidden")
876+ if templ_7745c5c3_Err != nil {
877+ return templ_7745c5c3_Err
878+ }
879+ }
880+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, ">")
871881 if templ_7745c5c3_Err != nil {
872882 return templ_7745c5c3_Err
873883 }
874884 if p.Since != nil {
875- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "<nav class=\"since\" aria-label=\"Diff range\"><a href=\"")
885+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<nav class=\"since\" aria-label=\"Diff range\"><a href=\"")
876886 if templ_7745c5c3_Err != nil {
877887 return templ_7745c5c3_Err
878888 }
879889 var templ_7745c5c3_Var44 templ.SafeURL
880890 templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Since.AllHref))
881891 if templ_7745c5c3_Err != nil {
882- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 163, Col: 42}
892+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 164, Col: 43}
883893 }
884894 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
885895 if templ_7745c5c3_Err != nil {
886896 return templ_7745c5c3_Err
887897 }
888- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "\"")
898+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "\"")
889899 if templ_7745c5c3_Err != nil {
890900 return templ_7745c5c3_Err
891901 }
892902 if !p.Since.Current {
893- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, " aria-current=\"page\"")
903+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, " aria-current=\"page\"")
894904 if templ_7745c5c3_Err != nil {
895905 return templ_7745c5c3_Err
896906 }
897907 }
898- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, ">all changes <span class=\"mute\">vs ")
908+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, ">all changes <span class=\"mute\">vs ")
899909 if templ_7745c5c3_Err != nil {
900910 return templ_7745c5c3_Err
901911 }
902912 var templ_7745c5c3_Var45 string
903913 templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
904914 if templ_7745c5c3_Err != nil {
905- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 167, Col: 49}
915+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 168, Col: 50}
906916 }
907917 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
908918 if templ_7745c5c3_Err != nil {
909919 return templ_7745c5c3_Err
910920 }
911- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "</span></a> <a href=\"")
921+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "</span></a> <a href=\"")
912922 if templ_7745c5c3_Err != nil {
913923 return templ_7745c5c3_Err
914924 }
915925 var templ_7745c5c3_Var46 templ.SafeURL
916926 templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Since.SinceHref))
917927 if templ_7745c5c3_Err != nil {
918- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 169, Col: 44}
928+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 170, Col: 45}
919929 }
920930 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
921931 if templ_7745c5c3_Err != nil {
922932 return templ_7745c5c3_Err
923933 }
924- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "\"")
934+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\"")
925935 if templ_7745c5c3_Err != nil {
926936 return templ_7745c5c3_Err
927937 }
928938 if p.Since.Current {
929- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, " aria-current=\"page\"")
939+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, " aria-current=\"page\"")
930940 if templ_7745c5c3_Err != nil {
931941 return templ_7745c5c3_Err
932942 }
933943 }
934- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, ">since your last read <span class=\"mute\">")
944+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, ">since your last read <span class=\"mute\">")
935945 if templ_7745c5c3_Err != nil {
936946 return templ_7745c5c3_Err
937947 }
938948 var templ_7745c5c3_Var47 string
939949 templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(p.Since.ReadShort)
940950 if templ_7745c5c3_Err != nil {
941- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 173, Col: 64}
951+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 174, Col: 65}
942952 }
943953 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
944954 if templ_7745c5c3_Err != nil {
945955 return templ_7745c5c3_Err
946956 }
947- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, " → ")
957+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, " → ")
948958 if templ_7745c5c3_Err != nil {
949959 return templ_7745c5c3_Err
950960 }
951961 var templ_7745c5c3_Var48 string
952962 templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(p.Since.HeadShort)
953963 if templ_7745c5c3_Err != nil {
954- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 173, Col: 90}
964+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 174, Col: 91}
955965 }
956966 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
957967 if templ_7745c5c3_Err != nil {
958968 return templ_7745c5c3_Err
959969 }
960- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</span></a></nav>")
970+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "</span></a></nav>")
961971 if templ_7745c5c3_Err != nil {
962972 return templ_7745c5c3_Err
963973 }
964974 }
965- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, " ")
966- if templ_7745c5c3_Err != nil {
967- return templ_7745c5c3_Err
968- }
969975 if p.SinceNote != "" {
970- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<p class=\"notice\">")
976+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "<p class=\"notice\">")
971977 if templ_7745c5c3_Err != nil {
972978 return templ_7745c5c3_Err
973979 }
974980 var templ_7745c5c3_Var49 string
975981 templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(p.SinceNote)
976982 if templ_7745c5c3_Err != nil {
977- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 177, Col: 34}
983+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 178, Col: 35}
978984 }
979985 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
980986 if templ_7745c5c3_Err != nil {
981987 return templ_7745c5c3_Err
982988 }
983- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "</p>")
989+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</p>")
984990 if templ_7745c5c3_Err != nil {
985991 return templ_7745c5c3_Err
986992 }
987993 }
988- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, " ")
994+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</div>")
989995 if templ_7745c5c3_Err != nil {
990996 return templ_7745c5c3_Err
991997 }
@@ -993,106 +999,112 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
993999 if templ_7745c5c3_Err != nil {
9941000 return templ_7745c5c3_Err
9951001 }
996- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, " ")
1002+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, " <div id=\"mr-diff-notices\"")
9971003 if templ_7745c5c3_Err != nil {
9981004 return templ_7745c5c3_Err
9991005 }
1000- if p.Invisible {
1001- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
1006+ if !p.Invisible && p.Note == "" {
1007+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, " hidden")
10021008 if templ_7745c5c3_Err != nil {
10031009 return templ_7745c5c3_Err
10041010 }
10051011 }
1006- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, " ")
1012+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, ">")
10071013 if templ_7745c5c3_Err != nil {
10081014 return templ_7745c5c3_Err
10091015 }
1016+ if p.Invisible {
1017+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
1018+ if templ_7745c5c3_Err != nil {
1019+ return templ_7745c5c3_Err
1020+ }
1021+ }
10101022 if p.Note != "" {
1011- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<p class=\"notice\">")
1023+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<p class=\"notice\">")
10121024 if templ_7745c5c3_Err != nil {
10131025 return templ_7745c5c3_Err
10141026 }
10151027 var templ_7745c5c3_Var50 string
10161028 templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
10171029 if templ_7745c5c3_Err != nil {
1018- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 187, Col: 29}
1030+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 190, Col: 30}
10191031 }
10201032 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
10211033 if templ_7745c5c3_Err != nil {
10221034 return templ_7745c5c3_Err
10231035 }
1024- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "</p>")
1036+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "</p>")
10251037 if templ_7745c5c3_Err != nil {
10261038 return templ_7745c5c3_Err
10271039 }
10281040 }
1029- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, " <div id=\"diffs\" data-mr")
1041+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</div><div id=\"diffs\" data-mr")
10301042 if templ_7745c5c3_Err != nil {
10311043 return templ_7745c5c3_Err
10321044 }
10331045 if p.Canonical != "" {
1034- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, " data-canonical=\"")
1046+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " data-canonical=\"")
10351047 if templ_7745c5c3_Err != nil {
10361048 return templ_7745c5c3_Err
10371049 }
10381050 var templ_7745c5c3_Var51 string
10391051 templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Canonical)
10401052 if templ_7745c5c3_Err != nil {
1041- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 193, Col: 32}
1053+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 197, Col: 32}
10421054 }
10431055 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var51)
10441056 if templ_7745c5c3_Err != nil {
10451057 return templ_7745c5c3_Err
10461058 }
1047- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "\"")
1059+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"")
10481060 if templ_7745c5c3_Err != nil {
10491061 return templ_7745c5c3_Err
10501062 }
10511063 }
10521064 if p.Both {
1053- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " data-diff=\"")
1065+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, " data-diff=\"")
10541066 if templ_7745c5c3_Err != nil {
10551067 return templ_7745c5c3_Err
10561068 }
10571069 var templ_7745c5c3_Var52 string
10581070 templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
10591071 if templ_7745c5c3_Err != nil {
1060- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 196, Col: 22}
1072+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 200, Col: 22}
10611073 }
10621074 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var52)
10631075 if templ_7745c5c3_Err != nil {
10641076 return templ_7745c5c3_Err
10651077 }
1066- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"")
1078+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\"")
10671079 if templ_7745c5c3_Err != nil {
10681080 return templ_7745c5c3_Err
10691081 }
10701082 } else {
1071- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, " data-view=\"")
1083+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " data-view=\"")
10721084 if templ_7745c5c3_Err != nil {
10731085 return templ_7745c5c3_Err
10741086 }
10751087 var templ_7745c5c3_Var53 string
10761088 templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
10771089 if templ_7745c5c3_Err != nil {
1078- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 198, Col: 22}
1090+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 202, Col: 22}
10791091 }
10801092 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var53)
10811093 if templ_7745c5c3_Err != nil {
10821094 return templ_7745c5c3_Err
10831095 }
1084- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\"")
1096+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"")
10851097 if templ_7745c5c3_Err != nil {
10861098 return templ_7745c5c3_Err
10871099 }
10881100 }
10891101 if p.Both && !p.Pinned {
1090- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
1102+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
10911103 if templ_7745c5c3_Err != nil {
10921104 return templ_7745c5c3_Err
10931105 }
10941106 }
1095- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, ">")
1107+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, ">")
10961108 if templ_7745c5c3_Err != nil {
10971109 return templ_7745c5c3_Err
10981110 }
@@ -1103,38 +1115,38 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
11031115 }
11041116 }
11051117 if len(p.Files) == 0 {
1106- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "<p class=\"note\">no changed files.</p>")
1118+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "<p class=\"note\">no changed files.</p>")
11071119 if templ_7745c5c3_Err != nil {
11081120 return templ_7745c5c3_Err
11091121 }
11101122 }
1111- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</div><h2 class=\"rule-h\" id=\"comments\"><span>Comments</span><span class=\"count\">")
1123+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "</div><h2 class=\"rule-h\" id=\"comments\"><span>Comments</span><span class=\"count\">")
11121124 if templ_7745c5c3_Err != nil {
11131125 return templ_7745c5c3_Err
11141126 }
11151127 var templ_7745c5c3_Var54 string
11161128 templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.NUnresolved))
11171129 if templ_7745c5c3_Err != nil {
1118- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 211, Col: 97}
1130+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 215, Col: 97}
11191131 }
11201132 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
11211133 if templ_7745c5c3_Err != nil {
11221134 return templ_7745c5c3_Err
11231135 }
1124- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, " open / ")
1136+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, " open / ")
11251137 if templ_7745c5c3_Err != nil {
11261138 return templ_7745c5c3_Err
11271139 }
11281140 var templ_7745c5c3_Var55 string
11291141 templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.NComments))
11301142 if templ_7745c5c3_Err != nil {
1131- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 211, Col: 126}
1143+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 215, Col: 126}
11321144 }
11331145 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
11341146 if templ_7745c5c3_Err != nil {
11351147 return templ_7745c5c3_Err
11361148 }
1137- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "</span></h2>")
1149+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "</span></h2>")
11381150 if templ_7745c5c3_Err != nil {
11391151 return templ_7745c5c3_Err
11401152 }
@@ -1150,17 +1162,17 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
11501162 return templ_7745c5c3_Err
11511163 }
11521164 }
1153- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, " ")
1165+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, " ")
11541166 if templ_7745c5c3_Err != nil {
11551167 return templ_7745c5c3_Err
11561168 }
11571169 if p.NComments == 0 {
1158- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "<p class=\"dim\">no comments yet.</p>")
1170+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "<p class=\"dim\">no comments yet.</p>")
11591171 if templ_7745c5c3_Err != nil {
11601172 return templ_7745c5c3_Err
11611173 }
11621174 }
1163- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, " ")
1175+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, " ")
11641176 if templ_7745c5c3_Err != nil {
11651177 return templ_7745c5c3_Err
11661178 }
@@ -1202,33 +1214,33 @@ func branchLink(name, href string) templ.Component {
12021214 }
12031215 ctx = templ.ClearChildren(ctx)
12041216 if href != "" {
1205- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "<a href=\"")
1217+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "<a href=\"")
12061218 if templ_7745c5c3_Err != nil {
12071219 return templ_7745c5c3_Err
12081220 }
12091221 var templ_7745c5c3_Var57 templ.SafeURL
12101222 templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(href))
12111223 if templ_7745c5c3_Err != nil {
1212- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 229, Col: 31}
1224+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 233, Col: 31}
12131225 }
12141226 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))
12151227 if templ_7745c5c3_Err != nil {
12161228 return templ_7745c5c3_Err
12171229 }
1218- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "\">")
1230+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "\">")
12191231 if templ_7745c5c3_Err != nil {
12201232 return templ_7745c5c3_Err
12211233 }
12221234 var templ_7745c5c3_Var58 string
12231235 templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(name)
12241236 if templ_7745c5c3_Err != nil {
1225- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 229, Col: 40}
1237+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 233, Col: 40}
12261238 }
12271239 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
12281240 if templ_7745c5c3_Err != nil {
12291241 return templ_7745c5c3_Err
12301242 }
1231- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "</a>")
1243+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "</a>")
12321244 if templ_7745c5c3_Err != nil {
12331245 return templ_7745c5c3_Err
12341246 }
@@ -1236,7 +1248,7 @@ func branchLink(name, href string) templ.Component {
12361248 var templ_7745c5c3_Var59 string
12371249 templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.JoinStringErrs(name)
12381250 if templ_7745c5c3_Err != nil {
1239- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 231, Col: 8}
1251+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 235, Col: 8}
12401252 }
12411253 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var59))
12421254 if templ_7745c5c3_Err != nil {
@@ -1310,56 +1322,56 @@ func commentView(c CommentView, suffix string) templ.Component {
13101322 templ_7745c5c3_Var61 = templ.NopComponent
13111323 }
13121324 ctx = templ.ClearChildren(ctx)
1313- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "<div class=\"cmt\" id=\"")
1325+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<div class=\"cmt\" id=\"")
13141326 if templ_7745c5c3_Err != nil {
13151327 return templ_7745c5c3_Err
13161328 }
13171329 var templ_7745c5c3_Var62 string
13181330 templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.ResolveAttributeValue("c" + c.ID + suffix)
13191331 if templ_7745c5c3_Err != nil {
1320- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 250, Col: 42}
1332+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 42}
13211333 }
13221334 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var62)
13231335 if templ_7745c5c3_Err != nil {
13241336 return templ_7745c5c3_Err
13251337 }
1326- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "\" data-resolved=\"")
1338+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-resolved=\"")
13271339 if templ_7745c5c3_Err != nil {
13281340 return templ_7745c5c3_Err
13291341 }
13301342 var templ_7745c5c3_Var63 string
13311343 templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolText(c.Resolved))
13321344 if templ_7745c5c3_Err != nil {
1333- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 250, Col: 81}
1345+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 81}
13341346 }
13351347 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var63)
13361348 if templ_7745c5c3_Err != nil {
13371349 return templ_7745c5c3_Err
13381350 }
1339- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "\"")
1351+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\"")
13401352 if templ_7745c5c3_Err != nil {
13411353 return templ_7745c5c3_Err
13421354 }
13431355 if c.Reply != nil {
1344- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, " data-thread")
1356+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, " data-thread")
13451357 if templ_7745c5c3_Err != nil {
13461358 return templ_7745c5c3_Err
13471359 }
13481360 }
1349- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "><p class=\"c-head\"><span class=\"c-who\">")
1361+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "><p class=\"c-head\"><span class=\"c-who\">")
13501362 if templ_7745c5c3_Err != nil {
13511363 return templ_7745c5c3_Err
13521364 }
13531365 var templ_7745c5c3_Var64 string
13541366 templ_7745c5c3_Var64, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
13551367 if templ_7745c5c3_Err != nil {
1356- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 252, Col: 33}
1368+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 256, Col: 33}
13571369 }
13581370 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var64))
13591371 if templ_7745c5c3_Err != nil {
13601372 return templ_7745c5c3_Err
13611373 }
1362- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "</span> ")
1374+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "</span> ")
13631375 if templ_7745c5c3_Err != nil {
13641376 return templ_7745c5c3_Err
13651377 }
@@ -1367,52 +1379,52 @@ func commentView(c CommentView, suffix string) templ.Component {
13671379 var templ_7745c5c3_Var65 string
13681380 templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
13691381 if templ_7745c5c3_Err != nil {
1370- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 9}
1382+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 9}
13711383 }
13721384 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))
13731385 if templ_7745c5c3_Err != nil {
13741386 return templ_7745c5c3_Err
13751387 }
1376- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "<time class=\"mute\" datetime=\"")
1388+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "<time class=\"mute\" datetime=\"")
13771389 if templ_7745c5c3_Err != nil {
13781390 return templ_7745c5c3_Err
13791391 }
13801392 var templ_7745c5c3_Var66 string
13811393 templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
13821394 if templ_7745c5c3_Err != nil {
1383- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 49}
1395+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 49}
13841396 }
13851397 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var66)
13861398 if templ_7745c5c3_Err != nil {
13871399 return templ_7745c5c3_Err
13881400 }
1389- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "\" title=\"")
1401+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "\" title=\"")
13901402 if templ_7745c5c3_Err != nil {
13911403 return templ_7745c5c3_Err
13921404 }
13931405 var templ_7745c5c3_Var67 string
13941406 templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.Abs)
13951407 if templ_7745c5c3_Err != nil {
1396- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 65}
1408+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 65}
13971409 }
13981410 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67)
13991411 if templ_7745c5c3_Err != nil {
14001412 return templ_7745c5c3_Err
14011413 }
1402- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "\">")
1414+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "\">")
14031415 if templ_7745c5c3_Err != nil {
14041416 return templ_7745c5c3_Err
14051417 }
14061418 var templ_7745c5c3_Var68 string
14071419 templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
14081420 if templ_7745c5c3_Err != nil {
1409- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 76}
1421+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 76}
14101422 }
14111423 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))
14121424 if templ_7745c5c3_Err != nil {
14131425 return templ_7745c5c3_Err
14141426 }
1415- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "</time> ")
1427+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "</time> ")
14161428 if templ_7745c5c3_Err != nil {
14171429 return templ_7745c5c3_Err
14181430 }
@@ -1421,13 +1433,13 @@ func commentView(c CommentView, suffix string) templ.Component {
14211433 var templ_7745c5c3_Var69 string
14221434 templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
14231435 if templ_7745c5c3_Err != nil {
1424- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 257, Col: 9}
1436+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 261, Col: 9}
14251437 }
14261438 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))
14271439 if templ_7745c5c3_Err != nil {
14281440 return templ_7745c5c3_Err
14291441 }
1430- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "<span class=\"c-state\">resolved</span> ")
1442+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "<span class=\"c-state\">resolved</span> ")
14311443 if templ_7745c5c3_Err != nil {
14321444 return templ_7745c5c3_Err
14331445 }
@@ -1436,13 +1448,13 @@ func commentView(c CommentView, suffix string) templ.Component {
14361448 var templ_7745c5c3_Var70 string
14371449 templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
14381450 if templ_7745c5c3_Err != nil {
1439- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 260, Col: 9}
1451+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 264, Col: 9}
14401452 }
14411453 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))
14421454 if templ_7745c5c3_Err != nil {
14431455 return templ_7745c5c3_Err
14441456 }
1445- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<span class=\"c-state\" title=\"written on an earlier head; the line may have moved\">outdated</span> ")
1457+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "<span class=\"c-state\" title=\"written on an earlier head; the line may have moved\">outdated</span> ")
14461458 if templ_7745c5c3_Err != nil {
14471459 return templ_7745c5c3_Err
14481460 }
@@ -1451,36 +1463,36 @@ func commentView(c CommentView, suffix string) templ.Component {
14511463 var templ_7745c5c3_Var71 string
14521464 templ_7745c5c3_Var71, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
14531465 if templ_7745c5c3_Err != nil {
1454- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 263, Col: 9}
1466+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 267, Col: 9}
14551467 }
14561468 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var71))
14571469 if templ_7745c5c3_Err != nil {
14581470 return templ_7745c5c3_Err
14591471 }
1460- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "<span class=\"c-where mute\">")
1472+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "<span class=\"c-where mute\">")
14611473 if templ_7745c5c3_Err != nil {
14621474 return templ_7745c5c3_Err
14631475 }
14641476 var templ_7745c5c3_Var72 string
14651477 templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.JoinStringErrs(c.Where)
14661478 if templ_7745c5c3_Err != nil {
1467- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 263, Col: 47}
1479+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 267, Col: 47}
14681480 }
14691481 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var72))
14701482 if templ_7745c5c3_Err != nil {
14711483 return templ_7745c5c3_Err
14721484 }
1473- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "</span>")
1485+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "</span>")
14741486 if templ_7745c5c3_Err != nil {
14751487 return templ_7745c5c3_Err
14761488 }
14771489 }
1478- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "</p>")
1490+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</p>")
14791491 if templ_7745c5c3_Err != nil {
14801492 return templ_7745c5c3_Err
14811493 }
14821494 if len(c.Parts) > 0 {
1483- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "<p class=\"c-text\">")
1495+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "<p class=\"c-text\">")
14841496 if templ_7745c5c3_Err != nil {
14851497 return templ_7745c5c3_Err
14861498 }
@@ -1488,24 +1500,24 @@ func commentView(c CommentView, suffix string) templ.Component {
14881500 if templ_7745c5c3_Err != nil {
14891501 return templ_7745c5c3_Err
14901502 }
1491- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</p>")
1503+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "</p>")
14921504 if templ_7745c5c3_Err != nil {
14931505 return templ_7745c5c3_Err
14941506 }
14951507 } else if c.Deleted {
14961508 if c.Verdict != "" {
1497- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "<p class=\"mute\">text deleted</p>")
1509+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "<p class=\"mute\">text deleted</p>")
14981510 if templ_7745c5c3_Err != nil {
14991511 return templ_7745c5c3_Err
15001512 }
15011513 } else {
1502- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "<p class=\"mute\">deleted note</p>")
1514+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "<p class=\"mute\">deleted note</p>")
15031515 if templ_7745c5c3_Err != nil {
15041516 return templ_7745c5c3_Err
15051517 }
15061518 }
15071519 } else {
1508- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "<div class=\"c-body prose\">")
1520+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "<div class=\"c-body prose\">")
15091521 if templ_7745c5c3_Err != nil {
15101522 return templ_7745c5c3_Err
15111523 }
@@ -1520,147 +1532,147 @@ func commentView(c CommentView, suffix string) templ.Component {
15201532 return templ_7745c5c3_Err
15211533 }
15221534 }
1523- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "</div>")
1535+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "</div>")
15241536 if templ_7745c5c3_Err != nil {
15251537 return templ_7745c5c3_Err
15261538 }
15271539 }
15281540 if c.Edited {
1529- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "<span class=\"mute\">edited</span> ")
1541+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "<span class=\"mute\">edited</span> ")
15301542 if templ_7745c5c3_Err != nil {
15311543 return templ_7745c5c3_Err
15321544 }
15331545 }
15341546 if c.Verdict != "" {
1535- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "<span class=\"c-state\">")
1547+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "<span class=\"c-state\">")
15361548 if templ_7745c5c3_Err != nil {
15371549 return templ_7745c5c3_Err
15381550 }
15391551 var templ_7745c5c3_Var73 string
15401552 templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(c.Verdict)
15411553 if templ_7745c5c3_Err != nil {
1542- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 287, Col: 36}
1554+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 291, Col: 36}
15431555 }
15441556 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73))
15451557 if templ_7745c5c3_Err != nil {
15461558 return templ_7745c5c3_Err
15471559 }
1548- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "</span> ")
1560+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "</span> ")
15491561 if templ_7745c5c3_Err != nil {
15501562 return templ_7745c5c3_Err
15511563 }
15521564 }
15531565 if c.Range != "" {
1554- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "<span class=\"mute\">")
1566+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "<span class=\"mute\">")
15551567 if templ_7745c5c3_Err != nil {
15561568 return templ_7745c5c3_Err
15571569 }
15581570 var templ_7745c5c3_Var74 string
15591571 templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinStringErrs(c.Range)
15601572 if templ_7745c5c3_Err != nil {
1561- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 290, Col: 31}
1573+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 294, Col: 31}
15621574 }
15631575 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))
15641576 if templ_7745c5c3_Err != nil {
15651577 return templ_7745c5c3_Err
15661578 }
1567- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "</span> ")
1579+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "</span> ")
15681580 if templ_7745c5c3_Err != nil {
15691581 return templ_7745c5c3_Err
15701582 }
15711583 }
15721584 if c.Quote != "" {
1573- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "<button type=\"button\" class=\"btn\" data-js data-quote=\"")
1585+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<button type=\"button\" class=\"btn\" data-js data-quote=\"")
15741586 if templ_7745c5c3_Err != nil {
15751587 return templ_7745c5c3_Err
15761588 }
15771589 var templ_7745c5c3_Var75 string
15781590 templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.Quote)
15791591 if templ_7745c5c3_Err != nil {
1580- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 293, Col: 65}
1592+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 297, Col: 65}
15811593 }
15821594 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)
15831595 if templ_7745c5c3_Err != nil {
15841596 return templ_7745c5c3_Err
15851597 }
1586- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "\">Quote</button> ")
1598+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "\">Quote</button> ")
15871599 if templ_7745c5c3_Err != nil {
15881600 return templ_7745c5c3_Err
15891601 }
15901602 }
15911603 if c.Edit != nil {
1592- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<details><summary>Edit</summary><form method=\"post\" action=\"")
1604+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "<details><summary>Edit</summary><form method=\"post\" action=\"")
15931605 if templ_7745c5c3_Err != nil {
15941606 return templ_7745c5c3_Err
15951607 }
15961608 var templ_7745c5c3_Var76 templ.SafeURL
15971609 templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Edit.Action))
15981610 if templ_7745c5c3_Err != nil {
1599- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 296, Col: 92}
1611+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 300, Col: 92}
16001612 }
16011613 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))
16021614 if templ_7745c5c3_Err != nil {
16031615 return templ_7745c5c3_Err
16041616 }
1605- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "\"><input type=\"hidden\" name=\"from\" value=\"")
1617+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "\"><input type=\"hidden\" name=\"from\" value=\"")
16061618 if templ_7745c5c3_Err != nil {
16071619 return templ_7745c5c3_Err
16081620 }
16091621 var templ_7745c5c3_Var77 string
16101622 templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Edit.From))
16111623 if templ_7745c5c3_Err != nil {
1612- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 296, Col: 153}
1624+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 300, Col: 153}
16131625 }
16141626 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77)
16151627 if templ_7745c5c3_Err != nil {
16161628 return templ_7745c5c3_Err
16171629 }
1618- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "\"><textarea name=\"text\" maxlength=\"8000\">")
1630+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "\"><textarea name=\"text\" maxlength=\"8000\">")
16191631 if templ_7745c5c3_Err != nil {
16201632 return templ_7745c5c3_Err
16211633 }
16221634 var templ_7745c5c3_Var78 string
16231635 templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(c.Edit.Text)
16241636 if templ_7745c5c3_Err != nil {
1625- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 296, Col: 209}
1637+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 300, Col: 209}
16261638 }
16271639 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78))
16281640 if templ_7745c5c3_Err != nil {
16291641 return templ_7745c5c3_Err
16301642 }
1631- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "</textarea><button class=\"btn\" type=\"submit\">Save</button></form></details> ")
1643+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "</textarea><button class=\"btn\" type=\"submit\">Save</button></form></details> ")
16321644 if templ_7745c5c3_Err != nil {
16331645 return templ_7745c5c3_Err
16341646 }
16351647 }
16361648 if c.Delete != nil {
1637- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "<details><summary>Delete</summary><form method=\"post\" action=\"")
1649+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "<details><summary>Delete</summary><form method=\"post\" action=\"")
16381650 if templ_7745c5c3_Err != nil {
16391651 return templ_7745c5c3_Err
16401652 }
16411653 var templ_7745c5c3_Var79 templ.SafeURL
16421654 templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Delete.Action))
16431655 if templ_7745c5c3_Err != nil {
1644- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 299, Col: 96}
1656+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 303, Col: 96}
16451657 }
16461658 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))
16471659 if templ_7745c5c3_Err != nil {
16481660 return templ_7745c5c3_Err
16491661 }
1650- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "\"><input type=\"hidden\" name=\"from\" value=\"")
1662+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "\"><input type=\"hidden\" name=\"from\" value=\"")
16511663 if templ_7745c5c3_Err != nil {
16521664 return templ_7745c5c3_Err
16531665 }
16541666 var templ_7745c5c3_Var80 string
16551667 templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Delete.From))
16561668 if templ_7745c5c3_Err != nil {
1657- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 299, Col: 159}
1669+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 303, Col: 159}
16581670 }
16591671 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)
16601672 if templ_7745c5c3_Err != nil {
16611673 return templ_7745c5c3_Err
16621674 }
1663- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "\"><p>Delete this note?</p><button class=\"btn\" type=\"submit\">Confirm delete</button></form></details> ")
1675+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "\"><p>Delete this note?</p><button class=\"btn\" type=\"submit\">Confirm delete</button></form></details> ")
16641676 if templ_7745c5c3_Err != nil {
16651677 return templ_7745c5c3_Err
16661678 }
@@ -1672,7 +1684,7 @@ func commentView(c CommentView, suffix string) templ.Component {
16721684 }
16731685 }
16741686 if c.Reply != nil {
1675- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "<details data-reply><summary>Reply</summary>")
1687+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "<details data-reply><summary>Reply</summary>")
16761688 if templ_7745c5c3_Err != nil {
16771689 return templ_7745c5c3_Err
16781690 }
@@ -1680,80 +1692,80 @@ func commentView(c CommentView, suffix string) templ.Component {
16801692 if templ_7745c5c3_Err != nil {
16811693 return templ_7745c5c3_Err
16821694 }
1683- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "</details> ")
1695+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "</details> ")
16841696 if templ_7745c5c3_Err != nil {
16851697 return templ_7745c5c3_Err
16861698 }
16871699 }
16881700 if c.Resolve != nil {
1689- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "<form class=\"c-act\" method=\"post\" action=\"")
1701+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "<form class=\"c-act\" method=\"post\" action=\"")
16901702 if templ_7745c5c3_Err != nil {
16911703 return templ_7745c5c3_Err
16921704 }
16931705 var templ_7745c5c3_Var81 templ.SafeURL
16941706 templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Resolve.Action))
16951707 if templ_7745c5c3_Err != nil {
1696- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 310, Col: 77}
1708+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 314, Col: 77}
16971709 }
16981710 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))
16991711 if templ_7745c5c3_Err != nil {
17001712 return templ_7745c5c3_Err
17011713 }
1702- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "\"><input type=\"hidden\" name=\"resolved\" value=\"")
1714+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "\"><input type=\"hidden\" name=\"resolved\" value=\"")
17031715 if templ_7745c5c3_Err != nil {
17041716 return templ_7745c5c3_Err
17051717 }
17061718 var templ_7745c5c3_Var82 string
17071719 templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolText(c.Resolve.Value))
17081720 if templ_7745c5c3_Err != nil {
1709- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 311, Col: 74}
1721+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 315, Col: 74}
17101722 }
17111723 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var82)
17121724 if templ_7745c5c3_Err != nil {
17131725 return templ_7745c5c3_Err
17141726 }
1715- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "\"> ")
1727+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "\"> ")
17161728 if templ_7745c5c3_Err != nil {
17171729 return templ_7745c5c3_Err
17181730 }
17191731 if c.Resolve.From > 0 {
1720- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "<input type=\"hidden\" name=\"from\" value=\"")
1732+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "<input type=\"hidden\" name=\"from\" value=\"")
17211733 if templ_7745c5c3_Err != nil {
17221734 return templ_7745c5c3_Err
17231735 }
17241736 var templ_7745c5c3_Var83 string
17251737 templ_7745c5c3_Var83, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Resolve.From))
17261738 if templ_7745c5c3_Err != nil {
1727- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 313, Col: 66}
1739+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 317, Col: 66}
17281740 }
17291741 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var83)
17301742 if templ_7745c5c3_Err != nil {
17311743 return templ_7745c5c3_Err
17321744 }
1733- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "\"> ")
1745+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "\"> ")
17341746 if templ_7745c5c3_Err != nil {
17351747 return templ_7745c5c3_Err
17361748 }
17371749 }
1738- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "<button type=\"submit\" class=\"btn\">")
1750+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "<button type=\"submit\" class=\"btn\">")
17391751 if templ_7745c5c3_Err != nil {
17401752 return templ_7745c5c3_Err
17411753 }
17421754 var templ_7745c5c3_Var84 string
17431755 templ_7745c5c3_Var84, templ_7745c5c3_Err = templ.JoinStringErrs(c.Resolve.Label)
17441756 if templ_7745c5c3_Err != nil {
1745- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 315, Col: 55}
1757+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 319, Col: 55}
17461758 }
17471759 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var84))
17481760 if templ_7745c5c3_Err != nil {
17491761 return templ_7745c5c3_Err
17501762 }
1751- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "</button></form>")
1763+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "</button></form>")
17521764 if templ_7745c5c3_Err != nil {
17531765 return templ_7745c5c3_Err
17541766 }
17551767 }
1756- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "</div>")
1768+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "</div>")
17571769 if templ_7745c5c3_Err != nil {
17581770 return templ_7745c5c3_Err
17591771 }
@@ -1790,209 +1802,209 @@ func commentForm(f CommentForm, suffix string) templ.Component {
17901802 templ_7745c5c3_Var85 = templ.NopComponent
17911803 }
17921804 ctx = templ.ClearChildren(ctx)
1793- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "<form class=\"cform\" method=\"post\" action=\"")
1805+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "<form class=\"cform\" method=\"post\" action=\"")
17941806 if templ_7745c5c3_Err != nil {
17951807 return templ_7745c5c3_Err
17961808 }
17971809 var templ_7745c5c3_Var86 templ.SafeURL
17981810 templ_7745c5c3_Var86, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(f.Action))
17991811 if templ_7745c5c3_Err != nil {
1800- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 330, Col: 67}
1812+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 334, Col: 67}
18011813 }
18021814 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var86))
18031815 if templ_7745c5c3_Err != nil {
18041816 return templ_7745c5c3_Err
18051817 }
1806- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "\"><label for=\"")
1818+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "\"><label for=\"")
18071819 if templ_7745c5c3_Err != nil {
18081820 return templ_7745c5c3_Err
18091821 }
18101822 var templ_7745c5c3_Var87 string
18111823 templ_7745c5c3_Var87, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID + suffix)
18121824 if templ_7745c5c3_Err != nil {
1813- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 331, Col: 28}
1825+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 335, Col: 28}
18141826 }
18151827 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var87)
18161828 if templ_7745c5c3_Err != nil {
18171829 return templ_7745c5c3_Err
18181830 }
1819- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "\">")
1831+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\">")
18201832 if templ_7745c5c3_Err != nil {
18211833 return templ_7745c5c3_Err
18221834 }
18231835 var templ_7745c5c3_Var88 string
18241836 templ_7745c5c3_Var88, templ_7745c5c3_Err = templ.JoinStringErrs(f.Title)
18251837 if templ_7745c5c3_Err != nil {
1826- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 331, Col: 40}
1838+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 335, Col: 40}
18271839 }
18281840 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var88))
18291841 if templ_7745c5c3_Err != nil {
18301842 return templ_7745c5c3_Err
18311843 }
1832- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "</label> <textarea id=\"")
1844+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, "</label> <textarea id=\"")
18331845 if templ_7745c5c3_Err != nil {
18341846 return templ_7745c5c3_Err
18351847 }
18361848 var templ_7745c5c3_Var89 string
18371849 templ_7745c5c3_Var89, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID + suffix)
18381850 if templ_7745c5c3_Err != nil {
1839- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 333, Col: 21}
1851+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 337, Col: 21}
18401852 }
18411853 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var89)
18421854 if templ_7745c5c3_Err != nil {
18431855 return templ_7745c5c3_Err
18441856 }
1845- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\" name=\"text\" rows=\"3\" maxlength=\"8000\"")
1857+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, "\" name=\"text\" rows=\"3\" maxlength=\"8000\"")
18461858 if templ_7745c5c3_Err != nil {
18471859 return templ_7745c5c3_Err
18481860 }
18491861 if f.Plain {
1850- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, " required placeholder=\"plain text, 8000 characters at most\"")
1862+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, " required placeholder=\"plain text, 8000 characters at most\"")
18511863 if templ_7745c5c3_Err != nil {
18521864 return templ_7745c5c3_Err
18531865 }
18541866 } else {
1855- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, " placeholder=\"Markdown, 8000 characters at most\"")
1867+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, " placeholder=\"Markdown, 8000 characters at most\"")
18561868 if templ_7745c5c3_Err != nil {
18571869 return templ_7745c5c3_Err
18581870 }
18591871 }
18601872 if f.Focus {
1861- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, " autofocus")
1873+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, " autofocus")
18621874 if templ_7745c5c3_Err != nil {
18631875 return templ_7745c5c3_Err
18641876 }
18651877 }
1866- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, "></textarea> ")
1878+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "></textarea> ")
18671879 if templ_7745c5c3_Err != nil {
18681880 return templ_7745c5c3_Err
18691881 }
18701882 if f.Path != "" {
1871- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, "<input type=\"hidden\" name=\"path\" value=\"")
1883+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "<input type=\"hidden\" name=\"path\" value=\"")
18721884 if templ_7745c5c3_Err != nil {
18731885 return templ_7745c5c3_Err
18741886 }
18751887 var templ_7745c5c3_Var90 string
18761888 templ_7745c5c3_Var90, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path)
18771889 if templ_7745c5c3_Err != nil {
1878- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 348, Col: 50}
1890+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 352, Col: 50}
18791891 }
18801892 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var90)
18811893 if templ_7745c5c3_Err != nil {
18821894 return templ_7745c5c3_Err
18831895 }
1884- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "\"> <input type=\"hidden\" name=\"line\" value=\"")
1896+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "\"> <input type=\"hidden\" name=\"line\" value=\"")
18851897 if templ_7745c5c3_Err != nil {
18861898 return templ_7745c5c3_Err
18871899 }
18881900 var templ_7745c5c3_Var91 string
18891901 templ_7745c5c3_Var91, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Line)
18901902 if templ_7745c5c3_Err != nil {
1891- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 349, Col: 50}
1903+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 353, Col: 50}
18921904 }
18931905 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var91)
18941906 if templ_7745c5c3_Err != nil {
18951907 return templ_7745c5c3_Err
18961908 }
1897- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "\"> <input type=\"hidden\" name=\"side\" value=\"")
1909+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "\"> <input type=\"hidden\" name=\"side\" value=\"")
18981910 if templ_7745c5c3_Err != nil {
18991911 return templ_7745c5c3_Err
19001912 }
19011913 var templ_7745c5c3_Var92 string
19021914 templ_7745c5c3_Var92, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Side)
19031915 if templ_7745c5c3_Err != nil {
1904- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 350, Col: 50}
1916+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 354, Col: 50}
19051917 }
19061918 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var92)
19071919 if templ_7745c5c3_Err != nil {
19081920 return templ_7745c5c3_Err
19091921 }
1910- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "\"> <label>from line <input type=\"number\" name=\"start_line\" min=\"1\" value=\"")
1922+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "\"> <label>from line <input type=\"number\" name=\"start_line\" min=\"1\" value=\"")
19111923 if templ_7745c5c3_Err != nil {
19121924 return templ_7745c5c3_Err
19131925 }
19141926 var templ_7745c5c3_Var93 string
19151927 templ_7745c5c3_Var93, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.StartLine)
19161928 if templ_7745c5c3_Err != nil {
1917- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 351, Col: 86}
1929+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 355, Col: 86}
19181930 }
19191931 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var93)
19201932 if templ_7745c5c3_Err != nil {
19211933 return templ_7745c5c3_Err
19221934 }
1923- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "\"></label> ")
1935+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "\"></label> ")
19241936 if templ_7745c5c3_Err != nil {
19251937 return templ_7745c5c3_Err
19261938 }
19271939 }
19281940 if f.ReplyTo != "" {
1929- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "<input type=\"hidden\" name=\"reply_to\" value=\"")
1941+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "<input type=\"hidden\" name=\"reply_to\" value=\"")
19301942 if templ_7745c5c3_Err != nil {
19311943 return templ_7745c5c3_Err
19321944 }
19331945 var templ_7745c5c3_Var94 string
19341946 templ_7745c5c3_Var94, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ReplyTo)
19351947 if templ_7745c5c3_Err != nil {
1936- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 354, Col: 57}
1948+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 358, Col: 57}
19371949 }
19381950 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var94)
19391951 if templ_7745c5c3_Err != nil {
19401952 return templ_7745c5c3_Err
19411953 }
1942- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "\"> ")
1954+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "\"> ")
19431955 if templ_7745c5c3_Err != nil {
19441956 return templ_7745c5c3_Err
19451957 }
19461958 }
19471959 if f.Path == "" && f.ReplyTo == "" && !f.Plain {
1948- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "<fieldset><legend>Verdict</legend><label><input type=\"radio\" name=\"verdict\" value=\"\" checked>Note</label><label><input type=\"radio\" name=\"verdict\" value=\"approve\">Approve</label><label><input type=\"radio\" name=\"verdict\" value=\"changes_requested\">Request changes</label></fieldset>")
1960+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "<fieldset><legend>Verdict</legend><label><input type=\"radio\" name=\"verdict\" value=\"\" checked>Note</label><label><input type=\"radio\" name=\"verdict\" value=\"approve\">Approve</label><label><input type=\"radio\" name=\"verdict\" value=\"changes_requested\">Request changes</label></fieldset>")
19491961 if templ_7745c5c3_Err != nil {
19501962 return templ_7745c5c3_Err
19511963 }
19521964 }
19531965 if f.From > 0 {
1954- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "<input type=\"hidden\" name=\"from\" value=\"")
1966+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "<input type=\"hidden\" name=\"from\" value=\"")
19551967 if templ_7745c5c3_Err != nil {
19561968 return templ_7745c5c3_Err
19571969 }
19581970 var templ_7745c5c3_Var95 string
19591971 templ_7745c5c3_Var95, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(f.From))
19601972 if templ_7745c5c3_Err != nil {
1961- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 360, Col: 56}
1973+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 364, Col: 56}
19621974 }
19631975 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var95)
19641976 if templ_7745c5c3_Err != nil {
19651977 return templ_7745c5c3_Err
19661978 }
1967- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "\">")
1979+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "\">")
19681980 if templ_7745c5c3_Err != nil {
19691981 return templ_7745c5c3_Err
19701982 }
19711983 }
1972- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "<div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Comment</button> ")
1984+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "<div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Comment</button> ")
19731985 if templ_7745c5c3_Err != nil {
19741986 return templ_7745c5c3_Err
19751987 }
19761988 if f.Cancel != "" {
1977- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "<a class=\"btn\" href=\"")
1989+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "<a class=\"btn\" href=\"")
19781990 if templ_7745c5c3_Err != nil {
19791991 return templ_7745c5c3_Err
19801992 }
19811993 var templ_7745c5c3_Var96 templ.SafeURL
19821994 templ_7745c5c3_Var96, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(f.Cancel))
19831995 if templ_7745c5c3_Err != nil {
1984- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 365, Col: 49}
1996+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 369, Col: 49}
19851997 }
19861998 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var96))
19871999 if templ_7745c5c3_Err != nil {
19882000 return templ_7745c5c3_Err
19892001 }
1990- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "\">Cancel</a>")
2002+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "\">Cancel</a>")
19912003 if templ_7745c5c3_Err != nil {
19922004 return templ_7745c5c3_Err
19932005 }
19942006 }
1995- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "</div></form>")
2007+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "</div></form>")
19962008 if templ_7745c5c3_Err != nil {
19972009 return templ_7745c5c3_Err
19982010 }
@@ -2021,46 +2033,46 @@ func mrFooter(p MRPage) templ.Component {
20212033 templ_7745c5c3_Var97 = templ.NopComponent
20222034 }
20232035 ctx = templ.ClearChildren(ctx)
2024- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "<footer class=\"mr-footer\"><details id=\"mr-panels\"><summary>Commits <span class=\"count\">")
2036+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "<footer class=\"mr-footer\"><details id=\"mr-panels\"><summary>Commits <span class=\"count\">")
20252037 if templ_7745c5c3_Err != nil {
20262038 return templ_7745c5c3_Err
20272039 }
20282040 var templ_7745c5c3_Var98 string
20292041 templ_7745c5c3_Var98, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitCount)
20302042 if templ_7745c5c3_Err != nil {
2031- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 374, Col: 55}
2043+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 378, Col: 55}
20322044 }
20332045 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var98))
20342046 if templ_7745c5c3_Err != nil {
20352047 return templ_7745c5c3_Err
20362048 }
2037- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "</span> · Checks</summary><nav data-mr-tabs aria-label=\"Branch details\"><a id=\"mr-tab-commits\" href=\"#mr-commits\">Commits <span class=\"count\">")
2049+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, "</span> · Checks</summary><nav data-mr-tabs aria-label=\"Branch details\"><a id=\"mr-tab-commits\" href=\"#mr-commits\">Commits <span class=\"count\">")
20382050 if templ_7745c5c3_Err != nil {
20392051 return templ_7745c5c3_Err
20402052 }
20412053 var templ_7745c5c3_Var99 string
20422054 templ_7745c5c3_Var99, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitCount)
20432055 if templ_7745c5c3_Err != nil {
2044- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 376, Col: 89}
2056+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 380, Col: 89}
20452057 }
20462058 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var99))
20472059 if templ_7745c5c3_Err != nil {
20482060 return templ_7745c5c3_Err
20492061 }
2050- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "</span></a> <a id=\"mr-tab-checks\" href=\"#mr-checks\">")
2062+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "</span></a> <a id=\"mr-tab-checks\" href=\"#mr-checks\">")
20512063 if templ_7745c5c3_Err != nil {
20522064 return templ_7745c5c3_Err
20532065 }
20542066 var templ_7745c5c3_Var100 string
20552067 templ_7745c5c3_Var100, templ_7745c5c3_Err = templ.JoinStringErrs("Checks ")
20562068 if templ_7745c5c3_Err != nil {
2057- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 378, Col: 16}
2069+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 382, Col: 16}
20582070 }
20592071 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var100))
20602072 if templ_7745c5c3_Err != nil {
20612073 return templ_7745c5c3_Err
20622074 }
2063- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, " <span data-checks-label>")
2075+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, " <span data-checks-label>")
20642076 if templ_7745c5c3_Err != nil {
20652077 return templ_7745c5c3_Err
20662078 }
@@ -2068,122 +2080,122 @@ func mrFooter(p MRPage) templ.Component {
20682080 var templ_7745c5c3_Var101 string
20692081 templ_7745c5c3_Var101, templ_7745c5c3_Err = templ.JoinStringErrs(p.ChecksSum.Title)
20702082 if templ_7745c5c3_Err != nil {
2071- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 381, Col: 26}
2083+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 385, Col: 26}
20722084 }
20732085 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var101))
20742086 if templ_7745c5c3_Err != nil {
20752087 return templ_7745c5c3_Err
20762088 }
20772089 } else {
2078- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "no checks")
2090+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 191, "no checks")
20792091 if templ_7745c5c3_Err != nil {
20802092 return templ_7745c5c3_Err
20812093 }
20822094 }
2083- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, "</span></a></nav><div id=\"mr-commits\" data-mr-panel aria-labelledby=\"mr-tab-commits\"><table class=\"mr-commits\"><thead><tr><th>Commit</th><th>Subject</th><th>Author</th><th>Date</th><th>Signature</th><th>Status</th></tr></thead> <tbody>")
2095+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 192, "</span></a></nav><div id=\"mr-commits\" data-mr-panel aria-labelledby=\"mr-tab-commits\"><table class=\"mr-commits\"><thead><tr><th>Commit</th><th>Subject</th><th>Author</th><th>Date</th><th>Signature</th><th>Status</th></tr></thead> <tbody>")
20842096 if templ_7745c5c3_Err != nil {
20852097 return templ_7745c5c3_Err
20862098 }
20872099 for _, c := range p.Commits {
2088- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 191, "<tr")
2100+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 193, "<tr")
20892101 if templ_7745c5c3_Err != nil {
20902102 return templ_7745c5c3_Err
20912103 }
20922104 if c.New {
2093- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 192, " data-new")
2105+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 194, " data-new")
20942106 if templ_7745c5c3_Err != nil {
20952107 return templ_7745c5c3_Err
20962108 }
20972109 }
2098- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 193, "><td><a href=\"")
2110+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 195, "><td><a href=\"")
20992111 if templ_7745c5c3_Err != nil {
21002112 return templ_7745c5c3_Err
21012113 }
21022114 var templ_7745c5c3_Var102 templ.SafeURL
21032115 templ_7745c5c3_Var102, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Href))
21042116 if templ_7745c5c3_Err != nil {
2105- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 394, Col: 43}
2117+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 398, Col: 43}
21062118 }
21072119 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var102))
21082120 if templ_7745c5c3_Err != nil {
21092121 return templ_7745c5c3_Err
21102122 }
2111- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 194, "\">")
2123+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 196, "\">")
21122124 if templ_7745c5c3_Err != nil {
21132125 return templ_7745c5c3_Err
21142126 }
21152127 var templ_7745c5c3_Var103 string
21162128 templ_7745c5c3_Var103, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)
21172129 if templ_7745c5c3_Err != nil {
2118- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 394, Col: 55}
2130+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 398, Col: 55}
21192131 }
21202132 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var103))
21212133 if templ_7745c5c3_Err != nil {
21222134 return templ_7745c5c3_Err
21232135 }
2124- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 195, "</a></td><td>")
2136+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 197, "</a></td><td>")
21252137 if templ_7745c5c3_Err != nil {
21262138 return templ_7745c5c3_Err
21272139 }
21282140 var templ_7745c5c3_Var104 string
21292141 templ_7745c5c3_Var104, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)
21302142 if templ_7745c5c3_Err != nil {
2131- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 395, Col: 23}
2143+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 399, Col: 23}
21322144 }
21332145 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var104))
21342146 if templ_7745c5c3_Err != nil {
21352147 return templ_7745c5c3_Err
21362148 }
2137- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 196, "</td><td>")
2149+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 198, "</td><td>")
21382150 if templ_7745c5c3_Err != nil {
21392151 return templ_7745c5c3_Err
21402152 }
21412153 var templ_7745c5c3_Var105 string
21422154 templ_7745c5c3_Var105, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
21432155 if templ_7745c5c3_Err != nil {
2144- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 396, Col: 22}
2156+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 400, Col: 22}
21452157 }
21462158 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var105))
21472159 if templ_7745c5c3_Err != nil {
21482160 return templ_7745c5c3_Err
21492161 }
2150- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 197, "</td><td>")
2162+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 199, "</td><td>")
21512163 if templ_7745c5c3_Err != nil {
21522164 return templ_7745c5c3_Err
21532165 }
21542166 if c.WhenAt != "" {
2155- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 198, "<time datetime=\"")
2167+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 200, "<time datetime=\"")
21562168 if templ_7745c5c3_Err != nil {
21572169 return templ_7745c5c3_Err
21582170 }
21592171 var templ_7745c5c3_Var106 string
21602172 templ_7745c5c3_Var106, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
21612173 if templ_7745c5c3_Err != nil {
2162- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 399, Col: 35}
2174+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 403, Col: 35}
21632175 }
21642176 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var106)
21652177 if templ_7745c5c3_Err != nil {
21662178 return templ_7745c5c3_Err
21672179 }
2168- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 199, "\">")
2180+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 201, "\">")
21692181 if templ_7745c5c3_Err != nil {
21702182 return templ_7745c5c3_Err
21712183 }
21722184 var templ_7745c5c3_Var107 string
21732185 templ_7745c5c3_Var107, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
21742186 if templ_7745c5c3_Err != nil {
2175- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 399, Col: 46}
2187+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 403, Col: 46}
21762188 }
21772189 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var107))
21782190 if templ_7745c5c3_Err != nil {
21792191 return templ_7745c5c3_Err
21802192 }
2181- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 200, "</time>")
2193+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 202, "</time>")
21822194 if templ_7745c5c3_Err != nil {
21832195 return templ_7745c5c3_Err
21842196 }
21852197 }
2186- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 201, "</td><td>")
2198+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 203, "</td><td>")
21872199 if templ_7745c5c3_Err != nil {
21882200 return templ_7745c5c3_Err
21892201 }
@@ -2193,51 +2205,51 @@ func mrFooter(p MRPage) templ.Component {
21932205 return templ_7745c5c3_Err
21942206 }
21952207 }
2196- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 202, "</td><td>")
2208+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 204, "</td><td>")
21972209 if templ_7745c5c3_Err != nil {
21982210 return templ_7745c5c3_Err
21992211 }
22002212 if c.New {
2201- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 203, "<span>new</span>")
2213+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 205, "<span>new</span>")
22022214 if templ_7745c5c3_Err != nil {
22032215 return templ_7745c5c3_Err
22042216 }
22052217 }
2206- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 204, "</td></tr>")
2218+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 206, "</td></tr>")
22072219 if templ_7745c5c3_Err != nil {
22082220 return templ_7745c5c3_Err
22092221 }
22102222 }
2211- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 205, "</tbody></table>")
2223+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 207, "</tbody></table>")
22122224 if templ_7745c5c3_Err != nil {
22132225 return templ_7745c5c3_Err
22142226 }
22152227 if len(p.Commits) == 0 {
2216- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 206, "<p class=\"dim\">no commit to merge.</p>")
2228+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 208, "<p class=\"dim\">no commit to merge.</p>")
22172229 if templ_7745c5c3_Err != nil {
22182230 return templ_7745c5c3_Err
22192231 }
22202232 }
22212233 if p.CommitsNote != "" {
2222- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 207, "<p class=\"note\">")
2234+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 209, "<p class=\"note\">")
22232235 if templ_7745c5c3_Err != nil {
22242236 return templ_7745c5c3_Err
22252237 }
22262238 var templ_7745c5c3_Var108 string
22272239 templ_7745c5c3_Var108, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitsNote)
22282240 if templ_7745c5c3_Err != nil {
2229- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 420, Col: 36}
2241+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 424, Col: 36}
22302242 }
22312243 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var108))
22322244 if templ_7745c5c3_Err != nil {
22332245 return templ_7745c5c3_Err
22342246 }
2235- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 208, "</p>")
2247+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 210, "</p>")
22362248 if templ_7745c5c3_Err != nil {
22372249 return templ_7745c5c3_Err
22382250 }
22392251 }
2240- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 209, "</div><div id=\"mr-checks-panel\" data-mr-panel aria-labelledby=\"mr-tab-checks\">")
2252+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 211, "</div><div id=\"mr-checks-panel\" data-mr-panel aria-labelledby=\"mr-tab-checks\">")
22412253 if templ_7745c5c3_Err != nil {
22422254 return templ_7745c5c3_Err
22432255 }
@@ -2245,7 +2257,7 @@ func mrFooter(p MRPage) templ.Component {
22452257 if templ_7745c5c3_Err != nil {
22462258 return templ_7745c5c3_Err
22472259 }
2248- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 210, "</div></details></footer>")
2260+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 212, "</div></details></footer>")
22492261 if templ_7745c5c3_Err != nil {
22502262 return templ_7745c5c3_Err
22512263 }
@@ -2274,20 +2286,20 @@ func mrRail(p MRPage) templ.Component {
22742286 templ_7745c5c3_Var109 = templ.NopComponent
22752287 }
22762288 ctx = templ.ClearChildren(ctx)
2277- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 211, "<section aria-labelledby=\"r-files\" class=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
2289+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 213, "<section aria-labelledby=\"r-files\" class=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
22782290 if templ_7745c5c3_Err != nil {
22792291 return templ_7745c5c3_Err
22802292 }
22812293 var templ_7745c5c3_Var110 string
22822294 templ_7745c5c3_Var110, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
22832295 if templ_7745c5c3_Err != nil {
2284- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 433, Col: 49}
2296+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 437, Col: 49}
22852297 }
22862298 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var110))
22872299 if templ_7745c5c3_Err != nil {
22882300 return templ_7745c5c3_Err
22892301 }
2290- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 212, "</span><kbd aria-hidden=\"true\">g f</kbd> <button type=\"button\" class=\"btn icon fold\" data-js aria-expanded=\"true\" title=\"fold the list of files\" hx-on:click=\"ermiteMR.foldFiles()\"><span class=\"ico i-chevron\" aria-hidden=\"true\"></span><span class=\"sr\">fold the list of files</span></button></h2>")
2302+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 214, "</span><kbd aria-hidden=\"true\">g f</kbd> <button type=\"button\" class=\"btn icon fold\" data-js aria-expanded=\"true\" title=\"fold the list of files\" hx-on:click=\"ermiteMR.foldFiles()\"><span class=\"ico i-chevron\" aria-hidden=\"true\"></span><span class=\"sr\">fold the list of files</span></button></h2>")
22912303 if templ_7745c5c3_Err != nil {
22922304 return templ_7745c5c3_Err
22932305 }
@@ -2295,71 +2307,71 @@ func mrRail(p MRPage) templ.Component {
22952307 if templ_7745c5c3_Err != nil {
22962308 return templ_7745c5c3_Err
22972309 }
2298- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 213, "</section>")
2310+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 215, "</section>")
22992311 if templ_7745c5c3_Err != nil {
23002312 return templ_7745c5c3_Err
23012313 }
23022314 if len(p.Verdicts) > 0 {
2303- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 214, "<section><h2>Verdicts</h2><ul>")
2315+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 216, "<section><h2>Verdicts</h2><ul>")
23042316 if templ_7745c5c3_Err != nil {
23052317 return templ_7745c5c3_Err
23062318 }
23072319 for _, v := range p.Verdicts {
2308- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 215, "<li><a href=\"")
2320+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 217, "<li><a href=\"")
23092321 if templ_7745c5c3_Err != nil {
23102322 return templ_7745c5c3_Err
23112323 }
23122324 var templ_7745c5c3_Var111 templ.SafeURL
23132325 templ_7745c5c3_Var111, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(v.Href))
23142326 if templ_7745c5c3_Err != nil {
2315- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 446, Col: 37}
2327+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 450, Col: 37}
23162328 }
23172329 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var111))
23182330 if templ_7745c5c3_Err != nil {
23192331 return templ_7745c5c3_Err
23202332 }
2321- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 216, "\">")
2333+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 218, "\">")
23222334 if templ_7745c5c3_Err != nil {
23232335 return templ_7745c5c3_Err
23242336 }
23252337 var templ_7745c5c3_Var112 string
23262338 templ_7745c5c3_Var112, templ_7745c5c3_Err = templ.JoinStringErrs(v.Author)
23272339 if templ_7745c5c3_Err != nil {
2328- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 446, Col: 50}
2340+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 450, Col: 50}
23292341 }
23302342 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var112))
23312343 if templ_7745c5c3_Err != nil {
23322344 return templ_7745c5c3_Err
23332345 }
2334- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 217, ": ")
2346+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 219, ": ")
23352347 if templ_7745c5c3_Err != nil {
23362348 return templ_7745c5c3_Err
23372349 }
23382350 var templ_7745c5c3_Var113 string
23392351 templ_7745c5c3_Var113, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)
23402352 if templ_7745c5c3_Err != nil {
2341- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 446, Col: 63}
2353+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 450, Col: 63}
23422354 }
23432355 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var113))
23442356 if templ_7745c5c3_Err != nil {
23452357 return templ_7745c5c3_Err
23462358 }
2347- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 218, "</a> ")
2359+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 220, "</a> ")
23482360 if templ_7745c5c3_Err != nil {
23492361 return templ_7745c5c3_Err
23502362 }
23512363 if v.Stale {
2352- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 219, "<span class=\"mute\">(stale)</span>")
2364+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 221, "<span class=\"mute\">(stale)</span>")
23532365 if templ_7745c5c3_Err != nil {
23542366 return templ_7745c5c3_Err
23552367 }
23562368 }
2357- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 220, "</li>")
2369+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 222, "</li>")
23582370 if templ_7745c5c3_Err != nil {
23592371 return templ_7745c5c3_Err
23602372 }
23612373 }
2362- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 221, "</ul></section>")
2374+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 223, "</ul></section>")
23632375 if templ_7745c5c3_Err != nil {
23642376 return templ_7745c5c3_Err
23652377 }
@@ -2393,46 +2405,46 @@ func mrBar(p MRPage) templ.Component {
23932405 templ_7745c5c3_Var114 = templ.NopComponent
23942406 }
23952407 ctx = templ.ClearChildren(ctx)
2396- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 222, "<div class=\"diff-tools mr-bar\" role=\"group\" aria-label=\"Diff view and merge\"><span class=\"dim\">")
2408+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 224, "<div class=\"diff-tools mr-bar\" role=\"group\" aria-label=\"Diff view and merge\"><span class=\"dim\">")
23972409 if templ_7745c5c3_Err != nil {
23982410 return templ_7745c5c3_Err
23992411 }
24002412 var templ_7745c5c3_Var115 string
24012413 templ_7745c5c3_Var115, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))
24022414 if templ_7745c5c3_Err != nil {
2403- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 463, Col: 55}
2415+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 467, Col: 55}
24042416 }
24052417 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var115))
24062418 if templ_7745c5c3_Err != nil {
24072419 return templ_7745c5c3_Err
24082420 }
2409- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 223, " · <span class=\"plus\">+")
2421+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 225, " · <span class=\"plus\">+")
24102422 if templ_7745c5c3_Err != nil {
24112423 return templ_7745c5c3_Err
24122424 }
24132425 var templ_7745c5c3_Var116 string
24142426 templ_7745c5c3_Var116, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))
24152427 if templ_7745c5c3_Err != nil {
2416- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 463, Col: 95}
2428+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 467, Col: 95}
24172429 }
24182430 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var116))
24192431 if templ_7745c5c3_Err != nil {
24202432 return templ_7745c5c3_Err
24212433 }
2422- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 224, "</span> <span class=\"minus\">-")
2434+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 226, "</span> <span class=\"minus\">-")
24232435 if templ_7745c5c3_Err != nil {
24242436 return templ_7745c5c3_Err
24252437 }
24262438 var templ_7745c5c3_Var117 string
24272439 templ_7745c5c3_Var117, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))
24282440 if templ_7745c5c3_Err != nil {
2429- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 463, Col: 140}
2441+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 467, Col: 140}
24302442 }
24312443 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var117))
24322444 if templ_7745c5c3_Err != nil {
24332445 return templ_7745c5c3_Err
24342446 }
2435- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 225, "</span></span>")
2447+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 227, "</span></span>")
24362448 if templ_7745c5c3_Err != nil {
24372449 return templ_7745c5c3_Err
24382450 }
@@ -2440,7 +2452,7 @@ func mrBar(p MRPage) templ.Component {
24402452 if templ_7745c5c3_Err != nil {
24412453 return templ_7745c5c3_Err
24422454 }
2443- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 226, "<span class=\"grow\"></span>")
2455+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 228, "<span class=\"grow\"></span>")
24442456 if templ_7745c5c3_Err != nil {
24452457 return templ_7745c5c3_Err
24462458 }
@@ -2458,7 +2470,7 @@ func mrBar(p MRPage) templ.Component {
24582470 if templ_7745c5c3_Err != nil {
24592471 return templ_7745c5c3_Err
24602472 }
2461- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 227, "</div>")
2473+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 229, "</div>")
24622474 if templ_7745c5c3_Err != nil {
24632475 return templ_7745c5c3_Err
24642476 }
@@ -2495,75 +2507,75 @@ func mergeMenu(p MRPage) templ.Component {
24952507 templ_7745c5c3_Var118 = templ.NopComponent
24962508 }
24972509 ctx = templ.ClearChildren(ctx)
2498- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 228, "<details class=\"menu mmenu\" id=\"merge-menu\" data-state=\"open\"")
2510+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 230, "<details class=\"menu mmenu\" id=\"merge-menu\" data-state=\"open\"")
24992511 if templ_7745c5c3_Err != nil {
25002512 return templ_7745c5c3_Err
25012513 }
25022514 if p.Box.Error != "" {
2503- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 229, " open")
2515+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 231, " open")
25042516 if templ_7745c5c3_Err != nil {
25052517 return templ_7745c5c3_Err
25062518 }
25072519 }
2508- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 230, "><summary class=\"btn primary\" aria-keyshortcuts=\"Shift+M\">")
2520+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 232, "><summary class=\"btn primary\" aria-keyshortcuts=\"Shift+M\">")
25092521 if templ_7745c5c3_Err != nil {
25102522 return templ_7745c5c3_Err
25112523 }
25122524 if p.Box.ReadyAction != "" {
2513- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 231, "Draft ")
2525+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 233, "Draft ")
25142526 if templ_7745c5c3_Err != nil {
25152527 return templ_7745c5c3_Err
25162528 }
25172529 } else {
2518- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 232, "Merge ")
2530+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 234, "Merge ")
25192531 if templ_7745c5c3_Err != nil {
25202532 return templ_7745c5c3_Err
25212533 }
25222534 }
2523- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 233, "<kbd aria-hidden=\"true\">M</kbd></summary><div class=\"menu-pop\" role=\"group\" aria-label=\"Merge\">")
2535+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 235, "<kbd aria-hidden=\"true\">M</kbd></summary><div class=\"menu-pop\" role=\"group\" aria-label=\"Merge\">")
25242536 if templ_7745c5c3_Err != nil {
25252537 return templ_7745c5c3_Err
25262538 }
25272539 if p.Box.HeadGone {
2528- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 234, "<p class=\"dim\">the source branch was deleted</p>")
2540+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 236, "<p class=\"dim\">the source branch was deleted</p>")
25292541 if templ_7745c5c3_Err != nil {
25302542 return templ_7745c5c3_Err
25312543 }
25322544 }
25332545 if p.Box.Error != "" {
2534- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 235, "<p class=\"d-err\" role=\"alert\">")
2546+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 237, "<p class=\"d-err\" role=\"alert\">")
25352547 if templ_7745c5c3_Err != nil {
25362548 return templ_7745c5c3_Err
25372549 }
25382550 var templ_7745c5c3_Var119 string
25392551 templ_7745c5c3_Var119, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Error)
25402552 if templ_7745c5c3_Err != nil {
2541- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 497, Col: 47}
2553+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 501, Col: 47}
25422554 }
25432555 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var119))
25442556 if templ_7745c5c3_Err != nil {
25452557 return templ_7745c5c3_Err
25462558 }
2547- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 236, "</p>")
2559+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 238, "</p>")
25482560 if templ_7745c5c3_Err != nil {
25492561 return templ_7745c5c3_Err
25502562 }
25512563 }
25522564 if p.Box.ReadyAction != "" {
2553- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 237, "<p class=\"d-draft\">this is a draft: it cannot be merged until it is ready for review.</p><form class=\"d-btns\" method=\"post\" action=\"")
2565+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 239, "<p class=\"d-draft\">this is a draft: it cannot be merged until it is ready for review.</p><form class=\"d-btns\" method=\"post\" action=\"")
25542566 if templ_7745c5c3_Err != nil {
25552567 return templ_7745c5c3_Err
25562568 }
25572569 var templ_7745c5c3_Var120 templ.SafeURL
25582570 templ_7745c5c3_Var120, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadyAction))
25592571 if templ_7745c5c3_Err != nil {
2560- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 501, Col: 80}
2572+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 505, Col: 80}
25612573 }
25622574 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var120))
25632575 if templ_7745c5c3_Err != nil {
25642576 return templ_7745c5c3_Err
25652577 }
2566- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 238, "\"><button type=\"submit\" class=\"btn primary\" data-default title=\"remove the draft prefix from the title\">Ready for review</button></form>")
2578+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 240, "\"><button type=\"submit\" class=\"btn primary\" data-default title=\"remove the draft prefix from the title\">Ready for review</button></form>")
25672579 if templ_7745c5c3_Err != nil {
25682580 return templ_7745c5c3_Err
25692581 }
@@ -2572,185 +2584,185 @@ func mergeMenu(p MRPage) templ.Component {
25722584 if templ_7745c5c3_Err != nil {
25732585 return templ_7745c5c3_Err
25742586 }
2575- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 239, " <form class=\"d-acts\" method=\"post\" action=\"")
2587+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 241, " <form class=\"d-acts\" method=\"post\" action=\"")
25762588 if templ_7745c5c3_Err != nil {
25772589 return templ_7745c5c3_Err
25782590 }
25792591 var templ_7745c5c3_Var121 templ.SafeURL
25802592 templ_7745c5c3_Var121, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.MergeAction))
25812593 if templ_7745c5c3_Err != nil {
2582- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 506, Col: 80}
2594+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 510, Col: 80}
25832595 }
25842596 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var121))
25852597 if templ_7745c5c3_Err != nil {
25862598 return templ_7745c5c3_Err
25872599 }
2588- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 240, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
2600+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 242, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
25892601 if templ_7745c5c3_Err != nil {
25902602 return templ_7745c5c3_Err
25912603 }
25922604 var templ_7745c5c3_Var122 string
25932605 templ_7745c5c3_Var122, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
25942606 if templ_7745c5c3_Err != nil {
2595- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 507, Col: 59}
2607+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 511, Col: 59}
25962608 }
25972609 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var122)
25982610 if templ_7745c5c3_Err != nil {
25992611 return templ_7745c5c3_Err
26002612 }
2601- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 241, "\"><fieldset class=\"d-modes\"><legend class=\"sr\">merge mode</legend> ")
2613+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 243, "\"><fieldset class=\"d-modes\"><legend class=\"sr\">merge mode</legend> ")
26022614 if templ_7745c5c3_Err != nil {
26032615 return templ_7745c5c3_Err
26042616 }
26052617 for i, m := range p.Box.Modes {
2606- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 242, "<label><input type=\"radio\" name=\"mode\" value=\"")
2618+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 244, "<label><input type=\"radio\" name=\"mode\" value=\"")
26072619 if templ_7745c5c3_Err != nil {
26082620 return templ_7745c5c3_Err
26092621 }
26102622 var templ_7745c5c3_Var123 string
26112623 templ_7745c5c3_Var123, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Value)
26122624 if templ_7745c5c3_Err != nil {
2613- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 515, Col: 24}
2625+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 519, Col: 24}
26142626 }
26152627 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var123)
26162628 if templ_7745c5c3_Err != nil {
26172629 return templ_7745c5c3_Err
26182630 }
2619- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 243, "\"")
2631+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 245, "\"")
26202632 if templ_7745c5c3_Err != nil {
26212633 return templ_7745c5c3_Err
26222634 }
26232635 if i == p.Box.Checked() {
2624- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 244, " checked")
2636+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 246, " checked")
26252637 if templ_7745c5c3_Err != nil {
26262638 return templ_7745c5c3_Err
26272639 }
26282640 }
26292641 if m.Disabled {
2630- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 245, " disabled")
2642+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 247, " disabled")
26312643 if templ_7745c5c3_Err != nil {
26322644 return templ_7745c5c3_Err
26332645 }
26342646 }
2635- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 246, " title=\"")
2647+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 248, " title=\"")
26362648 if templ_7745c5c3_Err != nil {
26372649 return templ_7745c5c3_Err
26382650 }
26392651 var templ_7745c5c3_Var124 string
26402652 templ_7745c5c3_Var124, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Reason)
26412653 if templ_7745c5c3_Err != nil {
2642- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 518, Col: 25}
2654+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 522, Col: 25}
26432655 }
26442656 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var124)
26452657 if templ_7745c5c3_Err != nil {
26462658 return templ_7745c5c3_Err
26472659 }
2648- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 247, "\" :disabled=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffOk !== true : q('[data-mergeability]').data.mergeOk !== true\" :title=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffReason : q('[data-mergeability]').data.mergeReason\"> ")
2660+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 249, "\" :disabled=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffOk !== true : q('[data-mergeability]').data.mergeOk !== true\" :title=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffReason : q('[data-mergeability]').data.mergeReason\"> ")
26492661 if templ_7745c5c3_Err != nil {
26502662 return templ_7745c5c3_Err
26512663 }
26522664 var templ_7745c5c3_Var125 string
26532665 templ_7745c5c3_Var125, templ_7745c5c3_Err = templ.JoinStringErrs(m.Label)
26542666 if templ_7745c5c3_Err != nil {
2655- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 522, Col: 17}
2667+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 526, Col: 17}
26562668 }
26572669 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var125))
26582670 if templ_7745c5c3_Err != nil {
26592671 return templ_7745c5c3_Err
26602672 }
2661- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 248, " ")
2673+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 250, " ")
26622674 if templ_7745c5c3_Err != nil {
26632675 return templ_7745c5c3_Err
26642676 }
26652677 if i < 9 {
2666- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 249, "<kbd aria-hidden=\"true\">")
2678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 251, "<kbd aria-hidden=\"true\">")
26672679 if templ_7745c5c3_Err != nil {
26682680 return templ_7745c5c3_Err
26692681 }
26702682 var templ_7745c5c3_Var126 string
26712683 templ_7745c5c3_Var126, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(i + 1))
26722684 if templ_7745c5c3_Err != nil {
2673- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 524, Col: 46}
2685+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 528, Col: 46}
26742686 }
26752687 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var126))
26762688 if templ_7745c5c3_Err != nil {
26772689 return templ_7745c5c3_Err
26782690 }
2679- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 250, "</kbd>")
2691+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 252, "</kbd>")
26802692 if templ_7745c5c3_Err != nil {
26812693 return templ_7745c5c3_Err
26822694 }
26832695 }
2684- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 251, "</label>")
2696+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 253, "</label>")
26852697 if templ_7745c5c3_Err != nil {
26862698 return templ_7745c5c3_Err
26872699 }
26882700 }
2689- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 252, "</fieldset>")
2701+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 254, "</fieldset>")
26902702 if templ_7745c5c3_Err != nil {
26912703 return templ_7745c5c3_Err
26922704 }
26932705 if p.Box.CanDeleteBranch {
2694- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 253, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")
2706+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 255, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")
26952707 if templ_7745c5c3_Err != nil {
26962708 return templ_7745c5c3_Err
26972709 }
26982710 var templ_7745c5c3_Var127 string
26992711 templ_7745c5c3_Var127, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
27002712 if templ_7745c5c3_Err != nil {
2701- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 530, Col: 102}
2713+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 534, Col: 102}
27022714 }
27032715 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var127))
27042716 if templ_7745c5c3_Err != nil {
27052717 return templ_7745c5c3_Err
27062718 }
2707- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 254, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")
2719+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 256, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")
27082720 if templ_7745c5c3_Err != nil {
27092721 return templ_7745c5c3_Err
27102722 }
27112723 }
2712- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 255, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")
2724+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 257, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")
27132725 if templ_7745c5c3_Err != nil {
27142726 return templ_7745c5c3_Err
27152727 }
27162728 if !p.Box.CanMerge() {
2717- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 256, " disabled")
2729+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 258, " disabled")
27182730 if templ_7745c5c3_Err != nil {
27192731 return templ_7745c5c3_Err
27202732 }
27212733 }
2722- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 257, " title=\"")
2734+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 259, " title=\"")
27232735 if templ_7745c5c3_Err != nil {
27242736 return templ_7745c5c3_Err
27252737 }
27262738 var templ_7745c5c3_Var128 string
27272739 templ_7745c5c3_Var128, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.MergeTitle())
27282740 if templ_7745c5c3_Err != nil {
2729- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 538, Col: 33}
2741+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 542, Col: 33}
27302742 }
27312743 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var128)
27322744 if templ_7745c5c3_Err != nil {
27332745 return templ_7745c5c3_Err
27342746 }
2735- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 258, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")
2747+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 260, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")
27362748 if templ_7745c5c3_Err != nil {
27372749 return templ_7745c5c3_Err
27382750 }
27392751 var templ_7745c5c3_Var129 string
27402752 templ_7745c5c3_Var129, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
27412753 if templ_7745c5c3_Err != nil {
2742- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 541, Col: 28}
2754+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 545, Col: 28}
27432755 }
27442756 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var129))
27452757 if templ_7745c5c3_Err != nil {
27462758 return templ_7745c5c3_Err
27472759 }
2748- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 259, "</button></div></form>")
2760+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 261, "</button></div></form>")
27492761 if templ_7745c5c3_Err != nil {
27502762 return templ_7745c5c3_Err
27512763 }
27522764 }
2753- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 260, "</div></details>")
2765+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 262, "</div></details>")
27542766 if templ_7745c5c3_Err != nil {
27552767 return templ_7745c5c3_Err
27562768 }
@@ -2781,98 +2793,98 @@ func MRMergeability(v MergeabilityView) templ.Component {
27812793 templ_7745c5c3_Var130 = templ.NopComponent
27822794 }
27832795 ctx = templ.ClearChildren(ctx)
2784- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 261, "<span data-mergeability data-state=\"")
2796+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 263, "<span data-mergeability data-state=\"")
27852797 if templ_7745c5c3_Err != nil {
27862798 return templ_7745c5c3_Err
27872799 }
27882800 var templ_7745c5c3_Var131 string
27892801 templ_7745c5c3_Var131, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
27902802 if templ_7745c5c3_Err != nil {
2791- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 554, Col: 22}
2803+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 558, Col: 22}
27922804 }
27932805 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var131)
27942806 if templ_7745c5c3_Err != nil {
27952807 return templ_7745c5c3_Err
27962808 }
2797- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 262, "\" data-ff-ok=\"")
2809+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "\" data-ff-ok=\"")
27982810 if templ_7745c5c3_Err != nil {
27992811 return templ_7745c5c3_Err
28002812 }
28012813 var templ_7745c5c3_Var132 string
28022814 templ_7745c5c3_Var132, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.FFOk))
28032815 if templ_7745c5c3_Err != nil {
2804- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 555, Col: 41}
2816+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 559, Col: 41}
28052817 }
28062818 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var132)
28072819 if templ_7745c5c3_Err != nil {
28082820 return templ_7745c5c3_Err
28092821 }
2810- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 263, "\" data-merge-ok=\"")
2822+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, "\" data-merge-ok=\"")
28112823 if templ_7745c5c3_Err != nil {
28122824 return templ_7745c5c3_Err
28132825 }
28142826 var templ_7745c5c3_Var133 string
28152827 templ_7745c5c3_Var133, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.MergeOk))
28162828 if templ_7745c5c3_Err != nil {
2817- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 556, Col: 47}
2829+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 47}
28182830 }
28192831 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var133)
28202832 if templ_7745c5c3_Err != nil {
28212833 return templ_7745c5c3_Err
28222834 }
2823- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "\" data-ff-reason=\"")
2835+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "\" data-ff-reason=\"")
28242836 if templ_7745c5c3_Err != nil {
28252837 return templ_7745c5c3_Err
28262838 }
28272839 var templ_7745c5c3_Var134 string
28282840 templ_7745c5c3_Var134, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.FFReason)
28292841 if templ_7745c5c3_Err != nil {
2830- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 557, Col: 29}
2842+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 561, Col: 29}
28312843 }
28322844 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var134)
28332845 if templ_7745c5c3_Err != nil {
28342846 return templ_7745c5c3_Err
28352847 }
2836- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, "\" data-merge-reason=\"")
2848+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, "\" data-merge-reason=\"")
28372849 if templ_7745c5c3_Err != nil {
28382850 return templ_7745c5c3_Err
28392851 }
28402852 var templ_7745c5c3_Var135 string
28412853 templ_7745c5c3_Var135, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.MergeReason)
28422854 if templ_7745c5c3_Err != nil {
2843- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 558, Col: 35}
2855+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 562, Col: 35}
28442856 }
28452857 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var135)
28462858 if templ_7745c5c3_Err != nil {
28472859 return templ_7745c5c3_Err
28482860 }
2849- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "\"><span class=\"badge\" data-state=\"")
2861+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, "\"><span class=\"badge\" data-state=\"")
28502862 if templ_7745c5c3_Err != nil {
28512863 return templ_7745c5c3_Err
28522864 }
28532865 var templ_7745c5c3_Var136 string
28542866 templ_7745c5c3_Var136, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
28552867 if templ_7745c5c3_Err != nil {
2856- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 42}
2868+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 42}
28572869 }
28582870 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var136)
28592871 if templ_7745c5c3_Err != nil {
28602872 return templ_7745c5c3_Err
28612873 }
2862- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, "\">")
2874+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, "\">")
28632875 if templ_7745c5c3_Err != nil {
28642876 return templ_7745c5c3_Err
28652877 }
28662878 var templ_7745c5c3_Var137 string
28672879 templ_7745c5c3_Var137, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)
28682880 if templ_7745c5c3_Err != nil {
2869- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 54}
2881+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 54}
28702882 }
28712883 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var137))
28722884 if templ_7745c5c3_Err != nil {
28732885 return templ_7745c5c3_Err
28742886 }
2875- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, "</span> ")
2887+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, "</span> ")
28762888 if templ_7745c5c3_Err != nil {
28772889 return templ_7745c5c3_Err
28782890 }
@@ -2880,78 +2892,78 @@ func MRMergeability(v MergeabilityView) templ.Component {
28802892 var templ_7745c5c3_Var138 string
28812893 templ_7745c5c3_Var138, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
28822894 if templ_7745c5c3_Err != nil {
2883- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 562, Col: 8}
2895+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 566, Col: 8}
28842896 }
28852897 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var138))
28862898 if templ_7745c5c3_Err != nil {
28872899 return templ_7745c5c3_Err
28882900 }
2889- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, "<span class=\"dim\">")
2901+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "<span class=\"dim\">")
28902902 if templ_7745c5c3_Err != nil {
28912903 return templ_7745c5c3_Err
28922904 }
28932905 var templ_7745c5c3_Var139 string
28942906 templ_7745c5c3_Var139, templ_7745c5c3_Err = templ.JoinStringErrs(v.Detail)
28952907 if templ_7745c5c3_Err != nil {
2896- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 562, Col: 38}
2908+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 566, Col: 38}
28972909 }
28982910 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var139))
28992911 if templ_7745c5c3_Err != nil {
29002912 return templ_7745c5c3_Err
29012913 }
2902- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, "</span>")
2914+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "</span>")
29032915 if templ_7745c5c3_Err != nil {
29042916 return templ_7745c5c3_Err
29052917 }
29062918 }
2907- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "</span> ")
2919+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "</span> ")
29082920 if templ_7745c5c3_Err != nil {
29092921 return templ_7745c5c3_Err
29102922 }
29112923 if len(v.Paths) > 0 {
2912- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")
2924+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")
29132925 if templ_7745c5c3_Err != nil {
29142926 return templ_7745c5c3_Err
29152927 }
29162928 for _, path := range v.Paths {
2917- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "<li><code>")
2929+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "<li><code>")
29182930 if templ_7745c5c3_Err != nil {
29192931 return templ_7745c5c3_Err
29202932 }
29212933 var templ_7745c5c3_Var140 string
29222934 templ_7745c5c3_Var140, templ_7745c5c3_Err = templ.JoinStringErrs(path)
29232935 if templ_7745c5c3_Err != nil {
2924- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 568, Col: 20}
2936+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 572, Col: 20}
29252937 }
29262938 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var140))
29272939 if templ_7745c5c3_Err != nil {
29282940 return templ_7745c5c3_Err
29292941 }
2930- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "</code></li>")
2942+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, "</code></li>")
29312943 if templ_7745c5c3_Err != nil {
29322944 return templ_7745c5c3_Err
29332945 }
29342946 }
2935- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "</ul>")
2947+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "</ul>")
29362948 if templ_7745c5c3_Err != nil {
29372949 return templ_7745c5c3_Err
29382950 }
29392951 }
29402952 if v.PathsNote != "" {
2941- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, "<p class=\"dim\">")
2953+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, "<p class=\"dim\">")
29422954 if templ_7745c5c3_Err != nil {
29432955 return templ_7745c5c3_Err
29442956 }
29452957 var templ_7745c5c3_Var141 string
29462958 templ_7745c5c3_Var141, templ_7745c5c3_Err = templ.JoinStringErrs(v.PathsNote)
29472959 if templ_7745c5c3_Err != nil {
2948- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 573, Col: 30}
2960+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 577, Col: 30}
29492961 }
29502962 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var141))
29512963 if templ_7745c5c3_Err != nil {
29522964 return templ_7745c5c3_Err
29532965 }
2954- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "</p>")
2966+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "</p>")
29552967 if templ_7745c5c3_Err != nil {
29562968 return templ_7745c5c3_Err
29572969 }
@@ -2983,7 +2995,7 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
29832995 templ_7745c5c3_Var142 = templ.NopComponent
29842996 }
29852997 ctx = templ.ClearChildren(ctx)
2986- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")
2998+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")
29872999 if templ_7745c5c3_Err != nil {
29883000 return templ_7745c5c3_Err
29893001 }
@@ -2991,7 +3003,7 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
29913003 if templ_7745c5c3_Err != nil {
29923004 return templ_7745c5c3_Err
29933005 }
2994- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "</div>")
3006+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, "</div>")
29953007 if templ_7745c5c3_Err != nil {
29963008 return templ_7745c5c3_Err
29973009 }
@@ -3052,123 +3064,123 @@ func moreMenu(p MRPage) templ.Component {
30523064 templ_7745c5c3_Var144 = templ.NopComponent
30533065 }
30543066 ctx = templ.ClearChildren(ctx)
3055- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")
3067+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")
30563068 if templ_7745c5c3_Err != nil {
30573069 return templ_7745c5c3_Err
30583070 }
30593071 var templ_7745c5c3_Var145 string
30603072 templ_7745c5c3_Var145, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(p.Modes, ", "))
30613073 if templ_7745c5c3_Err != nil {
3062- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 600, Col: 38}
3074+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 604, Col: 38}
30633075 }
30643076 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var145))
30653077 if templ_7745c5c3_Err != nil {
30663078 return templ_7745c5c3_Err
30673079 }
3068- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, "</dd><dt>checks</dt><dd>")
3080+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, "</dd><dt>checks</dt><dd>")
30693081 if templ_7745c5c3_Err != nil {
30703082 return templ_7745c5c3_Err
30713083 }
30723084 if p.ChecksBlock {
3073- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, "failing ones block the merge")
3085+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "failing ones block the merge")
30743086 if templ_7745c5c3_Err != nil {
30753087 return templ_7745c5c3_Err
30763088 }
30773089 } else {
3078- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, "do not block the merge")
3090+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "do not block the merge")
30793091 if templ_7745c5c3_Err != nil {
30803092 return templ_7745c5c3_Err
30813093 }
30823094 }
3083- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "</dd></dl></section>")
3095+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "</dd></dl></section>")
30843096 if templ_7745c5c3_Err != nil {
30853097 return templ_7745c5c3_Err
30863098 }
30873099 if p.Box != nil {
30883100 if p.Box.Signed {
3089- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")
3101+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")
30903102 if templ_7745c5c3_Err != nil {
30913103 return templ_7745c5c3_Err
30923104 }
30933105 if p.Box.Fingerprint != "" {
3094- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "fingerprint <code>")
3106+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "fingerprint <code>")
30953107 if templ_7745c5c3_Err != nil {
30963108 return templ_7745c5c3_Err
30973109 }
30983110 var templ_7745c5c3_Var146 string
30993111 templ_7745c5c3_Var146, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Fingerprint)
31003112 if templ_7745c5c3_Err != nil {
3101- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 616, Col: 44}
3113+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 620, Col: 44}
31023114 }
31033115 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var146))
31043116 if templ_7745c5c3_Err != nil {
31053117 return templ_7745c5c3_Err
31063118 }
3107- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "</code> ")
3119+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, "</code> ")
31083120 if templ_7745c5c3_Err != nil {
31093121 return templ_7745c5c3_Err
31103122 }
31113123 }
3112- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "<code>ermite signing-key show</code> prints it.</p>")
3124+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "<code>ermite signing-key show</code> prints it.</p>")
31133125 if templ_7745c5c3_Err != nil {
31143126 return templ_7745c5c3_Err
31153127 }
31163128 }
3117- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, " ")
3129+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, " ")
31183130 if templ_7745c5c3_Err != nil {
31193131 return templ_7745c5c3_Err
31203132 }
31213133 if p.Box.CanMarkRead {
3122- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "<form method=\"post\" action=\"")
3134+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "<form method=\"post\" action=\"")
31233135 if templ_7745c5c3_Err != nil {
31243136 return templ_7745c5c3_Err
31253137 }
31263138 var templ_7745c5c3_Var147 templ.SafeURL
31273139 templ_7745c5c3_Var147, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadAction))
31283140 if templ_7745c5c3_Err != nil {
3129- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 622, Col: 65}
3141+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 626, Col: 65}
31303142 }
31313143 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var147))
31323144 if templ_7745c5c3_Err != nil {
31333145 return templ_7745c5c3_Err
31343146 }
3135- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
3147+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
31363148 if templ_7745c5c3_Err != nil {
31373149 return templ_7745c5c3_Err
31383150 }
31393151 var templ_7745c5c3_Var148 string
31403152 templ_7745c5c3_Var148, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
31413153 if templ_7745c5c3_Err != nil {
3142- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 623, Col: 60}
3154+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 627, Col: 60}
31433155 }
31443156 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var148)
31453157 if templ_7745c5c3_Err != nil {
31463158 return templ_7745c5c3_Err
31473159 }
3148- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")
3160+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")
31493161 if templ_7745c5c3_Err != nil {
31503162 return templ_7745c5c3_Err
31513163 }
31523164 }
3153- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, " <form method=\"post\" action=\"")
3165+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, " <form method=\"post\" action=\"")
31543166 if templ_7745c5c3_Err != nil {
31553167 return templ_7745c5c3_Err
31563168 }
31573169 var templ_7745c5c3_Var149 templ.SafeURL
31583170 templ_7745c5c3_Var149, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.CloseAction))
31593171 if templ_7745c5c3_Err != nil {
3160- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 627, Col: 65}
3172+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 631, Col: 65}
31613173 }
31623174 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var149))
31633175 if templ_7745c5c3_Err != nil {
31643176 return templ_7745c5c3_Err
31653177 }
3166- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")
3178+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")
31673179 if templ_7745c5c3_Err != nil {
31683180 return templ_7745c5c3_Err
31693181 }
31703182 if !p.Box.HeadGone && p.Box.ReadyAction == "" {
3171- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")
3183+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")
31723184 if templ_7745c5c3_Err != nil {
31733185 return templ_7745c5c3_Err
31743186 }
@@ -3176,13 +3188,13 @@ func moreMenu(p MRPage) templ.Component {
31763188 if templ_7745c5c3_Err != nil {
31773189 return templ_7745c5c3_Err
31783190 }
3179- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "</details>")
3191+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "</details>")
31803192 if templ_7745c5c3_Err != nil {
31813193 return templ_7745c5c3_Err
31823194 }
31833195 }
31843196 }
3185- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "</div></details>")
3197+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, "</div></details>")
31863198 if templ_7745c5c3_Err != nil {
31873199 return templ_7745c5c3_Err
31883200 }
@@ -3223,263 +3235,263 @@ func Compare(l Layout, p ComparePage) templ.Component {
32233235 }()
32243236 }
32253237 ctx = templ.InitializeContext(ctx)
3226- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "<header class=\"show mr-h\"><h1>")
3238+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "<header class=\"show mr-h\"><h1>")
32273239 if templ_7745c5c3_Err != nil {
32283240 return templ_7745c5c3_Err
32293241 }
32303242 var templ_7745c5c3_Var152 string
32313243 templ_7745c5c3_Var152, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
32323244 if templ_7745c5c3_Err != nil {
3233- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 644, Col: 17}
3245+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 648, Col: 17}
32343246 }
32353247 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var152))
32363248 if templ_7745c5c3_Err != nil {
32373249 return templ_7745c5c3_Err
32383250 }
3239- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, " → ")
3251+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, " → ")
32403252 if templ_7745c5c3_Err != nil {
32413253 return templ_7745c5c3_Err
32423254 }
32433255 var templ_7745c5c3_Var153 string
32443256 templ_7745c5c3_Var153, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
32453257 if templ_7745c5c3_Err != nil {
3246- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 644, Col: 34}
3258+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 648, Col: 34}
32473259 }
32483260 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var153))
32493261 if templ_7745c5c3_Err != nil {
32503262 return templ_7745c5c3_Err
32513263 }
3252- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")
3264+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")
32533265 if templ_7745c5c3_Err != nil {
32543266 return templ_7745c5c3_Err
32553267 }
32563268 var templ_7745c5c3_Var154 templ.SafeURL
32573269 templ_7745c5c3_Var154, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.SourceHref))
32583270 if templ_7745c5c3_Err != nil {
3259- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 647, Col: 45}
3271+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 651, Col: 45}
32603272 }
32613273 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var154))
32623274 if templ_7745c5c3_Err != nil {
32633275 return templ_7745c5c3_Err
32643276 }
3265- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, "\">")
3277+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "\">")
32663278 if templ_7745c5c3_Err != nil {
32673279 return templ_7745c5c3_Err
32683280 }
32693281 var templ_7745c5c3_Var155 string
32703282 templ_7745c5c3_Var155, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
32713283 if templ_7745c5c3_Err != nil {
3272- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 647, Col: 58}
3284+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 651, Col: 58}
32733285 }
32743286 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var155))
32753287 if templ_7745c5c3_Err != nil {
32763288 return templ_7745c5c3_Err
32773289 }
3278- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "</a></dd><dt>target</dt><dd><a href=\"")
3290+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "</a></dd><dt>target</dt><dd><a href=\"")
32793291 if templ_7745c5c3_Err != nil {
32803292 return templ_7745c5c3_Err
32813293 }
32823294 var templ_7745c5c3_Var156 templ.SafeURL
32833295 templ_7745c5c3_Var156, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.TargetHref))
32843296 if templ_7745c5c3_Err != nil {
3285- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 649, Col: 45}
3297+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 653, Col: 45}
32863298 }
32873299 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var156))
32883300 if templ_7745c5c3_Err != nil {
32893301 return templ_7745c5c3_Err
32903302 }
3291- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "\">")
3303+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "\">")
32923304 if templ_7745c5c3_Err != nil {
32933305 return templ_7745c5c3_Err
32943306 }
32953307 var templ_7745c5c3_Var157 string
32963308 templ_7745c5c3_Var157, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
32973309 if templ_7745c5c3_Err != nil {
3298- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 649, Col: 58}
3310+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 653, Col: 58}
32993311 }
33003312 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var157))
33013313 if templ_7745c5c3_Err != nil {
33023314 return templ_7745c5c3_Err
33033315 }
3304- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "</a></dd><dt>ahead</dt><dd>")
3316+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "</a></dd><dt>ahead</dt><dd>")
33053317 if templ_7745c5c3_Err != nil {
33063318 return templ_7745c5c3_Err
33073319 }
33083320 var templ_7745c5c3_Var158 string
33093321 templ_7745c5c3_Var158, templ_7745c5c3_Err = templ.JoinStringErrs(p.AheadText)
33103322 if templ_7745c5c3_Err != nil {
3311- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 651, Col: 21}
3323+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 655, Col: 21}
33123324 }
33133325 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var158))
33143326 if templ_7745c5c3_Err != nil {
33153327 return templ_7745c5c3_Err
33163328 }
3317- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "</dd></dl></header>")
3329+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "</dd></dl></header>")
33183330 if templ_7745c5c3_Err != nil {
33193331 return templ_7745c5c3_Err
33203332 }
33213333 if p.Note != "" {
3322- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "<p class=\"notice\">")
3334+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, "<p class=\"notice\">")
33233335 if templ_7745c5c3_Err != nil {
33243336 return templ_7745c5c3_Err
33253337 }
33263338 var templ_7745c5c3_Var159 string
33273339 templ_7745c5c3_Var159, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
33283340 if templ_7745c5c3_Err != nil {
3329- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 655, Col: 29}
3341+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 659, Col: 29}
33303342 }
33313343 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var159))
33323344 if templ_7745c5c3_Err != nil {
33333345 return templ_7745c5c3_Err
33343346 }
3335- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "</p>")
3347+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "</p>")
33363348 if templ_7745c5c3_Err != nil {
33373349 return templ_7745c5c3_Err
33383350 }
33393351 }
3340- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, " ")
3352+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, " ")
33413353 if templ_7745c5c3_Err != nil {
33423354 return templ_7745c5c3_Err
33433355 }
33443356 if p.Existing != nil {
3345- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")
3357+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")
33463358 if templ_7745c5c3_Err != nil {
33473359 return templ_7745c5c3_Err
33483360 }
33493361 var templ_7745c5c3_Var160 templ.SafeURL
33503362 templ_7745c5c3_Var160, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Existing.Href))
33513363 if templ_7745c5c3_Err != nil {
3352- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 658, Col: 114}
3364+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 662, Col: 114}
33533365 }
33543366 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var160))
33553367 if templ_7745c5c3_Err != nil {
33563368 return templ_7745c5c3_Err
33573369 }
3358- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, "\">")
3370+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, "\">")
33593371 if templ_7745c5c3_Err != nil {
33603372 return templ_7745c5c3_Err
33613373 }
33623374 var templ_7745c5c3_Var161 string
33633375 templ_7745c5c3_Var161, templ_7745c5c3_Err = templ.JoinStringErrs(p.Existing.Label)
33643376 if templ_7745c5c3_Err != nil {
3365- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 658, Col: 135}
3377+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 662, Col: 135}
33663378 }
33673379 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var161))
33683380 if templ_7745c5c3_Err != nil {
33693381 return templ_7745c5c3_Err
33703382 }
3371- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, "</a></p>")
3383+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, "</a></p>")
33723384 if templ_7745c5c3_Err != nil {
33733385 return templ_7745c5c3_Err
33743386 }
33753387 }
3376- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, " ")
3388+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, " ")
33773389 if templ_7745c5c3_Err != nil {
33783390 return templ_7745c5c3_Err
33793391 }
33803392 if p.Create != nil {
3381- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, "<form class=\"cform create\" method=\"post\" action=\"")
3393+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, "<form class=\"cform create\" method=\"post\" action=\"")
33823394 if templ_7745c5c3_Err != nil {
33833395 return templ_7745c5c3_Err
33843396 }
33853397 var templ_7745c5c3_Var162 templ.SafeURL
33863398 templ_7745c5c3_Var162, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Create.Action))
33873399 if templ_7745c5c3_Err != nil {
3388- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 661, Col: 83}
3400+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 665, Col: 83}
33893401 }
33903402 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var162))
33913403 if templ_7745c5c3_Err != nil {
33923404 return templ_7745c5c3_Err
33933405 }
3394- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, "\"><input type=\"hidden\" name=\"source\" value=\"")
3406+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"><input type=\"hidden\" name=\"source\" value=\"")
33953407 if templ_7745c5c3_Err != nil {
33963408 return templ_7745c5c3_Err
33973409 }
33983410 var templ_7745c5c3_Var163 string
33993411 templ_7745c5c3_Var163, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Source)
34003412 if templ_7745c5c3_Err != nil {
3401- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 662, Col: 62}
3413+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 666, Col: 62}
34023414 }
34033415 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var163)
34043416 if templ_7745c5c3_Err != nil {
34053417 return templ_7745c5c3_Err
34063418 }
3407- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, "\"> <input type=\"hidden\" name=\"target\" value=\"")
3419+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, "\"> <input type=\"hidden\" name=\"target\" value=\"")
34083420 if templ_7745c5c3_Err != nil {
34093421 return templ_7745c5c3_Err
34103422 }
34113423 var templ_7745c5c3_Var164 string
34123424 templ_7745c5c3_Var164, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Target)
34133425 if templ_7745c5c3_Err != nil {
3414- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 663, Col: 62}
3426+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 667, Col: 62}
34153427 }
34163428 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var164)
34173429 if templ_7745c5c3_Err != nil {
34183430 return templ_7745c5c3_Err
34193431 }
3420- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")
3432+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")
34213433 if templ_7745c5c3_Err != nil {
34223434 return templ_7745c5c3_Err
34233435 }
34243436 var templ_7745c5c3_Var165 string
34253437 templ_7745c5c3_Var165, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Title)
34263438 if templ_7745c5c3_Err != nil {
3427- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 665, Col: 97}
3439+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 669, Col: 97}
34283440 }
34293441 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var165)
34303442 if templ_7745c5c3_Err != nil {
34313443 return templ_7745c5c3_Err
34323444 }
3433- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")
3445+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")
34343446 if templ_7745c5c3_Err != nil {
34353447 return templ_7745c5c3_Err
34363448 }
34373449 }
3438- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, " ")
3450+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, " ")
34393451 if templ_7745c5c3_Err != nil {
34403452 return templ_7745c5c3_Err
34413453 }
34423454 if p.HasDiff {
3443- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")
3455+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")
34443456 if templ_7745c5c3_Err != nil {
34453457 return templ_7745c5c3_Err
34463458 }
34473459 var templ_7745c5c3_Var166 string
34483460 templ_7745c5c3_Var166, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))
34493461 if templ_7745c5c3_Err != nil {
3450- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 675, Col: 57}
3462+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 679, Col: 57}
34513463 }
34523464 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var166))
34533465 if templ_7745c5c3_Err != nil {
34543466 return templ_7745c5c3_Err
34553467 }
3456- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, " · <span class=\"plus\">+")
3468+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, " · <span class=\"plus\">+")
34573469 if templ_7745c5c3_Err != nil {
34583470 return templ_7745c5c3_Err
34593471 }
34603472 var templ_7745c5c3_Var167 string
34613473 templ_7745c5c3_Var167, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))
34623474 if templ_7745c5c3_Err != nil {
3463- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 675, Col: 97}
3475+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 679, Col: 97}
34643476 }
34653477 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var167))
34663478 if templ_7745c5c3_Err != nil {
34673479 return templ_7745c5c3_Err
34683480 }
3469- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, "</span> <span class=\"minus\">-")
3481+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, "</span> <span class=\"minus\">-")
34703482 if templ_7745c5c3_Err != nil {
34713483 return templ_7745c5c3_Err
34723484 }
34733485 var templ_7745c5c3_Var168 string
34743486 templ_7745c5c3_Var168, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))
34753487 if templ_7745c5c3_Err != nil {
3476- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 675, Col: 142}
3488+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 679, Col: 142}
34773489 }
34783490 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var168))
34793491 if templ_7745c5c3_Err != nil {
34803492 return templ_7745c5c3_Err
34813493 }
3482- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, "</span></span> <span class=\"grow\"></span>")
3494+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "</span></span> <span class=\"grow\"></span>")
34833495 if templ_7745c5c3_Err != nil {
34843496 return templ_7745c5c3_Err
34853497 }
@@ -3487,64 +3499,64 @@ func Compare(l Layout, p ComparePage) templ.Component {
34873499 if templ_7745c5c3_Err != nil {
34883500 return templ_7745c5c3_Err
34893501 }
3490- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, "</div>")
3502+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, "</div>")
34913503 if templ_7745c5c3_Err != nil {
34923504 return templ_7745c5c3_Err
34933505 }
34943506 if p.Invisible {
3495- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
3507+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
34963508 if templ_7745c5c3_Err != nil {
34973509 return templ_7745c5c3_Err
34983510 }
34993511 }
3500- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, " <div id=\"diffs\"")
3512+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, " <div id=\"diffs\"")
35013513 if templ_7745c5c3_Err != nil {
35023514 return templ_7745c5c3_Err
35033515 }
35043516 if p.Both {
3505- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, " data-diff=\"")
3517+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, " data-diff=\"")
35063518 if templ_7745c5c3_Err != nil {
35073519 return templ_7745c5c3_Err
35083520 }
35093521 var templ_7745c5c3_Var169 string
35103522 templ_7745c5c3_Var169, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
35113523 if templ_7745c5c3_Err != nil {
3512- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 688, Col: 23}
3524+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 692, Col: 23}
35133525 }
35143526 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var169)
35153527 if templ_7745c5c3_Err != nil {
35163528 return templ_7745c5c3_Err
35173529 }
3518- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, "\"")
3530+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "\"")
35193531 if templ_7745c5c3_Err != nil {
35203532 return templ_7745c5c3_Err
35213533 }
35223534 } else {
3523- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, " data-view=\"")
3535+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, " data-view=\"")
35243536 if templ_7745c5c3_Err != nil {
35253537 return templ_7745c5c3_Err
35263538 }
35273539 var templ_7745c5c3_Var170 string
35283540 templ_7745c5c3_Var170, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
35293541 if templ_7745c5c3_Err != nil {
3530- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 690, Col: 23}
3542+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 694, Col: 23}
35313543 }
35323544 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var170)
35333545 if templ_7745c5c3_Err != nil {
35343546 return templ_7745c5c3_Err
35353547 }
3536- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "\"")
3548+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, "\"")
35373549 if templ_7745c5c3_Err != nil {
35383550 return templ_7745c5c3_Err
35393551 }
35403552 }
35413553 if p.Both && !p.Pinned {
3542- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
3554+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
35433555 if templ_7745c5c3_Err != nil {
35443556 return templ_7745c5c3_Err
35453557 }
35463558 }
3547- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, ">")
3559+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, ">")
35483560 if templ_7745c5c3_Err != nil {
35493561 return templ_7745c5c3_Err
35503562 }
@@ -3554,7 +3566,7 @@ func Compare(l Layout, p ComparePage) templ.Component {
35543566 return templ_7745c5c3_Err
35553567 }
35563568 }
3557- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, "</div>")
3569+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, "</div>")
35583570 if templ_7745c5c3_Err != nil {
35593571 return templ_7745c5c3_Err
35603572 }
@@ -3590,77 +3602,77 @@ func compareRail(p ComparePage) templ.Component {
35903602 templ_7745c5c3_Var171 = templ.NopComponent
35913603 }
35923604 ctx = templ.ClearChildren(ctx)
3593- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")
3605+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")
35943606 if templ_7745c5c3_Err != nil {
35953607 return templ_7745c5c3_Err
35963608 }
35973609 var templ_7745c5c3_Var172 string
35983610 templ_7745c5c3_Var172, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Ahead)))
35993611 if templ_7745c5c3_Err != nil {
3600- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 706, Col: 67}
3612+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 710, Col: 67}
36013613 }
36023614 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var172))
36033615 if templ_7745c5c3_Err != nil {
36043616 return templ_7745c5c3_Err
36053617 }
3606- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, "</span></h2><ul class=\"pcommits\">")
3618+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, "</span></h2><ul class=\"pcommits\">")
36073619 if templ_7745c5c3_Err != nil {
36083620 return templ_7745c5c3_Err
36093621 }
36103622 for _, c := range p.Ahead {
3611- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "<li><a href=\"")
3623+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "<li><a href=\"")
36123624 if templ_7745c5c3_Err != nil {
36133625 return templ_7745c5c3_Err
36143626 }
36153627 var templ_7745c5c3_Var173 templ.SafeURL
36163628 templ_7745c5c3_Var173, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.CHref))
36173629 if templ_7745c5c3_Err != nil {
3618- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 710, Col: 37}
3630+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 714, Col: 37}
36193631 }
36203632 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var173))
36213633 if templ_7745c5c3_Err != nil {
36223634 return templ_7745c5c3_Err
36233635 }
3624- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, "\">")
3636+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "\">")
36253637 if templ_7745c5c3_Err != nil {
36263638 return templ_7745c5c3_Err
36273639 }
36283640 var templ_7745c5c3_Var174 string
36293641 templ_7745c5c3_Var174, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)
36303642 if templ_7745c5c3_Err != nil {
3631- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 710, Col: 49}
3643+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 714, Col: 49}
36323644 }
36333645 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var174))
36343646 if templ_7745c5c3_Err != nil {
36353647 return templ_7745c5c3_Err
36363648 }
3637- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "</a> <span class=\"s\">")
3649+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, "</a> <span class=\"s\">")
36383650 if templ_7745c5c3_Err != nil {
36393651 return templ_7745c5c3_Err
36403652 }
36413653 var templ_7745c5c3_Var175 string
36423654 templ_7745c5c3_Var175, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)
36433655 if templ_7745c5c3_Err != nil {
3644- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 711, Col: 32}
3656+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 32}
36453657 }
36463658 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var175))
36473659 if templ_7745c5c3_Err != nil {
36483660 return templ_7745c5c3_Err
36493661 }
3650- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "</span> <span class=\"mute\">")
3662+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, "</span> <span class=\"mute\">")
36513663 if templ_7745c5c3_Err != nil {
36523664 return templ_7745c5c3_Err
36533665 }
36543666 var templ_7745c5c3_Var176 string
36553667 templ_7745c5c3_Var176, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
36563668 if templ_7745c5c3_Err != nil {
3657- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 713, Col: 16}
3669+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 717, Col: 16}
36583670 }
36593671 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var176))
36603672 if templ_7745c5c3_Err != nil {
36613673 return templ_7745c5c3_Err
36623674 }
3663- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, " ")
3675+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, " ")
36643676 if templ_7745c5c3_Err != nil {
36653677 return templ_7745c5c3_Err
36663678 }
@@ -3668,90 +3680,90 @@ func compareRail(p ComparePage) templ.Component {
36683680 var templ_7745c5c3_Var177 string
36693681 templ_7745c5c3_Var177, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
36703682 if templ_7745c5c3_Err != nil {
3671- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 15}
3683+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 719, Col: 15}
36723684 }
36733685 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var177))
36743686 if templ_7745c5c3_Err != nil {
36753687 return templ_7745c5c3_Err
36763688 }
3677- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, "<time datetime=\"")
3689+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, "<time datetime=\"")
36783690 if templ_7745c5c3_Err != nil {
36793691 return templ_7745c5c3_Err
36803692 }
36813693 var templ_7745c5c3_Var178 string
36823694 templ_7745c5c3_Var178, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
36833695 if templ_7745c5c3_Err != nil {
3684- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 42}
3696+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 719, Col: 42}
36853697 }
36863698 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var178)
36873699 if templ_7745c5c3_Err != nil {
36883700 return templ_7745c5c3_Err
36893701 }
3690- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, "\">")
3702+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "\">")
36913703 if templ_7745c5c3_Err != nil {
36923704 return templ_7745c5c3_Err
36933705 }
36943706 var templ_7745c5c3_Var179 string
36953707 templ_7745c5c3_Var179, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
36963708 if templ_7745c5c3_Err != nil {
3697- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 53}
3709+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 719, Col: 53}
36983710 }
36993711 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var179))
37003712 if templ_7745c5c3_Err != nil {
37013713 return templ_7745c5c3_Err
37023714 }
3703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, "</time>")
3715+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, "</time>")
37043716 if templ_7745c5c3_Err != nil {
37053717 return templ_7745c5c3_Err
37063718 }
37073719 }
3708- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "</span></li>")
3720+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "</span></li>")
37093721 if templ_7745c5c3_Err != nil {
37103722 return templ_7745c5c3_Err
37113723 }
37123724 }
3713- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, "</ul>")
3725+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, "</ul>")
37143726 if templ_7745c5c3_Err != nil {
37153727 return templ_7745c5c3_Err
37163728 }
37173729 if len(p.Ahead) == 0 {
3718- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "<p class=\"dim\">no commit ahead of ")
3730+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, "<p class=\"dim\">no commit ahead of ")
37193731 if templ_7745c5c3_Err != nil {
37203732 return templ_7745c5c3_Err
37213733 }
37223734 var templ_7745c5c3_Var180 string
37233735 templ_7745c5c3_Var180, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
37243736 if templ_7745c5c3_Err != nil {
3725- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 722, Col: 47}
3737+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 726, Col: 47}
37263738 }
37273739 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var180))
37283740 if templ_7745c5c3_Err != nil {
37293741 return templ_7745c5c3_Err
37303742 }
3731- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, ".</p>")
3743+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, ".</p>")
37323744 if templ_7745c5c3_Err != nil {
37333745 return templ_7745c5c3_Err
37343746 }
37353747 }
3736- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, "</section>")
3748+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, "</section>")
37373749 if templ_7745c5c3_Err != nil {
37383750 return templ_7745c5c3_Err
37393751 }
37403752 if p.HasDiff {
3741- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
3753+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
37423754 if templ_7745c5c3_Err != nil {
37433755 return templ_7745c5c3_Err
37443756 }
37453757 var templ_7745c5c3_Var181 string
37463758 templ_7745c5c3_Var181, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
37473759 if templ_7745c5c3_Err != nil {
3748- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 727, Col: 66}
3760+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 731, Col: 66}
37493761 }
37503762 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var181))
37513763 if templ_7745c5c3_Err != nil {
37523764 return templ_7745c5c3_Err
37533765 }
3754- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, "</span></h2>")
3766+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "</span></h2>")
37553767 if templ_7745c5c3_Err != nil {
37563768 return templ_7745c5c3_Err
37573769 }
@@ -3759,12 +3771,12 @@ func compareRail(p ComparePage) templ.Component {
37593771 if templ_7745c5c3_Err != nil {
37603772 return templ_7745c5c3_Err
37613773 }
3762- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, "</section>")
3774+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, "</section>")
37633775 if templ_7745c5c3_Err != nil {
37643776 return templ_7745c5c3_Err
37653777 }
37663778 }
3767- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")
3779+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 353, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")
37683780 if templ_7745c5c3_Err != nil {
37693781 return templ_7745c5c3_Err
37703782 }
@@ -3772,7 +3784,7 @@ func compareRail(p ComparePage) templ.Component {
37723784 if templ_7745c5c3_Err != nil {
37733785 return templ_7745c5c3_Err
37743786 }
3775- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, "</section>")
3787+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 354, "</section>")
37763788 if templ_7745c5c3_Err != nil {
37773789 return templ_7745c5c3_Err
37783790 }
@@ -867,125 +867,131 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
867 if templ_7745c5c3_Err != nil {867 if templ_7745c5c3_Err != nil {
868 return templ_7745c5c3_Err868 return templ_7745c5c3_Err
869 }869 }
870- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, " ")870+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, " <div id=\"mr-range\"")
871+ if templ_7745c5c3_Err != nil {
872+ return templ_7745c5c3_Err
873+ }
874+ if p.Since == nil && p.SinceNote == "" {
875+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, " hidden")
876+ if templ_7745c5c3_Err != nil {
877+ return templ_7745c5c3_Err
878+ }
879+ }
880+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, ">")
871 if templ_7745c5c3_Err != nil {881 if templ_7745c5c3_Err != nil {
872 return templ_7745c5c3_Err882 return templ_7745c5c3_Err
873 }883 }
874 if p.Since != nil {884 if p.Since != nil {
875- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "<nav class=\"since\" aria-label=\"Diff range\"><a href=\"")885+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<nav class=\"since\" aria-label=\"Diff range\"><a href=\"")
876 if templ_7745c5c3_Err != nil {886 if templ_7745c5c3_Err != nil {
877 return templ_7745c5c3_Err887 return templ_7745c5c3_Err
878 }888 }
879 var templ_7745c5c3_Var44 templ.SafeURL889 var templ_7745c5c3_Var44 templ.SafeURL
880 templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Since.AllHref))890 templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Since.AllHref))
881 if templ_7745c5c3_Err != nil {891 if templ_7745c5c3_Err != nil {
882- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 163, Col: 42}892+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 164, Col: 43}
883 }893 }
884 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))894 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
885 if templ_7745c5c3_Err != nil {895 if templ_7745c5c3_Err != nil {
886 return templ_7745c5c3_Err896 return templ_7745c5c3_Err
887 }897 }
888- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "\"")898+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "\"")
889 if templ_7745c5c3_Err != nil {899 if templ_7745c5c3_Err != nil {
890 return templ_7745c5c3_Err900 return templ_7745c5c3_Err
891 }901 }
892 if !p.Since.Current {902 if !p.Since.Current {
893- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, " aria-current=\"page\"")903+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, " aria-current=\"page\"")
894 if templ_7745c5c3_Err != nil {904 if templ_7745c5c3_Err != nil {
895 return templ_7745c5c3_Err905 return templ_7745c5c3_Err
896 }906 }
897 }907 }
898- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, ">all changes <span class=\"mute\">vs ")908+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, ">all changes <span class=\"mute\">vs ")
899 if templ_7745c5c3_Err != nil {909 if templ_7745c5c3_Err != nil {
900 return templ_7745c5c3_Err910 return templ_7745c5c3_Err
901 }911 }
902 var templ_7745c5c3_Var45 string912 var templ_7745c5c3_Var45 string
903 templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)913 templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
904 if templ_7745c5c3_Err != nil {914 if templ_7745c5c3_Err != nil {
905- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 167, Col: 49}915+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 168, Col: 50}
906 }916 }
907 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))917 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
908 if templ_7745c5c3_Err != nil {918 if templ_7745c5c3_Err != nil {
909 return templ_7745c5c3_Err919 return templ_7745c5c3_Err
910 }920 }
911- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "</span></a> <a href=\"")921+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "</span></a> <a href=\"")
912 if templ_7745c5c3_Err != nil {922 if templ_7745c5c3_Err != nil {
913 return templ_7745c5c3_Err923 return templ_7745c5c3_Err
914 }924 }
915 var templ_7745c5c3_Var46 templ.SafeURL925 var templ_7745c5c3_Var46 templ.SafeURL
916 templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Since.SinceHref))926 templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Since.SinceHref))
917 if templ_7745c5c3_Err != nil {927 if templ_7745c5c3_Err != nil {
918- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 169, Col: 44}928+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 170, Col: 45}
919 }929 }
920 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))930 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
921 if templ_7745c5c3_Err != nil {931 if templ_7745c5c3_Err != nil {
922 return templ_7745c5c3_Err932 return templ_7745c5c3_Err
923 }933 }
924- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "\"")934+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\"")
925 if templ_7745c5c3_Err != nil {935 if templ_7745c5c3_Err != nil {
926 return templ_7745c5c3_Err936 return templ_7745c5c3_Err
927 }937 }
928 if p.Since.Current {938 if p.Since.Current {
929- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, " aria-current=\"page\"")939+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, " aria-current=\"page\"")
930 if templ_7745c5c3_Err != nil {940 if templ_7745c5c3_Err != nil {
931 return templ_7745c5c3_Err941 return templ_7745c5c3_Err
932 }942 }
933 }943 }
934- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, ">since your last read <span class=\"mute\">")944+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, ">since your last read <span class=\"mute\">")
935 if templ_7745c5c3_Err != nil {945 if templ_7745c5c3_Err != nil {
936 return templ_7745c5c3_Err946 return templ_7745c5c3_Err
937 }947 }
938 var templ_7745c5c3_Var47 string948 var templ_7745c5c3_Var47 string
939 templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(p.Since.ReadShort)949 templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(p.Since.ReadShort)
940 if templ_7745c5c3_Err != nil {950 if templ_7745c5c3_Err != nil {
941- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 173, Col: 64}951+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 174, Col: 65}
942 }952 }
943 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))953 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
944 if templ_7745c5c3_Err != nil {954 if templ_7745c5c3_Err != nil {
945 return templ_7745c5c3_Err955 return templ_7745c5c3_Err
946 }956 }
947- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, " → ")957+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, " → ")
948 if templ_7745c5c3_Err != nil {958 if templ_7745c5c3_Err != nil {
949 return templ_7745c5c3_Err959 return templ_7745c5c3_Err
950 }960 }
951 var templ_7745c5c3_Var48 string961 var templ_7745c5c3_Var48 string
952 templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(p.Since.HeadShort)962 templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(p.Since.HeadShort)
953 if templ_7745c5c3_Err != nil {963 if templ_7745c5c3_Err != nil {
954- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 173, Col: 90}964+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 174, Col: 91}
955 }965 }
956 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))966 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
957 if templ_7745c5c3_Err != nil {967 if templ_7745c5c3_Err != nil {
958 return templ_7745c5c3_Err968 return templ_7745c5c3_Err
959 }969 }
960- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</span></a></nav>")970+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "</span></a></nav>")
961 if templ_7745c5c3_Err != nil {971 if templ_7745c5c3_Err != nil {
962 return templ_7745c5c3_Err972 return templ_7745c5c3_Err
963 }973 }
964 }974 }
965- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, " ")
966- if templ_7745c5c3_Err != nil {
967- return templ_7745c5c3_Err
968- }
969 if p.SinceNote != "" {975 if p.SinceNote != "" {
970- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<p class=\"notice\">")976+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "<p class=\"notice\">")
971 if templ_7745c5c3_Err != nil {977 if templ_7745c5c3_Err != nil {
972 return templ_7745c5c3_Err978 return templ_7745c5c3_Err
973 }979 }
974 var templ_7745c5c3_Var49 string980 var templ_7745c5c3_Var49 string
975 templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(p.SinceNote)981 templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(p.SinceNote)
976 if templ_7745c5c3_Err != nil {982 if templ_7745c5c3_Err != nil {
977- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 177, Col: 34}983+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 178, Col: 35}
978 }984 }
979 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))985 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
980 if templ_7745c5c3_Err != nil {986 if templ_7745c5c3_Err != nil {
981 return templ_7745c5c3_Err987 return templ_7745c5c3_Err
982 }988 }
983- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "</p>")989+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</p>")
984 if templ_7745c5c3_Err != nil {990 if templ_7745c5c3_Err != nil {
985 return templ_7745c5c3_Err991 return templ_7745c5c3_Err
986 }992 }
987 }993 }
988- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, " ")994+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</div>")
989 if templ_7745c5c3_Err != nil {995 if templ_7745c5c3_Err != nil {
990 return templ_7745c5c3_Err996 return templ_7745c5c3_Err
991 }997 }
@@ -993,106 +999,112 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
993 if templ_7745c5c3_Err != nil {999 if templ_7745c5c3_Err != nil {
994 return templ_7745c5c3_Err1000 return templ_7745c5c3_Err
995 }1001 }
996- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, " ")1002+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, " <div id=\"mr-diff-notices\"")
997 if templ_7745c5c3_Err != nil {1003 if templ_7745c5c3_Err != nil {
998 return templ_7745c5c3_Err1004 return templ_7745c5c3_Err
999 }1005 }
1000- if p.Invisible {1006+ if !p.Invisible && p.Note == "" {
1001- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")1007+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, " hidden")
1002 if templ_7745c5c3_Err != nil {1008 if templ_7745c5c3_Err != nil {
1003 return templ_7745c5c3_Err1009 return templ_7745c5c3_Err
1004 }1010 }
1005 }1011 }
1006- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, " ")1012+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, ">")
1007 if templ_7745c5c3_Err != nil {1013 if templ_7745c5c3_Err != nil {
1008 return templ_7745c5c3_Err1014 return templ_7745c5c3_Err
1009 }1015 }
1016+ if p.Invisible {
1017+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
1018+ if templ_7745c5c3_Err != nil {
1019+ return templ_7745c5c3_Err
1020+ }
1021+ }
1010 if p.Note != "" {1022 if p.Note != "" {
1011- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<p class=\"notice\">")1023+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<p class=\"notice\">")
1012 if templ_7745c5c3_Err != nil {1024 if templ_7745c5c3_Err != nil {
1013 return templ_7745c5c3_Err1025 return templ_7745c5c3_Err
1014 }1026 }
1015 var templ_7745c5c3_Var50 string1027 var templ_7745c5c3_Var50 string
1016 templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)1028 templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
1017 if templ_7745c5c3_Err != nil {1029 if templ_7745c5c3_Err != nil {
1018- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 187, Col: 29}1030+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 190, Col: 30}
1019 }1031 }
1020 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))1032 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
1021 if templ_7745c5c3_Err != nil {1033 if templ_7745c5c3_Err != nil {
1022 return templ_7745c5c3_Err1034 return templ_7745c5c3_Err
1023 }1035 }
1024- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "</p>")1036+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "</p>")
1025 if templ_7745c5c3_Err != nil {1037 if templ_7745c5c3_Err != nil {
1026 return templ_7745c5c3_Err1038 return templ_7745c5c3_Err
1027 }1039 }
1028 }1040 }
1029- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, " <div id=\"diffs\" data-mr")1041+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</div><div id=\"diffs\" data-mr")
1030 if templ_7745c5c3_Err != nil {1042 if templ_7745c5c3_Err != nil {
1031 return templ_7745c5c3_Err1043 return templ_7745c5c3_Err
1032 }1044 }
1033 if p.Canonical != "" {1045 if p.Canonical != "" {
1034- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, " data-canonical=\"")1046+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " data-canonical=\"")
1035 if templ_7745c5c3_Err != nil {1047 if templ_7745c5c3_Err != nil {
1036 return templ_7745c5c3_Err1048 return templ_7745c5c3_Err
1037 }1049 }
1038 var templ_7745c5c3_Var51 string1050 var templ_7745c5c3_Var51 string
1039 templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Canonical)1051 templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Canonical)
1040 if templ_7745c5c3_Err != nil {1052 if templ_7745c5c3_Err != nil {
1041- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 193, Col: 32}1053+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 197, Col: 32}
1042 }1054 }
1043 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var51)1055 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var51)
1044 if templ_7745c5c3_Err != nil {1056 if templ_7745c5c3_Err != nil {
1045 return templ_7745c5c3_Err1057 return templ_7745c5c3_Err
1046 }1058 }
1047- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "\"")1059+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"")
1048 if templ_7745c5c3_Err != nil {1060 if templ_7745c5c3_Err != nil {
1049 return templ_7745c5c3_Err1061 return templ_7745c5c3_Err
1050 }1062 }
1051 }1063 }
1052 if p.Both {1064 if p.Both {
1053- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " data-diff=\"")1065+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, " data-diff=\"")
1054 if templ_7745c5c3_Err != nil {1066 if templ_7745c5c3_Err != nil {
1055 return templ_7745c5c3_Err1067 return templ_7745c5c3_Err
1056 }1068 }
1057 var templ_7745c5c3_Var52 string1069 var templ_7745c5c3_Var52 string
1058 templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)1070 templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
1059 if templ_7745c5c3_Err != nil {1071 if templ_7745c5c3_Err != nil {
1060- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 196, Col: 22}1072+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 200, Col: 22}
1061 }1073 }
1062 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var52)1074 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var52)
1063 if templ_7745c5c3_Err != nil {1075 if templ_7745c5c3_Err != nil {
1064 return templ_7745c5c3_Err1076 return templ_7745c5c3_Err
1065 }1077 }
1066- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"")1078+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\"")
1067 if templ_7745c5c3_Err != nil {1079 if templ_7745c5c3_Err != nil {
1068 return templ_7745c5c3_Err1080 return templ_7745c5c3_Err
1069 }1081 }
1070 } else {1082 } else {
1071- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, " data-view=\"")1083+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " data-view=\"")
1072 if templ_7745c5c3_Err != nil {1084 if templ_7745c5c3_Err != nil {
1073 return templ_7745c5c3_Err1085 return templ_7745c5c3_Err
1074 }1086 }
1075 var templ_7745c5c3_Var53 string1087 var templ_7745c5c3_Var53 string
1076 templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)1088 templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
1077 if templ_7745c5c3_Err != nil {1089 if templ_7745c5c3_Err != nil {
1078- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 198, Col: 22}1090+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 202, Col: 22}
1079 }1091 }
1080 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var53)1092 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var53)
1081 if templ_7745c5c3_Err != nil {1093 if templ_7745c5c3_Err != nil {
1082 return templ_7745c5c3_Err1094 return templ_7745c5c3_Err
1083 }1095 }
1084- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "\"")1096+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"")
1085 if templ_7745c5c3_Err != nil {1097 if templ_7745c5c3_Err != nil {
1086 return templ_7745c5c3_Err1098 return templ_7745c5c3_Err
1087 }1099 }
1088 }1100 }
1089 if p.Both && !p.Pinned {1101 if p.Both && !p.Pinned {
1090- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")1102+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
1091 if templ_7745c5c3_Err != nil {1103 if templ_7745c5c3_Err != nil {
1092 return templ_7745c5c3_Err1104 return templ_7745c5c3_Err
1093 }1105 }
1094 }1106 }
1095- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, ">")1107+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, ">")
1096 if templ_7745c5c3_Err != nil {1108 if templ_7745c5c3_Err != nil {
1097 return templ_7745c5c3_Err1109 return templ_7745c5c3_Err
1098 }1110 }
@@ -1103,38 +1115,38 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
1103 }1115 }
1104 }1116 }
1105 if len(p.Files) == 0 {1117 if len(p.Files) == 0 {
1106- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "<p class=\"note\">no changed files.</p>")1118+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "<p class=\"note\">no changed files.</p>")
1107 if templ_7745c5c3_Err != nil {1119 if templ_7745c5c3_Err != nil {
1108 return templ_7745c5c3_Err1120 return templ_7745c5c3_Err
1109 }1121 }
1110 }1122 }
1111- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</div><h2 class=\"rule-h\" id=\"comments\"><span>Comments</span><span class=\"count\">")1123+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "</div><h2 class=\"rule-h\" id=\"comments\"><span>Comments</span><span class=\"count\">")
1112 if templ_7745c5c3_Err != nil {1124 if templ_7745c5c3_Err != nil {
1113 return templ_7745c5c3_Err1125 return templ_7745c5c3_Err
1114 }1126 }
1115 var templ_7745c5c3_Var54 string1127 var templ_7745c5c3_Var54 string
1116 templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.NUnresolved))1128 templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.NUnresolved))
1117 if templ_7745c5c3_Err != nil {1129 if templ_7745c5c3_Err != nil {
1118- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 211, Col: 97}1130+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 215, Col: 97}
1119 }1131 }
1120 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))1132 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
1121 if templ_7745c5c3_Err != nil {1133 if templ_7745c5c3_Err != nil {
1122 return templ_7745c5c3_Err1134 return templ_7745c5c3_Err
1123 }1135 }
1124- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, " open / ")1136+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, " open / ")
1125 if templ_7745c5c3_Err != nil {1137 if templ_7745c5c3_Err != nil {
1126 return templ_7745c5c3_Err1138 return templ_7745c5c3_Err
1127 }1139 }
1128 var templ_7745c5c3_Var55 string1140 var templ_7745c5c3_Var55 string
1129 templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.NComments))1141 templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.NComments))
1130 if templ_7745c5c3_Err != nil {1142 if templ_7745c5c3_Err != nil {
1131- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 211, Col: 126}1143+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 215, Col: 126}
1132 }1144 }
1133 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))1145 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
1134 if templ_7745c5c3_Err != nil {1146 if templ_7745c5c3_Err != nil {
1135 return templ_7745c5c3_Err1147 return templ_7745c5c3_Err
1136 }1148 }
1137- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "</span></h2>")1149+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "</span></h2>")
1138 if templ_7745c5c3_Err != nil {1150 if templ_7745c5c3_Err != nil {
1139 return templ_7745c5c3_Err1151 return templ_7745c5c3_Err
1140 }1152 }
@@ -1150,17 +1162,17 @@ func MergeRequest(l Layout, p MRPage) templ.Component {
1150 return templ_7745c5c3_Err1162 return templ_7745c5c3_Err
1151 }1163 }
1152 }1164 }
1153- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, " ")1165+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, " ")
1154 if templ_7745c5c3_Err != nil {1166 if templ_7745c5c3_Err != nil {
1155 return templ_7745c5c3_Err1167 return templ_7745c5c3_Err
1156 }1168 }
1157 if p.NComments == 0 {1169 if p.NComments == 0 {
1158- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "<p class=\"dim\">no comments yet.</p>")1170+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "<p class=\"dim\">no comments yet.</p>")
1159 if templ_7745c5c3_Err != nil {1171 if templ_7745c5c3_Err != nil {
1160 return templ_7745c5c3_Err1172 return templ_7745c5c3_Err
1161 }1173 }
1162 }1174 }
1163- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, " ")1175+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, " ")
1164 if templ_7745c5c3_Err != nil {1176 if templ_7745c5c3_Err != nil {
1165 return templ_7745c5c3_Err1177 return templ_7745c5c3_Err
1166 }1178 }
@@ -1202,33 +1214,33 @@ func branchLink(name, href string) templ.Component {
1202 }1214 }
1203 ctx = templ.ClearChildren(ctx)1215 ctx = templ.ClearChildren(ctx)
1204 if href != "" {1216 if href != "" {
1205- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "<a href=\"")1217+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "<a href=\"")
1206 if templ_7745c5c3_Err != nil {1218 if templ_7745c5c3_Err != nil {
1207 return templ_7745c5c3_Err1219 return templ_7745c5c3_Err
1208 }1220 }
1209 var templ_7745c5c3_Var57 templ.SafeURL1221 var templ_7745c5c3_Var57 templ.SafeURL
1210 templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(href))1222 templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(href))
1211 if templ_7745c5c3_Err != nil {1223 if templ_7745c5c3_Err != nil {
1212- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 229, Col: 31}1224+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 233, Col: 31}
1213 }1225 }
1214 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))1226 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))
1215 if templ_7745c5c3_Err != nil {1227 if templ_7745c5c3_Err != nil {
1216 return templ_7745c5c3_Err1228 return templ_7745c5c3_Err
1217 }1229 }
1218- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "\">")1230+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "\">")
1219 if templ_7745c5c3_Err != nil {1231 if templ_7745c5c3_Err != nil {
1220 return templ_7745c5c3_Err1232 return templ_7745c5c3_Err
1221 }1233 }
1222 var templ_7745c5c3_Var58 string1234 var templ_7745c5c3_Var58 string
1223 templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(name)1235 templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(name)
1224 if templ_7745c5c3_Err != nil {1236 if templ_7745c5c3_Err != nil {
1225- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 229, Col: 40}1237+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 233, Col: 40}
1226 }1238 }
1227 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))1239 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
1228 if templ_7745c5c3_Err != nil {1240 if templ_7745c5c3_Err != nil {
1229 return templ_7745c5c3_Err1241 return templ_7745c5c3_Err
1230 }1242 }
1231- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "</a>")1243+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "</a>")
1232 if templ_7745c5c3_Err != nil {1244 if templ_7745c5c3_Err != nil {
1233 return templ_7745c5c3_Err1245 return templ_7745c5c3_Err
1234 }1246 }
@@ -1236,7 +1248,7 @@ func branchLink(name, href string) templ.Component {
1236 var templ_7745c5c3_Var59 string1248 var templ_7745c5c3_Var59 string
1237 templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.JoinStringErrs(name)1249 templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.JoinStringErrs(name)
1238 if templ_7745c5c3_Err != nil {1250 if templ_7745c5c3_Err != nil {
1239- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 231, Col: 8}1251+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 235, Col: 8}
1240 }1252 }
1241 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var59))1253 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var59))
1242 if templ_7745c5c3_Err != nil {1254 if templ_7745c5c3_Err != nil {
@@ -1310,56 +1322,56 @@ func commentView(c CommentView, suffix string) templ.Component {
1310 templ_7745c5c3_Var61 = templ.NopComponent1322 templ_7745c5c3_Var61 = templ.NopComponent
1311 }1323 }
1312 ctx = templ.ClearChildren(ctx)1324 ctx = templ.ClearChildren(ctx)
1313- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "<div class=\"cmt\" id=\"")1325+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<div class=\"cmt\" id=\"")
1314 if templ_7745c5c3_Err != nil {1326 if templ_7745c5c3_Err != nil {
1315 return templ_7745c5c3_Err1327 return templ_7745c5c3_Err
1316 }1328 }
1317 var templ_7745c5c3_Var62 string1329 var templ_7745c5c3_Var62 string
1318 templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.ResolveAttributeValue("c" + c.ID + suffix)1330 templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.ResolveAttributeValue("c" + c.ID + suffix)
1319 if templ_7745c5c3_Err != nil {1331 if templ_7745c5c3_Err != nil {
1320- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 250, Col: 42}1332+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 42}
1321 }1333 }
1322 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var62)1334 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var62)
1323 if templ_7745c5c3_Err != nil {1335 if templ_7745c5c3_Err != nil {
1324 return templ_7745c5c3_Err1336 return templ_7745c5c3_Err
1325 }1337 }
1326- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "\" data-resolved=\"")1338+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-resolved=\"")
1327 if templ_7745c5c3_Err != nil {1339 if templ_7745c5c3_Err != nil {
1328 return templ_7745c5c3_Err1340 return templ_7745c5c3_Err
1329 }1341 }
1330 var templ_7745c5c3_Var63 string1342 var templ_7745c5c3_Var63 string
1331 templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolText(c.Resolved))1343 templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolText(c.Resolved))
1332 if templ_7745c5c3_Err != nil {1344 if templ_7745c5c3_Err != nil {
1333- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 250, Col: 81}1345+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 81}
1334 }1346 }
1335 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var63)1347 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var63)
1336 if templ_7745c5c3_Err != nil {1348 if templ_7745c5c3_Err != nil {
1337 return templ_7745c5c3_Err1349 return templ_7745c5c3_Err
1338 }1350 }
1339- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "\"")1351+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\"")
1340 if templ_7745c5c3_Err != nil {1352 if templ_7745c5c3_Err != nil {
1341 return templ_7745c5c3_Err1353 return templ_7745c5c3_Err
1342 }1354 }
1343 if c.Reply != nil {1355 if c.Reply != nil {
1344- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, " data-thread")1356+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, " data-thread")
1345 if templ_7745c5c3_Err != nil {1357 if templ_7745c5c3_Err != nil {
1346 return templ_7745c5c3_Err1358 return templ_7745c5c3_Err
1347 }1359 }
1348 }1360 }
1349- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "><p class=\"c-head\"><span class=\"c-who\">")1361+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "><p class=\"c-head\"><span class=\"c-who\">")
1350 if templ_7745c5c3_Err != nil {1362 if templ_7745c5c3_Err != nil {
1351 return templ_7745c5c3_Err1363 return templ_7745c5c3_Err
1352 }1364 }
1353 var templ_7745c5c3_Var64 string1365 var templ_7745c5c3_Var64 string
1354 templ_7745c5c3_Var64, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)1366 templ_7745c5c3_Var64, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
1355 if templ_7745c5c3_Err != nil {1367 if templ_7745c5c3_Err != nil {
1356- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 252, Col: 33}1368+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 256, Col: 33}
1357 }1369 }
1358 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var64))1370 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var64))
1359 if templ_7745c5c3_Err != nil {1371 if templ_7745c5c3_Err != nil {
1360 return templ_7745c5c3_Err1372 return templ_7745c5c3_Err
1361 }1373 }
1362- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "</span> ")1374+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "</span> ")
1363 if templ_7745c5c3_Err != nil {1375 if templ_7745c5c3_Err != nil {
1364 return templ_7745c5c3_Err1376 return templ_7745c5c3_Err
1365 }1377 }
@@ -1367,52 +1379,52 @@ func commentView(c CommentView, suffix string) templ.Component {
1367 var templ_7745c5c3_Var65 string1379 var templ_7745c5c3_Var65 string
1368 templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1380 templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1369 if templ_7745c5c3_Err != nil {1381 if templ_7745c5c3_Err != nil {
1370- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 9}1382+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 9}
1371 }1383 }
1372 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))1384 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65))
1373 if templ_7745c5c3_Err != nil {1385 if templ_7745c5c3_Err != nil {
1374 return templ_7745c5c3_Err1386 return templ_7745c5c3_Err
1375 }1387 }
1376- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "<time class=\"mute\" datetime=\"")1388+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "<time class=\"mute\" datetime=\"")
1377 if templ_7745c5c3_Err != nil {1389 if templ_7745c5c3_Err != nil {
1378 return templ_7745c5c3_Err1390 return templ_7745c5c3_Err
1379 }1391 }
1380 var templ_7745c5c3_Var66 string1392 var templ_7745c5c3_Var66 string
1381 templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)1393 templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
1382 if templ_7745c5c3_Err != nil {1394 if templ_7745c5c3_Err != nil {
1383- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 49}1395+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 49}
1384 }1396 }
1385 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var66)1397 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var66)
1386 if templ_7745c5c3_Err != nil {1398 if templ_7745c5c3_Err != nil {
1387 return templ_7745c5c3_Err1399 return templ_7745c5c3_Err
1388 }1400 }
1389- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "\" title=\"")1401+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "\" title=\"")
1390 if templ_7745c5c3_Err != nil {1402 if templ_7745c5c3_Err != nil {
1391 return templ_7745c5c3_Err1403 return templ_7745c5c3_Err
1392 }1404 }
1393 var templ_7745c5c3_Var67 string1405 var templ_7745c5c3_Var67 string
1394 templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.Abs)1406 templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.Abs)
1395 if templ_7745c5c3_Err != nil {1407 if templ_7745c5c3_Err != nil {
1396- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 65}1408+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 65}
1397 }1409 }
1398 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67)1410 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67)
1399 if templ_7745c5c3_Err != nil {1411 if templ_7745c5c3_Err != nil {
1400 return templ_7745c5c3_Err1412 return templ_7745c5c3_Err
1401 }1413 }
1402- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, "\">")1414+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "\">")
1403 if templ_7745c5c3_Err != nil {1415 if templ_7745c5c3_Err != nil {
1404 return templ_7745c5c3_Err1416 return templ_7745c5c3_Err
1405 }1417 }
1406 var templ_7745c5c3_Var68 string1418 var templ_7745c5c3_Var68 string
1407 templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)1419 templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
1408 if templ_7745c5c3_Err != nil {1420 if templ_7745c5c3_Err != nil {
1409- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 254, Col: 76}1421+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 258, Col: 76}
1410 }1422 }
1411 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))1423 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68))
1412 if templ_7745c5c3_Err != nil {1424 if templ_7745c5c3_Err != nil {
1413 return templ_7745c5c3_Err1425 return templ_7745c5c3_Err
1414 }1426 }
1415- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "</time> ")1427+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "</time> ")
1416 if templ_7745c5c3_Err != nil {1428 if templ_7745c5c3_Err != nil {
1417 return templ_7745c5c3_Err1429 return templ_7745c5c3_Err
1418 }1430 }
@@ -1421,13 +1433,13 @@ func commentView(c CommentView, suffix string) templ.Component {
1421 var templ_7745c5c3_Var69 string1433 var templ_7745c5c3_Var69 string
1422 templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1434 templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1423 if templ_7745c5c3_Err != nil {1435 if templ_7745c5c3_Err != nil {
1424- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 257, Col: 9}1436+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 261, Col: 9}
1425 }1437 }
1426 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))1438 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69))
1427 if templ_7745c5c3_Err != nil {1439 if templ_7745c5c3_Err != nil {
1428 return templ_7745c5c3_Err1440 return templ_7745c5c3_Err
1429 }1441 }
1430- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "<span class=\"c-state\">resolved</span> ")1442+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "<span class=\"c-state\">resolved</span> ")
1431 if templ_7745c5c3_Err != nil {1443 if templ_7745c5c3_Err != nil {
1432 return templ_7745c5c3_Err1444 return templ_7745c5c3_Err
1433 }1445 }
@@ -1436,13 +1448,13 @@ func commentView(c CommentView, suffix string) templ.Component {
1436 var templ_7745c5c3_Var70 string1448 var templ_7745c5c3_Var70 string
1437 templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1449 templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1438 if templ_7745c5c3_Err != nil {1450 if templ_7745c5c3_Err != nil {
1439- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 260, Col: 9}1451+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 264, Col: 9}
1440 }1452 }
1441 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))1453 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70))
1442 if templ_7745c5c3_Err != nil {1454 if templ_7745c5c3_Err != nil {
1443 return templ_7745c5c3_Err1455 return templ_7745c5c3_Err
1444 }1456 }
1445- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<span class=\"c-state\" title=\"written on an earlier head; the line may have moved\">outdated</span> ")1457+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "<span class=\"c-state\" title=\"written on an earlier head; the line may have moved\">outdated</span> ")
1446 if templ_7745c5c3_Err != nil {1458 if templ_7745c5c3_Err != nil {
1447 return templ_7745c5c3_Err1459 return templ_7745c5c3_Err
1448 }1460 }
@@ -1451,36 +1463,36 @@ func commentView(c CommentView, suffix string) templ.Component {
1451 var templ_7745c5c3_Var71 string1463 var templ_7745c5c3_Var71 string
1452 templ_7745c5c3_Var71, templ_7745c5c3_Err = templ.JoinStringErrs(" ")1464 templ_7745c5c3_Var71, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
1453 if templ_7745c5c3_Err != nil {1465 if templ_7745c5c3_Err != nil {
1454- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 263, Col: 9}1466+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 267, Col: 9}
1455 }1467 }
1456 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var71))1468 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var71))
1457 if templ_7745c5c3_Err != nil {1469 if templ_7745c5c3_Err != nil {
1458 return templ_7745c5c3_Err1470 return templ_7745c5c3_Err
1459 }1471 }
1460- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "<span class=\"c-where mute\">")1472+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "<span class=\"c-where mute\">")
1461 if templ_7745c5c3_Err != nil {1473 if templ_7745c5c3_Err != nil {
1462 return templ_7745c5c3_Err1474 return templ_7745c5c3_Err
1463 }1475 }
1464 var templ_7745c5c3_Var72 string1476 var templ_7745c5c3_Var72 string
1465 templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.JoinStringErrs(c.Where)1477 templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.JoinStringErrs(c.Where)
1466 if templ_7745c5c3_Err != nil {1478 if templ_7745c5c3_Err != nil {
1467- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 263, Col: 47}1479+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 267, Col: 47}
1468 }1480 }
1469 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var72))1481 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var72))
1470 if templ_7745c5c3_Err != nil {1482 if templ_7745c5c3_Err != nil {
1471 return templ_7745c5c3_Err1483 return templ_7745c5c3_Err
1472 }1484 }
1473- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "</span>")1485+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "</span>")
1474 if templ_7745c5c3_Err != nil {1486 if templ_7745c5c3_Err != nil {
1475 return templ_7745c5c3_Err1487 return templ_7745c5c3_Err
1476 }1488 }
1477 }1489 }
1478- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "</p>")1490+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</p>")
1479 if templ_7745c5c3_Err != nil {1491 if templ_7745c5c3_Err != nil {
1480 return templ_7745c5c3_Err1492 return templ_7745c5c3_Err
1481 }1493 }
1482 if len(c.Parts) > 0 {1494 if len(c.Parts) > 0 {
1483- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 132, "<p class=\"c-text\">")1495+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "<p class=\"c-text\">")
1484 if templ_7745c5c3_Err != nil {1496 if templ_7745c5c3_Err != nil {
1485 return templ_7745c5c3_Err1497 return templ_7745c5c3_Err
1486 }1498 }
@@ -1488,24 +1500,24 @@ func commentView(c CommentView, suffix string) templ.Component {
1488 if templ_7745c5c3_Err != nil {1500 if templ_7745c5c3_Err != nil {
1489 return templ_7745c5c3_Err1501 return templ_7745c5c3_Err
1490 }1502 }
1491- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 133, "</p>")1503+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "</p>")
1492 if templ_7745c5c3_Err != nil {1504 if templ_7745c5c3_Err != nil {
1493 return templ_7745c5c3_Err1505 return templ_7745c5c3_Err
1494 }1506 }
1495 } else if c.Deleted {1507 } else if c.Deleted {
1496 if c.Verdict != "" {1508 if c.Verdict != "" {
1497- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, "<p class=\"mute\">text deleted</p>")1509+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "<p class=\"mute\">text deleted</p>")
1498 if templ_7745c5c3_Err != nil {1510 if templ_7745c5c3_Err != nil {
1499 return templ_7745c5c3_Err1511 return templ_7745c5c3_Err
1500 }1512 }
1501 } else {1513 } else {
1502- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "<p class=\"mute\">deleted note</p>")1514+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "<p class=\"mute\">deleted note</p>")
1503 if templ_7745c5c3_Err != nil {1515 if templ_7745c5c3_Err != nil {
1504 return templ_7745c5c3_Err1516 return templ_7745c5c3_Err
1505 }1517 }
1506 }1518 }
1507 } else {1519 } else {
1508- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, "<div class=\"c-body prose\">")1520+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "<div class=\"c-body prose\">")
1509 if templ_7745c5c3_Err != nil {1521 if templ_7745c5c3_Err != nil {
1510 return templ_7745c5c3_Err1522 return templ_7745c5c3_Err
1511 }1523 }
@@ -1520,147 +1532,147 @@ func commentView(c CommentView, suffix string) templ.Component {
1520 return templ_7745c5c3_Err1532 return templ_7745c5c3_Err
1521 }1533 }
1522 }1534 }
1523- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 137, "</div>")1535+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "</div>")
1524 if templ_7745c5c3_Err != nil {1536 if templ_7745c5c3_Err != nil {
1525 return templ_7745c5c3_Err1537 return templ_7745c5c3_Err
1526 }1538 }
1527 }1539 }
1528 if c.Edited {1540 if c.Edited {
1529- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 138, "<span class=\"mute\">edited</span> ")1541+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "<span class=\"mute\">edited</span> ")
1530 if templ_7745c5c3_Err != nil {1542 if templ_7745c5c3_Err != nil {
1531 return templ_7745c5c3_Err1543 return templ_7745c5c3_Err
1532 }1544 }
1533 }1545 }
1534 if c.Verdict != "" {1546 if c.Verdict != "" {
1535- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 139, "<span class=\"c-state\">")1547+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "<span class=\"c-state\">")
1536 if templ_7745c5c3_Err != nil {1548 if templ_7745c5c3_Err != nil {
1537 return templ_7745c5c3_Err1549 return templ_7745c5c3_Err
1538 }1550 }
1539 var templ_7745c5c3_Var73 string1551 var templ_7745c5c3_Var73 string
1540 templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(c.Verdict)1552 templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(c.Verdict)
1541 if templ_7745c5c3_Err != nil {1553 if templ_7745c5c3_Err != nil {
1542- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 287, Col: 36}1554+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 291, Col: 36}
1543 }1555 }
1544 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73))1556 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73))
1545 if templ_7745c5c3_Err != nil {1557 if templ_7745c5c3_Err != nil {
1546 return templ_7745c5c3_Err1558 return templ_7745c5c3_Err
1547 }1559 }
1548- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 140, "</span> ")1560+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "</span> ")
1549 if templ_7745c5c3_Err != nil {1561 if templ_7745c5c3_Err != nil {
1550 return templ_7745c5c3_Err1562 return templ_7745c5c3_Err
1551 }1563 }
1552 }1564 }
1553 if c.Range != "" {1565 if c.Range != "" {
1554- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 141, "<span class=\"mute\">")1566+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "<span class=\"mute\">")
1555 if templ_7745c5c3_Err != nil {1567 if templ_7745c5c3_Err != nil {
1556 return templ_7745c5c3_Err1568 return templ_7745c5c3_Err
1557 }1569 }
1558 var templ_7745c5c3_Var74 string1570 var templ_7745c5c3_Var74 string
1559 templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinStringErrs(c.Range)1571 templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinStringErrs(c.Range)
1560 if templ_7745c5c3_Err != nil {1572 if templ_7745c5c3_Err != nil {
1561- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 290, Col: 31}1573+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 294, Col: 31}
1562 }1574 }
1563 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))1575 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74))
1564 if templ_7745c5c3_Err != nil {1576 if templ_7745c5c3_Err != nil {
1565 return templ_7745c5c3_Err1577 return templ_7745c5c3_Err
1566 }1578 }
1567- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "</span> ")1579+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "</span> ")
1568 if templ_7745c5c3_Err != nil {1580 if templ_7745c5c3_Err != nil {
1569 return templ_7745c5c3_Err1581 return templ_7745c5c3_Err
1570 }1582 }
1571 }1583 }
1572 if c.Quote != "" {1584 if c.Quote != "" {
1573- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "<button type=\"button\" class=\"btn\" data-js data-quote=\"")1585+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<button type=\"button\" class=\"btn\" data-js data-quote=\"")
1574 if templ_7745c5c3_Err != nil {1586 if templ_7745c5c3_Err != nil {
1575 return templ_7745c5c3_Err1587 return templ_7745c5c3_Err
1576 }1588 }
1577 var templ_7745c5c3_Var75 string1589 var templ_7745c5c3_Var75 string
1578 templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.Quote)1590 templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.Quote)
1579 if templ_7745c5c3_Err != nil {1591 if templ_7745c5c3_Err != nil {
1580- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 293, Col: 65}1592+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 297, Col: 65}
1581 }1593 }
1582 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)1594 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75)
1583 if templ_7745c5c3_Err != nil {1595 if templ_7745c5c3_Err != nil {
1584 return templ_7745c5c3_Err1596 return templ_7745c5c3_Err
1585 }1597 }
1586- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "\">Quote</button> ")1598+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "\">Quote</button> ")
1587 if templ_7745c5c3_Err != nil {1599 if templ_7745c5c3_Err != nil {
1588 return templ_7745c5c3_Err1600 return templ_7745c5c3_Err
1589 }1601 }
1590 }1602 }
1591 if c.Edit != nil {1603 if c.Edit != nil {
1592- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "<details><summary>Edit</summary><form method=\"post\" action=\"")1604+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "<details><summary>Edit</summary><form method=\"post\" action=\"")
1593 if templ_7745c5c3_Err != nil {1605 if templ_7745c5c3_Err != nil {
1594 return templ_7745c5c3_Err1606 return templ_7745c5c3_Err
1595 }1607 }
1596 var templ_7745c5c3_Var76 templ.SafeURL1608 var templ_7745c5c3_Var76 templ.SafeURL
1597 templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Edit.Action))1609 templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Edit.Action))
1598 if templ_7745c5c3_Err != nil {1610 if templ_7745c5c3_Err != nil {
1599- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 296, Col: 92}1611+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 300, Col: 92}
1600 }1612 }
1601 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))1613 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76))
1602 if templ_7745c5c3_Err != nil {1614 if templ_7745c5c3_Err != nil {
1603 return templ_7745c5c3_Err1615 return templ_7745c5c3_Err
1604 }1616 }
1605- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 146, "\"><input type=\"hidden\" name=\"from\" value=\"")1617+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "\"><input type=\"hidden\" name=\"from\" value=\"")
1606 if templ_7745c5c3_Err != nil {1618 if templ_7745c5c3_Err != nil {
1607 return templ_7745c5c3_Err1619 return templ_7745c5c3_Err
1608 }1620 }
1609 var templ_7745c5c3_Var77 string1621 var templ_7745c5c3_Var77 string
1610 templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Edit.From))1622 templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Edit.From))
1611 if templ_7745c5c3_Err != nil {1623 if templ_7745c5c3_Err != nil {
1612- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 296, Col: 153}1624+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 300, Col: 153}
1613 }1625 }
1614 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77)1626 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77)
1615 if templ_7745c5c3_Err != nil {1627 if templ_7745c5c3_Err != nil {
1616 return templ_7745c5c3_Err1628 return templ_7745c5c3_Err
1617 }1629 }
1618- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 147, "\"><textarea name=\"text\" maxlength=\"8000\">")1630+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "\"><textarea name=\"text\" maxlength=\"8000\">")
1619 if templ_7745c5c3_Err != nil {1631 if templ_7745c5c3_Err != nil {
1620 return templ_7745c5c3_Err1632 return templ_7745c5c3_Err
1621 }1633 }
1622 var templ_7745c5c3_Var78 string1634 var templ_7745c5c3_Var78 string
1623 templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(c.Edit.Text)1635 templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(c.Edit.Text)
1624 if templ_7745c5c3_Err != nil {1636 if templ_7745c5c3_Err != nil {
1625- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 296, Col: 209}1637+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 300, Col: 209}
1626 }1638 }
1627 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78))1639 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78))
1628 if templ_7745c5c3_Err != nil {1640 if templ_7745c5c3_Err != nil {
1629 return templ_7745c5c3_Err1641 return templ_7745c5c3_Err
1630 }1642 }
1631- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 148, "</textarea><button class=\"btn\" type=\"submit\">Save</button></form></details> ")1643+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "</textarea><button class=\"btn\" type=\"submit\">Save</button></form></details> ")
1632 if templ_7745c5c3_Err != nil {1644 if templ_7745c5c3_Err != nil {
1633 return templ_7745c5c3_Err1645 return templ_7745c5c3_Err
1634 }1646 }
1635 }1647 }
1636 if c.Delete != nil {1648 if c.Delete != nil {
1637- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 149, "<details><summary>Delete</summary><form method=\"post\" action=\"")1649+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "<details><summary>Delete</summary><form method=\"post\" action=\"")
1638 if templ_7745c5c3_Err != nil {1650 if templ_7745c5c3_Err != nil {
1639 return templ_7745c5c3_Err1651 return templ_7745c5c3_Err
1640 }1652 }
1641 var templ_7745c5c3_Var79 templ.SafeURL1653 var templ_7745c5c3_Var79 templ.SafeURL
1642 templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Delete.Action))1654 templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Delete.Action))
1643 if templ_7745c5c3_Err != nil {1655 if templ_7745c5c3_Err != nil {
1644- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 299, Col: 96}1656+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 303, Col: 96}
1645 }1657 }
1646 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))1658 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79))
1647 if templ_7745c5c3_Err != nil {1659 if templ_7745c5c3_Err != nil {
1648 return templ_7745c5c3_Err1660 return templ_7745c5c3_Err
1649 }1661 }
1650- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 150, "\"><input type=\"hidden\" name=\"from\" value=\"")1662+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "\"><input type=\"hidden\" name=\"from\" value=\"")
1651 if templ_7745c5c3_Err != nil {1663 if templ_7745c5c3_Err != nil {
1652 return templ_7745c5c3_Err1664 return templ_7745c5c3_Err
1653 }1665 }
1654 var templ_7745c5c3_Var80 string1666 var templ_7745c5c3_Var80 string
1655 templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Delete.From))1667 templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Delete.From))
1656 if templ_7745c5c3_Err != nil {1668 if templ_7745c5c3_Err != nil {
1657- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 299, Col: 159}1669+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 303, Col: 159}
1658 }1670 }
1659 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)1671 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80)
1660 if templ_7745c5c3_Err != nil {1672 if templ_7745c5c3_Err != nil {
1661 return templ_7745c5c3_Err1673 return templ_7745c5c3_Err
1662 }1674 }
1663- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 151, "\"><p>Delete this note?</p><button class=\"btn\" type=\"submit\">Confirm delete</button></form></details> ")1675+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "\"><p>Delete this note?</p><button class=\"btn\" type=\"submit\">Confirm delete</button></form></details> ")
1664 if templ_7745c5c3_Err != nil {1676 if templ_7745c5c3_Err != nil {
1665 return templ_7745c5c3_Err1677 return templ_7745c5c3_Err
1666 }1678 }
@@ -1672,7 +1684,7 @@ func commentView(c CommentView, suffix string) templ.Component {
1672 }1684 }
1673 }1685 }
1674 if c.Reply != nil {1686 if c.Reply != nil {
1675- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 152, "<details data-reply><summary>Reply</summary>")1687+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "<details data-reply><summary>Reply</summary>")
1676 if templ_7745c5c3_Err != nil {1688 if templ_7745c5c3_Err != nil {
1677 return templ_7745c5c3_Err1689 return templ_7745c5c3_Err
1678 }1690 }
@@ -1680,80 +1692,80 @@ func commentView(c CommentView, suffix string) templ.Component {
1680 if templ_7745c5c3_Err != nil {1692 if templ_7745c5c3_Err != nil {
1681 return templ_7745c5c3_Err1693 return templ_7745c5c3_Err
1682 }1694 }
1683- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 153, "</details> ")1695+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "</details> ")
1684 if templ_7745c5c3_Err != nil {1696 if templ_7745c5c3_Err != nil {
1685 return templ_7745c5c3_Err1697 return templ_7745c5c3_Err
1686 }1698 }
1687 }1699 }
1688 if c.Resolve != nil {1700 if c.Resolve != nil {
1689- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 154, "<form class=\"c-act\" method=\"post\" action=\"")1701+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "<form class=\"c-act\" method=\"post\" action=\"")
1690 if templ_7745c5c3_Err != nil {1702 if templ_7745c5c3_Err != nil {
1691 return templ_7745c5c3_Err1703 return templ_7745c5c3_Err
1692 }1704 }
1693 var templ_7745c5c3_Var81 templ.SafeURL1705 var templ_7745c5c3_Var81 templ.SafeURL
1694 templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Resolve.Action))1706 templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Resolve.Action))
1695 if templ_7745c5c3_Err != nil {1707 if templ_7745c5c3_Err != nil {
1696- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 310, Col: 77}1708+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 314, Col: 77}
1697 }1709 }
1698 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))1710 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81))
1699 if templ_7745c5c3_Err != nil {1711 if templ_7745c5c3_Err != nil {
1700 return templ_7745c5c3_Err1712 return templ_7745c5c3_Err
1701 }1713 }
1702- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 155, "\"><input type=\"hidden\" name=\"resolved\" value=\"")1714+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "\"><input type=\"hidden\" name=\"resolved\" value=\"")
1703 if templ_7745c5c3_Err != nil {1715 if templ_7745c5c3_Err != nil {
1704 return templ_7745c5c3_Err1716 return templ_7745c5c3_Err
1705 }1717 }
1706 var templ_7745c5c3_Var82 string1718 var templ_7745c5c3_Var82 string
1707 templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolText(c.Resolve.Value))1719 templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.ResolveAttributeValue(boolText(c.Resolve.Value))
1708 if templ_7745c5c3_Err != nil {1720 if templ_7745c5c3_Err != nil {
1709- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 311, Col: 74}1721+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 315, Col: 74}
1710 }1722 }
1711 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var82)1723 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var82)
1712 if templ_7745c5c3_Err != nil {1724 if templ_7745c5c3_Err != nil {
1713 return templ_7745c5c3_Err1725 return templ_7745c5c3_Err
1714 }1726 }
1715- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 156, "\"> ")1727+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "\"> ")
1716 if templ_7745c5c3_Err != nil {1728 if templ_7745c5c3_Err != nil {
1717 return templ_7745c5c3_Err1729 return templ_7745c5c3_Err
1718 }1730 }
1719 if c.Resolve.From > 0 {1731 if c.Resolve.From > 0 {
1720- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 157, "<input type=\"hidden\" name=\"from\" value=\"")1732+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "<input type=\"hidden\" name=\"from\" value=\"")
1721 if templ_7745c5c3_Err != nil {1733 if templ_7745c5c3_Err != nil {
1722 return templ_7745c5c3_Err1734 return templ_7745c5c3_Err
1723 }1735 }
1724 var templ_7745c5c3_Var83 string1736 var templ_7745c5c3_Var83 string
1725 templ_7745c5c3_Var83, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Resolve.From))1737 templ_7745c5c3_Var83, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(c.Resolve.From))
1726 if templ_7745c5c3_Err != nil {1738 if templ_7745c5c3_Err != nil {
1727- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 313, Col: 66}1739+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 317, Col: 66}
1728 }1740 }
1729 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var83)1741 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var83)
1730 if templ_7745c5c3_Err != nil {1742 if templ_7745c5c3_Err != nil {
1731 return templ_7745c5c3_Err1743 return templ_7745c5c3_Err
1732 }1744 }
1733- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 158, "\"> ")1745+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "\"> ")
1734 if templ_7745c5c3_Err != nil {1746 if templ_7745c5c3_Err != nil {
1735 return templ_7745c5c3_Err1747 return templ_7745c5c3_Err
1736 }1748 }
1737 }1749 }
1738- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 159, "<button type=\"submit\" class=\"btn\">")1750+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "<button type=\"submit\" class=\"btn\">")
1739 if templ_7745c5c3_Err != nil {1751 if templ_7745c5c3_Err != nil {
1740 return templ_7745c5c3_Err1752 return templ_7745c5c3_Err
1741 }1753 }
1742 var templ_7745c5c3_Var84 string1754 var templ_7745c5c3_Var84 string
1743 templ_7745c5c3_Var84, templ_7745c5c3_Err = templ.JoinStringErrs(c.Resolve.Label)1755 templ_7745c5c3_Var84, templ_7745c5c3_Err = templ.JoinStringErrs(c.Resolve.Label)
1744 if templ_7745c5c3_Err != nil {1756 if templ_7745c5c3_Err != nil {
1745- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 315, Col: 55}1757+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 319, Col: 55}
1746 }1758 }
1747 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var84))1759 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var84))
1748 if templ_7745c5c3_Err != nil {1760 if templ_7745c5c3_Err != nil {
1749 return templ_7745c5c3_Err1761 return templ_7745c5c3_Err
1750 }1762 }
1751- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 160, "</button></form>")1763+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "</button></form>")
1752 if templ_7745c5c3_Err != nil {1764 if templ_7745c5c3_Err != nil {
1753 return templ_7745c5c3_Err1765 return templ_7745c5c3_Err
1754 }1766 }
1755 }1767 }
1756- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 161, "</div>")1768+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "</div>")
1757 if templ_7745c5c3_Err != nil {1769 if templ_7745c5c3_Err != nil {
1758 return templ_7745c5c3_Err1770 return templ_7745c5c3_Err
1759 }1771 }
@@ -1790,209 +1802,209 @@ func commentForm(f CommentForm, suffix string) templ.Component {
1790 templ_7745c5c3_Var85 = templ.NopComponent1802 templ_7745c5c3_Var85 = templ.NopComponent
1791 }1803 }
1792 ctx = templ.ClearChildren(ctx)1804 ctx = templ.ClearChildren(ctx)
1793- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 162, "<form class=\"cform\" method=\"post\" action=\"")1805+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "<form class=\"cform\" method=\"post\" action=\"")
1794 if templ_7745c5c3_Err != nil {1806 if templ_7745c5c3_Err != nil {
1795 return templ_7745c5c3_Err1807 return templ_7745c5c3_Err
1796 }1808 }
1797 var templ_7745c5c3_Var86 templ.SafeURL1809 var templ_7745c5c3_Var86 templ.SafeURL
1798 templ_7745c5c3_Var86, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(f.Action))1810 templ_7745c5c3_Var86, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(f.Action))
1799 if templ_7745c5c3_Err != nil {1811 if templ_7745c5c3_Err != nil {
1800- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 330, Col: 67}1812+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 334, Col: 67}
1801 }1813 }
1802 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var86))1814 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var86))
1803 if templ_7745c5c3_Err != nil {1815 if templ_7745c5c3_Err != nil {
1804 return templ_7745c5c3_Err1816 return templ_7745c5c3_Err
1805 }1817 }
1806- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 163, "\"><label for=\"")1818+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "\"><label for=\"")
1807 if templ_7745c5c3_Err != nil {1819 if templ_7745c5c3_Err != nil {
1808 return templ_7745c5c3_Err1820 return templ_7745c5c3_Err
1809 }1821 }
1810 var templ_7745c5c3_Var87 string1822 var templ_7745c5c3_Var87 string
1811 templ_7745c5c3_Var87, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID + suffix)1823 templ_7745c5c3_Var87, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID + suffix)
1812 if templ_7745c5c3_Err != nil {1824 if templ_7745c5c3_Err != nil {
1813- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 331, Col: 28}1825+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 335, Col: 28}
1814 }1826 }
1815 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var87)1827 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var87)
1816 if templ_7745c5c3_Err != nil {1828 if templ_7745c5c3_Err != nil {
1817 return templ_7745c5c3_Err1829 return templ_7745c5c3_Err
1818 }1830 }
1819- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 164, "\">")1831+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\">")
1820 if templ_7745c5c3_Err != nil {1832 if templ_7745c5c3_Err != nil {
1821 return templ_7745c5c3_Err1833 return templ_7745c5c3_Err
1822 }1834 }
1823 var templ_7745c5c3_Var88 string1835 var templ_7745c5c3_Var88 string
1824 templ_7745c5c3_Var88, templ_7745c5c3_Err = templ.JoinStringErrs(f.Title)1836 templ_7745c5c3_Var88, templ_7745c5c3_Err = templ.JoinStringErrs(f.Title)
1825 if templ_7745c5c3_Err != nil {1837 if templ_7745c5c3_Err != nil {
1826- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 331, Col: 40}1838+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 335, Col: 40}
1827 }1839 }
1828 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var88))1840 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var88))
1829 if templ_7745c5c3_Err != nil {1841 if templ_7745c5c3_Err != nil {
1830 return templ_7745c5c3_Err1842 return templ_7745c5c3_Err
1831 }1843 }
1832- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 165, "</label> <textarea id=\"")1844+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, "</label> <textarea id=\"")
1833 if templ_7745c5c3_Err != nil {1845 if templ_7745c5c3_Err != nil {
1834 return templ_7745c5c3_Err1846 return templ_7745c5c3_Err
1835 }1847 }
1836 var templ_7745c5c3_Var89 string1848 var templ_7745c5c3_Var89 string
1837 templ_7745c5c3_Var89, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID + suffix)1849 templ_7745c5c3_Var89, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ID + suffix)
1838 if templ_7745c5c3_Err != nil {1850 if templ_7745c5c3_Err != nil {
1839- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 333, Col: 21}1851+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 337, Col: 21}
1840 }1852 }
1841 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var89)1853 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var89)
1842 if templ_7745c5c3_Err != nil {1854 if templ_7745c5c3_Err != nil {
1843 return templ_7745c5c3_Err1855 return templ_7745c5c3_Err
1844 }1856 }
1845- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 166, "\" name=\"text\" rows=\"3\" maxlength=\"8000\"")1857+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, "\" name=\"text\" rows=\"3\" maxlength=\"8000\"")
1846 if templ_7745c5c3_Err != nil {1858 if templ_7745c5c3_Err != nil {
1847 return templ_7745c5c3_Err1859 return templ_7745c5c3_Err
1848 }1860 }
1849 if f.Plain {1861 if f.Plain {
1850- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 167, " required placeholder=\"plain text, 8000 characters at most\"")1862+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, " required placeholder=\"plain text, 8000 characters at most\"")
1851 if templ_7745c5c3_Err != nil {1863 if templ_7745c5c3_Err != nil {
1852 return templ_7745c5c3_Err1864 return templ_7745c5c3_Err
1853 }1865 }
1854 } else {1866 } else {
1855- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 168, " placeholder=\"Markdown, 8000 characters at most\"")1867+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, " placeholder=\"Markdown, 8000 characters at most\"")
1856 if templ_7745c5c3_Err != nil {1868 if templ_7745c5c3_Err != nil {
1857 return templ_7745c5c3_Err1869 return templ_7745c5c3_Err
1858 }1870 }
1859 }1871 }
1860 if f.Focus {1872 if f.Focus {
1861- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 169, " autofocus")1873+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, " autofocus")
1862 if templ_7745c5c3_Err != nil {1874 if templ_7745c5c3_Err != nil {
1863 return templ_7745c5c3_Err1875 return templ_7745c5c3_Err
1864 }1876 }
1865 }1877 }
1866- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 170, "></textarea> ")1878+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "></textarea> ")
1867 if templ_7745c5c3_Err != nil {1879 if templ_7745c5c3_Err != nil {
1868 return templ_7745c5c3_Err1880 return templ_7745c5c3_Err
1869 }1881 }
1870 if f.Path != "" {1882 if f.Path != "" {
1871- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 171, "<input type=\"hidden\" name=\"path\" value=\"")1883+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "<input type=\"hidden\" name=\"path\" value=\"")
1872 if templ_7745c5c3_Err != nil {1884 if templ_7745c5c3_Err != nil {
1873 return templ_7745c5c3_Err1885 return templ_7745c5c3_Err
1874 }1886 }
1875 var templ_7745c5c3_Var90 string1887 var templ_7745c5c3_Var90 string
1876 templ_7745c5c3_Var90, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path)1888 templ_7745c5c3_Var90, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Path)
1877 if templ_7745c5c3_Err != nil {1889 if templ_7745c5c3_Err != nil {
1878- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 348, Col: 50}1890+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 352, Col: 50}
1879 }1891 }
1880 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var90)1892 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var90)
1881 if templ_7745c5c3_Err != nil {1893 if templ_7745c5c3_Err != nil {
1882 return templ_7745c5c3_Err1894 return templ_7745c5c3_Err
1883 }1895 }
1884- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 172, "\"> <input type=\"hidden\" name=\"line\" value=\"")1896+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "\"> <input type=\"hidden\" name=\"line\" value=\"")
1885 if templ_7745c5c3_Err != nil {1897 if templ_7745c5c3_Err != nil {
1886 return templ_7745c5c3_Err1898 return templ_7745c5c3_Err
1887 }1899 }
1888 var templ_7745c5c3_Var91 string1900 var templ_7745c5c3_Var91 string
1889 templ_7745c5c3_Var91, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Line)1901 templ_7745c5c3_Var91, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Line)
1890 if templ_7745c5c3_Err != nil {1902 if templ_7745c5c3_Err != nil {
1891- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 349, Col: 50}1903+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 353, Col: 50}
1892 }1904 }
1893 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var91)1905 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var91)
1894 if templ_7745c5c3_Err != nil {1906 if templ_7745c5c3_Err != nil {
1895 return templ_7745c5c3_Err1907 return templ_7745c5c3_Err
1896 }1908 }
1897- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 173, "\"> <input type=\"hidden\" name=\"side\" value=\"")1909+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "\"> <input type=\"hidden\" name=\"side\" value=\"")
1898 if templ_7745c5c3_Err != nil {1910 if templ_7745c5c3_Err != nil {
1899 return templ_7745c5c3_Err1911 return templ_7745c5c3_Err
1900 }1912 }
1901 var templ_7745c5c3_Var92 string1913 var templ_7745c5c3_Var92 string
1902 templ_7745c5c3_Var92, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Side)1914 templ_7745c5c3_Var92, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.Side)
1903 if templ_7745c5c3_Err != nil {1915 if templ_7745c5c3_Err != nil {
1904- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 350, Col: 50}1916+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 354, Col: 50}
1905 }1917 }
1906 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var92)1918 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var92)
1907 if templ_7745c5c3_Err != nil {1919 if templ_7745c5c3_Err != nil {
1908 return templ_7745c5c3_Err1920 return templ_7745c5c3_Err
1909 }1921 }
1910- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 174, "\"> <label>from line <input type=\"number\" name=\"start_line\" min=\"1\" value=\"")1922+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "\"> <label>from line <input type=\"number\" name=\"start_line\" min=\"1\" value=\"")
1911 if templ_7745c5c3_Err != nil {1923 if templ_7745c5c3_Err != nil {
1912 return templ_7745c5c3_Err1924 return templ_7745c5c3_Err
1913 }1925 }
1914 var templ_7745c5c3_Var93 string1926 var templ_7745c5c3_Var93 string
1915 templ_7745c5c3_Var93, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.StartLine)1927 templ_7745c5c3_Var93, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.StartLine)
1916 if templ_7745c5c3_Err != nil {1928 if templ_7745c5c3_Err != nil {
1917- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 351, Col: 86}1929+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 355, Col: 86}
1918 }1930 }
1919 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var93)1931 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var93)
1920 if templ_7745c5c3_Err != nil {1932 if templ_7745c5c3_Err != nil {
1921 return templ_7745c5c3_Err1933 return templ_7745c5c3_Err
1922 }1934 }
1923- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 175, "\"></label> ")1935+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "\"></label> ")
1924 if templ_7745c5c3_Err != nil {1936 if templ_7745c5c3_Err != nil {
1925 return templ_7745c5c3_Err1937 return templ_7745c5c3_Err
1926 }1938 }
1927 }1939 }
1928 if f.ReplyTo != "" {1940 if f.ReplyTo != "" {
1929- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 176, "<input type=\"hidden\" name=\"reply_to\" value=\"")1941+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "<input type=\"hidden\" name=\"reply_to\" value=\"")
1930 if templ_7745c5c3_Err != nil {1942 if templ_7745c5c3_Err != nil {
1931 return templ_7745c5c3_Err1943 return templ_7745c5c3_Err
1932 }1944 }
1933 var templ_7745c5c3_Var94 string1945 var templ_7745c5c3_Var94 string
1934 templ_7745c5c3_Var94, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ReplyTo)1946 templ_7745c5c3_Var94, templ_7745c5c3_Err = templ.ResolveAttributeValue(f.ReplyTo)
1935 if templ_7745c5c3_Err != nil {1947 if templ_7745c5c3_Err != nil {
1936- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 354, Col: 57}1948+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 358, Col: 57}
1937 }1949 }
1938 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var94)1950 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var94)
1939 if templ_7745c5c3_Err != nil {1951 if templ_7745c5c3_Err != nil {
1940 return templ_7745c5c3_Err1952 return templ_7745c5c3_Err
1941 }1953 }
1942- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 177, "\"> ")1954+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "\"> ")
1943 if templ_7745c5c3_Err != nil {1955 if templ_7745c5c3_Err != nil {
1944 return templ_7745c5c3_Err1956 return templ_7745c5c3_Err
1945 }1957 }
1946 }1958 }
1947 if f.Path == "" && f.ReplyTo == "" && !f.Plain {1959 if f.Path == "" && f.ReplyTo == "" && !f.Plain {
1948- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 178, "<fieldset><legend>Verdict</legend><label><input type=\"radio\" name=\"verdict\" value=\"\" checked>Note</label><label><input type=\"radio\" name=\"verdict\" value=\"approve\">Approve</label><label><input type=\"radio\" name=\"verdict\" value=\"changes_requested\">Request changes</label></fieldset>")1960+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "<fieldset><legend>Verdict</legend><label><input type=\"radio\" name=\"verdict\" value=\"\" checked>Note</label><label><input type=\"radio\" name=\"verdict\" value=\"approve\">Approve</label><label><input type=\"radio\" name=\"verdict\" value=\"changes_requested\">Request changes</label></fieldset>")
1949 if templ_7745c5c3_Err != nil {1961 if templ_7745c5c3_Err != nil {
1950 return templ_7745c5c3_Err1962 return templ_7745c5c3_Err
1951 }1963 }
1952 }1964 }
1953 if f.From > 0 {1965 if f.From > 0 {
1954- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 179, "<input type=\"hidden\" name=\"from\" value=\"")1966+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "<input type=\"hidden\" name=\"from\" value=\"")
1955 if templ_7745c5c3_Err != nil {1967 if templ_7745c5c3_Err != nil {
1956 return templ_7745c5c3_Err1968 return templ_7745c5c3_Err
1957 }1969 }
1958 var templ_7745c5c3_Var95 string1970 var templ_7745c5c3_Var95 string
1959 templ_7745c5c3_Var95, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(f.From))1971 templ_7745c5c3_Var95, templ_7745c5c3_Err = templ.ResolveAttributeValue(itoa(f.From))
1960 if templ_7745c5c3_Err != nil {1972 if templ_7745c5c3_Err != nil {
1961- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 360, Col: 56}1973+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 364, Col: 56}
1962 }1974 }
1963 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var95)1975 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var95)
1964 if templ_7745c5c3_Err != nil {1976 if templ_7745c5c3_Err != nil {
1965 return templ_7745c5c3_Err1977 return templ_7745c5c3_Err
1966 }1978 }
1967- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 180, "\">")1979+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "\">")
1968 if templ_7745c5c3_Err != nil {1980 if templ_7745c5c3_Err != nil {
1969 return templ_7745c5c3_Err1981 return templ_7745c5c3_Err
1970 }1982 }
1971 }1983 }
1972- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 181, "<div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Comment</button> ")1984+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "<div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Comment</button> ")
1973 if templ_7745c5c3_Err != nil {1985 if templ_7745c5c3_Err != nil {
1974 return templ_7745c5c3_Err1986 return templ_7745c5c3_Err
1975 }1987 }
1976 if f.Cancel != "" {1988 if f.Cancel != "" {
1977- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 182, "<a class=\"btn\" href=\"")1989+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "<a class=\"btn\" href=\"")
1978 if templ_7745c5c3_Err != nil {1990 if templ_7745c5c3_Err != nil {
1979 return templ_7745c5c3_Err1991 return templ_7745c5c3_Err
1980 }1992 }
1981 var templ_7745c5c3_Var96 templ.SafeURL1993 var templ_7745c5c3_Var96 templ.SafeURL
1982 templ_7745c5c3_Var96, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(f.Cancel))1994 templ_7745c5c3_Var96, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(f.Cancel))
1983 if templ_7745c5c3_Err != nil {1995 if templ_7745c5c3_Err != nil {
1984- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 365, Col: 49}1996+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 369, Col: 49}
1985 }1997 }
1986 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var96))1998 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var96))
1987 if templ_7745c5c3_Err != nil {1999 if templ_7745c5c3_Err != nil {
1988 return templ_7745c5c3_Err2000 return templ_7745c5c3_Err
1989 }2001 }
1990- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 183, "\">Cancel</a>")2002+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "\">Cancel</a>")
1991 if templ_7745c5c3_Err != nil {2003 if templ_7745c5c3_Err != nil {
1992 return templ_7745c5c3_Err2004 return templ_7745c5c3_Err
1993 }2005 }
1994 }2006 }
1995- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 184, "</div></form>")2007+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "</div></form>")
1996 if templ_7745c5c3_Err != nil {2008 if templ_7745c5c3_Err != nil {
1997 return templ_7745c5c3_Err2009 return templ_7745c5c3_Err
1998 }2010 }
@@ -2021,46 +2033,46 @@ func mrFooter(p MRPage) templ.Component {
2021 templ_7745c5c3_Var97 = templ.NopComponent2033 templ_7745c5c3_Var97 = templ.NopComponent
2022 }2034 }
2023 ctx = templ.ClearChildren(ctx)2035 ctx = templ.ClearChildren(ctx)
2024- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 185, "<footer class=\"mr-footer\"><details id=\"mr-panels\"><summary>Commits <span class=\"count\">")2036+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "<footer class=\"mr-footer\"><details id=\"mr-panels\"><summary>Commits <span class=\"count\">")
2025 if templ_7745c5c3_Err != nil {2037 if templ_7745c5c3_Err != nil {
2026 return templ_7745c5c3_Err2038 return templ_7745c5c3_Err
2027 }2039 }
2028 var templ_7745c5c3_Var98 string2040 var templ_7745c5c3_Var98 string
2029 templ_7745c5c3_Var98, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitCount)2041 templ_7745c5c3_Var98, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitCount)
2030 if templ_7745c5c3_Err != nil {2042 if templ_7745c5c3_Err != nil {
2031- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 374, Col: 55}2043+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 378, Col: 55}
2032 }2044 }
2033 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var98))2045 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var98))
2034 if templ_7745c5c3_Err != nil {2046 if templ_7745c5c3_Err != nil {
2035 return templ_7745c5c3_Err2047 return templ_7745c5c3_Err
2036 }2048 }
2037- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 186, "</span> · Checks</summary><nav data-mr-tabs aria-label=\"Branch details\"><a id=\"mr-tab-commits\" href=\"#mr-commits\">Commits <span class=\"count\">")2049+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, "</span> · Checks</summary><nav data-mr-tabs aria-label=\"Branch details\"><a id=\"mr-tab-commits\" href=\"#mr-commits\">Commits <span class=\"count\">")
2038 if templ_7745c5c3_Err != nil {2050 if templ_7745c5c3_Err != nil {
2039 return templ_7745c5c3_Err2051 return templ_7745c5c3_Err
2040 }2052 }
2041 var templ_7745c5c3_Var99 string2053 var templ_7745c5c3_Var99 string
2042 templ_7745c5c3_Var99, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitCount)2054 templ_7745c5c3_Var99, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitCount)
2043 if templ_7745c5c3_Err != nil {2055 if templ_7745c5c3_Err != nil {
2044- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 376, Col: 89}2056+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 380, Col: 89}
2045 }2057 }
2046 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var99))2058 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var99))
2047 if templ_7745c5c3_Err != nil {2059 if templ_7745c5c3_Err != nil {
2048 return templ_7745c5c3_Err2060 return templ_7745c5c3_Err
2049 }2061 }
2050- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 187, "</span></a> <a id=\"mr-tab-checks\" href=\"#mr-checks\">")2062+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "</span></a> <a id=\"mr-tab-checks\" href=\"#mr-checks\">")
2051 if templ_7745c5c3_Err != nil {2063 if templ_7745c5c3_Err != nil {
2052 return templ_7745c5c3_Err2064 return templ_7745c5c3_Err
2053 }2065 }
2054 var templ_7745c5c3_Var100 string2066 var templ_7745c5c3_Var100 string
2055 templ_7745c5c3_Var100, templ_7745c5c3_Err = templ.JoinStringErrs("Checks ")2067 templ_7745c5c3_Var100, templ_7745c5c3_Err = templ.JoinStringErrs("Checks ")
2056 if templ_7745c5c3_Err != nil {2068 if templ_7745c5c3_Err != nil {
2057- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 378, Col: 16}2069+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 382, Col: 16}
2058 }2070 }
2059 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var100))2071 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var100))
2060 if templ_7745c5c3_Err != nil {2072 if templ_7745c5c3_Err != nil {
2061 return templ_7745c5c3_Err2073 return templ_7745c5c3_Err
2062 }2074 }
2063- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 188, " <span data-checks-label>")2075+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, " <span data-checks-label>")
2064 if templ_7745c5c3_Err != nil {2076 if templ_7745c5c3_Err != nil {
2065 return templ_7745c5c3_Err2077 return templ_7745c5c3_Err
2066 }2078 }
@@ -2068,122 +2080,122 @@ func mrFooter(p MRPage) templ.Component {
2068 var templ_7745c5c3_Var101 string2080 var templ_7745c5c3_Var101 string
2069 templ_7745c5c3_Var101, templ_7745c5c3_Err = templ.JoinStringErrs(p.ChecksSum.Title)2081 templ_7745c5c3_Var101, templ_7745c5c3_Err = templ.JoinStringErrs(p.ChecksSum.Title)
2070 if templ_7745c5c3_Err != nil {2082 if templ_7745c5c3_Err != nil {
2071- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 381, Col: 26}2083+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 385, Col: 26}
2072 }2084 }
2073 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var101))2085 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var101))
2074 if templ_7745c5c3_Err != nil {2086 if templ_7745c5c3_Err != nil {
2075 return templ_7745c5c3_Err2087 return templ_7745c5c3_Err
2076 }2088 }
2077 } else {2089 } else {
2078- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 189, "no checks")2090+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 191, "no checks")
2079 if templ_7745c5c3_Err != nil {2091 if templ_7745c5c3_Err != nil {
2080 return templ_7745c5c3_Err2092 return templ_7745c5c3_Err
2081 }2093 }
2082 }2094 }
2083- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 190, "</span></a></nav><div id=\"mr-commits\" data-mr-panel aria-labelledby=\"mr-tab-commits\"><table class=\"mr-commits\"><thead><tr><th>Commit</th><th>Subject</th><th>Author</th><th>Date</th><th>Signature</th><th>Status</th></tr></thead> <tbody>")2095+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 192, "</span></a></nav><div id=\"mr-commits\" data-mr-panel aria-labelledby=\"mr-tab-commits\"><table class=\"mr-commits\"><thead><tr><th>Commit</th><th>Subject</th><th>Author</th><th>Date</th><th>Signature</th><th>Status</th></tr></thead> <tbody>")
2084 if templ_7745c5c3_Err != nil {2096 if templ_7745c5c3_Err != nil {
2085 return templ_7745c5c3_Err2097 return templ_7745c5c3_Err
2086 }2098 }
2087 for _, c := range p.Commits {2099 for _, c := range p.Commits {
2088- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 191, "<tr")2100+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 193, "<tr")
2089 if templ_7745c5c3_Err != nil {2101 if templ_7745c5c3_Err != nil {
2090 return templ_7745c5c3_Err2102 return templ_7745c5c3_Err
2091 }2103 }
2092 if c.New {2104 if c.New {
2093- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 192, " data-new")2105+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 194, " data-new")
2094 if templ_7745c5c3_Err != nil {2106 if templ_7745c5c3_Err != nil {
2095 return templ_7745c5c3_Err2107 return templ_7745c5c3_Err
2096 }2108 }
2097 }2109 }
2098- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 193, "><td><a href=\"")2110+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 195, "><td><a href=\"")
2099 if templ_7745c5c3_Err != nil {2111 if templ_7745c5c3_Err != nil {
2100 return templ_7745c5c3_Err2112 return templ_7745c5c3_Err
2101 }2113 }
2102 var templ_7745c5c3_Var102 templ.SafeURL2114 var templ_7745c5c3_Var102 templ.SafeURL
2103 templ_7745c5c3_Var102, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Href))2115 templ_7745c5c3_Var102, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.Href))
2104 if templ_7745c5c3_Err != nil {2116 if templ_7745c5c3_Err != nil {
2105- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 394, Col: 43}2117+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 398, Col: 43}
2106 }2118 }
2107 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var102))2119 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var102))
2108 if templ_7745c5c3_Err != nil {2120 if templ_7745c5c3_Err != nil {
2109 return templ_7745c5c3_Err2121 return templ_7745c5c3_Err
2110 }2122 }
2111- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 194, "\">")2123+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 196, "\">")
2112 if templ_7745c5c3_Err != nil {2124 if templ_7745c5c3_Err != nil {
2113 return templ_7745c5c3_Err2125 return templ_7745c5c3_Err
2114 }2126 }
2115 var templ_7745c5c3_Var103 string2127 var templ_7745c5c3_Var103 string
2116 templ_7745c5c3_Var103, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)2128 templ_7745c5c3_Var103, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)
2117 if templ_7745c5c3_Err != nil {2129 if templ_7745c5c3_Err != nil {
2118- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 394, Col: 55}2130+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 398, Col: 55}
2119 }2131 }
2120 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var103))2132 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var103))
2121 if templ_7745c5c3_Err != nil {2133 if templ_7745c5c3_Err != nil {
2122 return templ_7745c5c3_Err2134 return templ_7745c5c3_Err
2123 }2135 }
2124- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 195, "</a></td><td>")2136+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 197, "</a></td><td>")
2125 if templ_7745c5c3_Err != nil {2137 if templ_7745c5c3_Err != nil {
2126 return templ_7745c5c3_Err2138 return templ_7745c5c3_Err
2127 }2139 }
2128 var templ_7745c5c3_Var104 string2140 var templ_7745c5c3_Var104 string
2129 templ_7745c5c3_Var104, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)2141 templ_7745c5c3_Var104, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)
2130 if templ_7745c5c3_Err != nil {2142 if templ_7745c5c3_Err != nil {
2131- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 395, Col: 23}2143+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 399, Col: 23}
2132 }2144 }
2133 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var104))2145 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var104))
2134 if templ_7745c5c3_Err != nil {2146 if templ_7745c5c3_Err != nil {
2135 return templ_7745c5c3_Err2147 return templ_7745c5c3_Err
2136 }2148 }
2137- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 196, "</td><td>")2149+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 198, "</td><td>")
2138 if templ_7745c5c3_Err != nil {2150 if templ_7745c5c3_Err != nil {
2139 return templ_7745c5c3_Err2151 return templ_7745c5c3_Err
2140 }2152 }
2141 var templ_7745c5c3_Var105 string2153 var templ_7745c5c3_Var105 string
2142 templ_7745c5c3_Var105, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)2154 templ_7745c5c3_Var105, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
2143 if templ_7745c5c3_Err != nil {2155 if templ_7745c5c3_Err != nil {
2144- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 396, Col: 22}2156+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 400, Col: 22}
2145 }2157 }
2146 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var105))2158 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var105))
2147 if templ_7745c5c3_Err != nil {2159 if templ_7745c5c3_Err != nil {
2148 return templ_7745c5c3_Err2160 return templ_7745c5c3_Err
2149 }2161 }
2150- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 197, "</td><td>")2162+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 199, "</td><td>")
2151 if templ_7745c5c3_Err != nil {2163 if templ_7745c5c3_Err != nil {
2152 return templ_7745c5c3_Err2164 return templ_7745c5c3_Err
2153 }2165 }
2154 if c.WhenAt != "" {2166 if c.WhenAt != "" {
2155- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 198, "<time datetime=\"")2167+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 200, "<time datetime=\"")
2156 if templ_7745c5c3_Err != nil {2168 if templ_7745c5c3_Err != nil {
2157 return templ_7745c5c3_Err2169 return templ_7745c5c3_Err
2158 }2170 }
2159 var templ_7745c5c3_Var106 string2171 var templ_7745c5c3_Var106 string
2160 templ_7745c5c3_Var106, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)2172 templ_7745c5c3_Var106, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
2161 if templ_7745c5c3_Err != nil {2173 if templ_7745c5c3_Err != nil {
2162- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 399, Col: 35}2174+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 403, Col: 35}
2163 }2175 }
2164 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var106)2176 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var106)
2165 if templ_7745c5c3_Err != nil {2177 if templ_7745c5c3_Err != nil {
2166 return templ_7745c5c3_Err2178 return templ_7745c5c3_Err
2167 }2179 }
2168- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 199, "\">")2180+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 201, "\">")
2169 if templ_7745c5c3_Err != nil {2181 if templ_7745c5c3_Err != nil {
2170 return templ_7745c5c3_Err2182 return templ_7745c5c3_Err
2171 }2183 }
2172 var templ_7745c5c3_Var107 string2184 var templ_7745c5c3_Var107 string
2173 templ_7745c5c3_Var107, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)2185 templ_7745c5c3_Var107, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
2174 if templ_7745c5c3_Err != nil {2186 if templ_7745c5c3_Err != nil {
2175- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 399, Col: 46}2187+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 403, Col: 46}
2176 }2188 }
2177 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var107))2189 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var107))
2178 if templ_7745c5c3_Err != nil {2190 if templ_7745c5c3_Err != nil {
2179 return templ_7745c5c3_Err2191 return templ_7745c5c3_Err
2180 }2192 }
2181- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 200, "</time>")2193+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 202, "</time>")
2182 if templ_7745c5c3_Err != nil {2194 if templ_7745c5c3_Err != nil {
2183 return templ_7745c5c3_Err2195 return templ_7745c5c3_Err
2184 }2196 }
2185 }2197 }
2186- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 201, "</td><td>")2198+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 203, "</td><td>")
2187 if templ_7745c5c3_Err != nil {2199 if templ_7745c5c3_Err != nil {
2188 return templ_7745c5c3_Err2200 return templ_7745c5c3_Err
2189 }2201 }
@@ -2193,51 +2205,51 @@ func mrFooter(p MRPage) templ.Component {
2193 return templ_7745c5c3_Err2205 return templ_7745c5c3_Err
2194 }2206 }
2195 }2207 }
2196- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 202, "</td><td>")2208+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 204, "</td><td>")
2197 if templ_7745c5c3_Err != nil {2209 if templ_7745c5c3_Err != nil {
2198 return templ_7745c5c3_Err2210 return templ_7745c5c3_Err
2199 }2211 }
2200 if c.New {2212 if c.New {
2201- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 203, "<span>new</span>")2213+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 205, "<span>new</span>")
2202 if templ_7745c5c3_Err != nil {2214 if templ_7745c5c3_Err != nil {
2203 return templ_7745c5c3_Err2215 return templ_7745c5c3_Err
2204 }2216 }
2205 }2217 }
2206- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 204, "</td></tr>")2218+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 206, "</td></tr>")
2207 if templ_7745c5c3_Err != nil {2219 if templ_7745c5c3_Err != nil {
2208 return templ_7745c5c3_Err2220 return templ_7745c5c3_Err
2209 }2221 }
2210 }2222 }
2211- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 205, "</tbody></table>")2223+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 207, "</tbody></table>")
2212 if templ_7745c5c3_Err != nil {2224 if templ_7745c5c3_Err != nil {
2213 return templ_7745c5c3_Err2225 return templ_7745c5c3_Err
2214 }2226 }
2215 if len(p.Commits) == 0 {2227 if len(p.Commits) == 0 {
2216- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 206, "<p class=\"dim\">no commit to merge.</p>")2228+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 208, "<p class=\"dim\">no commit to merge.</p>")
2217 if templ_7745c5c3_Err != nil {2229 if templ_7745c5c3_Err != nil {
2218 return templ_7745c5c3_Err2230 return templ_7745c5c3_Err
2219 }2231 }
2220 }2232 }
2221 if p.CommitsNote != "" {2233 if p.CommitsNote != "" {
2222- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 207, "<p class=\"note\">")2234+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 209, "<p class=\"note\">")
2223 if templ_7745c5c3_Err != nil {2235 if templ_7745c5c3_Err != nil {
2224 return templ_7745c5c3_Err2236 return templ_7745c5c3_Err
2225 }2237 }
2226 var templ_7745c5c3_Var108 string2238 var templ_7745c5c3_Var108 string
2227 templ_7745c5c3_Var108, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitsNote)2239 templ_7745c5c3_Var108, templ_7745c5c3_Err = templ.JoinStringErrs(p.CommitsNote)
2228 if templ_7745c5c3_Err != nil {2240 if templ_7745c5c3_Err != nil {
2229- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 420, Col: 36}2241+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 424, Col: 36}
2230 }2242 }
2231 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var108))2243 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var108))
2232 if templ_7745c5c3_Err != nil {2244 if templ_7745c5c3_Err != nil {
2233 return templ_7745c5c3_Err2245 return templ_7745c5c3_Err
2234 }2246 }
2235- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 208, "</p>")2247+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 210, "</p>")
2236 if templ_7745c5c3_Err != nil {2248 if templ_7745c5c3_Err != nil {
2237 return templ_7745c5c3_Err2249 return templ_7745c5c3_Err
2238 }2250 }
2239 }2251 }
2240- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 209, "</div><div id=\"mr-checks-panel\" data-mr-panel aria-labelledby=\"mr-tab-checks\">")2252+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 211, "</div><div id=\"mr-checks-panel\" data-mr-panel aria-labelledby=\"mr-tab-checks\">")
2241 if templ_7745c5c3_Err != nil {2253 if templ_7745c5c3_Err != nil {
2242 return templ_7745c5c3_Err2254 return templ_7745c5c3_Err
2243 }2255 }
@@ -2245,7 +2257,7 @@ func mrFooter(p MRPage) templ.Component {
2245 if templ_7745c5c3_Err != nil {2257 if templ_7745c5c3_Err != nil {
2246 return templ_7745c5c3_Err2258 return templ_7745c5c3_Err
2247 }2259 }
2248- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 210, "</div></details></footer>")2260+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 212, "</div></details></footer>")
2249 if templ_7745c5c3_Err != nil {2261 if templ_7745c5c3_Err != nil {
2250 return templ_7745c5c3_Err2262 return templ_7745c5c3_Err
2251 }2263 }
@@ -2274,20 +2286,20 @@ func mrRail(p MRPage) templ.Component {
2274 templ_7745c5c3_Var109 = templ.NopComponent2286 templ_7745c5c3_Var109 = templ.NopComponent
2275 }2287 }
2276 ctx = templ.ClearChildren(ctx)2288 ctx = templ.ClearChildren(ctx)
2277- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 211, "<section aria-labelledby=\"r-files\" class=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")2289+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 213, "<section aria-labelledby=\"r-files\" class=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
2278 if templ_7745c5c3_Err != nil {2290 if templ_7745c5c3_Err != nil {
2279 return templ_7745c5c3_Err2291 return templ_7745c5c3_Err
2280 }2292 }
2281 var templ_7745c5c3_Var110 string2293 var templ_7745c5c3_Var110 string
2282 templ_7745c5c3_Var110, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))2294 templ_7745c5c3_Var110, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
2283 if templ_7745c5c3_Err != nil {2295 if templ_7745c5c3_Err != nil {
2284- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 433, Col: 49}2296+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 437, Col: 49}
2285 }2297 }
2286 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var110))2298 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var110))
2287 if templ_7745c5c3_Err != nil {2299 if templ_7745c5c3_Err != nil {
2288 return templ_7745c5c3_Err2300 return templ_7745c5c3_Err
2289 }2301 }
2290- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 212, "</span><kbd aria-hidden=\"true\">g f</kbd> <button type=\"button\" class=\"btn icon fold\" data-js aria-expanded=\"true\" title=\"fold the list of files\" hx-on:click=\"ermiteMR.foldFiles()\"><span class=\"ico i-chevron\" aria-hidden=\"true\"></span><span class=\"sr\">fold the list of files</span></button></h2>")2302+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 214, "</span><kbd aria-hidden=\"true\">g f</kbd> <button type=\"button\" class=\"btn icon fold\" data-js aria-expanded=\"true\" title=\"fold the list of files\" hx-on:click=\"ermiteMR.foldFiles()\"><span class=\"ico i-chevron\" aria-hidden=\"true\"></span><span class=\"sr\">fold the list of files</span></button></h2>")
2291 if templ_7745c5c3_Err != nil {2303 if templ_7745c5c3_Err != nil {
2292 return templ_7745c5c3_Err2304 return templ_7745c5c3_Err
2293 }2305 }
@@ -2295,71 +2307,71 @@ func mrRail(p MRPage) templ.Component {
2295 if templ_7745c5c3_Err != nil {2307 if templ_7745c5c3_Err != nil {
2296 return templ_7745c5c3_Err2308 return templ_7745c5c3_Err
2297 }2309 }
2298- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 213, "</section>")2310+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 215, "</section>")
2299 if templ_7745c5c3_Err != nil {2311 if templ_7745c5c3_Err != nil {
2300 return templ_7745c5c3_Err2312 return templ_7745c5c3_Err
2301 }2313 }
2302 if len(p.Verdicts) > 0 {2314 if len(p.Verdicts) > 0 {
2303- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 214, "<section><h2>Verdicts</h2><ul>")2315+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 216, "<section><h2>Verdicts</h2><ul>")
2304 if templ_7745c5c3_Err != nil {2316 if templ_7745c5c3_Err != nil {
2305 return templ_7745c5c3_Err2317 return templ_7745c5c3_Err
2306 }2318 }
2307 for _, v := range p.Verdicts {2319 for _, v := range p.Verdicts {
2308- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 215, "<li><a href=\"")2320+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 217, "<li><a href=\"")
2309 if templ_7745c5c3_Err != nil {2321 if templ_7745c5c3_Err != nil {
2310 return templ_7745c5c3_Err2322 return templ_7745c5c3_Err
2311 }2323 }
2312 var templ_7745c5c3_Var111 templ.SafeURL2324 var templ_7745c5c3_Var111 templ.SafeURL
2313 templ_7745c5c3_Var111, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(v.Href))2325 templ_7745c5c3_Var111, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(v.Href))
2314 if templ_7745c5c3_Err != nil {2326 if templ_7745c5c3_Err != nil {
2315- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 446, Col: 37}2327+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 450, Col: 37}
2316 }2328 }
2317 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var111))2329 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var111))
2318 if templ_7745c5c3_Err != nil {2330 if templ_7745c5c3_Err != nil {
2319 return templ_7745c5c3_Err2331 return templ_7745c5c3_Err
2320 }2332 }
2321- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 216, "\">")2333+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 218, "\">")
2322 if templ_7745c5c3_Err != nil {2334 if templ_7745c5c3_Err != nil {
2323 return templ_7745c5c3_Err2335 return templ_7745c5c3_Err
2324 }2336 }
2325 var templ_7745c5c3_Var112 string2337 var templ_7745c5c3_Var112 string
2326 templ_7745c5c3_Var112, templ_7745c5c3_Err = templ.JoinStringErrs(v.Author)2338 templ_7745c5c3_Var112, templ_7745c5c3_Err = templ.JoinStringErrs(v.Author)
2327 if templ_7745c5c3_Err != nil {2339 if templ_7745c5c3_Err != nil {
2328- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 446, Col: 50}2340+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 450, Col: 50}
2329 }2341 }
2330 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var112))2342 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var112))
2331 if templ_7745c5c3_Err != nil {2343 if templ_7745c5c3_Err != nil {
2332 return templ_7745c5c3_Err2344 return templ_7745c5c3_Err
2333 }2345 }
2334- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 217, ": ")2346+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 219, ": ")
2335 if templ_7745c5c3_Err != nil {2347 if templ_7745c5c3_Err != nil {
2336 return templ_7745c5c3_Err2348 return templ_7745c5c3_Err
2337 }2349 }
2338 var templ_7745c5c3_Var113 string2350 var templ_7745c5c3_Var113 string
2339 templ_7745c5c3_Var113, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)2351 templ_7745c5c3_Var113, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)
2340 if templ_7745c5c3_Err != nil {2352 if templ_7745c5c3_Err != nil {
2341- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 446, Col: 63}2353+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 450, Col: 63}
2342 }2354 }
2343 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var113))2355 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var113))
2344 if templ_7745c5c3_Err != nil {2356 if templ_7745c5c3_Err != nil {
2345 return templ_7745c5c3_Err2357 return templ_7745c5c3_Err
2346 }2358 }
2347- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 218, "</a> ")2359+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 220, "</a> ")
2348 if templ_7745c5c3_Err != nil {2360 if templ_7745c5c3_Err != nil {
2349 return templ_7745c5c3_Err2361 return templ_7745c5c3_Err
2350 }2362 }
2351 if v.Stale {2363 if v.Stale {
2352- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 219, "<span class=\"mute\">(stale)</span>")2364+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 221, "<span class=\"mute\">(stale)</span>")
2353 if templ_7745c5c3_Err != nil {2365 if templ_7745c5c3_Err != nil {
2354 return templ_7745c5c3_Err2366 return templ_7745c5c3_Err
2355 }2367 }
2356 }2368 }
2357- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 220, "</li>")2369+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 222, "</li>")
2358 if templ_7745c5c3_Err != nil {2370 if templ_7745c5c3_Err != nil {
2359 return templ_7745c5c3_Err2371 return templ_7745c5c3_Err
2360 }2372 }
2361 }2373 }
2362- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 221, "</ul></section>")2374+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 223, "</ul></section>")
2363 if templ_7745c5c3_Err != nil {2375 if templ_7745c5c3_Err != nil {
2364 return templ_7745c5c3_Err2376 return templ_7745c5c3_Err
2365 }2377 }
@@ -2393,46 +2405,46 @@ func mrBar(p MRPage) templ.Component {
2393 templ_7745c5c3_Var114 = templ.NopComponent2405 templ_7745c5c3_Var114 = templ.NopComponent
2394 }2406 }
2395 ctx = templ.ClearChildren(ctx)2407 ctx = templ.ClearChildren(ctx)
2396- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 222, "<div class=\"diff-tools mr-bar\" role=\"group\" aria-label=\"Diff view and merge\"><span class=\"dim\">")2408+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 224, "<div class=\"diff-tools mr-bar\" role=\"group\" aria-label=\"Diff view and merge\"><span class=\"dim\">")
2397 if templ_7745c5c3_Err != nil {2409 if templ_7745c5c3_Err != nil {
2398 return templ_7745c5c3_Err2410 return templ_7745c5c3_Err
2399 }2411 }
2400 var templ_7745c5c3_Var115 string2412 var templ_7745c5c3_Var115 string
2401 templ_7745c5c3_Var115, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))2413 templ_7745c5c3_Var115, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))
2402 if templ_7745c5c3_Err != nil {2414 if templ_7745c5c3_Err != nil {
2403- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 463, Col: 55}2415+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 467, Col: 55}
2404 }2416 }
2405 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var115))2417 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var115))
2406 if templ_7745c5c3_Err != nil {2418 if templ_7745c5c3_Err != nil {
2407 return templ_7745c5c3_Err2419 return templ_7745c5c3_Err
2408 }2420 }
2409- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 223, " · <span class=\"plus\">+")2421+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 225, " · <span class=\"plus\">+")
2410 if templ_7745c5c3_Err != nil {2422 if templ_7745c5c3_Err != nil {
2411 return templ_7745c5c3_Err2423 return templ_7745c5c3_Err
2412 }2424 }
2413 var templ_7745c5c3_Var116 string2425 var templ_7745c5c3_Var116 string
2414 templ_7745c5c3_Var116, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))2426 templ_7745c5c3_Var116, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))
2415 if templ_7745c5c3_Err != nil {2427 if templ_7745c5c3_Err != nil {
2416- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 463, Col: 95}2428+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 467, Col: 95}
2417 }2429 }
2418 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var116))2430 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var116))
2419 if templ_7745c5c3_Err != nil {2431 if templ_7745c5c3_Err != nil {
2420 return templ_7745c5c3_Err2432 return templ_7745c5c3_Err
2421 }2433 }
2422- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 224, "</span> <span class=\"minus\">-")2434+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 226, "</span> <span class=\"minus\">-")
2423 if templ_7745c5c3_Err != nil {2435 if templ_7745c5c3_Err != nil {
2424 return templ_7745c5c3_Err2436 return templ_7745c5c3_Err
2425 }2437 }
2426 var templ_7745c5c3_Var117 string2438 var templ_7745c5c3_Var117 string
2427 templ_7745c5c3_Var117, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))2439 templ_7745c5c3_Var117, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))
2428 if templ_7745c5c3_Err != nil {2440 if templ_7745c5c3_Err != nil {
2429- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 463, Col: 140}2441+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 467, Col: 140}
2430 }2442 }
2431 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var117))2443 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var117))
2432 if templ_7745c5c3_Err != nil {2444 if templ_7745c5c3_Err != nil {
2433 return templ_7745c5c3_Err2445 return templ_7745c5c3_Err
2434 }2446 }
2435- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 225, "</span></span>")2447+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 227, "</span></span>")
2436 if templ_7745c5c3_Err != nil {2448 if templ_7745c5c3_Err != nil {
2437 return templ_7745c5c3_Err2449 return templ_7745c5c3_Err
2438 }2450 }
@@ -2440,7 +2452,7 @@ func mrBar(p MRPage) templ.Component {
2440 if templ_7745c5c3_Err != nil {2452 if templ_7745c5c3_Err != nil {
2441 return templ_7745c5c3_Err2453 return templ_7745c5c3_Err
2442 }2454 }
2443- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 226, "<span class=\"grow\"></span>")2455+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 228, "<span class=\"grow\"></span>")
2444 if templ_7745c5c3_Err != nil {2456 if templ_7745c5c3_Err != nil {
2445 return templ_7745c5c3_Err2457 return templ_7745c5c3_Err
2446 }2458 }
@@ -2458,7 +2470,7 @@ func mrBar(p MRPage) templ.Component {
2458 if templ_7745c5c3_Err != nil {2470 if templ_7745c5c3_Err != nil {
2459 return templ_7745c5c3_Err2471 return templ_7745c5c3_Err
2460 }2472 }
2461- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 227, "</div>")2473+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 229, "</div>")
2462 if templ_7745c5c3_Err != nil {2474 if templ_7745c5c3_Err != nil {
2463 return templ_7745c5c3_Err2475 return templ_7745c5c3_Err
2464 }2476 }
@@ -2495,75 +2507,75 @@ func mergeMenu(p MRPage) templ.Component {
2495 templ_7745c5c3_Var118 = templ.NopComponent2507 templ_7745c5c3_Var118 = templ.NopComponent
2496 }2508 }
2497 ctx = templ.ClearChildren(ctx)2509 ctx = templ.ClearChildren(ctx)
2498- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 228, "<details class=\"menu mmenu\" id=\"merge-menu\" data-state=\"open\"")2510+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 230, "<details class=\"menu mmenu\" id=\"merge-menu\" data-state=\"open\"")
2499 if templ_7745c5c3_Err != nil {2511 if templ_7745c5c3_Err != nil {
2500 return templ_7745c5c3_Err2512 return templ_7745c5c3_Err
2501 }2513 }
2502 if p.Box.Error != "" {2514 if p.Box.Error != "" {
2503- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 229, " open")2515+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 231, " open")
2504 if templ_7745c5c3_Err != nil {2516 if templ_7745c5c3_Err != nil {
2505 return templ_7745c5c3_Err2517 return templ_7745c5c3_Err
2506 }2518 }
2507 }2519 }
2508- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 230, "><summary class=\"btn primary\" aria-keyshortcuts=\"Shift+M\">")2520+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 232, "><summary class=\"btn primary\" aria-keyshortcuts=\"Shift+M\">")
2509 if templ_7745c5c3_Err != nil {2521 if templ_7745c5c3_Err != nil {
2510 return templ_7745c5c3_Err2522 return templ_7745c5c3_Err
2511 }2523 }
2512 if p.Box.ReadyAction != "" {2524 if p.Box.ReadyAction != "" {
2513- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 231, "Draft ")2525+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 233, "Draft ")
2514 if templ_7745c5c3_Err != nil {2526 if templ_7745c5c3_Err != nil {
2515 return templ_7745c5c3_Err2527 return templ_7745c5c3_Err
2516 }2528 }
2517 } else {2529 } else {
2518- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 232, "Merge ")2530+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 234, "Merge ")
2519 if templ_7745c5c3_Err != nil {2531 if templ_7745c5c3_Err != nil {
2520 return templ_7745c5c3_Err2532 return templ_7745c5c3_Err
2521 }2533 }
2522 }2534 }
2523- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 233, "<kbd aria-hidden=\"true\">M</kbd></summary><div class=\"menu-pop\" role=\"group\" aria-label=\"Merge\">")2535+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 235, "<kbd aria-hidden=\"true\">M</kbd></summary><div class=\"menu-pop\" role=\"group\" aria-label=\"Merge\">")
2524 if templ_7745c5c3_Err != nil {2536 if templ_7745c5c3_Err != nil {
2525 return templ_7745c5c3_Err2537 return templ_7745c5c3_Err
2526 }2538 }
2527 if p.Box.HeadGone {2539 if p.Box.HeadGone {
2528- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 234, "<p class=\"dim\">the source branch was deleted</p>")2540+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 236, "<p class=\"dim\">the source branch was deleted</p>")
2529 if templ_7745c5c3_Err != nil {2541 if templ_7745c5c3_Err != nil {
2530 return templ_7745c5c3_Err2542 return templ_7745c5c3_Err
2531 }2543 }
2532 }2544 }
2533 if p.Box.Error != "" {2545 if p.Box.Error != "" {
2534- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 235, "<p class=\"d-err\" role=\"alert\">")2546+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 237, "<p class=\"d-err\" role=\"alert\">")
2535 if templ_7745c5c3_Err != nil {2547 if templ_7745c5c3_Err != nil {
2536 return templ_7745c5c3_Err2548 return templ_7745c5c3_Err
2537 }2549 }
2538 var templ_7745c5c3_Var119 string2550 var templ_7745c5c3_Var119 string
2539 templ_7745c5c3_Var119, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Error)2551 templ_7745c5c3_Var119, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Error)
2540 if templ_7745c5c3_Err != nil {2552 if templ_7745c5c3_Err != nil {
2541- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 497, Col: 47}2553+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 501, Col: 47}
2542 }2554 }
2543 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var119))2555 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var119))
2544 if templ_7745c5c3_Err != nil {2556 if templ_7745c5c3_Err != nil {
2545 return templ_7745c5c3_Err2557 return templ_7745c5c3_Err
2546 }2558 }
2547- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 236, "</p>")2559+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 238, "</p>")
2548 if templ_7745c5c3_Err != nil {2560 if templ_7745c5c3_Err != nil {
2549 return templ_7745c5c3_Err2561 return templ_7745c5c3_Err
2550 }2562 }
2551 }2563 }
2552 if p.Box.ReadyAction != "" {2564 if p.Box.ReadyAction != "" {
2553- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 237, "<p class=\"d-draft\">this is a draft: it cannot be merged until it is ready for review.</p><form class=\"d-btns\" method=\"post\" action=\"")2565+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 239, "<p class=\"d-draft\">this is a draft: it cannot be merged until it is ready for review.</p><form class=\"d-btns\" method=\"post\" action=\"")
2554 if templ_7745c5c3_Err != nil {2566 if templ_7745c5c3_Err != nil {
2555 return templ_7745c5c3_Err2567 return templ_7745c5c3_Err
2556 }2568 }
2557 var templ_7745c5c3_Var120 templ.SafeURL2569 var templ_7745c5c3_Var120 templ.SafeURL
2558 templ_7745c5c3_Var120, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadyAction))2570 templ_7745c5c3_Var120, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadyAction))
2559 if templ_7745c5c3_Err != nil {2571 if templ_7745c5c3_Err != nil {
2560- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 501, Col: 80}2572+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 505, Col: 80}
2561 }2573 }
2562 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var120))2574 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var120))
2563 if templ_7745c5c3_Err != nil {2575 if templ_7745c5c3_Err != nil {
2564 return templ_7745c5c3_Err2576 return templ_7745c5c3_Err
2565 }2577 }
2566- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 238, "\"><button type=\"submit\" class=\"btn primary\" data-default title=\"remove the draft prefix from the title\">Ready for review</button></form>")2578+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 240, "\"><button type=\"submit\" class=\"btn primary\" data-default title=\"remove the draft prefix from the title\">Ready for review</button></form>")
2567 if templ_7745c5c3_Err != nil {2579 if templ_7745c5c3_Err != nil {
2568 return templ_7745c5c3_Err2580 return templ_7745c5c3_Err
2569 }2581 }
@@ -2572,185 +2584,185 @@ func mergeMenu(p MRPage) templ.Component {
2572 if templ_7745c5c3_Err != nil {2584 if templ_7745c5c3_Err != nil {
2573 return templ_7745c5c3_Err2585 return templ_7745c5c3_Err
2574 }2586 }
2575- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 239, " <form class=\"d-acts\" method=\"post\" action=\"")2587+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 241, " <form class=\"d-acts\" method=\"post\" action=\"")
2576 if templ_7745c5c3_Err != nil {2588 if templ_7745c5c3_Err != nil {
2577 return templ_7745c5c3_Err2589 return templ_7745c5c3_Err
2578 }2590 }
2579 var templ_7745c5c3_Var121 templ.SafeURL2591 var templ_7745c5c3_Var121 templ.SafeURL
2580 templ_7745c5c3_Var121, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.MergeAction))2592 templ_7745c5c3_Var121, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.MergeAction))
2581 if templ_7745c5c3_Err != nil {2593 if templ_7745c5c3_Err != nil {
2582- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 506, Col: 80}2594+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 510, Col: 80}
2583 }2595 }
2584 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var121))2596 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var121))
2585 if templ_7745c5c3_Err != nil {2597 if templ_7745c5c3_Err != nil {
2586 return templ_7745c5c3_Err2598 return templ_7745c5c3_Err
2587 }2599 }
2588- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 240, "\"><input type=\"hidden\" name=\"head_id\" value=\"")2600+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 242, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
2589 if templ_7745c5c3_Err != nil {2601 if templ_7745c5c3_Err != nil {
2590 return templ_7745c5c3_Err2602 return templ_7745c5c3_Err
2591 }2603 }
2592 var templ_7745c5c3_Var122 string2604 var templ_7745c5c3_Var122 string
2593 templ_7745c5c3_Var122, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)2605 templ_7745c5c3_Var122, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
2594 if templ_7745c5c3_Err != nil {2606 if templ_7745c5c3_Err != nil {
2595- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 507, Col: 59}2607+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 511, Col: 59}
2596 }2608 }
2597 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var122)2609 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var122)
2598 if templ_7745c5c3_Err != nil {2610 if templ_7745c5c3_Err != nil {
2599 return templ_7745c5c3_Err2611 return templ_7745c5c3_Err
2600 }2612 }
2601- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 241, "\"><fieldset class=\"d-modes\"><legend class=\"sr\">merge mode</legend> ")2613+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 243, "\"><fieldset class=\"d-modes\"><legend class=\"sr\">merge mode</legend> ")
2602 if templ_7745c5c3_Err != nil {2614 if templ_7745c5c3_Err != nil {
2603 return templ_7745c5c3_Err2615 return templ_7745c5c3_Err
2604 }2616 }
2605 for i, m := range p.Box.Modes {2617 for i, m := range p.Box.Modes {
2606- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 242, "<label><input type=\"radio\" name=\"mode\" value=\"")2618+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 244, "<label><input type=\"radio\" name=\"mode\" value=\"")
2607 if templ_7745c5c3_Err != nil {2619 if templ_7745c5c3_Err != nil {
2608 return templ_7745c5c3_Err2620 return templ_7745c5c3_Err
2609 }2621 }
2610 var templ_7745c5c3_Var123 string2622 var templ_7745c5c3_Var123 string
2611 templ_7745c5c3_Var123, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Value)2623 templ_7745c5c3_Var123, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Value)
2612 if templ_7745c5c3_Err != nil {2624 if templ_7745c5c3_Err != nil {
2613- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 515, Col: 24}2625+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 519, Col: 24}
2614 }2626 }
2615 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var123)2627 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var123)
2616 if templ_7745c5c3_Err != nil {2628 if templ_7745c5c3_Err != nil {
2617 return templ_7745c5c3_Err2629 return templ_7745c5c3_Err
2618 }2630 }
2619- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 243, "\"")2631+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 245, "\"")
2620 if templ_7745c5c3_Err != nil {2632 if templ_7745c5c3_Err != nil {
2621 return templ_7745c5c3_Err2633 return templ_7745c5c3_Err
2622 }2634 }
2623 if i == p.Box.Checked() {2635 if i == p.Box.Checked() {
2624- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 244, " checked")2636+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 246, " checked")
2625 if templ_7745c5c3_Err != nil {2637 if templ_7745c5c3_Err != nil {
2626 return templ_7745c5c3_Err2638 return templ_7745c5c3_Err
2627 }2639 }
2628 }2640 }
2629 if m.Disabled {2641 if m.Disabled {
2630- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 245, " disabled")2642+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 247, " disabled")
2631 if templ_7745c5c3_Err != nil {2643 if templ_7745c5c3_Err != nil {
2632 return templ_7745c5c3_Err2644 return templ_7745c5c3_Err
2633 }2645 }
2634 }2646 }
2635- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 246, " title=\"")2647+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 248, " title=\"")
2636 if templ_7745c5c3_Err != nil {2648 if templ_7745c5c3_Err != nil {
2637 return templ_7745c5c3_Err2649 return templ_7745c5c3_Err
2638 }2650 }
2639 var templ_7745c5c3_Var124 string2651 var templ_7745c5c3_Var124 string
2640 templ_7745c5c3_Var124, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Reason)2652 templ_7745c5c3_Var124, templ_7745c5c3_Err = templ.ResolveAttributeValue(m.Reason)
2641 if templ_7745c5c3_Err != nil {2653 if templ_7745c5c3_Err != nil {
2642- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 518, Col: 25}2654+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 522, Col: 25}
2643 }2655 }
2644 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var124)2656 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var124)
2645 if templ_7745c5c3_Err != nil {2657 if templ_7745c5c3_Err != nil {
2646 return templ_7745c5c3_Err2658 return templ_7745c5c3_Err
2647 }2659 }
2648- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 247, "\" :disabled=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffOk !== true : q('[data-mergeability]').data.mergeOk !== true\" :title=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffReason : q('[data-mergeability]').data.mergeReason\"> ")2660+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 249, "\" :disabled=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffOk !== true : q('[data-mergeability]').data.mergeOk !== true\" :title=\"this.value === 'fast-forward' ? q('[data-mergeability]').data.ffReason : q('[data-mergeability]').data.mergeReason\"> ")
2649 if templ_7745c5c3_Err != nil {2661 if templ_7745c5c3_Err != nil {
2650 return templ_7745c5c3_Err2662 return templ_7745c5c3_Err
2651 }2663 }
2652 var templ_7745c5c3_Var125 string2664 var templ_7745c5c3_Var125 string
2653 templ_7745c5c3_Var125, templ_7745c5c3_Err = templ.JoinStringErrs(m.Label)2665 templ_7745c5c3_Var125, templ_7745c5c3_Err = templ.JoinStringErrs(m.Label)
2654 if templ_7745c5c3_Err != nil {2666 if templ_7745c5c3_Err != nil {
2655- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 522, Col: 17}2667+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 526, Col: 17}
2656 }2668 }
2657 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var125))2669 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var125))
2658 if templ_7745c5c3_Err != nil {2670 if templ_7745c5c3_Err != nil {
2659 return templ_7745c5c3_Err2671 return templ_7745c5c3_Err
2660 }2672 }
2661- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 248, " ")2673+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 250, " ")
2662 if templ_7745c5c3_Err != nil {2674 if templ_7745c5c3_Err != nil {
2663 return templ_7745c5c3_Err2675 return templ_7745c5c3_Err
2664 }2676 }
2665 if i < 9 {2677 if i < 9 {
2666- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 249, "<kbd aria-hidden=\"true\">")2678+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 251, "<kbd aria-hidden=\"true\">")
2667 if templ_7745c5c3_Err != nil {2679 if templ_7745c5c3_Err != nil {
2668 return templ_7745c5c3_Err2680 return templ_7745c5c3_Err
2669 }2681 }
2670 var templ_7745c5c3_Var126 string2682 var templ_7745c5c3_Var126 string
2671 templ_7745c5c3_Var126, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(i + 1))2683 templ_7745c5c3_Var126, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(i + 1))
2672 if templ_7745c5c3_Err != nil {2684 if templ_7745c5c3_Err != nil {
2673- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 524, Col: 46}2685+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 528, Col: 46}
2674 }2686 }
2675 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var126))2687 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var126))
2676 if templ_7745c5c3_Err != nil {2688 if templ_7745c5c3_Err != nil {
2677 return templ_7745c5c3_Err2689 return templ_7745c5c3_Err
2678 }2690 }
2679- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 250, "</kbd>")2691+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 252, "</kbd>")
2680 if templ_7745c5c3_Err != nil {2692 if templ_7745c5c3_Err != nil {
2681 return templ_7745c5c3_Err2693 return templ_7745c5c3_Err
2682 }2694 }
2683 }2695 }
2684- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 251, "</label>")2696+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 253, "</label>")
2685 if templ_7745c5c3_Err != nil {2697 if templ_7745c5c3_Err != nil {
2686 return templ_7745c5c3_Err2698 return templ_7745c5c3_Err
2687 }2699 }
2688 }2700 }
2689- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 252, "</fieldset>")2701+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 254, "</fieldset>")
2690 if templ_7745c5c3_Err != nil {2702 if templ_7745c5c3_Err != nil {
2691 return templ_7745c5c3_Err2703 return templ_7745c5c3_Err
2692 }2704 }
2693 if p.Box.CanDeleteBranch {2705 if p.Box.CanDeleteBranch {
2694- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 253, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")2706+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 255, "<label class=\"d-check\"><input type=\"checkbox\" name=\"delete_branch\" value=\"1\"> delete ")
2695 if templ_7745c5c3_Err != nil {2707 if templ_7745c5c3_Err != nil {
2696 return templ_7745c5c3_Err2708 return templ_7745c5c3_Err
2697 }2709 }
2698 var templ_7745c5c3_Var127 string2710 var templ_7745c5c3_Var127 string
2699 templ_7745c5c3_Var127, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)2711 templ_7745c5c3_Var127, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
2700 if templ_7745c5c3_Err != nil {2712 if templ_7745c5c3_Err != nil {
2701- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 530, Col: 102}2713+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 534, Col: 102}
2702 }2714 }
2703 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var127))2715 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var127))
2704 if templ_7745c5c3_Err != nil {2716 if templ_7745c5c3_Err != nil {
2705 return templ_7745c5c3_Err2717 return templ_7745c5c3_Err
2706 }2718 }
2707- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 254, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")2719+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 256, " after the merge <kbd aria-hidden=\"true\">D</kbd></label>")
2708 if templ_7745c5c3_Err != nil {2720 if templ_7745c5c3_Err != nil {
2709 return templ_7745c5c3_Err2721 return templ_7745c5c3_Err
2710 }2722 }
2711 }2723 }
2712- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 255, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")2724+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 257, "<div class=\"d-btns\"><button type=\"submit\" class=\"btn primary\" data-default")
2713 if templ_7745c5c3_Err != nil {2725 if templ_7745c5c3_Err != nil {
2714 return templ_7745c5c3_Err2726 return templ_7745c5c3_Err
2715 }2727 }
2716 if !p.Box.CanMerge() {2728 if !p.Box.CanMerge() {
2717- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 256, " disabled")2729+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 258, " disabled")
2718 if templ_7745c5c3_Err != nil {2730 if templ_7745c5c3_Err != nil {
2719 return templ_7745c5c3_Err2731 return templ_7745c5c3_Err
2720 }2732 }
2721 }2733 }
2722- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 257, " title=\"")2734+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 259, " title=\"")
2723 if templ_7745c5c3_Err != nil {2735 if templ_7745c5c3_Err != nil {
2724 return templ_7745c5c3_Err2736 return templ_7745c5c3_Err
2725 }2737 }
2726 var templ_7745c5c3_Var128 string2738 var templ_7745c5c3_Var128 string
2727 templ_7745c5c3_Var128, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.MergeTitle())2739 templ_7745c5c3_Var128, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.MergeTitle())
2728 if templ_7745c5c3_Err != nil {2740 if templ_7745c5c3_Err != nil {
2729- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 538, Col: 33}2741+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 542, Col: 33}
2730 }2742 }
2731 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var128)2743 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var128)
2732 if templ_7745c5c3_Err != nil {2744 if templ_7745c5c3_Err != nil {
2733 return templ_7745c5c3_Err2745 return templ_7745c5c3_Err
2734 }2746 }
2735- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 258, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")2747+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 260, "\" :disabled=\"!this.form.querySelector('input[name=mode]:checked:not(:disabled)')\" :title=\"(this.form.querySelector('input[name=mode]:checked') || {}).title || ''\">Merge into ")
2736 if templ_7745c5c3_Err != nil {2748 if templ_7745c5c3_Err != nil {
2737 return templ_7745c5c3_Err2749 return templ_7745c5c3_Err
2738 }2750 }
2739 var templ_7745c5c3_Var129 string2751 var templ_7745c5c3_Var129 string
2740 templ_7745c5c3_Var129, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)2752 templ_7745c5c3_Var129, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
2741 if templ_7745c5c3_Err != nil {2753 if templ_7745c5c3_Err != nil {
2742- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 541, Col: 28}2754+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 545, Col: 28}
2743 }2755 }
2744 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var129))2756 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var129))
2745 if templ_7745c5c3_Err != nil {2757 if templ_7745c5c3_Err != nil {
2746 return templ_7745c5c3_Err2758 return templ_7745c5c3_Err
2747 }2759 }
2748- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 259, "</button></div></form>")2760+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 261, "</button></div></form>")
2749 if templ_7745c5c3_Err != nil {2761 if templ_7745c5c3_Err != nil {
2750 return templ_7745c5c3_Err2762 return templ_7745c5c3_Err
2751 }2763 }
2752 }2764 }
2753- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 260, "</div></details>")2765+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 262, "</div></details>")
2754 if templ_7745c5c3_Err != nil {2766 if templ_7745c5c3_Err != nil {
2755 return templ_7745c5c3_Err2767 return templ_7745c5c3_Err
2756 }2768 }
@@ -2781,98 +2793,98 @@ func MRMergeability(v MergeabilityView) templ.Component {
2781 templ_7745c5c3_Var130 = templ.NopComponent2793 templ_7745c5c3_Var130 = templ.NopComponent
2782 }2794 }
2783 ctx = templ.ClearChildren(ctx)2795 ctx = templ.ClearChildren(ctx)
2784- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 261, "<span data-mergeability data-state=\"")2796+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 263, "<span data-mergeability data-state=\"")
2785 if templ_7745c5c3_Err != nil {2797 if templ_7745c5c3_Err != nil {
2786 return templ_7745c5c3_Err2798 return templ_7745c5c3_Err
2787 }2799 }
2788 var templ_7745c5c3_Var131 string2800 var templ_7745c5c3_Var131 string
2789 templ_7745c5c3_Var131, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)2801 templ_7745c5c3_Var131, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
2790 if templ_7745c5c3_Err != nil {2802 if templ_7745c5c3_Err != nil {
2791- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 554, Col: 22}2803+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 558, Col: 22}
2792 }2804 }
2793 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var131)2805 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var131)
2794 if templ_7745c5c3_Err != nil {2806 if templ_7745c5c3_Err != nil {
2795 return templ_7745c5c3_Err2807 return templ_7745c5c3_Err
2796 }2808 }
2797- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 262, "\" data-ff-ok=\"")2809+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "\" data-ff-ok=\"")
2798 if templ_7745c5c3_Err != nil {2810 if templ_7745c5c3_Err != nil {
2799 return templ_7745c5c3_Err2811 return templ_7745c5c3_Err
2800 }2812 }
2801 var templ_7745c5c3_Var132 string2813 var templ_7745c5c3_Var132 string
2802 templ_7745c5c3_Var132, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.FFOk))2814 templ_7745c5c3_Var132, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.FFOk))
2803 if templ_7745c5c3_Err != nil {2815 if templ_7745c5c3_Err != nil {
2804- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 555, Col: 41}2816+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 559, Col: 41}
2805 }2817 }
2806 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var132)2818 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var132)
2807 if templ_7745c5c3_Err != nil {2819 if templ_7745c5c3_Err != nil {
2808 return templ_7745c5c3_Err2820 return templ_7745c5c3_Err
2809 }2821 }
2810- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 263, "\" data-merge-ok=\"")2822+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, "\" data-merge-ok=\"")
2811 if templ_7745c5c3_Err != nil {2823 if templ_7745c5c3_Err != nil {
2812 return templ_7745c5c3_Err2824 return templ_7745c5c3_Err
2813 }2825 }
2814 var templ_7745c5c3_Var133 string2826 var templ_7745c5c3_Var133 string
2815 templ_7745c5c3_Var133, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.MergeOk))2827 templ_7745c5c3_Var133, templ_7745c5c3_Err = templ.ResolveAttributeValue(strconv.FormatBool(v.MergeOk))
2816 if templ_7745c5c3_Err != nil {2828 if templ_7745c5c3_Err != nil {
2817- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 556, Col: 47}2829+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 47}
2818 }2830 }
2819 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var133)2831 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var133)
2820 if templ_7745c5c3_Err != nil {2832 if templ_7745c5c3_Err != nil {
2821 return templ_7745c5c3_Err2833 return templ_7745c5c3_Err
2822 }2834 }
2823- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 264, "\" data-ff-reason=\"")2835+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "\" data-ff-reason=\"")
2824 if templ_7745c5c3_Err != nil {2836 if templ_7745c5c3_Err != nil {
2825 return templ_7745c5c3_Err2837 return templ_7745c5c3_Err
2826 }2838 }
2827 var templ_7745c5c3_Var134 string2839 var templ_7745c5c3_Var134 string
2828 templ_7745c5c3_Var134, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.FFReason)2840 templ_7745c5c3_Var134, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.FFReason)
2829 if templ_7745c5c3_Err != nil {2841 if templ_7745c5c3_Err != nil {
2830- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 557, Col: 29}2842+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 561, Col: 29}
2831 }2843 }
2832 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var134)2844 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var134)
2833 if templ_7745c5c3_Err != nil {2845 if templ_7745c5c3_Err != nil {
2834 return templ_7745c5c3_Err2846 return templ_7745c5c3_Err
2835 }2847 }
2836- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 265, "\" data-merge-reason=\"")2848+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, "\" data-merge-reason=\"")
2837 if templ_7745c5c3_Err != nil {2849 if templ_7745c5c3_Err != nil {
2838 return templ_7745c5c3_Err2850 return templ_7745c5c3_Err
2839 }2851 }
2840 var templ_7745c5c3_Var135 string2852 var templ_7745c5c3_Var135 string
2841 templ_7745c5c3_Var135, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.MergeReason)2853 templ_7745c5c3_Var135, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.MergeReason)
2842 if templ_7745c5c3_Err != nil {2854 if templ_7745c5c3_Err != nil {
2843- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 558, Col: 35}2855+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 562, Col: 35}
2844 }2856 }
2845 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var135)2857 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var135)
2846 if templ_7745c5c3_Err != nil {2858 if templ_7745c5c3_Err != nil {
2847 return templ_7745c5c3_Err2859 return templ_7745c5c3_Err
2848 }2860 }
2849- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 266, "\"><span class=\"badge\" data-state=\"")2861+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, "\"><span class=\"badge\" data-state=\"")
2850 if templ_7745c5c3_Err != nil {2862 if templ_7745c5c3_Err != nil {
2851 return templ_7745c5c3_Err2863 return templ_7745c5c3_Err
2852 }2864 }
2853 var templ_7745c5c3_Var136 string2865 var templ_7745c5c3_Var136 string
2854 templ_7745c5c3_Var136, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)2866 templ_7745c5c3_Var136, templ_7745c5c3_Err = templ.ResolveAttributeValue(v.State)
2855 if templ_7745c5c3_Err != nil {2867 if templ_7745c5c3_Err != nil {
2856- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 42}2868+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 42}
2857 }2869 }
2858 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var136)2870 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var136)
2859 if templ_7745c5c3_Err != nil {2871 if templ_7745c5c3_Err != nil {
2860 return templ_7745c5c3_Err2872 return templ_7745c5c3_Err
2861 }2873 }
2862- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 267, "\">")2874+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, "\">")
2863 if templ_7745c5c3_Err != nil {2875 if templ_7745c5c3_Err != nil {
2864 return templ_7745c5c3_Err2876 return templ_7745c5c3_Err
2865 }2877 }
2866 var templ_7745c5c3_Var137 string2878 var templ_7745c5c3_Var137 string
2867 templ_7745c5c3_Var137, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)2879 templ_7745c5c3_Var137, templ_7745c5c3_Err = templ.JoinStringErrs(v.Label)
2868 if templ_7745c5c3_Err != nil {2880 if templ_7745c5c3_Err != nil {
2869- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 560, Col: 54}2881+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 564, Col: 54}
2870 }2882 }
2871 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var137))2883 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var137))
2872 if templ_7745c5c3_Err != nil {2884 if templ_7745c5c3_Err != nil {
2873 return templ_7745c5c3_Err2885 return templ_7745c5c3_Err
2874 }2886 }
2875- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 268, "</span> ")2887+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, "</span> ")
2876 if templ_7745c5c3_Err != nil {2888 if templ_7745c5c3_Err != nil {
2877 return templ_7745c5c3_Err2889 return templ_7745c5c3_Err
2878 }2890 }
@@ -2880,78 +2892,78 @@ func MRMergeability(v MergeabilityView) templ.Component {
2880 var templ_7745c5c3_Var138 string2892 var templ_7745c5c3_Var138 string
2881 templ_7745c5c3_Var138, templ_7745c5c3_Err = templ.JoinStringErrs(" ")2893 templ_7745c5c3_Var138, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
2882 if templ_7745c5c3_Err != nil {2894 if templ_7745c5c3_Err != nil {
2883- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 562, Col: 8}2895+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 566, Col: 8}
2884 }2896 }
2885 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var138))2897 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var138))
2886 if templ_7745c5c3_Err != nil {2898 if templ_7745c5c3_Err != nil {
2887 return templ_7745c5c3_Err2899 return templ_7745c5c3_Err
2888 }2900 }
2889- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 269, "<span class=\"dim\">")2901+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "<span class=\"dim\">")
2890 if templ_7745c5c3_Err != nil {2902 if templ_7745c5c3_Err != nil {
2891 return templ_7745c5c3_Err2903 return templ_7745c5c3_Err
2892 }2904 }
2893 var templ_7745c5c3_Var139 string2905 var templ_7745c5c3_Var139 string
2894 templ_7745c5c3_Var139, templ_7745c5c3_Err = templ.JoinStringErrs(v.Detail)2906 templ_7745c5c3_Var139, templ_7745c5c3_Err = templ.JoinStringErrs(v.Detail)
2895 if templ_7745c5c3_Err != nil {2907 if templ_7745c5c3_Err != nil {
2896- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 562, Col: 38}2908+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 566, Col: 38}
2897 }2909 }
2898 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var139))2910 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var139))
2899 if templ_7745c5c3_Err != nil {2911 if templ_7745c5c3_Err != nil {
2900 return templ_7745c5c3_Err2912 return templ_7745c5c3_Err
2901 }2913 }
2902- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 270, "</span>")2914+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "</span>")
2903 if templ_7745c5c3_Err != nil {2915 if templ_7745c5c3_Err != nil {
2904 return templ_7745c5c3_Err2916 return templ_7745c5c3_Err
2905 }2917 }
2906 }2918 }
2907- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 271, "</span> ")2919+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "</span> ")
2908 if templ_7745c5c3_Err != nil {2920 if templ_7745c5c3_Err != nil {
2909 return templ_7745c5c3_Err2921 return templ_7745c5c3_Err
2910 }2922 }
2911 if len(v.Paths) > 0 {2923 if len(v.Paths) > 0 {
2912- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 272, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")2924+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "<ul class=\"mg-paths\" aria-label=\"conflicting files\">")
2913 if templ_7745c5c3_Err != nil {2925 if templ_7745c5c3_Err != nil {
2914 return templ_7745c5c3_Err2926 return templ_7745c5c3_Err
2915 }2927 }
2916 for _, path := range v.Paths {2928 for _, path := range v.Paths {
2917- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 273, "<li><code>")2929+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "<li><code>")
2918 if templ_7745c5c3_Err != nil {2930 if templ_7745c5c3_Err != nil {
2919 return templ_7745c5c3_Err2931 return templ_7745c5c3_Err
2920 }2932 }
2921 var templ_7745c5c3_Var140 string2933 var templ_7745c5c3_Var140 string
2922 templ_7745c5c3_Var140, templ_7745c5c3_Err = templ.JoinStringErrs(path)2934 templ_7745c5c3_Var140, templ_7745c5c3_Err = templ.JoinStringErrs(path)
2923 if templ_7745c5c3_Err != nil {2935 if templ_7745c5c3_Err != nil {
2924- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 568, Col: 20}2936+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 572, Col: 20}
2925 }2937 }
2926 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var140))2938 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var140))
2927 if templ_7745c5c3_Err != nil {2939 if templ_7745c5c3_Err != nil {
2928 return templ_7745c5c3_Err2940 return templ_7745c5c3_Err
2929 }2941 }
2930- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 274, "</code></li>")2942+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, "</code></li>")
2931 if templ_7745c5c3_Err != nil {2943 if templ_7745c5c3_Err != nil {
2932 return templ_7745c5c3_Err2944 return templ_7745c5c3_Err
2933 }2945 }
2934 }2946 }
2935- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 275, "</ul>")2947+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "</ul>")
2936 if templ_7745c5c3_Err != nil {2948 if templ_7745c5c3_Err != nil {
2937 return templ_7745c5c3_Err2949 return templ_7745c5c3_Err
2938 }2950 }
2939 }2951 }
2940 if v.PathsNote != "" {2952 if v.PathsNote != "" {
2941- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 276, "<p class=\"dim\">")2953+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, "<p class=\"dim\">")
2942 if templ_7745c5c3_Err != nil {2954 if templ_7745c5c3_Err != nil {
2943 return templ_7745c5c3_Err2955 return templ_7745c5c3_Err
2944 }2956 }
2945 var templ_7745c5c3_Var141 string2957 var templ_7745c5c3_Var141 string
2946 templ_7745c5c3_Var141, templ_7745c5c3_Err = templ.JoinStringErrs(v.PathsNote)2958 templ_7745c5c3_Var141, templ_7745c5c3_Err = templ.JoinStringErrs(v.PathsNote)
2947 if templ_7745c5c3_Err != nil {2959 if templ_7745c5c3_Err != nil {
2948- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 573, Col: 30}2960+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 577, Col: 30}
2949 }2961 }
2950 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var141))2962 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var141))
2951 if templ_7745c5c3_Err != nil {2963 if templ_7745c5c3_Err != nil {
2952 return templ_7745c5c3_Err2964 return templ_7745c5c3_Err
2953 }2965 }
2954- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 277, "</p>")2966+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "</p>")
2955 if templ_7745c5c3_Err != nil {2967 if templ_7745c5c3_Err != nil {
2956 return templ_7745c5c3_Err2968 return templ_7745c5c3_Err
2957 }2969 }
@@ -2983,7 +2995,7 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
2983 templ_7745c5c3_Var142 = templ.NopComponent2995 templ_7745c5c3_Var142 = templ.NopComponent
2984 }2996 }
2985 ctx = templ.ClearChildren(ctx)2997 ctx = templ.ClearChildren(ctx)
2986- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 278, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")2998+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, "<div id=\"mr-mergeability\" class=\"live-slot\" role=\"status\" data-slot>")
2987 if templ_7745c5c3_Err != nil {2999 if templ_7745c5c3_Err != nil {
2988 return templ_7745c5c3_Err3000 return templ_7745c5c3_Err
2989 }3001 }
@@ -2991,7 +3003,7 @@ func mrMergeabilitySlot(v MergeabilityView) templ.Component {
2991 if templ_7745c5c3_Err != nil {3003 if templ_7745c5c3_Err != nil {
2992 return templ_7745c5c3_Err3004 return templ_7745c5c3_Err
2993 }3005 }
2994- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 279, "</div>")3006+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, "</div>")
2995 if templ_7745c5c3_Err != nil {3007 if templ_7745c5c3_Err != nil {
2996 return templ_7745c5c3_Err3008 return templ_7745c5c3_Err
2997 }3009 }
@@ -3052,123 +3064,123 @@ func moreMenu(p MRPage) templ.Component {
3052 templ_7745c5c3_Var144 = templ.NopComponent3064 templ_7745c5c3_Var144 = templ.NopComponent
3053 }3065 }
3054 ctx = templ.ClearChildren(ctx)3066 ctx = templ.ClearChildren(ctx)
3055- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 280, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")3067+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, "<details class=\"menu omenu\"><summary class=\"btn icon\" aria-label=\"More actions\" title=\"more actions\">⋯</summary><div class=\"menu-pop\" role=\"group\" aria-label=\"More actions\"><section class=\"merge-settings\"><h2>Merge settings</h2><dl class=\"kv\"><dt>modes</dt><dd>")
3056 if templ_7745c5c3_Err != nil {3068 if templ_7745c5c3_Err != nil {
3057 return templ_7745c5c3_Err3069 return templ_7745c5c3_Err
3058 }3070 }
3059 var templ_7745c5c3_Var145 string3071 var templ_7745c5c3_Var145 string
3060 templ_7745c5c3_Var145, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(p.Modes, ", "))3072 templ_7745c5c3_Var145, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(p.Modes, ", "))
3061 if templ_7745c5c3_Err != nil {3073 if templ_7745c5c3_Err != nil {
3062- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 600, Col: 38}3074+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 604, Col: 38}
3063 }3075 }
3064 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var145))3076 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var145))
3065 if templ_7745c5c3_Err != nil {3077 if templ_7745c5c3_Err != nil {
3066 return templ_7745c5c3_Err3078 return templ_7745c5c3_Err
3067 }3079 }
3068- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 281, "</dd><dt>checks</dt><dd>")3080+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, "</dd><dt>checks</dt><dd>")
3069 if templ_7745c5c3_Err != nil {3081 if templ_7745c5c3_Err != nil {
3070 return templ_7745c5c3_Err3082 return templ_7745c5c3_Err
3071 }3083 }
3072 if p.ChecksBlock {3084 if p.ChecksBlock {
3073- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 282, "failing ones block the merge")3085+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "failing ones block the merge")
3074 if templ_7745c5c3_Err != nil {3086 if templ_7745c5c3_Err != nil {
3075 return templ_7745c5c3_Err3087 return templ_7745c5c3_Err
3076 }3088 }
3077 } else {3089 } else {
3078- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 283, "do not block the merge")3090+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "do not block the merge")
3079 if templ_7745c5c3_Err != nil {3091 if templ_7745c5c3_Err != nil {
3080 return templ_7745c5c3_Err3092 return templ_7745c5c3_Err
3081 }3093 }
3082 }3094 }
3083- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 284, "</dd></dl></section>")3095+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "</dd></dl></section>")
3084 if templ_7745c5c3_Err != nil {3096 if templ_7745c5c3_Err != nil {
3085 return templ_7745c5c3_Err3097 return templ_7745c5c3_Err
3086 }3098 }
3087 if p.Box != nil {3099 if p.Box != nil {
3088 if p.Box.Signed {3100 if p.Box.Signed {
3089- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 285, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")3101+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "<p class=\"d-note\" id=\"mr-signing\">squash and merge commits are signed with ermite's own key (generated on first start). ")
3090 if templ_7745c5c3_Err != nil {3102 if templ_7745c5c3_Err != nil {
3091 return templ_7745c5c3_Err3103 return templ_7745c5c3_Err
3092 }3104 }
3093 if p.Box.Fingerprint != "" {3105 if p.Box.Fingerprint != "" {
3094- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 286, "fingerprint <code>")3106+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "fingerprint <code>")
3095 if templ_7745c5c3_Err != nil {3107 if templ_7745c5c3_Err != nil {
3096 return templ_7745c5c3_Err3108 return templ_7745c5c3_Err
3097 }3109 }
3098 var templ_7745c5c3_Var146 string3110 var templ_7745c5c3_Var146 string
3099 templ_7745c5c3_Var146, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Fingerprint)3111 templ_7745c5c3_Var146, templ_7745c5c3_Err = templ.JoinStringErrs(p.Box.Fingerprint)
3100 if templ_7745c5c3_Err != nil {3112 if templ_7745c5c3_Err != nil {
3101- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 616, Col: 44}3113+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 620, Col: 44}
3102 }3114 }
3103 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var146))3115 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var146))
3104 if templ_7745c5c3_Err != nil {3116 if templ_7745c5c3_Err != nil {
3105 return templ_7745c5c3_Err3117 return templ_7745c5c3_Err
3106 }3118 }
3107- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 287, "</code> ")3119+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, "</code> ")
3108 if templ_7745c5c3_Err != nil {3120 if templ_7745c5c3_Err != nil {
3109 return templ_7745c5c3_Err3121 return templ_7745c5c3_Err
3110 }3122 }
3111 }3123 }
3112- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 288, "<code>ermite signing-key show</code> prints it.</p>")3124+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "<code>ermite signing-key show</code> prints it.</p>")
3113 if templ_7745c5c3_Err != nil {3125 if templ_7745c5c3_Err != nil {
3114 return templ_7745c5c3_Err3126 return templ_7745c5c3_Err
3115 }3127 }
3116 }3128 }
3117- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 289, " ")3129+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, " ")
3118 if templ_7745c5c3_Err != nil {3130 if templ_7745c5c3_Err != nil {
3119 return templ_7745c5c3_Err3131 return templ_7745c5c3_Err
3120 }3132 }
3121 if p.Box.CanMarkRead {3133 if p.Box.CanMarkRead {
3122- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 290, "<form method=\"post\" action=\"")3134+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "<form method=\"post\" action=\"")
3123 if templ_7745c5c3_Err != nil {3135 if templ_7745c5c3_Err != nil {
3124 return templ_7745c5c3_Err3136 return templ_7745c5c3_Err
3125 }3137 }
3126 var templ_7745c5c3_Var147 templ.SafeURL3138 var templ_7745c5c3_Var147 templ.SafeURL
3127 templ_7745c5c3_Var147, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadAction))3139 templ_7745c5c3_Var147, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.ReadAction))
3128 if templ_7745c5c3_Err != nil {3140 if templ_7745c5c3_Err != nil {
3129- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 622, Col: 65}3141+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 626, Col: 65}
3130 }3142 }
3131 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var147))3143 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var147))
3132 if templ_7745c5c3_Err != nil {3144 if templ_7745c5c3_Err != nil {
3133 return templ_7745c5c3_Err3145 return templ_7745c5c3_Err
3134 }3146 }
3135- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 291, "\"><input type=\"hidden\" name=\"head_id\" value=\"")3147+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, "\"><input type=\"hidden\" name=\"head_id\" value=\"")
3136 if templ_7745c5c3_Err != nil {3148 if templ_7745c5c3_Err != nil {
3137 return templ_7745c5c3_Err3149 return templ_7745c5c3_Err
3138 }3150 }
3139 var templ_7745c5c3_Var148 string3151 var templ_7745c5c3_Var148 string
3140 templ_7745c5c3_Var148, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)3152 templ_7745c5c3_Var148, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Box.Head)
3141 if templ_7745c5c3_Err != nil {3153 if templ_7745c5c3_Err != nil {
3142- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 623, Col: 60}3154+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 627, Col: 60}
3143 }3155 }
3144 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var148)3156 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var148)
3145 if templ_7745c5c3_Err != nil {3157 if templ_7745c5c3_Err != nil {
3146 return templ_7745c5c3_Err3158 return templ_7745c5c3_Err
3147 }3159 }
3148- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 292, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")3160+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "\"> <button type=\"submit\" title=\"the next visit can show only what changed after this head\" class=\"btn\" aria-keyshortcuts=\"Shift+R\" data-read>Mark read <kbd aria-hidden=\"true\">R</kbd></button></form>")
3149 if templ_7745c5c3_Err != nil {3161 if templ_7745c5c3_Err != nil {
3150 return templ_7745c5c3_Err3162 return templ_7745c5c3_Err
3151 }3163 }
3152 }3164 }
3153- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 293, " <form method=\"post\" action=\"")3165+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, " <form method=\"post\" action=\"")
3154 if templ_7745c5c3_Err != nil {3166 if templ_7745c5c3_Err != nil {
3155 return templ_7745c5c3_Err3167 return templ_7745c5c3_Err
3156 }3168 }
3157 var templ_7745c5c3_Var149 templ.SafeURL3169 var templ_7745c5c3_Var149 templ.SafeURL
3158 templ_7745c5c3_Var149, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.CloseAction))3170 templ_7745c5c3_Var149, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Box.CloseAction))
3159 if templ_7745c5c3_Err != nil {3171 if templ_7745c5c3_Err != nil {
3160- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 627, Col: 65}3172+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 631, Col: 65}
3161 }3173 }
3162 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var149))3174 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var149))
3163 if templ_7745c5c3_Err != nil {3175 if templ_7745c5c3_Err != nil {
3164 return templ_7745c5c3_Err3176 return templ_7745c5c3_Err
3165 }3177 }
3166- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 294, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")3178+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "\"><button type=\"submit\" title=\"close without merging; the branch is kept\" class=\"btn danger\">Close</button></form>")
3167 if templ_7745c5c3_Err != nil {3179 if templ_7745c5c3_Err != nil {
3168 return templ_7745c5c3_Err3180 return templ_7745c5c3_Err
3169 }3181 }
3170 if !p.Box.HeadGone && p.Box.ReadyAction == "" {3182 if !p.Box.HeadGone && p.Box.ReadyAction == "" {
3171- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 295, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")3183+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "<details class=\"d-or\"><summary class=\"mute\">or from a terminal</summary>")
3172 if templ_7745c5c3_Err != nil {3184 if templ_7745c5c3_Err != nil {
3173 return templ_7745c5c3_Err3185 return templ_7745c5c3_Err
3174 }3186 }
@@ -3176,13 +3188,13 @@ func moreMenu(p MRPage) templ.Component {
3176 if templ_7745c5c3_Err != nil {3188 if templ_7745c5c3_Err != nil {
3177 return templ_7745c5c3_Err3189 return templ_7745c5c3_Err
3178 }3190 }
3179- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 296, "</details>")3191+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "</details>")
3180 if templ_7745c5c3_Err != nil {3192 if templ_7745c5c3_Err != nil {
3181 return templ_7745c5c3_Err3193 return templ_7745c5c3_Err
3182 }3194 }
3183 }3195 }
3184 }3196 }
3185- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 297, "</div></details>")3197+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, "</div></details>")
3186 if templ_7745c5c3_Err != nil {3198 if templ_7745c5c3_Err != nil {
3187 return templ_7745c5c3_Err3199 return templ_7745c5c3_Err
3188 }3200 }
@@ -3223,263 +3235,263 @@ func Compare(l Layout, p ComparePage) templ.Component {
3223 }()3235 }()
3224 }3236 }
3225 ctx = templ.InitializeContext(ctx)3237 ctx = templ.InitializeContext(ctx)
3226- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 298, "<header class=\"show mr-h\"><h1>")3238+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "<header class=\"show mr-h\"><h1>")
3227 if templ_7745c5c3_Err != nil {3239 if templ_7745c5c3_Err != nil {
3228 return templ_7745c5c3_Err3240 return templ_7745c5c3_Err
3229 }3241 }
3230 var templ_7745c5c3_Var152 string3242 var templ_7745c5c3_Var152 string
3231 templ_7745c5c3_Var152, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)3243 templ_7745c5c3_Var152, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
3232 if templ_7745c5c3_Err != nil {3244 if templ_7745c5c3_Err != nil {
3233- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 644, Col: 17}3245+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 648, Col: 17}
3234 }3246 }
3235 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var152))3247 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var152))
3236 if templ_7745c5c3_Err != nil {3248 if templ_7745c5c3_Err != nil {
3237 return templ_7745c5c3_Err3249 return templ_7745c5c3_Err
3238 }3250 }
3239- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 299, " → ")3251+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, " → ")
3240 if templ_7745c5c3_Err != nil {3252 if templ_7745c5c3_Err != nil {
3241 return templ_7745c5c3_Err3253 return templ_7745c5c3_Err
3242 }3254 }
3243 var templ_7745c5c3_Var153 string3255 var templ_7745c5c3_Var153 string
3244 templ_7745c5c3_Var153, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)3256 templ_7745c5c3_Var153, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3245 if templ_7745c5c3_Err != nil {3257 if templ_7745c5c3_Err != nil {
3246- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 644, Col: 34}3258+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 648, Col: 34}
3247 }3259 }
3248 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var153))3260 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var153))
3249 if templ_7745c5c3_Err != nil {3261 if templ_7745c5c3_Err != nil {
3250 return templ_7745c5c3_Err3262 return templ_7745c5c3_Err
3251 }3263 }
3252- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 300, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")3264+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "</h1><dl class=\"kv show-kv\"><dt>branch</dt><dd><a href=\"")
3253 if templ_7745c5c3_Err != nil {3265 if templ_7745c5c3_Err != nil {
3254 return templ_7745c5c3_Err3266 return templ_7745c5c3_Err
3255 }3267 }
3256 var templ_7745c5c3_Var154 templ.SafeURL3268 var templ_7745c5c3_Var154 templ.SafeURL
3257 templ_7745c5c3_Var154, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.SourceHref))3269 templ_7745c5c3_Var154, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.SourceHref))
3258 if templ_7745c5c3_Err != nil {3270 if templ_7745c5c3_Err != nil {
3259- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 647, Col: 45}3271+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 651, Col: 45}
3260 }3272 }
3261 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var154))3273 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var154))
3262 if templ_7745c5c3_Err != nil {3274 if templ_7745c5c3_Err != nil {
3263 return templ_7745c5c3_Err3275 return templ_7745c5c3_Err
3264 }3276 }
3265- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 301, "\">")3277+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "\">")
3266 if templ_7745c5c3_Err != nil {3278 if templ_7745c5c3_Err != nil {
3267 return templ_7745c5c3_Err3279 return templ_7745c5c3_Err
3268 }3280 }
3269 var templ_7745c5c3_Var155 string3281 var templ_7745c5c3_Var155 string
3270 templ_7745c5c3_Var155, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)3282 templ_7745c5c3_Var155, templ_7745c5c3_Err = templ.JoinStringErrs(p.Source)
3271 if templ_7745c5c3_Err != nil {3283 if templ_7745c5c3_Err != nil {
3272- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 647, Col: 58}3284+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 651, Col: 58}
3273 }3285 }
3274 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var155))3286 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var155))
3275 if templ_7745c5c3_Err != nil {3287 if templ_7745c5c3_Err != nil {
3276 return templ_7745c5c3_Err3288 return templ_7745c5c3_Err
3277 }3289 }
3278- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 302, "</a></dd><dt>target</dt><dd><a href=\"")3290+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "</a></dd><dt>target</dt><dd><a href=\"")
3279 if templ_7745c5c3_Err != nil {3291 if templ_7745c5c3_Err != nil {
3280 return templ_7745c5c3_Err3292 return templ_7745c5c3_Err
3281 }3293 }
3282 var templ_7745c5c3_Var156 templ.SafeURL3294 var templ_7745c5c3_Var156 templ.SafeURL
3283 templ_7745c5c3_Var156, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.TargetHref))3295 templ_7745c5c3_Var156, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.TargetHref))
3284 if templ_7745c5c3_Err != nil {3296 if templ_7745c5c3_Err != nil {
3285- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 649, Col: 45}3297+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 653, Col: 45}
3286 }3298 }
3287 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var156))3299 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var156))
3288 if templ_7745c5c3_Err != nil {3300 if templ_7745c5c3_Err != nil {
3289 return templ_7745c5c3_Err3301 return templ_7745c5c3_Err
3290 }3302 }
3291- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 303, "\">")3303+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "\">")
3292 if templ_7745c5c3_Err != nil {3304 if templ_7745c5c3_Err != nil {
3293 return templ_7745c5c3_Err3305 return templ_7745c5c3_Err
3294 }3306 }
3295 var templ_7745c5c3_Var157 string3307 var templ_7745c5c3_Var157 string
3296 templ_7745c5c3_Var157, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)3308 templ_7745c5c3_Var157, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3297 if templ_7745c5c3_Err != nil {3309 if templ_7745c5c3_Err != nil {
3298- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 649, Col: 58}3310+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 653, Col: 58}
3299 }3311 }
3300 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var157))3312 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var157))
3301 if templ_7745c5c3_Err != nil {3313 if templ_7745c5c3_Err != nil {
3302 return templ_7745c5c3_Err3314 return templ_7745c5c3_Err
3303 }3315 }
3304- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 304, "</a></dd><dt>ahead</dt><dd>")3316+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "</a></dd><dt>ahead</dt><dd>")
3305 if templ_7745c5c3_Err != nil {3317 if templ_7745c5c3_Err != nil {
3306 return templ_7745c5c3_Err3318 return templ_7745c5c3_Err
3307 }3319 }
3308 var templ_7745c5c3_Var158 string3320 var templ_7745c5c3_Var158 string
3309 templ_7745c5c3_Var158, templ_7745c5c3_Err = templ.JoinStringErrs(p.AheadText)3321 templ_7745c5c3_Var158, templ_7745c5c3_Err = templ.JoinStringErrs(p.AheadText)
3310 if templ_7745c5c3_Err != nil {3322 if templ_7745c5c3_Err != nil {
3311- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 651, Col: 21}3323+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 655, Col: 21}
3312 }3324 }
3313 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var158))3325 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var158))
3314 if templ_7745c5c3_Err != nil {3326 if templ_7745c5c3_Err != nil {
3315 return templ_7745c5c3_Err3327 return templ_7745c5c3_Err
3316 }3328 }
3317- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 305, "</dd></dl></header>")3329+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "</dd></dl></header>")
3318 if templ_7745c5c3_Err != nil {3330 if templ_7745c5c3_Err != nil {
3319 return templ_7745c5c3_Err3331 return templ_7745c5c3_Err
3320 }3332 }
3321 if p.Note != "" {3333 if p.Note != "" {
3322- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 306, "<p class=\"notice\">")3334+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, "<p class=\"notice\">")
3323 if templ_7745c5c3_Err != nil {3335 if templ_7745c5c3_Err != nil {
3324 return templ_7745c5c3_Err3336 return templ_7745c5c3_Err
3325 }3337 }
3326 var templ_7745c5c3_Var159 string3338 var templ_7745c5c3_Var159 string
3327 templ_7745c5c3_Var159, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)3339 templ_7745c5c3_Var159, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note)
3328 if templ_7745c5c3_Err != nil {3340 if templ_7745c5c3_Err != nil {
3329- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 655, Col: 29}3341+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 659, Col: 29}
3330 }3342 }
3331 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var159))3343 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var159))
3332 if templ_7745c5c3_Err != nil {3344 if templ_7745c5c3_Err != nil {
3333 return templ_7745c5c3_Err3345 return templ_7745c5c3_Err
3334 }3346 }
3335- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 307, "</p>")3347+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "</p>")
3336 if templ_7745c5c3_Err != nil {3348 if templ_7745c5c3_Err != nil {
3337 return templ_7745c5c3_Err3349 return templ_7745c5c3_Err
3338 }3350 }
3339 }3351 }
3340- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 308, " ")3352+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, " ")
3341 if templ_7745c5c3_Err != nil {3353 if templ_7745c5c3_Err != nil {
3342 return templ_7745c5c3_Err3354 return templ_7745c5c3_Err
3343 }3355 }
3344 if p.Existing != nil {3356 if p.Existing != nil {
3345- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 309, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")3357+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, "<p class=\"notice\">an open merge request already covers these branches: <a href=\"")
3346 if templ_7745c5c3_Err != nil {3358 if templ_7745c5c3_Err != nil {
3347 return templ_7745c5c3_Err3359 return templ_7745c5c3_Err
3348 }3360 }
3349 var templ_7745c5c3_Var160 templ.SafeURL3361 var templ_7745c5c3_Var160 templ.SafeURL
3350 templ_7745c5c3_Var160, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Existing.Href))3362 templ_7745c5c3_Var160, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Existing.Href))
3351 if templ_7745c5c3_Err != nil {3363 if templ_7745c5c3_Err != nil {
3352- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 658, Col: 114}3364+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 662, Col: 114}
3353 }3365 }
3354 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var160))3366 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var160))
3355 if templ_7745c5c3_Err != nil {3367 if templ_7745c5c3_Err != nil {
3356 return templ_7745c5c3_Err3368 return templ_7745c5c3_Err
3357 }3369 }
3358- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 310, "\">")3370+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, "\">")
3359 if templ_7745c5c3_Err != nil {3371 if templ_7745c5c3_Err != nil {
3360 return templ_7745c5c3_Err3372 return templ_7745c5c3_Err
3361 }3373 }
3362 var templ_7745c5c3_Var161 string3374 var templ_7745c5c3_Var161 string
3363 templ_7745c5c3_Var161, templ_7745c5c3_Err = templ.JoinStringErrs(p.Existing.Label)3375 templ_7745c5c3_Var161, templ_7745c5c3_Err = templ.JoinStringErrs(p.Existing.Label)
3364 if templ_7745c5c3_Err != nil {3376 if templ_7745c5c3_Err != nil {
3365- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 658, Col: 135}3377+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 662, Col: 135}
3366 }3378 }
3367 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var161))3379 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var161))
3368 if templ_7745c5c3_Err != nil {3380 if templ_7745c5c3_Err != nil {
3369 return templ_7745c5c3_Err3381 return templ_7745c5c3_Err
3370 }3382 }
3371- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 311, "</a></p>")3383+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, "</a></p>")
3372 if templ_7745c5c3_Err != nil {3384 if templ_7745c5c3_Err != nil {
3373 return templ_7745c5c3_Err3385 return templ_7745c5c3_Err
3374 }3386 }
3375 }3387 }
3376- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 312, " ")3388+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, " ")
3377 if templ_7745c5c3_Err != nil {3389 if templ_7745c5c3_Err != nil {
3378 return templ_7745c5c3_Err3390 return templ_7745c5c3_Err
3379 }3391 }
3380 if p.Create != nil {3392 if p.Create != nil {
3381- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 313, "<form class=\"cform create\" method=\"post\" action=\"")3393+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, "<form class=\"cform create\" method=\"post\" action=\"")
3382 if templ_7745c5c3_Err != nil {3394 if templ_7745c5c3_Err != nil {
3383 return templ_7745c5c3_Err3395 return templ_7745c5c3_Err
3384 }3396 }
3385 var templ_7745c5c3_Var162 templ.SafeURL3397 var templ_7745c5c3_Var162 templ.SafeURL
3386 templ_7745c5c3_Var162, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Create.Action))3398 templ_7745c5c3_Var162, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Create.Action))
3387 if templ_7745c5c3_Err != nil {3399 if templ_7745c5c3_Err != nil {
3388- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 661, Col: 83}3400+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 665, Col: 83}
3389 }3401 }
3390 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var162))3402 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var162))
3391 if templ_7745c5c3_Err != nil {3403 if templ_7745c5c3_Err != nil {
3392 return templ_7745c5c3_Err3404 return templ_7745c5c3_Err
3393 }3405 }
3394- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 314, "\"><input type=\"hidden\" name=\"source\" value=\"")3406+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"><input type=\"hidden\" name=\"source\" value=\"")
3395 if templ_7745c5c3_Err != nil {3407 if templ_7745c5c3_Err != nil {
3396 return templ_7745c5c3_Err3408 return templ_7745c5c3_Err
3397 }3409 }
3398 var templ_7745c5c3_Var163 string3410 var templ_7745c5c3_Var163 string
3399 templ_7745c5c3_Var163, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Source)3411 templ_7745c5c3_Var163, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Source)
3400 if templ_7745c5c3_Err != nil {3412 if templ_7745c5c3_Err != nil {
3401- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 662, Col: 62}3413+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 666, Col: 62}
3402 }3414 }
3403 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var163)3415 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var163)
3404 if templ_7745c5c3_Err != nil {3416 if templ_7745c5c3_Err != nil {
3405 return templ_7745c5c3_Err3417 return templ_7745c5c3_Err
3406 }3418 }
3407- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 315, "\"> <input type=\"hidden\" name=\"target\" value=\"")3419+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, "\"> <input type=\"hidden\" name=\"target\" value=\"")
3408 if templ_7745c5c3_Err != nil {3420 if templ_7745c5c3_Err != nil {
3409 return templ_7745c5c3_Err3421 return templ_7745c5c3_Err
3410 }3422 }
3411 var templ_7745c5c3_Var164 string3423 var templ_7745c5c3_Var164 string
3412 templ_7745c5c3_Var164, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Target)3424 templ_7745c5c3_Var164, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Target)
3413 if templ_7745c5c3_Err != nil {3425 if templ_7745c5c3_Err != nil {
3414- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 663, Col: 62}3426+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 667, Col: 62}
3415 }3427 }
3416 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var164)3428 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var164)
3417 if templ_7745c5c3_Err != nil {3429 if templ_7745c5c3_Err != nil {
3418 return templ_7745c5c3_Err3430 return templ_7745c5c3_Err
3419 }3431 }
3420- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 316, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")3432+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, "\"> <label for=\"mr-title\">title</label> <input id=\"mr-title\" name=\"title\" type=\"text\" maxlength=\"120\" required value=\"")
3421 if templ_7745c5c3_Err != nil {3433 if templ_7745c5c3_Err != nil {
3422 return templ_7745c5c3_Err3434 return templ_7745c5c3_Err
3423 }3435 }
3424 var templ_7745c5c3_Var165 string3436 var templ_7745c5c3_Var165 string
3425 templ_7745c5c3_Var165, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Title)3437 templ_7745c5c3_Var165, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Create.Title)
3426 if templ_7745c5c3_Err != nil {3438 if templ_7745c5c3_Err != nil {
3427- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 665, Col: 97}3439+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 669, Col: 97}
3428 }3440 }
3429 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var165)3441 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var165)
3430 if templ_7745c5c3_Err != nil {3442 if templ_7745c5c3_Err != nil {
3431 return templ_7745c5c3_Err3443 return templ_7745c5c3_Err
3432 }3444 }
3433- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 317, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")3445+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "\" autocomplete=\"off\"> <label for=\"mr-desc\">description</label> <textarea id=\"mr-desc\" name=\"description\" rows=\"4\" maxlength=\"8000\" placeholder=\"Markdown, optional\"></textarea><div class=\"f-btns\"><button type=\"submit\" class=\"btn primary\">Create merge request</button></div></form>")
3434 if templ_7745c5c3_Err != nil {3446 if templ_7745c5c3_Err != nil {
3435 return templ_7745c5c3_Err3447 return templ_7745c5c3_Err
3436 }3448 }
3437 }3449 }
3438- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 318, " ")3450+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, " ")
3439 if templ_7745c5c3_Err != nil {3451 if templ_7745c5c3_Err != nil {
3440 return templ_7745c5c3_Err3452 return templ_7745c5c3_Err
3441 }3453 }
3442 if p.HasDiff {3454 if p.HasDiff {
3443- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 319, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")3455+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, "<div class=\"diff-tools\" role=\"group\" aria-label=\"Diff view\"><span class=\"dim\">")
3444 if templ_7745c5c3_Err != nil {3456 if templ_7745c5c3_Err != nil {
3445 return templ_7745c5c3_Err3457 return templ_7745c5c3_Err
3446 }3458 }
3447 var templ_7745c5c3_Var166 string3459 var templ_7745c5c3_Var166 string
3448 templ_7745c5c3_Var166, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))3460 templ_7745c5c3_Var166, templ_7745c5c3_Err = templ.JoinStringErrs(plural(p.NFiles, "file", "files"))
3449 if templ_7745c5c3_Err != nil {3461 if templ_7745c5c3_Err != nil {
3450- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 675, Col: 57}3462+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 679, Col: 57}
3451 }3463 }
3452 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var166))3464 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var166))
3453 if templ_7745c5c3_Err != nil {3465 if templ_7745c5c3_Err != nil {
3454 return templ_7745c5c3_Err3466 return templ_7745c5c3_Err
3455 }3467 }
3456- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 320, " · <span class=\"plus\">+")3468+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, " · <span class=\"plus\">+")
3457 if templ_7745c5c3_Err != nil {3469 if templ_7745c5c3_Err != nil {
3458 return templ_7745c5c3_Err3470 return templ_7745c5c3_Err
3459 }3471 }
3460 var templ_7745c5c3_Var167 string3472 var templ_7745c5c3_Var167 string
3461 templ_7745c5c3_Var167, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))3473 templ_7745c5c3_Var167, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Adds))
3462 if templ_7745c5c3_Err != nil {3474 if templ_7745c5c3_Err != nil {
3463- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 675, Col: 97}3475+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 679, Col: 97}
3464 }3476 }
3465 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var167))3477 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var167))
3466 if templ_7745c5c3_Err != nil {3478 if templ_7745c5c3_Err != nil {
3467 return templ_7745c5c3_Err3479 return templ_7745c5c3_Err
3468 }3480 }
3469- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 321, "</span> <span class=\"minus\">-")3481+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, "</span> <span class=\"minus\">-")
3470 if templ_7745c5c3_Err != nil {3482 if templ_7745c5c3_Err != nil {
3471 return templ_7745c5c3_Err3483 return templ_7745c5c3_Err
3472 }3484 }
3473 var templ_7745c5c3_Var168 string3485 var templ_7745c5c3_Var168 string
3474 templ_7745c5c3_Var168, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))3486 templ_7745c5c3_Var168, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Dels))
3475 if templ_7745c5c3_Err != nil {3487 if templ_7745c5c3_Err != nil {
3476- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 675, Col: 142}3488+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 679, Col: 142}
3477 }3489 }
3478 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var168))3490 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var168))
3479 if templ_7745c5c3_Err != nil {3491 if templ_7745c5c3_Err != nil {
3480 return templ_7745c5c3_Err3492 return templ_7745c5c3_Err
3481 }3493 }
3482- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 322, "</span></span> <span class=\"grow\"></span>")3494+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "</span></span> <span class=\"grow\"></span>")
3483 if templ_7745c5c3_Err != nil {3495 if templ_7745c5c3_Err != nil {
3484 return templ_7745c5c3_Err3496 return templ_7745c5c3_Err
3485 }3497 }
@@ -3487,64 +3499,64 @@ func Compare(l Layout, p ComparePage) templ.Component {
3487 if templ_7745c5c3_Err != nil {3499 if templ_7745c5c3_Err != nil {
3488 return templ_7745c5c3_Err3500 return templ_7745c5c3_Err
3489 }3501 }
3490- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 323, "</div>")3502+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, "</div>")
3491 if templ_7745c5c3_Err != nil {3503 if templ_7745c5c3_Err != nil {
3492 return templ_7745c5c3_Err3504 return templ_7745c5c3_Err
3493 }3505 }
3494 if p.Invisible {3506 if p.Invisible {
3495- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 324, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")3507+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, "<p class=\"notice\">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class=\"inv\">&lt;U+XXXX&gt;</span> markers, never applied.</p>")
3496 if templ_7745c5c3_Err != nil {3508 if templ_7745c5c3_Err != nil {
3497 return templ_7745c5c3_Err3509 return templ_7745c5c3_Err
3498 }3510 }
3499 }3511 }
3500- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 325, " <div id=\"diffs\"")3512+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, " <div id=\"diffs\"")
3501 if templ_7745c5c3_Err != nil {3513 if templ_7745c5c3_Err != nil {
3502 return templ_7745c5c3_Err3514 return templ_7745c5c3_Err
3503 }3515 }
3504 if p.Both {3516 if p.Both {
3505- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 326, " data-diff=\"")3517+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, " data-diff=\"")
3506 if templ_7745c5c3_Err != nil {3518 if templ_7745c5c3_Err != nil {
3507 return templ_7745c5c3_Err3519 return templ_7745c5c3_Err
3508 }3520 }
3509 var templ_7745c5c3_Var169 string3521 var templ_7745c5c3_Var169 string
3510 templ_7745c5c3_Var169, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)3522 templ_7745c5c3_Var169, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
3511 if templ_7745c5c3_Err != nil {3523 if templ_7745c5c3_Err != nil {
3512- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 688, Col: 23}3524+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 692, Col: 23}
3513 }3525 }
3514 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var169)3526 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var169)
3515 if templ_7745c5c3_Err != nil {3527 if templ_7745c5c3_Err != nil {
3516 return templ_7745c5c3_Err3528 return templ_7745c5c3_Err
3517 }3529 }
3518- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 327, "\"")3530+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "\"")
3519 if templ_7745c5c3_Err != nil {3531 if templ_7745c5c3_Err != nil {
3520 return templ_7745c5c3_Err3532 return templ_7745c5c3_Err
3521 }3533 }
3522 } else {3534 } else {
3523- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 328, " data-view=\"")3535+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, " data-view=\"")
3524 if templ_7745c5c3_Err != nil {3536 if templ_7745c5c3_Err != nil {
3525 return templ_7745c5c3_Err3537 return templ_7745c5c3_Err
3526 }3538 }
3527 var templ_7745c5c3_Var170 string3539 var templ_7745c5c3_Var170 string
3528 templ_7745c5c3_Var170, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)3540 templ_7745c5c3_Var170, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.View)
3529 if templ_7745c5c3_Err != nil {3541 if templ_7745c5c3_Err != nil {
3530- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 690, Col: 23}3542+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 694, Col: 23}
3531 }3543 }
3532 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var170)3544 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var170)
3533 if templ_7745c5c3_Err != nil {3545 if templ_7745c5c3_Err != nil {
3534 return templ_7745c5c3_Err3546 return templ_7745c5c3_Err
3535 }3547 }
3536- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 329, "\"")3548+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, "\"")
3537 if templ_7745c5c3_Err != nil {3549 if templ_7745c5c3_Err != nil {
3538 return templ_7745c5c3_Err3550 return templ_7745c5c3_Err
3539 }3551 }
3540 }3552 }
3541 if p.Both && !p.Pinned {3553 if p.Both && !p.Pinned {
3542- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 330, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")3554+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, " hx-live=\"this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff\"")
3543 if templ_7745c5c3_Err != nil {3555 if templ_7745c5c3_Err != nil {
3544 return templ_7745c5c3_Err3556 return templ_7745c5c3_Err
3545 }3557 }
3546 }3558 }
3547- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 331, ">")3559+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, ">")
3548 if templ_7745c5c3_Err != nil {3560 if templ_7745c5c3_Err != nil {
3549 return templ_7745c5c3_Err3561 return templ_7745c5c3_Err
3550 }3562 }
@@ -3554,7 +3566,7 @@ func Compare(l Layout, p ComparePage) templ.Component {
3554 return templ_7745c5c3_Err3566 return templ_7745c5c3_Err
3555 }3567 }
3556 }3568 }
3557- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 332, "</div>")3569+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, "</div>")
3558 if templ_7745c5c3_Err != nil {3570 if templ_7745c5c3_Err != nil {
3559 return templ_7745c5c3_Err3571 return templ_7745c5c3_Err
3560 }3572 }
@@ -3590,77 +3602,77 @@ func compareRail(p ComparePage) templ.Component {
3590 templ_7745c5c3_Var171 = templ.NopComponent3602 templ_7745c5c3_Var171 = templ.NopComponent
3591 }3603 }
3592 ctx = templ.ClearChildren(ctx)3604 ctx = templ.ClearChildren(ctx)
3593- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 333, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")3605+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "<section aria-labelledby=\"r-ahead\"><h2 id=\"r-ahead\">Commits <span class=\"count\">")
3594 if templ_7745c5c3_Err != nil {3606 if templ_7745c5c3_Err != nil {
3595 return templ_7745c5c3_Err3607 return templ_7745c5c3_Err
3596 }3608 }
3597 var templ_7745c5c3_Var172 string3609 var templ_7745c5c3_Var172 string
3598 templ_7745c5c3_Var172, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Ahead)))3610 templ_7745c5c3_Var172, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Ahead)))
3599 if templ_7745c5c3_Err != nil {3611 if templ_7745c5c3_Err != nil {
3600- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 706, Col: 67}3612+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 710, Col: 67}
3601 }3613 }
3602 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var172))3614 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var172))
3603 if templ_7745c5c3_Err != nil {3615 if templ_7745c5c3_Err != nil {
3604 return templ_7745c5c3_Err3616 return templ_7745c5c3_Err
3605 }3617 }
3606- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 334, "</span></h2><ul class=\"pcommits\">")3618+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, "</span></h2><ul class=\"pcommits\">")
3607 if templ_7745c5c3_Err != nil {3619 if templ_7745c5c3_Err != nil {
3608 return templ_7745c5c3_Err3620 return templ_7745c5c3_Err
3609 }3621 }
3610 for _, c := range p.Ahead {3622 for _, c := range p.Ahead {
3611- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 335, "<li><a href=\"")3623+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "<li><a href=\"")
3612 if templ_7745c5c3_Err != nil {3624 if templ_7745c5c3_Err != nil {
3613 return templ_7745c5c3_Err3625 return templ_7745c5c3_Err
3614 }3626 }
3615 var templ_7745c5c3_Var173 templ.SafeURL3627 var templ_7745c5c3_Var173 templ.SafeURL
3616 templ_7745c5c3_Var173, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.CHref))3628 templ_7745c5c3_Var173, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(c.CHref))
3617 if templ_7745c5c3_Err != nil {3629 if templ_7745c5c3_Err != nil {
3618- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 710, Col: 37}3630+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 714, Col: 37}
3619 }3631 }
3620 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var173))3632 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var173))
3621 if templ_7745c5c3_Err != nil {3633 if templ_7745c5c3_Err != nil {
3622 return templ_7745c5c3_Err3634 return templ_7745c5c3_Err
3623 }3635 }
3624- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 336, "\">")3636+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "\">")
3625 if templ_7745c5c3_Err != nil {3637 if templ_7745c5c3_Err != nil {
3626 return templ_7745c5c3_Err3638 return templ_7745c5c3_Err
3627 }3639 }
3628 var templ_7745c5c3_Var174 string3640 var templ_7745c5c3_Var174 string
3629 templ_7745c5c3_Var174, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)3641 templ_7745c5c3_Var174, templ_7745c5c3_Err = templ.JoinStringErrs(c.Short)
3630 if templ_7745c5c3_Err != nil {3642 if templ_7745c5c3_Err != nil {
3631- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 710, Col: 49}3643+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 714, Col: 49}
3632 }3644 }
3633 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var174))3645 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var174))
3634 if templ_7745c5c3_Err != nil {3646 if templ_7745c5c3_Err != nil {
3635 return templ_7745c5c3_Err3647 return templ_7745c5c3_Err
3636 }3648 }
3637- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 337, "</a> <span class=\"s\">")3649+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, "</a> <span class=\"s\">")
3638 if templ_7745c5c3_Err != nil {3650 if templ_7745c5c3_Err != nil {
3639 return templ_7745c5c3_Err3651 return templ_7745c5c3_Err
3640 }3652 }
3641 var templ_7745c5c3_Var175 string3653 var templ_7745c5c3_Var175 string
3642 templ_7745c5c3_Var175, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)3654 templ_7745c5c3_Var175, templ_7745c5c3_Err = templ.JoinStringErrs(c.Subject)
3643 if templ_7745c5c3_Err != nil {3655 if templ_7745c5c3_Err != nil {
3644- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 711, Col: 32}3656+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 32}
3645 }3657 }
3646 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var175))3658 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var175))
3647 if templ_7745c5c3_Err != nil {3659 if templ_7745c5c3_Err != nil {
3648 return templ_7745c5c3_Err3660 return templ_7745c5c3_Err
3649 }3661 }
3650- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 338, "</span> <span class=\"mute\">")3662+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, "</span> <span class=\"mute\">")
3651 if templ_7745c5c3_Err != nil {3663 if templ_7745c5c3_Err != nil {
3652 return templ_7745c5c3_Err3664 return templ_7745c5c3_Err
3653 }3665 }
3654 var templ_7745c5c3_Var176 string3666 var templ_7745c5c3_Var176 string
3655 templ_7745c5c3_Var176, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)3667 templ_7745c5c3_Var176, templ_7745c5c3_Err = templ.JoinStringErrs(c.Author)
3656 if templ_7745c5c3_Err != nil {3668 if templ_7745c5c3_Err != nil {
3657- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 713, Col: 16}3669+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 717, Col: 16}
3658 }3670 }
3659 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var176))3671 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var176))
3660 if templ_7745c5c3_Err != nil {3672 if templ_7745c5c3_Err != nil {
3661 return templ_7745c5c3_Err3673 return templ_7745c5c3_Err
3662 }3674 }
3663- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 339, " ")3675+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, " ")
3664 if templ_7745c5c3_Err != nil {3676 if templ_7745c5c3_Err != nil {
3665 return templ_7745c5c3_Err3677 return templ_7745c5c3_Err
3666 }3678 }
@@ -3668,90 +3680,90 @@ func compareRail(p ComparePage) templ.Component {
3668 var templ_7745c5c3_Var177 string3680 var templ_7745c5c3_Var177 string
3669 templ_7745c5c3_Var177, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")3681 templ_7745c5c3_Var177, templ_7745c5c3_Err = templ.JoinStringErrs(" · ")
3670 if templ_7745c5c3_Err != nil {3682 if templ_7745c5c3_Err != nil {
3671- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 15}3683+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 719, Col: 15}
3672 }3684 }
3673 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var177))3685 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var177))
3674 if templ_7745c5c3_Err != nil {3686 if templ_7745c5c3_Err != nil {
3675 return templ_7745c5c3_Err3687 return templ_7745c5c3_Err
3676 }3688 }
3677- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 340, "<time datetime=\"")3689+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, "<time datetime=\"")
3678 if templ_7745c5c3_Err != nil {3690 if templ_7745c5c3_Err != nil {
3679 return templ_7745c5c3_Err3691 return templ_7745c5c3_Err
3680 }3692 }
3681 var templ_7745c5c3_Var178 string3693 var templ_7745c5c3_Var178 string
3682 templ_7745c5c3_Var178, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)3694 templ_7745c5c3_Var178, templ_7745c5c3_Err = templ.ResolveAttributeValue(c.WhenAt)
3683 if templ_7745c5c3_Err != nil {3695 if templ_7745c5c3_Err != nil {
3684- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 42}3696+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 719, Col: 42}
3685 }3697 }
3686 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var178)3698 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var178)
3687 if templ_7745c5c3_Err != nil {3699 if templ_7745c5c3_Err != nil {
3688 return templ_7745c5c3_Err3700 return templ_7745c5c3_Err
3689 }3701 }
3690- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 341, "\">")3702+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "\">")
3691 if templ_7745c5c3_Err != nil {3703 if templ_7745c5c3_Err != nil {
3692 return templ_7745c5c3_Err3704 return templ_7745c5c3_Err
3693 }3705 }
3694 var templ_7745c5c3_Var179 string3706 var templ_7745c5c3_Var179 string
3695 templ_7745c5c3_Var179, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)3707 templ_7745c5c3_Var179, templ_7745c5c3_Err = templ.JoinStringErrs(c.When)
3696 if templ_7745c5c3_Err != nil {3708 if templ_7745c5c3_Err != nil {
3697- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 715, Col: 53}3709+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 719, Col: 53}
3698 }3710 }
3699 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var179))3711 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var179))
3700 if templ_7745c5c3_Err != nil {3712 if templ_7745c5c3_Err != nil {
3701 return templ_7745c5c3_Err3713 return templ_7745c5c3_Err
3702 }3714 }
3703- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 342, "</time>")3715+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, "</time>")
3704 if templ_7745c5c3_Err != nil {3716 if templ_7745c5c3_Err != nil {
3705 return templ_7745c5c3_Err3717 return templ_7745c5c3_Err
3706 }3718 }
3707 }3719 }
3708- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 343, "</span></li>")3720+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "</span></li>")
3709 if templ_7745c5c3_Err != nil {3721 if templ_7745c5c3_Err != nil {
3710 return templ_7745c5c3_Err3722 return templ_7745c5c3_Err
3711 }3723 }
3712 }3724 }
3713- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 344, "</ul>")3725+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, "</ul>")
3714 if templ_7745c5c3_Err != nil {3726 if templ_7745c5c3_Err != nil {
3715 return templ_7745c5c3_Err3727 return templ_7745c5c3_Err
3716 }3728 }
3717 if len(p.Ahead) == 0 {3729 if len(p.Ahead) == 0 {
3718- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 345, "<p class=\"dim\">no commit ahead of ")3730+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, "<p class=\"dim\">no commit ahead of ")
3719 if templ_7745c5c3_Err != nil {3731 if templ_7745c5c3_Err != nil {
3720 return templ_7745c5c3_Err3732 return templ_7745c5c3_Err
3721 }3733 }
3722 var templ_7745c5c3_Var180 string3734 var templ_7745c5c3_Var180 string
3723 templ_7745c5c3_Var180, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)3735 templ_7745c5c3_Var180, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
3724 if templ_7745c5c3_Err != nil {3736 if templ_7745c5c3_Err != nil {
3725- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 722, Col: 47}3737+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 726, Col: 47}
3726 }3738 }
3727 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var180))3739 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var180))
3728 if templ_7745c5c3_Err != nil {3740 if templ_7745c5c3_Err != nil {
3729 return templ_7745c5c3_Err3741 return templ_7745c5c3_Err
3730 }3742 }
3731- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 346, ".</p>")3743+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, ".</p>")
3732 if templ_7745c5c3_Err != nil {3744 if templ_7745c5c3_Err != nil {
3733 return templ_7745c5c3_Err3745 return templ_7745c5c3_Err
3734 }3746 }
3735 }3747 }
3736- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 347, "</section>")3748+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, "</section>")
3737 if templ_7745c5c3_Err != nil {3749 if templ_7745c5c3_Err != nil {
3738 return templ_7745c5c3_Err3750 return templ_7745c5c3_Err
3739 }3751 }
3740 if p.HasDiff {3752 if p.HasDiff {
3741- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 348, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")3753+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, "<section aria-labelledby=\"r-files\"><h2 id=\"r-files\">Files <span class=\"count\">")
3742 if templ_7745c5c3_Err != nil {3754 if templ_7745c5c3_Err != nil {
3743 return templ_7745c5c3_Err3755 return templ_7745c5c3_Err
3744 }3756 }
3745 var templ_7745c5c3_Var181 string3757 var templ_7745c5c3_Var181 string
3746 templ_7745c5c3_Var181, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))3758 templ_7745c5c3_Var181, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Files)))
3747 if templ_7745c5c3_Err != nil {3759 if templ_7745c5c3_Err != nil {
3748- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 727, Col: 66}3760+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/mr.templ`, Line: 731, Col: 66}
3749 }3761 }
3750 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var181))3762 _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var181))
3751 if templ_7745c5c3_Err != nil {3763 if templ_7745c5c3_Err != nil {
3752 return templ_7745c5c3_Err3764 return templ_7745c5c3_Err
3753 }3765 }
3754- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 349, "</span></h2>")3766+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "</span></h2>")
3755 if templ_7745c5c3_Err != nil {3767 if templ_7745c5c3_Err != nil {
3756 return templ_7745c5c3_Err3768 return templ_7745c5c3_Err
3757 }3769 }
@@ -3759,12 +3771,12 @@ func compareRail(p ComparePage) templ.Component {
3759 if templ_7745c5c3_Err != nil {3771 if templ_7745c5c3_Err != nil {
3760 return templ_7745c5c3_Err3772 return templ_7745c5c3_Err
3761 }3773 }
3762- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 350, "</section>")3774+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, "</section>")
3763 if templ_7745c5c3_Err != nil {3775 if templ_7745c5c3_Err != nil {
3764 return templ_7745c5c3_Err3776 return templ_7745c5c3_Err
3765 }3777 }
3766 }3778 }
3767- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 351, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")3779+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 353, "<section aria-labelledby=\"r-cli\"><h2 id=\"r-cli\">From a terminal</h2>")
3768 if templ_7745c5c3_Err != nil {3780 if templ_7745c5c3_Err != nil {
3769 return templ_7745c5c3_Err3781 return templ_7745c5c3_Err
3770 }3782 }
@@ -3772,7 +3784,7 @@ func compareRail(p ComparePage) templ.Component {
3772 if templ_7745c5c3_Err != nil {3784 if templ_7745c5c3_Err != nil {
3773 return templ_7745c5c3_Err3785 return templ_7745c5c3_Err
3774 }3786 }
3775- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 352, "</section>")3787+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 354, "</section>")
3776 if templ_7745c5c3_Err != nil {3788 if templ_7745c5c3_Err != nil {
3777 return templ_7745c5c3_Err3789 return templ_7745c5c3_Err
3778 }3790 }
M internal/adapters/web/static/css/80-live.css +5 -0
@@ -8,5 +8,10 @@
88 padding: var(--s3) var(--s4); font-weight: 700;
99 background: var(--bg-surface); border: 1px solid var(--border-strong); border-left: 3px solid var(--teal); border-radius: var(--r-s);
1010 }
11+ /* A deferred MR refresh must not insert height above a long diff. */
12+ #mr-refresh-status:has(a) {
13+ position: fixed; bottom: var(--s4); left: var(--s4); z-index: 24;
14+ max-width: min(42rem, calc(100vw - 2 * var(--s4))); font-size: var(--fs-s);
15+ }
1116 .live-slot a { color: var(--ink-hi); }
1217 }
@@ -8,5 +8,10 @@
8 padding: var(--s3) var(--s4); font-weight: 700;8 padding: var(--s3) var(--s4); font-weight: 700;
9 background: var(--bg-surface); border: 1px solid var(--border-strong); border-left: 3px solid var(--teal); border-radius: var(--r-s);9 background: var(--bg-surface); border: 1px solid var(--border-strong); border-left: 3px solid var(--teal); border-radius: var(--r-s);
10 }10 }
11+ /* A deferred MR refresh must not insert height above a long diff. */
12+ #mr-refresh-status:has(a) {
13+ position: fixed; bottom: var(--s4); left: var(--s4); z-index: 24;
14+ max-width: min(42rem, calc(100vw - 2 * var(--s4))); font-size: var(--fs-s);
15+ }
11 .live-slot a { color: var(--ink-hi); }16 .live-slot a { color: var(--ink-hi); }
12 }17 }
M internal/adapters/web/static/js/ermite.js +9 -1
@@ -731,13 +731,21 @@
731731 mark();
732732 }, { rootMargin: '0px 0px -67% 0px' });
733733 for (const f of files) io.observe(f);
734+ // A refreshed MR replaced the rail and the windowed diff. Rebuild once,
735+ // not once per file (which would make a large file list quadratic).
736+ ermite.refreshFiles = () => {
737+ io.disconnect(); inBand.clear(); current = null;
738+ files = $$('.dfile'); links.clear();
739+ for (const a of $$('.files a[href^="#"]')) links.set(a.hash.slice(1), a);
740+ for (const f of files) io.observe(f);
741+ };
734742 // A window of files of a merge request came in (mr.js): its files replace
735743 // placeholders, which the observer and the list knew by element.
736744 ermite.watchFile = (f, old) => {
737745 if (old) { io.unobserve(old); inBand.delete(old); }
738746 files = $$('.dfile');
739747 for (const x of [...inBand]) if (!x.isConnected) inBand.delete(x);
740- if (current && !current.isConnected) current = document.getElementById(current.id);
748+ if (current && !current.isConnected) current = null;
741749 io.observe(f);
742750 };
743751 }
@@ -731,13 +731,21 @@
731 mark();731 mark();
732 }, { rootMargin: '0px 0px -67% 0px' });732 }, { rootMargin: '0px 0px -67% 0px' });
733 for (const f of files) io.observe(f);733 for (const f of files) io.observe(f);
734+ // A refreshed MR replaced the rail and the windowed diff. Rebuild once,
735+ // not once per file (which would make a large file list quadratic).
736+ ermite.refreshFiles = () => {
737+ io.disconnect(); inBand.clear(); current = null;
738+ files = $$('.dfile'); links.clear();
739+ for (const a of $$('.files a[href^="#"]')) links.set(a.hash.slice(1), a);
740+ for (const f of files) io.observe(f);
741+ };
734 // A window of files of a merge request came in (mr.js): its files replace742 // A window of files of a merge request came in (mr.js): its files replace
735 // placeholders, which the observer and the list knew by element.743 // placeholders, which the observer and the list knew by element.
736 ermite.watchFile = (f, old) => {744 ermite.watchFile = (f, old) => {
737 if (old) { io.unobserve(old); inBand.delete(old); }745 if (old) { io.unobserve(old); inBand.delete(old); }
738 files = $$('.dfile');746 files = $$('.dfile');
739 for (const x of [...inBand]) if (!x.isConnected) inBand.delete(x);747 for (const x of [...inBand]) if (!x.isConnected) inBand.delete(x);
740- if (current && !current.isConnected) current = document.getElementById(current.id);748+ if (current && !current.isConnected) current = null;
741 io.observe(f);749 io.observe(f);
742 };750 };
743 }751 }
M internal/adapters/web/static/js/mr.js +254 -8
@@ -84,11 +84,13 @@ window.ermiteMR = (() => {
8484 let refreshTouchComments = () => {};
8585 let moved = false;
8686 let lazyIO = null; // the observer of the placeholders (watch)
87+ let diffGeneration = 0;
8788 let revealGen = 0; // the last reveal wins the scroll
8889
8990 // load fetches the window of a placeholder and swaps its files in. The
9091 // promise resolves once they are in the page (or the page said to reload).
9192 function load(ph) {
93+ const generation = diffGeneration;
9294 const src = ph?.dataset.src;
9395 if (!src || moved) return Promise.resolve();
9496 if (loading.has(src)) return loading.get(src);
@@ -102,12 +104,14 @@ window.ermiteMR = (() => {
102104 const p = fetch(url, { headers: { Accept: 'text/html' }, credentials: 'same-origin' })
103105 .then(async (res) => {
104106 const html = await res.text();
107+ if (generation !== diffGeneration) return;
105108 if (res.status === 409) return stale(html);
106109 if (!res.ok) throw new Error('loading files: ' + res.status);
107110 // A window of the old diff after the page went stale stays out.
108111 if (!moved) swap(html);
109112 })
110113 .catch((err) => {
114+ if (generation !== diffGeneration) return;
111115 loading.delete(src);
112116 for (const p of $$('.dlazy[data-loading]')) if (p.dataset.src === src) p.removeAttribute('data-loading');
113117 window.ermite?.flash?.(err.message, 4000);
@@ -195,6 +199,7 @@ window.ermiteMR = (() => {
195199 // that come in are marked in the list of files (ermite.js marks the one in
196200 // view).
197201 function watch() {
202+ lazyIO?.disconnect();
198203 if (!('IntersectionObserver' in window)) {
199204 for (const p of $$('.dlazy[data-src]')) load(p);
200205 return;
@@ -309,7 +314,9 @@ window.ermiteMR = (() => {
309314 }
310315
311316 // Enhance the ordinary anchor navigation only when scripts are available.
317+ let disposePanels = () => {};
312318 function panels() {
319+ disposePanels();
313320 const footer = $('#mr-panels'), nav = $('[data-mr-tabs]');
314321 if (!footer || !nav) return;
315322 const tabs = $$('a', nav), panels = $$('[data-mr-panel]', footer);
@@ -342,20 +349,30 @@ window.ermiteMR = (() => {
342349 footer.open = true; select(index);
343350 }
344351 // A repeated click on the same hash must also reopen a folded footer.
345- document.addEventListener('click', (e) => {
352+ const checksClick = (e) => {
346353 if (e.target.closest?.('#mr-ck')) { footer.open = true; select(1); }
347- });
354+ };
355+ document.addEventListener('click', checksClick);
356+ let observer;
348357 const summary = $('#mr-ck');
349358 if (summary) {
350359 const sync = () => { $('[data-checks-label]', nav).textContent = $('#mr-ck')?.title || $('#mr-ck')?.textContent.trim() || 'no checks'; };
351- new MutationObserver(sync).observe(summary.parentElement, { childList: true, subtree: true, characterData: true });
360+ observer = new MutationObserver(sync);
361+ observer.observe(summary.parentElement, { childList: true, subtree: true, characterData: true });
352362 sync();
353363 }
354364 select(0); hash();
355365 addEventListener('hashchange', hash);
366+ disposePanels = () => {
367+ document.removeEventListener?.('click', checksClick);
368+ window.removeEventListener?.('hashchange', hash);
369+ observer?.disconnect?.();
370+ };
356371 }
357372
358- function touchComments() {
373+ let disposeTouch = () => {};
374+ function touchComments(scroll = true) {
375+ disposeTouch();
359376 const diffs = $('#diffs');
360377 const bar = document.createElement('div');
361378 bar.className = 'mr-touch-range';
@@ -392,23 +409,252 @@ window.ermiteMR = (() => {
392409 marker.setAttribute('data-range-start', '');
393410 status.textContent = `Range starts at line ${link.textContent.trim()}. Tap the last line number (same file and side).`;
394411 });
395- touch?.addEventListener('change', () => {
412+ const changed = () => {
396413 if (touch.matches) return;
397414 enabled = false;
398415 clear();
399416 button.setAttribute('aria-pressed', 'false');
400417 status.textContent = '';
401- });
418+ };
419+ touch?.addEventListener('change', changed);
420+ disposeTouch = () => { touch?.removeEventListener?.('change', changed); bar.remove?.(); };
402421 // The server opens the line form. Scroll after layout without stealing
403422 // focus or forcing a mobile keyboard to appear.
404- if (new URL(location.href).searchParams.has('on')) requestAnimationFrame(() => {
423+ if (scroll && new URL(location.href).searchParams.has('on')) requestAnimationFrame(() => {
405424 const form = $$('.fnote .cform', diffs).find((f) => f.getClientRects().length);
406425 form?.scrollIntoView({ block: 'center' });
407426 });
408427 }
409428
429+ // A refresh scheduler has one request in flight, a trailing debounce, and
430+ // a dirty bit for pushes received during that request. Drafts are checked
431+ // again after the fetch: typing while the network is slow is safe too.
432+ function refresher({ blocked, fetchPage, apply, notice, failed, delay = 300 }) {
433+ let timer, busy = false, pending = false, force = false;
434+ const schedule = () => { clearTimeout(timer); timer = setTimeout(run, delay); };
435+ async function run() {
436+ if (busy || !pending) return;
437+ if (!force && blocked()) { notice(true); return; }
438+ busy = true;
439+ pending = false;
440+ const manual = force; force = false;
441+ try {
442+ const page = await fetchPage();
443+ if (!manual && blocked()) { pending = true; notice(true); return; }
444+ if (await apply(page, manual) === false) { pending = true; notice(true); }
445+ else notice(false);
446+ } catch { failed(); }
447+ finally {
448+ busy = false;
449+ if (pending && (force || !blocked())) schedule();
450+ }
451+ }
452+ return {
453+ request(manual = false) { pending = true; force ||= manual; schedule(); },
454+ resume() { if (pending) schedule(); },
455+ pending() { return pending || busy; },
456+ };
457+ }
458+
459+ function hasDraft() {
460+ return $$('textarea').some((t) => (t.value.length > 0 && t.value !== t.defaultValue) || document.activeElement === t) ||
461+ !!document.activeElement?.closest?.('.cform');
462+ }
463+
464+ // Path + side + line is stable when files are inserted before this one;
465+ // fN is only a positional anchor. Hidden unified/split rows are ignored.
466+ function scrollAnchor() {
467+ const top = Math.max(0, $('.hdr')?.getBoundingClientRect().bottom || 0,
468+ $('.mr-bar')?.getBoundingClientRect().bottom || 0);
469+ const diffs = $('#diffs');
470+ const bounds = diffs.getBoundingClientRect();
471+ const x = Math.max(1, Math.min(innerWidth - 1, bounds.left + Math.min(100, bounds.width / 2)));
472+ // A bounded number of probes, independent of the number of diff lines.
473+ for (const y of [top + 2, top + 24, top + 64, top + 128]) {
474+ if (y >= innerHeight) break;
475+ const hit = document.elementFromPoint(x, y);
476+ const file = hit?.closest('details.dfile');
477+ if (!file || !diffs.contains(file)) continue;
478+ const row = hit.closest('tr');
479+ const link = row && $('.ln a[href*="on="]', row);
480+ const header = $(':scope > summary', file);
481+ return { file: file.dataset.file,
482+ on: link && new URL(link.href, location.href).searchParams.get('on'),
483+ offset: (link ? row : header).getBoundingClientRect().top,
484+ headerOffset: header.getBoundingClientRect().top, y: scrollY };
485+ }
486+ return { y: scrollY };
487+ }
488+
489+ function restoreAnchor(anchor) {
490+ const file = $$('#diffs details.dfile').find((f) => f.dataset.file === anchor.file);
491+ let el, offset = anchor.offset;
492+ if (file && anchor.on) {
493+ // Exact href suffix: no traversal or measurement of every line. URLSearchParams
494+ // uses the same form encoding as the Go line links (space is '+').
495+ const parts = /^(new|old):(\d+):(.+)$/.exec(anchor.on);
496+ const path = parts && new URLSearchParams({ path: parts[3] }).toString().slice(5);
497+ const suffix = parts && 'on=' + parts[1] + ':' + parts[2] + ':' + path + '#' + file.id;
498+ const layout = $('#diffs').dataset.diff || $('#diffs').dataset.view;
499+ const table = $(layout === 'split' && !window.matchMedia?.('(max-width: 720px)').matches ? '.dt.spl' : '.dt.uni', file) || file;
500+ if (suffix) el = $('a[href$="' + CSS.escape(suffix) + '"]', table)?.closest('tr');
501+ }
502+ if (!el && file) { el = $(':scope > summary', file); offset = anchor.headerOffset ?? anchor.offset; }
503+ if (el) window.scrollBy({ top: el.getBoundingClientRect().top - offset, behavior: 'instant' });
504+ else window.scrollTo({ top: Math.max(0, Math.min(anchor.y, document.documentElement.scrollHeight - innerHeight)), behavior: 'instant' });
505+ }
506+
507+ async function fetchPage() {
508+ const res = await fetch(location.href, { credentials: 'same-origin', headers: { Accept: 'text/html' } });
509+ if (!res.ok || res.redirected) throw new Error('MR refresh refused');
510+ const page = new DOMParser().parseFromString(await res.text(), 'text/html');
511+ if (!$('#diffs[data-mr]', page) || !$('.mr-bar', page) || !$('.hint-live', page)) throw new Error('not an MR page');
512+ return page;
513+ }
514+
515+ // Use htmx's swap rather than replaceWith: its cleanup retires the old SSE
516+ // reader and hx-live bindings, and process activates the inserted controls.
517+ async function replaceRegion(old, fresh) {
518+ if (!old || !fresh) throw new Error('missing MR refresh region');
519+ for (const el of $$('[autofocus]', fresh)) el.removeAttribute('autofocus');
520+ await window.htmx.swap({ sourceElement: old, target: old, text: fresh.outerHTML,
521+ swap: 'outerHTML settle:0 transition:false focusScroll:false', push: false, replace: false });
522+ }
523+
524+ async function refreshPage(page, manual = false) {
525+ const regions = ['.mr-footer', '#mr-range', '.mr-bar', '#mr-diff-notices', '#diffs', '.rail', '.hint-live'];
526+ for (const sel of regions) if (!$(sel) || !$(sel, page)) throw new Error('missing MR region');
527+ let anchor = scrollAnchor();
528+ const anchorFile = $$('#diffs details.dfile', page).find((f) => f.dataset.file === anchor.file);
529+ const placeholder = anchorFile && $('.dlazy[data-src]', anchorFile);
530+ if (placeholder) {
531+ const d = $('#diffs').dataset;
532+ const url = placeholder.dataset.src + '&view=' + encodeURIComponent(d.diff || d.view || 'unified') + '&layouts=' + (d.diff ? 'both' : 'one');
533+ const res = await fetch(url, { credentials: 'same-origin', headers: { Accept: 'text/html' } });
534+ if (!res.ok || res.redirected) throw new Error('anchor window changed');
535+ const windowPage = new DOMParser().parseFromString(await res.text(), 'text/html');
536+ const byID = new Map($$('#diffs details.dfile', page).map((f) => [f.id, f]));
537+ for (const f of $$('details.dfile', windowPage)) byID.get(f.id)?.replaceWith(f);
538+ if (!manual && hasDraft()) return false;
539+ anchor = scrollAnchor();
540+ }
541+ const files = new Map($$('#diffs details.dfile').map((f) => [f.dataset.file, f.open]));
542+ const folded = $('.r-files')?.hasAttribute('data-folded');
543+ const railY = $('.rail')?.scrollTop, filesY = $('.r-files .files')?.scrollTop;
544+ const footerOpen = $('#mr-panels')?.open;
545+ const tab = $('[data-mr-tabs] [aria-selected="true"]')?.id;
546+ const active = document.activeElement;
547+ const focus = active && { menu: active.closest?.('details.menu')?.id, id: active.id, tag: active.tagName, name: active.getAttribute('name'), href: active.getAttribute('href') };
548+ // Manual refresh keeps even an active draft whose line disappeared. It
549+ // stays an ordinary form, under an explicit previous-diff label.
550+ const drafts = [...new Set($$('#diffs textarea').filter((t) => t.value !== t.defaultValue || t === active || t.closest('form')?.contains(active)).map((t) => t.closest('form')).filter(Boolean))];
551+ let draftID = 0;
552+ for (const form of drafts) {
553+ for (const t of $$('textarea', form)) {
554+ if (!t.id) t.id = 'mr-preserved-draft-' + (++draftID);
555+ if (t === active) focus.id = t.id;
556+ }
557+ const id = $('textarea', form)?.id;
558+ const replacement = id && $$('textarea', page).find((t) => t.id === id)?.closest('.cform');
559+ const copy = form.cloneNode(true);
560+ const originalFields = $$('textarea, input, select', form);
561+ $$('textarea, input, select', copy).forEach((field, i) => {
562+ const original = originalFields[i];
563+ if (field.tagName === 'TEXTAREA') field.textContent = original.defaultValue;
564+ else if (field.tagName === 'INPUT') { field.setAttribute('value', original.value); field.toggleAttribute('checked', original.checked); }
565+ });
566+ if (replacement) replacement.replaceWith(copy);
567+ else {
568+ const box = page.createElement('div');
569+ const label = page.createElement('p'); label.className = 'notice';
570+ label.textContent = 'Unsent comment on the previous diff (the line may have moved).';
571+ box.append(label, copy); $('#diffs', page).prepend(box);
572+ }
573+ }
574+ // Serializing markup does not retain textarea.value or selection. Restore
575+ // values after the htmx swap, without ever clearing the source drafts.
576+ const values = drafts.flatMap((f) => $$('textarea', f).map((t) => ({ id: t.id, value: t.value, start: t.selectionStart, end: t.selectionEnd })));
577+ for (const f of $$('#diffs details.dfile', page)) if (files.has(f.dataset.file)) f.open = files.get(f.dataset.file);
578+ ++diffGeneration; ++revealGen; moved = false; loading.clear(); lazyIO?.disconnect();
579+ // Keep the chosen client-side layout when the URL was not pinned.
580+ const layout = $('#diffs')?.dataset;
581+ if (layout?.diff && $('#diffs', page).dataset.diff) $('#diffs', page).dataset.diff = layout.diff;
582+ $('#diffs', page).dataset.mrStarted = 'true';
583+ for (const sel of regions) {
584+ const fresh = $(sel, page);
585+ await replaceRegion($(sel), fresh);
586+ fresh.remove(); // release each parsed region as soon as it is consumed
587+ }
588+ for (const v of values) {
589+ const t = document.getElementById(v.id);
590+ if (t) { t.value = v.value; t.setSelectionRange(v.start, v.end); }
591+ }
592+ for (const key of ['ref', 'sha', 'paths', 'blob']) {
593+ if (page.body.dataset[key] !== undefined) document.body.dataset[key] = page.body.dataset[key];
594+ }
595+ const oldSHA = $('.hdr .ref .sha'), newSHA = $('.hdr .ref .sha', page);
596+ if (oldSHA && newSHA) oldSHA.textContent = newSHA.textContent;
597+ panels();
598+ if (tab) {
599+ const oldURL = location.href;
600+ document.getElementById(tab)?.click();
601+ if (location.href !== oldURL) history.replaceState(history.state, '', oldURL);
602+ }
603+ if ($('#mr-panels')) $('#mr-panels').open = footerOpen;
604+ foldFiles(!!folded);
605+ if ($('.rail')) $('.rail').scrollTop = railY;
606+ if ($('.r-files .files')) $('.r-files .files').scrollTop = filesY;
607+ touchComments(false);
608+ $('#diffs').dataset.mobile = String(!!window.matchMedia?.('(max-width: 720px)').matches);
609+ window.ermite?.refreshFiles?.();
610+ watch();
611+ if (focus && active !== document.body) {
612+ const same = (e) => e.tagName === focus.tag && (focus.id ? e.id === focus.id :
613+ focus.href ? e.getAttribute('href') === focus.href : focus.name && e.getAttribute('name') === focus.name);
614+ const el = focus.menu && !focus.id && !focus.name && !focus.href ? document.getElementById(focus.menu)?.querySelector(':scope > summary') : focus.id ? document.getElementById(focus.id) : focus.href ? $('a[href="' + CSS.escape(focus.href) + '"]') : focus.name ? $('[name="' + CSS.escape(focus.name) + '"]') : null;
615+ if (el && (same(el) || focus.menu)) el.focus({ preventScroll: true });
616+ }
617+ restoreAnchor(anchor);
618+ }
619+
620+ function refreshNotice(deferred) {
621+ let slot = $('#mr-refresh-status');
622+ if (!slot) {
623+ slot = document.createElement('div'); slot.id = 'mr-refresh-status'; slot.className = 'live-slot';
624+ slot.setAttribute('role', 'status'); slot.setAttribute('aria-live', 'polite');
625+ $('#mr-notice')?.after(slot);
626+ }
627+ slot.className = deferred ? 'live-slot' : 'sr';
628+ slot.replaceChildren();
629+ if (!deferred) {
630+ const text = document.createElement('span'); text.textContent = 'branch updated'; slot.append(text);
631+ return;
632+ }
633+ slot.append('branch updated — refreshing after your comment. ');
634+ const a = document.createElement('a'); a.href = location.href; a.textContent = 'refresh now';
635+ a.addEventListener('click', (e) => { e.preventDefault(); headRefresh.request(true); });
636+ slot.append(a);
637+ }
638+ const headRefresh = refresher({ blocked: hasDraft, fetchPage, apply: refreshPage, notice: refreshNotice,
639+ failed: () => { if (hasDraft()) refreshNotice(true); else window.ermiteLive?.reload(); } });
640+ function headChanged() { if ($('#diffs[data-mr]')) headRefresh.request(); }
641+
410642 function start() {
411643 if (!$('#diffs[data-mr]')) return;
644+ // Global delegation is installed once; replacement regions have their own
645+ // disposable panel/touch hooks below.
646+ if ($('#diffs').dataset.mrStarted) return;
647+ $('#diffs').dataset.mrStarted = 'true';
648+ for (const type of ['input', 'focusout', 'reset', 'submit']) document.addEventListener?.(type, () => headRefresh.resume());
649+ document.addEventListener?.('click', (e) => {
650+ const cancel = e.target.closest?.('.cform .f-btns a');
651+ if (!cancel || !headRefresh.pending() || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return;
652+ e.preventDefault();
653+ const form = cancel.closest('.cform');
654+ for (const t of $$('textarea', form)) t.value = '';
655+ if (form.contains(document.activeElement)) document.activeElement.blur();
656+ headRefresh.resume();
657+ });
412658 panels();
413659 // Large diffs may contain only the split table. Ask the existing server
414660 // route for unified rather than writing the saved session preference.
@@ -457,7 +703,7 @@ window.ermiteMR = (() => {
457703 });
458704 }
459705
460- return { core, panels, start, load, reveal, openMerge, menuKey, markRead, focusFiles, stepFiles, leaveFiles, foldFiles, openFile };
706+ return { core, refresher, hasDraft, fetchPage, scrollAnchor, restoreAnchor, headChanged, panels, start, load, reveal, openMerge, menuKey, markRead, focusFiles, stepFiles, leaveFiles, foldFiles, openFile };
461707 })();
462708
463709 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => window.ermiteMR.start());
@@ -84,11 +84,13 @@ window.ermiteMR = (() => {
84 let refreshTouchComments = () => {};84 let refreshTouchComments = () => {};
85 let moved = false;85 let moved = false;
86 let lazyIO = null; // the observer of the placeholders (watch)86 let lazyIO = null; // the observer of the placeholders (watch)
87+ let diffGeneration = 0;
87 let revealGen = 0; // the last reveal wins the scroll88 let revealGen = 0; // the last reveal wins the scroll
88 89
89 // load fetches the window of a placeholder and swaps its files in. The90 // load fetches the window of a placeholder and swaps its files in. The
90 // promise resolves once they are in the page (or the page said to reload).91 // promise resolves once they are in the page (or the page said to reload).
91 function load(ph) {92 function load(ph) {
93+ const generation = diffGeneration;
92 const src = ph?.dataset.src;94 const src = ph?.dataset.src;
93 if (!src || moved) return Promise.resolve();95 if (!src || moved) return Promise.resolve();
94 if (loading.has(src)) return loading.get(src);96 if (loading.has(src)) return loading.get(src);
@@ -102,12 +104,14 @@ window.ermiteMR = (() => {
102 const p = fetch(url, { headers: { Accept: 'text/html' }, credentials: 'same-origin' })104 const p = fetch(url, { headers: { Accept: 'text/html' }, credentials: 'same-origin' })
103 .then(async (res) => {105 .then(async (res) => {
104 const html = await res.text();106 const html = await res.text();
107+ if (generation !== diffGeneration) return;
105 if (res.status === 409) return stale(html);108 if (res.status === 409) return stale(html);
106 if (!res.ok) throw new Error('loading files: ' + res.status);109 if (!res.ok) throw new Error('loading files: ' + res.status);
107 // A window of the old diff after the page went stale stays out.110 // A window of the old diff after the page went stale stays out.
108 if (!moved) swap(html);111 if (!moved) swap(html);
109 })112 })
110 .catch((err) => {113 .catch((err) => {
114+ if (generation !== diffGeneration) return;
111 loading.delete(src);115 loading.delete(src);
112 for (const p of $$('.dlazy[data-loading]')) if (p.dataset.src === src) p.removeAttribute('data-loading');116 for (const p of $$('.dlazy[data-loading]')) if (p.dataset.src === src) p.removeAttribute('data-loading');
113 window.ermite?.flash?.(err.message, 4000);117 window.ermite?.flash?.(err.message, 4000);
@@ -195,6 +199,7 @@ window.ermiteMR = (() => {
195 // that come in are marked in the list of files (ermite.js marks the one in199 // that come in are marked in the list of files (ermite.js marks the one in
196 // view).200 // view).
197 function watch() {201 function watch() {
202+ lazyIO?.disconnect();
198 if (!('IntersectionObserver' in window)) {203 if (!('IntersectionObserver' in window)) {
199 for (const p of $$('.dlazy[data-src]')) load(p);204 for (const p of $$('.dlazy[data-src]')) load(p);
200 return;205 return;
@@ -309,7 +314,9 @@ window.ermiteMR = (() => {
309 }314 }
310 315
311 // Enhance the ordinary anchor navigation only when scripts are available.316 // Enhance the ordinary anchor navigation only when scripts are available.
317+ let disposePanels = () => {};
312 function panels() {318 function panels() {
319+ disposePanels();
313 const footer = $('#mr-panels'), nav = $('[data-mr-tabs]');320 const footer = $('#mr-panels'), nav = $('[data-mr-tabs]');
314 if (!footer || !nav) return;321 if (!footer || !nav) return;
315 const tabs = $$('a', nav), panels = $$('[data-mr-panel]', footer);322 const tabs = $$('a', nav), panels = $$('[data-mr-panel]', footer);
@@ -342,20 +349,30 @@ window.ermiteMR = (() => {
342 footer.open = true; select(index);349 footer.open = true; select(index);
343 }350 }
344 // A repeated click on the same hash must also reopen a folded footer.351 // A repeated click on the same hash must also reopen a folded footer.
345- document.addEventListener('click', (e) => {352+ const checksClick = (e) => {
346 if (e.target.closest?.('#mr-ck')) { footer.open = true; select(1); }353 if (e.target.closest?.('#mr-ck')) { footer.open = true; select(1); }
347- });354+ };
355+ document.addEventListener('click', checksClick);
356+ let observer;
348 const summary = $('#mr-ck');357 const summary = $('#mr-ck');
349 if (summary) {358 if (summary) {
350 const sync = () => { $('[data-checks-label]', nav).textContent = $('#mr-ck')?.title || $('#mr-ck')?.textContent.trim() || 'no checks'; };359 const sync = () => { $('[data-checks-label]', nav).textContent = $('#mr-ck')?.title || $('#mr-ck')?.textContent.trim() || 'no checks'; };
351- new MutationObserver(sync).observe(summary.parentElement, { childList: true, subtree: true, characterData: true });360+ observer = new MutationObserver(sync);
361+ observer.observe(summary.parentElement, { childList: true, subtree: true, characterData: true });
352 sync();362 sync();
353 }363 }
354 select(0); hash();364 select(0); hash();
355 addEventListener('hashchange', hash);365 addEventListener('hashchange', hash);
366+ disposePanels = () => {
367+ document.removeEventListener?.('click', checksClick);
368+ window.removeEventListener?.('hashchange', hash);
369+ observer?.disconnect?.();
370+ };
356 }371 }
357 372
358- function touchComments() {373+ let disposeTouch = () => {};
374+ function touchComments(scroll = true) {
375+ disposeTouch();
359 const diffs = $('#diffs');376 const diffs = $('#diffs');
360 const bar = document.createElement('div');377 const bar = document.createElement('div');
361 bar.className = 'mr-touch-range';378 bar.className = 'mr-touch-range';
@@ -392,23 +409,252 @@ window.ermiteMR = (() => {
392 marker.setAttribute('data-range-start', '');409 marker.setAttribute('data-range-start', '');
393 status.textContent = `Range starts at line ${link.textContent.trim()}. Tap the last line number (same file and side).`;410 status.textContent = `Range starts at line ${link.textContent.trim()}. Tap the last line number (same file and side).`;
394 });411 });
395- touch?.addEventListener('change', () => {412+ const changed = () => {
396 if (touch.matches) return;413 if (touch.matches) return;
397 enabled = false;414 enabled = false;
398 clear();415 clear();
399 button.setAttribute('aria-pressed', 'false');416 button.setAttribute('aria-pressed', 'false');
400 status.textContent = '';417 status.textContent = '';
401- });418+ };
419+ touch?.addEventListener('change', changed);
420+ disposeTouch = () => { touch?.removeEventListener?.('change', changed); bar.remove?.(); };
402 // The server opens the line form. Scroll after layout without stealing421 // The server opens the line form. Scroll after layout without stealing
403 // focus or forcing a mobile keyboard to appear.422 // focus or forcing a mobile keyboard to appear.
404- if (new URL(location.href).searchParams.has('on')) requestAnimationFrame(() => {423+ if (scroll && new URL(location.href).searchParams.has('on')) requestAnimationFrame(() => {
405 const form = $$('.fnote .cform', diffs).find((f) => f.getClientRects().length);424 const form = $$('.fnote .cform', diffs).find((f) => f.getClientRects().length);
406 form?.scrollIntoView({ block: 'center' });425 form?.scrollIntoView({ block: 'center' });
407 });426 });
408 }427 }
409 428
429+ // A refresh scheduler has one request in flight, a trailing debounce, and
430+ // a dirty bit for pushes received during that request. Drafts are checked
431+ // again after the fetch: typing while the network is slow is safe too.
432+ function refresher({ blocked, fetchPage, apply, notice, failed, delay = 300 }) {
433+ let timer, busy = false, pending = false, force = false;
434+ const schedule = () => { clearTimeout(timer); timer = setTimeout(run, delay); };
435+ async function run() {
436+ if (busy || !pending) return;
437+ if (!force && blocked()) { notice(true); return; }
438+ busy = true;
439+ pending = false;
440+ const manual = force; force = false;
441+ try {
442+ const page = await fetchPage();
443+ if (!manual && blocked()) { pending = true; notice(true); return; }
444+ if (await apply(page, manual) === false) { pending = true; notice(true); }
445+ else notice(false);
446+ } catch { failed(); }
447+ finally {
448+ busy = false;
449+ if (pending && (force || !blocked())) schedule();
450+ }
451+ }
452+ return {
453+ request(manual = false) { pending = true; force ||= manual; schedule(); },
454+ resume() { if (pending) schedule(); },
455+ pending() { return pending || busy; },
456+ };
457+ }
458+
459+ function hasDraft() {
460+ return $$('textarea').some((t) => (t.value.length > 0 && t.value !== t.defaultValue) || document.activeElement === t) ||
461+ !!document.activeElement?.closest?.('.cform');
462+ }
463+
464+ // Path + side + line is stable when files are inserted before this one;
465+ // fN is only a positional anchor. Hidden unified/split rows are ignored.
466+ function scrollAnchor() {
467+ const top = Math.max(0, $('.hdr')?.getBoundingClientRect().bottom || 0,
468+ $('.mr-bar')?.getBoundingClientRect().bottom || 0);
469+ const diffs = $('#diffs');
470+ const bounds = diffs.getBoundingClientRect();
471+ const x = Math.max(1, Math.min(innerWidth - 1, bounds.left + Math.min(100, bounds.width / 2)));
472+ // A bounded number of probes, independent of the number of diff lines.
473+ for (const y of [top + 2, top + 24, top + 64, top + 128]) {
474+ if (y >= innerHeight) break;
475+ const hit = document.elementFromPoint(x, y);
476+ const file = hit?.closest('details.dfile');
477+ if (!file || !diffs.contains(file)) continue;
478+ const row = hit.closest('tr');
479+ const link = row && $('.ln a[href*="on="]', row);
480+ const header = $(':scope > summary', file);
481+ return { file: file.dataset.file,
482+ on: link && new URL(link.href, location.href).searchParams.get('on'),
483+ offset: (link ? row : header).getBoundingClientRect().top,
484+ headerOffset: header.getBoundingClientRect().top, y: scrollY };
485+ }
486+ return { y: scrollY };
487+ }
488+
489+ function restoreAnchor(anchor) {
490+ const file = $$('#diffs details.dfile').find((f) => f.dataset.file === anchor.file);
491+ let el, offset = anchor.offset;
492+ if (file && anchor.on) {
493+ // Exact href suffix: no traversal or measurement of every line. URLSearchParams
494+ // uses the same form encoding as the Go line links (space is '+').
495+ const parts = /^(new|old):(\d+):(.+)$/.exec(anchor.on);
496+ const path = parts && new URLSearchParams({ path: parts[3] }).toString().slice(5);
497+ const suffix = parts && 'on=' + parts[1] + ':' + parts[2] + ':' + path + '#' + file.id;
498+ const layout = $('#diffs').dataset.diff || $('#diffs').dataset.view;
499+ const table = $(layout === 'split' && !window.matchMedia?.('(max-width: 720px)').matches ? '.dt.spl' : '.dt.uni', file) || file;
500+ if (suffix) el = $('a[href$="' + CSS.escape(suffix) + '"]', table)?.closest('tr');
501+ }
502+ if (!el && file) { el = $(':scope > summary', file); offset = anchor.headerOffset ?? anchor.offset; }
503+ if (el) window.scrollBy({ top: el.getBoundingClientRect().top - offset, behavior: 'instant' });
504+ else window.scrollTo({ top: Math.max(0, Math.min(anchor.y, document.documentElement.scrollHeight - innerHeight)), behavior: 'instant' });
505+ }
506+
507+ async function fetchPage() {
508+ const res = await fetch(location.href, { credentials: 'same-origin', headers: { Accept: 'text/html' } });
509+ if (!res.ok || res.redirected) throw new Error('MR refresh refused');
510+ const page = new DOMParser().parseFromString(await res.text(), 'text/html');
511+ if (!$('#diffs[data-mr]', page) || !$('.mr-bar', page) || !$('.hint-live', page)) throw new Error('not an MR page');
512+ return page;
513+ }
514+
515+ // Use htmx's swap rather than replaceWith: its cleanup retires the old SSE
516+ // reader and hx-live bindings, and process activates the inserted controls.
517+ async function replaceRegion(old, fresh) {
518+ if (!old || !fresh) throw new Error('missing MR refresh region');
519+ for (const el of $$('[autofocus]', fresh)) el.removeAttribute('autofocus');
520+ await window.htmx.swap({ sourceElement: old, target: old, text: fresh.outerHTML,
521+ swap: 'outerHTML settle:0 transition:false focusScroll:false', push: false, replace: false });
522+ }
523+
524+ async function refreshPage(page, manual = false) {
525+ const regions = ['.mr-footer', '#mr-range', '.mr-bar', '#mr-diff-notices', '#diffs', '.rail', '.hint-live'];
526+ for (const sel of regions) if (!$(sel) || !$(sel, page)) throw new Error('missing MR region');
527+ let anchor = scrollAnchor();
528+ const anchorFile = $$('#diffs details.dfile', page).find((f) => f.dataset.file === anchor.file);
529+ const placeholder = anchorFile && $('.dlazy[data-src]', anchorFile);
530+ if (placeholder) {
531+ const d = $('#diffs').dataset;
532+ const url = placeholder.dataset.src + '&view=' + encodeURIComponent(d.diff || d.view || 'unified') + '&layouts=' + (d.diff ? 'both' : 'one');
533+ const res = await fetch(url, { credentials: 'same-origin', headers: { Accept: 'text/html' } });
534+ if (!res.ok || res.redirected) throw new Error('anchor window changed');
535+ const windowPage = new DOMParser().parseFromString(await res.text(), 'text/html');
536+ const byID = new Map($$('#diffs details.dfile', page).map((f) => [f.id, f]));
537+ for (const f of $$('details.dfile', windowPage)) byID.get(f.id)?.replaceWith(f);
538+ if (!manual && hasDraft()) return false;
539+ anchor = scrollAnchor();
540+ }
541+ const files = new Map($$('#diffs details.dfile').map((f) => [f.dataset.file, f.open]));
542+ const folded = $('.r-files')?.hasAttribute('data-folded');
543+ const railY = $('.rail')?.scrollTop, filesY = $('.r-files .files')?.scrollTop;
544+ const footerOpen = $('#mr-panels')?.open;
545+ const tab = $('[data-mr-tabs] [aria-selected="true"]')?.id;
546+ const active = document.activeElement;
547+ const focus = active && { menu: active.closest?.('details.menu')?.id, id: active.id, tag: active.tagName, name: active.getAttribute('name'), href: active.getAttribute('href') };
548+ // Manual refresh keeps even an active draft whose line disappeared. It
549+ // stays an ordinary form, under an explicit previous-diff label.
550+ const drafts = [...new Set($$('#diffs textarea').filter((t) => t.value !== t.defaultValue || t === active || t.closest('form')?.contains(active)).map((t) => t.closest('form')).filter(Boolean))];
551+ let draftID = 0;
552+ for (const form of drafts) {
553+ for (const t of $$('textarea', form)) {
554+ if (!t.id) t.id = 'mr-preserved-draft-' + (++draftID);
555+ if (t === active) focus.id = t.id;
556+ }
557+ const id = $('textarea', form)?.id;
558+ const replacement = id && $$('textarea', page).find((t) => t.id === id)?.closest('.cform');
559+ const copy = form.cloneNode(true);
560+ const originalFields = $$('textarea, input, select', form);
561+ $$('textarea, input, select', copy).forEach((field, i) => {
562+ const original = originalFields[i];
563+ if (field.tagName === 'TEXTAREA') field.textContent = original.defaultValue;
564+ else if (field.tagName === 'INPUT') { field.setAttribute('value', original.value); field.toggleAttribute('checked', original.checked); }
565+ });
566+ if (replacement) replacement.replaceWith(copy);
567+ else {
568+ const box = page.createElement('div');
569+ const label = page.createElement('p'); label.className = 'notice';
570+ label.textContent = 'Unsent comment on the previous diff (the line may have moved).';
571+ box.append(label, copy); $('#diffs', page).prepend(box);
572+ }
573+ }
574+ // Serializing markup does not retain textarea.value or selection. Restore
575+ // values after the htmx swap, without ever clearing the source drafts.
576+ const values = drafts.flatMap((f) => $$('textarea', f).map((t) => ({ id: t.id, value: t.value, start: t.selectionStart, end: t.selectionEnd })));
577+ for (const f of $$('#diffs details.dfile', page)) if (files.has(f.dataset.file)) f.open = files.get(f.dataset.file);
578+ ++diffGeneration; ++revealGen; moved = false; loading.clear(); lazyIO?.disconnect();
579+ // Keep the chosen client-side layout when the URL was not pinned.
580+ const layout = $('#diffs')?.dataset;
581+ if (layout?.diff && $('#diffs', page).dataset.diff) $('#diffs', page).dataset.diff = layout.diff;
582+ $('#diffs', page).dataset.mrStarted = 'true';
583+ for (const sel of regions) {
584+ const fresh = $(sel, page);
585+ await replaceRegion($(sel), fresh);
586+ fresh.remove(); // release each parsed region as soon as it is consumed
587+ }
588+ for (const v of values) {
589+ const t = document.getElementById(v.id);
590+ if (t) { t.value = v.value; t.setSelectionRange(v.start, v.end); }
591+ }
592+ for (const key of ['ref', 'sha', 'paths', 'blob']) {
593+ if (page.body.dataset[key] !== undefined) document.body.dataset[key] = page.body.dataset[key];
594+ }
595+ const oldSHA = $('.hdr .ref .sha'), newSHA = $('.hdr .ref .sha', page);
596+ if (oldSHA && newSHA) oldSHA.textContent = newSHA.textContent;
597+ panels();
598+ if (tab) {
599+ const oldURL = location.href;
600+ document.getElementById(tab)?.click();
601+ if (location.href !== oldURL) history.replaceState(history.state, '', oldURL);
602+ }
603+ if ($('#mr-panels')) $('#mr-panels').open = footerOpen;
604+ foldFiles(!!folded);
605+ if ($('.rail')) $('.rail').scrollTop = railY;
606+ if ($('.r-files .files')) $('.r-files .files').scrollTop = filesY;
607+ touchComments(false);
608+ $('#diffs').dataset.mobile = String(!!window.matchMedia?.('(max-width: 720px)').matches);
609+ window.ermite?.refreshFiles?.();
610+ watch();
611+ if (focus && active !== document.body) {
612+ const same = (e) => e.tagName === focus.tag && (focus.id ? e.id === focus.id :
613+ focus.href ? e.getAttribute('href') === focus.href : focus.name && e.getAttribute('name') === focus.name);
614+ const el = focus.menu && !focus.id && !focus.name && !focus.href ? document.getElementById(focus.menu)?.querySelector(':scope > summary') : focus.id ? document.getElementById(focus.id) : focus.href ? $('a[href="' + CSS.escape(focus.href) + '"]') : focus.name ? $('[name="' + CSS.escape(focus.name) + '"]') : null;
615+ if (el && (same(el) || focus.menu)) el.focus({ preventScroll: true });
616+ }
617+ restoreAnchor(anchor);
618+ }
619+
620+ function refreshNotice(deferred) {
621+ let slot = $('#mr-refresh-status');
622+ if (!slot) {
623+ slot = document.createElement('div'); slot.id = 'mr-refresh-status'; slot.className = 'live-slot';
624+ slot.setAttribute('role', 'status'); slot.setAttribute('aria-live', 'polite');
625+ $('#mr-notice')?.after(slot);
626+ }
627+ slot.className = deferred ? 'live-slot' : 'sr';
628+ slot.replaceChildren();
629+ if (!deferred) {
630+ const text = document.createElement('span'); text.textContent = 'branch updated'; slot.append(text);
631+ return;
632+ }
633+ slot.append('branch updated — refreshing after your comment. ');
634+ const a = document.createElement('a'); a.href = location.href; a.textContent = 'refresh now';
635+ a.addEventListener('click', (e) => { e.preventDefault(); headRefresh.request(true); });
636+ slot.append(a);
637+ }
638+ const headRefresh = refresher({ blocked: hasDraft, fetchPage, apply: refreshPage, notice: refreshNotice,
639+ failed: () => { if (hasDraft()) refreshNotice(true); else window.ermiteLive?.reload(); } });
640+ function headChanged() { if ($('#diffs[data-mr]')) headRefresh.request(); }
641+
410 function start() {642 function start() {
411 if (!$('#diffs[data-mr]')) return;643 if (!$('#diffs[data-mr]')) return;
644+ // Global delegation is installed once; replacement regions have their own
645+ // disposable panel/touch hooks below.
646+ if ($('#diffs').dataset.mrStarted) return;
647+ $('#diffs').dataset.mrStarted = 'true';
648+ for (const type of ['input', 'focusout', 'reset', 'submit']) document.addEventListener?.(type, () => headRefresh.resume());
649+ document.addEventListener?.('click', (e) => {
650+ const cancel = e.target.closest?.('.cform .f-btns a');
651+ if (!cancel || !headRefresh.pending() || e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return;
652+ e.preventDefault();
653+ const form = cancel.closest('.cform');
654+ for (const t of $$('textarea', form)) t.value = '';
655+ if (form.contains(document.activeElement)) document.activeElement.blur();
656+ headRefresh.resume();
657+ });
412 panels();658 panels();
413 // Large diffs may contain only the split table. Ask the existing server659 // Large diffs may contain only the split table. Ask the existing server
414 // route for unified rather than writing the saved session preference.660 // route for unified rather than writing the saved session preference.
@@ -457,7 +703,7 @@ window.ermiteMR = (() => {
457 });703 });
458 }704 }
459 705
460- return { core, panels, start, load, reveal, openMerge, menuKey, markRead, focusFiles, stepFiles, leaveFiles, foldFiles, openFile };706+ return { core, refresher, hasDraft, fetchPage, scrollAnchor, restoreAnchor, headChanged, panels, start, load, reveal, openMerge, menuKey, markRead, focusFiles, stepFiles, leaveFiles, foldFiles, openFile };
461 })();707 })();
462 708
463 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => window.ermiteMR.start());709 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => window.ermiteMR.start());
M internal/app/testdata/web/commits-root.html +1 -0
@@ -973,6 +973,7 @@
973973 htmx:sse:error -> ermiteLive.error(event.detail.status);
974974 htmx:sse:before:connection -> ermiteLive.gate(event);
975975 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
976+ mr-head -> ermiteMR.headChanged();
976977 gap -> ermiteLive.reload()">
977978 </span>
978979 </div>
@@ -973,6 +973,7 @@
973 htmx:sse:error -> ermiteLive.error(event.detail.status);973 htmx:sse:error -> ermiteLive.error(event.detail.status);
974 htmx:sse:before:connection -> ermiteLive.gate(event);974 htmx:sse:before:connection -> ermiteLive.gate(event);
975 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);975 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
976+ mr-head -> ermiteMR.headChanged();
976 gap -> ermiteLive.reload()">977 gap -> ermiteLive.reload()">
977 </span>978 </span>
978 </div>979 </div>
M internal/app/testdata/web/commits-small.html +1 -0
@@ -318,6 +318,7 @@
318318 htmx:sse:error -> ermiteLive.error(event.detail.status);
319319 htmx:sse:before:connection -> ermiteLive.gate(event);
320320 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
321+ mr-head -> ermiteMR.headChanged();
321322 gap -> ermiteLive.reload()">
322323 </span>
323324 </div>
@@ -318,6 +318,7 @@
318 htmx:sse:error -> ermiteLive.error(event.detail.status);318 htmx:sse:error -> ermiteLive.error(event.detail.status);
319 htmx:sse:before:connection -> ermiteLive.gate(event);319 htmx:sse:before:connection -> ermiteLive.gate(event);
320 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);320 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
321+ mr-head -> ermiteMR.headChanged();
321 gap -> ermiteLive.reload()">322 gap -> ermiteLive.reload()">
322 </span>323 </span>
323 </div>324 </div>
M internal/app/testdata/web/home.html +1 -0
@@ -194,6 +194,7 @@
194194 htmx:sse:error -> ermiteLive.error(event.detail.status);
195195 htmx:sse:before:connection -> ermiteLive.gate(event);
196196 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
197+ mr-head -> ermiteMR.headChanged();
197198 gap -> ermiteLive.reload()">
198199 </span>
199200 </div>
@@ -194,6 +194,7 @@
194 htmx:sse:error -> ermiteLive.error(event.detail.status);194 htmx:sse:error -> ermiteLive.error(event.detail.status);
195 htmx:sse:before:connection -> ermiteLive.gate(event);195 htmx:sse:before:connection -> ermiteLive.gate(event);
196 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);196 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
197+ mr-head -> ermiteMR.headChanged();
197 gap -> ermiteLive.reload()">198 gap -> ermiteLive.reload()">
198 </span>199 </span>
199 </div>200 </div>
M internal/app/testdata/web/refs.html +1 -0
@@ -200,6 +200,7 @@
200200 htmx:sse:error -> ermiteLive.error(event.detail.status);
201201 htmx:sse:before:connection -> ermiteLive.gate(event);
202202 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
203+ mr-head -> ermiteMR.headChanged();
203204 gap -> ermiteLive.reload()">
204205 </span>
205206 </div>
@@ -200,6 +200,7 @@
200 htmx:sse:error -> ermiteLive.error(event.detail.status);200 htmx:sse:error -> ermiteLive.error(event.detail.status);
201 htmx:sse:before:connection -> ermiteLive.gate(event);201 htmx:sse:before:connection -> ermiteLive.gate(event);
202 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);202 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
203+ mr-head -> ermiteMR.headChanged();
203 gap -> ermiteLive.reload()">204 gap -> ermiteLive.reload()">
204 </span>205 </span>
205 </div>206 </div>
M internal/app/testdata/web/summary.html +1 -0
@@ -226,6 +226,7 @@
226226 htmx:sse:error -> ermiteLive.error(event.detail.status);
227227 htmx:sse:before:connection -> ermiteLive.gate(event);
228228 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
229+ mr-head -> ermiteMR.headChanged();
229230 gap -> ermiteLive.reload()">
230231 </span>
231232 </div>
@@ -226,6 +226,7 @@
226 htmx:sse:error -> ermiteLive.error(event.detail.status);226 htmx:sse:error -> ermiteLive.error(event.detail.status);
227 htmx:sse:before:connection -> ermiteLive.gate(event);227 htmx:sse:before:connection -> ermiteLive.gate(event);
228 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);228 home-list, repo-last-push, refs-list, commits-head, mr-notice, mr-mergeability, ci-run, ci-job, inbox -> ermiteLive.swap(event.detail.data);
229+ mr-head -> ermiteMR.headChanged();
229 gap -> ermiteLive.reload()">230 gap -> ermiteLive.reload()">
230 </span>231 </span>
231 </div>232 </div>
M internal/app/web_mr_test.go +3 -2
@@ -595,8 +595,9 @@ func TestWebMergeRequestEvents(t *testing.T) {
595595
596596 r.writeFile(r.wt, "more.txt", []byte("more\n"))
597597 r.mustGit(r.wt, "push", "-q", r.url, "feat/search")
598- ev = nextNamed(t, one, "mr-notice")
599- assert.Contains(t, ev.data, "the branch changed")
598+ ev = nextNamed(t, one, "mr-head")
599+ assert.Equal(t, `<div id="mr-head"></div>`, ev.data)
600+ assert.NotContains(t, ev.data, "the branch changed")
600601
601602 r.cli(t, adminToken, "mr", "close", "proj", "1").ok(t)
602603 assert.Contains(t, nextNamed(t, one, "mr-notice").data, "was closed")
@@ -595,8 +595,9 @@ func TestWebMergeRequestEvents(t *testing.T) {
595 595
596 r.writeFile(r.wt, "more.txt", []byte("more\n"))596 r.writeFile(r.wt, "more.txt", []byte("more\n"))
597 r.mustGit(r.wt, "push", "-q", r.url, "feat/search")597 r.mustGit(r.wt, "push", "-q", r.url, "feat/search")
598- ev = nextNamed(t, one, "mr-notice")598+ ev = nextNamed(t, one, "mr-head")
599- assert.Contains(t, ev.data, "the branch changed")599+ assert.Equal(t, `<div id="mr-head"></div>`, ev.data)
600+ assert.NotContains(t, ev.data, "the branch changed")
600 601
601 r.cli(t, adminToken, "mr", "close", "proj", "1").ok(t)602 r.cli(t, adminToken, "mr", "close", "proj", "1").ok(t)
602 assert.Contains(t, nextNamed(t, one, "mr-notice").data, "was closed")603 assert.Contains(t, nextNamed(t, one, "mr-notice").data, "was closed")

Keyboard shortcuts

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

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

Branches 2

Tags 44

↑↓ moveenter openesc close