1{{define "icon-copy"}}<svg class="icon" viewBox="0 0 16 16" aria-hidden="true"><rect x="5" y="5" width="9" height="9" rx="1"/><path d="M11 5V3a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h2"/></svg>{{end}}
2{{define "icon-external"}}<svg class="icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M9 2h5v5M14 2 7 9M12 10v3a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h3"/></svg>{{end}}
3{{define "icon-warning"}}<svg class="icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 2 1.5 13.5h13Z"/><path d="M8 6.5v3.5M8 12v.01"/></svg>{{end}}
4{{define "admin-header"}}<header class="small"><div class="bar">{{if .Site}}<p>{{.Site}} · {{id .Host}}</p>{{else}}{{id .Host}}{{end}}<p>{{tr "session.signed_in_as" .Data.Viewer}} <a href="/logout">{{t "session.sign_out"}}</a></p></div>
5<nav><a href="/">{{t "admin.nav.dashboard"}}</a> <a href="/users">{{t "admin.nav.users"}}</a> <a href="/groups">{{t "admin.nav.groups"}}</a> <a href="/invitations">{{t "admin.nav.invitations"}}</a> <a href="/audit">{{t "admin.nav.audit"}}</a></nav></header>
6<hr>
7{{end}}
8{{define "admin-message"}}{{if .}}<p class="flash warning" role="alert">{{t .}}</p>
9{{end}}{{end}}
10{{define "admin-range"}}{{if .Shown}}<p class="small">{{t "admin.list.showing"}} {{.From}}–{{.To}} {{t "admin.list.of"}} {{.Total}}</p>
11{{end}}{{end}}
12{{define "admin-pager"}}{{if or .Prev .Next}}<div class="actions">{{if .Prev}}<form method="get" action="{{.Action}}">{{if .Query}}<input type="hidden" class="ident" name="q" value="{{.Query}}">{{end}}<input type="hidden" name="page" value="{{.Prev}}"><button type="submit">{{t "admin.list.prev"}}</button></form>{{end}}{{if .Next}}<form method="get" action="{{.Action}}">{{if .Query}}<input type="hidden" class="ident" name="q" value="{{.Query}}">{{end}}<input type="hidden" name="page" value="{{.Next}}"><button type="submit">{{t "admin.list.next"}}</button></form>{{end}}</div>
13{{end}}{{end}}
14{{define "admin-empty-page"}}<p>{{t "admin.list.empty_page"}} <a href="{{.Action}}">{{t "admin.list.first_page"}}</a></p>
15{{end}}
16{{define "admin-audit"}}{{if .}}<table>
17<thead><tr><th>{{t "admin.audit.time"}}</th><th>{{t "admin.audit.actor"}}</th><th>{{t "admin.audit.action"}}</th><th>{{t "admin.audit.subject"}}</th></tr></thead>
18<tbody>
19{{range .}}<tr><td>{{.At}}</td><td>{{id .Actor}}</td><td>{{if .Sentence}}{{t .Sentence}}{{else}}{{id .Action}}{{end}}</td><td>{{if .Subject}}{{id .Subject}}{{end}}</td></tr>
20{{end}}</tbody>
21</table>
22{{else}}<p>{{t "admin.audit.empty"}}</p>
23{{end}}{{end}}
24{{define "admin-profile-form"}}<form method="post" action="/users/{{.Data.ID}}/profile">
25<input type="hidden" name="csrf" value="{{.CSRF}}">
26<label for="display_name">{{t "admin.user.display_name"}}</label>
27<input id="display_name" name="display_name" value="{{.Data.DisplayName}}" autocomplete="off">
28<div class="actions"><button type="submit" class="primary" data-disable-on-submit>{{t "admin.user.save"}}</button></div>
29</form>
30{{end}}
31{{define "admin-group-add"}}<form method="post" action="/users/{{.Data.ID}}/groups">
32<input type="hidden" name="csrf" value="{{.CSRF}}">
33<input type="hidden" name="op" value="add">
34<label for="group">{{t "admin.user.group_add"}}</label>
35{{if .Data.Choices}}<select id="group" class="ident" name="group" required>
36<option value="">{{t "admin.user.group_choose"}}</option>
37{{range .Data.Choices}}<option value="{{.}}">{{.}}</option>
38{{end}}</select>
39{{else}}<input id="group" class="ident" name="group" value="{{.Data.GroupInput}}" autocomplete="off" autocapitalize="none" spellcheck="false" required>
40{{end}}<div class="actions"><button type="submit">{{t "admin.add"}}</button></div>
41</form>
42{{end}}
43{{define "admin-memberships"}}<ul>
44{{range .Data.Groups}}<li><span class="badge">{{id .Name}}</span>{{if .Primary}} <small>{{t "admin.user.primary"}}</small>{{else}} <form method="post" action="/users/{{$.Data.ID}}/groups"><input type="hidden" name="csrf" value="{{$.CSRF}}"><input type="hidden" name="op" value="remove"><input type="hidden" name="group_id" value="{{.ID}}"><button type="submit">{{t "admin.remove"}}</button></form>{{end}}</li>
45{{end}}</ul>
46{{end}}
47{{define "admin-members"}}{{if .Data.Members}}{{template "admin-range" .Data.Pager}}<table>
48<thead><tr><th>{{t "admin.col.username"}}</th><th>{{t "admin.col.name"}}</th>{{if .Data.Edit}}<th></th>{{end}}</tr></thead>
49<tbody>
50{{range .Data.Members}}<tr><td><a href="/users/{{.ID}}">{{id .Username}}</a></td><td>{{.DisplayName}}</td>{{if $.Data.Edit}}<td>{{if not $.Data.Primary}}<form method="post" action="/groups/{{$.Data.ID}}/members"><input type="hidden" name="csrf" value="{{$.CSRF}}"><input type="hidden" name="op" value="remove"><input type="hidden" name="user_id" value="{{.ID}}"><button type="submit">{{t "admin.remove"}}</button></form>{{end}}</td>{{end}}</tr>
51{{end}}</tbody>
52</table>
53{{template "admin-pager" .Data.Pager}}{{else if .Data.Pager.Total}}{{template "admin-empty-page" .Data.Pager}}{{else}}<p>{{t "admin.group.no_members"}}</p>
54{{end}}{{if .Data.Disabled}}<p>{{t "admin.group.disabled_members"}}</p>
55<ul>
56{{range .Data.Disabled}}<li><a href="/users/{{.ID}}">{{id .Username}}</a> <small>{{if .Pending}}{{t "admin.state.pending"}}{{else}}{{t "admin.state.disabled"}}{{end}}</small></li>
57{{end}}</ul>
58{{if .Data.DisabledMore}}<p><small>+{{.Data.DisabledMore}} {{t "admin.badges.more"}}</small></p>
59{{end}}{{end}}{{if .Data.Primary}}<p class="small">{{t "admin.group.primary_note"}}</p>
60{{else}}{{if not .Data.Edit}}<form method="get" action="/groups/{{.Data.ID}}/members"><button type="submit">{{t "admin.group.change_members"}}</button></form>
61{{end}}<form method="get" action="/groups/{{.Data.ID}}/members" class="toolbar">
62<label for="find">{{t "admin.group.member_add"}}</label>
63<input id="find" class="ident" name="find" type="search" value="{{.Data.Find}}" autocomplete="off" autocapitalize="none" spellcheck="false">
64<button type="submit">{{t "admin.group.member_search"}}</button>
65</form>
66{{if .Data.Candidates}}<table>
67<tbody>
68{{range .Data.Candidates}}<tr><td>{{id .Username}}</td><td>{{.DisplayName}}</td><td><form method="post" action="/groups/{{$.Data.ID}}/members"><input type="hidden" name="csrf" value="{{$.CSRF}}"><input type="hidden" name="op" value="add"><input type="hidden" class="ident" name="username" value="{{.Username}}"><button type="submit">{{t "admin.add"}}</button></form></td></tr>
69{{end}}</tbody>
70</table>
71{{else if .Data.Searched}}<p>{{t "admin.group.no_candidates"}}</p>
72{{end}}{{end}}{{end}}
73{{define "admin-description-form"}}<form method="post" action="/groups/{{.Data.ID}}/description">
74<input type="hidden" name="csrf" value="{{.CSRF}}">
75<label for="description">{{t "admin.group.description"}}</label>
76<input id="description" name="description" value="{{.Data.Description}}" autocomplete="off">
77<div class="actions"><button type="submit">{{t "admin.save"}}</button></div>
78</form>
79{{end}}
80{{define "account-header"}}<header class="small"><p>{{if .Site}}{{.Site}} · {{end}}{{id .Host}}</p><nav><a href="/">{{t "account.nav.overview"}}</a> <a href="/password">{{t "account.nav.password"}}</a> <a href="/sessions">{{t "account.nav.sessions"}}</a> <a href="/logout">{{t "session.sign_out"}}</a></nav></header>
81<hr>
82{{end}}
83{{define "qr"}}<svg class="qr" viewBox="0 0 {{.Size}} {{.Size}}" aria-hidden="true" shape-rendering="crispEdges"><path fill="#fff" d="M0 0h{{.Size}}v{{.Size}}H0z"/><path fill="none" stroke="#000" d="{{.Path}}"/></svg>{{end}}
84{{define "onetime-groups"}}{{with .Groups}}<p>{{t "onetime.groups"}} {{range .}}<span class="badge">{{id .}}</span> {{end}}{{if $.GroupsMore}}<small>+{{$.GroupsMore}} {{t "admin.badges.more"}}</small>{{end}}</p>
85{{end}}{{end}}
86{{define "ssh-keys"}}{{if .Rows}}<div class="ssh-keys">
87{{range .Rows}}<dl>
88<dt>{{if .Label}}{{.Label}}{{else}}{{t "ssh_keys.no_label"}}{{end}}</dt>
89<dd>{{id .Type}}</dd>
90<dd>{{id .Fingerprint}} · {{t "ssh_keys.added"}} {{.Added}}</dd>
91<dd><form method="get" action="{{$.Remove}}{{.ID}}/remove"><button type="submit">{{t "ssh_keys.remove"}}</button></form></dd>
92</dl>
93{{end}}</div>
94{{else}}<p>{{t "ssh_keys.none"}}</p>
95{{end}}{{if .Full}}<p class="small">{{t "ssh_keys.full"}}</p>
96{{else if .Add}}<div class="actions"><form method="get" action="{{.Add}}"><button type="submit">{{t "ssh_keys.add"}}</button></form></div>
97{{end}}{{end}}
98{{define "ssh-key-form"}}{{if .Data.Message}}<p class="flash warning" role="alert">{{t .Data.Message}}</p>
99{{end}}<form method="post" action="{{.Data.Action}}">
100<input type="hidden" name="csrf" value="{{.CSRF}}">
101<label for="key">{{t "ssh_key_new.key"}}</label>
102<textarea id="key" class="ident" name="key" rows="4" required autocomplete="off" autocapitalize="none" spellcheck="false">{{.Data.Key}}</textarea>
103<label for="label">{{t "ssh_key_new.label"}}</label>
104<input id="label" name="label" value="{{.Data.Label}}" autocomplete="off" aria-describedby="label-hint">
105<p class="small" id="label-hint">{{t "ssh_key_new.label_hint"}}</p>
106<div class="actions"><button type="submit" class="primary" data-disable-on-submit>{{t "ssh_key_new.submit"}}</button> <a href="{{.Data.Cancel}}">{{t "confirm.cancel"}}</a></div>
107</form>
108{{end}}