Raw
  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}}