changeset 3:00f99f702ad9 draft

feat: add /topics webcommand to list all topics
author Zeger Van de Vannet <zeger@vandevan.net>
date Fri, 30 May 2025 18:01:26 +0200
parents be3bd841abd2
children 5401fa8a11d4
files hgext3rd/__init__.py hgext3rd/topic_web.py templates/paper-extended/__init__.py templates/paper-extended/bookmarks.tmpl templates/paper-extended/branches.tmpl templates/paper-extended/changeset.tmpl templates/paper-extended/diffstat.tmpl templates/paper-extended/error.tmpl templates/paper-extended/fileannotate.tmpl templates/paper-extended/filecomparison.tmpl templates/paper-extended/filediff.tmpl templates/paper-extended/filelog.tmpl templates/paper-extended/filelogentry.tmpl templates/paper-extended/filerevision.tmpl templates/paper-extended/footer.tmpl templates/paper-extended/graph.tmpl templates/paper-extended/graphentry.tmpl templates/paper-extended/header.tmpl templates/paper-extended/help.tmpl templates/paper-extended/helptopics.tmpl templates/paper-extended/index.tmpl templates/paper-extended/manifest.tmpl templates/paper-extended/map templates/paper-extended/notfound.tmpl templates/paper-extended/search.tmpl templates/paper-extended/shortlog.tmpl templates/paper-extended/shortlogentry.tmpl templates/paper-extended/tags.tmpl templates/paper-extended/topics.tmpl
diffstat 28 files changed, 1615 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/__init__.py	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,3 @@
+from __future__ import absolute_import
+import pkgutil
+__path__ = pkgutil.extend_path(__path__, __name__)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/topic_web.py	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,55 @@
+""" Add topic support to hgweb templates """
+
+from mercurial.hgweb.common import paritygen
+from mercurial.hgweb import webcommands, webutil
+from mercurial import templateutil, extensions
+from mercurial.node import hex
+
[email protected](b"topics")
+def topics(web):
+    entries = topicentries(web.repo, web.stripecount)
+    latestentry = topicentries(web.repo, web.stripecount, 1)
+
+    return web.sendtemplate(b"topics", node=hex(web.repo.changelog.tip()), entries=entries, latestentry=latestentry)
+
+webcommands.topics = topics
+
+def topicentries(repo, stripecount, limit=0):
+    tips = []
+    parity = paritygen(stripecount)
+    sortkey = lambda item: (not item[1], item[0].rev())
+
+    def entries(context):
+        count = 0
+        if not tips:
+            for tag, hs, tip, closed in repo.branchmap().iterbranches():
+                tips.append((repo[tip], closed))
+        for ctx, closed in sorted(tips, key=sortkey, reverse=True):
+            if limit > 0 and count >= limit:
+                return
+            count += 1
+            yield {
+                b'parity': next(parity),
+                b'node': ctx.hex(),
+                b'date': ctx.date(),
+                b'fqbn': ctx.fqbn(),
+                b'topic': ctx.topic(),
+                b'topic_namespace': ctx.topic_namespace(),
+            }
+
+    return templateutil.mappinggenerator(entries)
+
+def commonentry(orig, repo, ctx):
+    data = orig(repo, ctx)
+    data[b'topic'] = ctx.topic()
+    return data
+
+def changesetentry(orig, web, ctx):
+    data = orig(web, ctx)
+    data['topic'] = ctx.topic()
+    data['topic_namespace'] = ctx.topic_namespace()
+    return data
+
+def uisetup(ui):
+    extensions.wrapfunction(webutil, "commonentry", commonentry)
+    extensions.wrapfunction(webutil, "changesetentry", changesetentry)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/bookmarks.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,53 @@
+{header}
+<title>{repo|escape}: bookmarks</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url|urlescape}atom-bookmarks" title="Atom feed for {repo|escape}: bookmarks" />
+<link rel="alternate" type="application/rss+xml"
+   href="{url|urlescape}rss-bookmarks" title="RSS feed for {repo|escape}: bookmarks" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li class="active">bookmarks</li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+<div class="atom-logo">
+<a href="{url|urlescape}atom-bookmarks" title="subscribe to atom feed">
+<img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="atom feed" />
+</a>
+</div>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>bookmarks</h3>
+
+{searchform}
+
+<table class="bigtable">
+<thead>
+<tr>
+ <th>bookmark</th>
+ <th>node</th>
+</tr>
+</thead>
+<tbody class="stripes2">
+{entries%bookmarkentry}
+</tbody>
+</table>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/branches.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,53 @@
+{header}
+<title>{repo|escape}: branches</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url|urlescape}atom-branches" title="Atom feed for {repo|escape}: branches" />
+<link rel="alternate" type="application/rss+xml"
+   href="{url|urlescape}rss-branches" title="RSS feed for {repo|escape}: branches" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li class="active">branches</li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+ <li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+<div class="atom-logo">
+<a href="{url|urlescape}atom-branches" title="subscribe to atom feed">
+<img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="atom feed" />
+</a>
+</div>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>branches</h3>
+
+{searchform}
+
+<table class="bigtable">
+<thead>
+<tr>
+ <th>branch</th>
+ <th>node</th>
+</tr>
+</thead>
+<tbody class="stripes2">
+{entries % branchentry}
+</tbody>
+</table>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/changeset.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,99 @@
+{header}
+<title>{repo|escape}: {node|short}</title>
+</head>
+<body>
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+ <li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+ <li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+ <li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+ <li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+ <li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+ <li class="active">changeset</li>
+ <li><a href="{url|urlescape}raw-rev/{symrev}{sessionvars%urlparameter}">raw</a></li>
+ <li><a href="{url|urlescape}file/{symrev}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+ {archives%archiveentry}
+</ul>
+<ul>
+ <li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>
+ changeset {rev}:<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ {alltags}
+</h3>
+
+{searchform}
+
+<div class="description">{desc|strip|escape|websub|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">{author|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date age">{date|rfc822date}</td>
+</tr>
+{if(topic, '<tr>
+ <th>topic</th>
+ <td><a href="{url|urlescape}stack/{topic|urlescape}{sessionvars%urlparameter}">{topic}</a></td>
+</tr>')}
+{if(obsolete, '<tr>
+ <th>obsolete</th>
+ <td>{join(succsandmarkers%obsfateentry, '<br>\n')}</td>
+</tr>')}
+{if(instabilities, '<tr>
+ <th>unstable</th>
+ <td>{join(whyunstable%whyunstableentry, '<br>\n')}</td>
+</tr>')}
+<tr>
+ <th class="author">parents</th>
+ <td class="author">{ifeq(count(parent), '2', parent%changesetparentdiff, parent%changesetparent)}</td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author">{child%changesetchild}</td>
+</tr>
+<tr>
+ <th class="files">files</th>
+ <td class="files">{files}</td>
+</tr>
+<tr>
+  <th class="diffstat">diffstat</th>
+  <td class="diffstat">
+    {diffsummary}
+    <a id="diffstatexpand" class="diffstattoggle" href="#">[<tt>+</tt>]</a>
+    <div id="diffstatdetails" style="display:none;">
+      <a class="diffstattoggle" href="#">[<tt>-</tt>]</a>
+      <table class="diffstat-table stripes2">{diffstat}</table>
+    </div>
+  </td>
+</tr>
+</table>
+
+<div class="overflow">
+<div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="#">on</a></div>
+<div class="sourcefirst"> line diff</div>
+<div class="stripes2 diffblocks">
+{diff}
+</div>
+</div>
+
+</div>
+</div>
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/diffstat.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,8 @@
+  <tr>
+    <td class="diffstat-file"><a href="#l{fileno}.1">{file|escape}</a></td>
+    <td class="diffstat-total" align="right">{total}</td>
+    <td class="diffstat-graph">
+      <span class="diffstat-add" style="width:{addpct}%;">&nbsp;</span>
+      <span class="diffstat-remove" style="width:{removepct}%;">&nbsp;</span>
+    </td>
+  </tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/error.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,42 @@
+{header}
+<title>{repo|escape}: error</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" width=75 height=90 border=0 alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>error</h3>
+
+{searchform}
+
+<div class="description">
+<p>
+An error occurred while processing your request:
+</p>
+<p>
+{error|escape}
+</p>
+</div>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/fileannotate.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,95 @@
+{header}
+<title>{repo|escape}: {file|escape} annotate</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url|urlescape}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
+<li><a href="{url|urlescape}diff/{symrev}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+<li><a href="{url|urlescape}comparison/{symrev}/{file|urlescape}{sessionvars%urlparameter}">comparison</a></li>
+<li class="active">annotate</li>
+<li><a href="{url|urlescape}log/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
+<li><a href="{url|urlescape}raw-file/{symrev}/{file|urlescape}">raw</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>
+ annotate {file|escape} @ {rev}:<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ {alltags}
+</h3>
+
+{searchform}
+
+<div class="description">{desc|strip|escape|websub|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">{author|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date age">{date|rfc822date}</td>
+</tr>
+<tr>
+ <th class="author">parents</th>
+ <td class="author">{parent%filerevparent}</td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author">{child%filerevchild}</td>
+</tr>
+</table>
+
+{diffoptsform}
+
+<script type="text/javascript"{if(nonce, ' nonce="{nonce}"')}>
+    renderDiffOptsForm();
+</script>
+
+<div class="overflow">
+<table class="bigtable">
+<thead>
+<tr>
+ <th class="annotate">rev</th>
+ <th class="line">&nbsp;&nbsp;line source</th>
+</tr>
+</thead>
+<tbody class="stripes2 sourcelines"
+       data-logurl="{url|urlescape}log/{symrev}/{file|urlescape}"
+       data-selectabletag="TR"
+       data-ishead="{ishead}">
+  {annotate%annotateline}
+</tbody>
+</table>
+</div>
+</div>
+</div>
+
+<script type="text/javascript" src="{staticurl|urlescape}followlines.js"></script>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/filecomparison.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,90 @@
+{header}
+<title>{repo|escape}: {file|escape} comparison</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url|urlescape}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
+<li><a href="{url|urlescape}diff/{symrev}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+<li class="active">comparison</li>
+<li><a href="{url|urlescape}annotate/{symrev}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+<li><a href="{url|urlescape}log/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
+<li><a href="{url|urlescape}raw-file/{symrev}/{file|urlescape}">raw</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>
+ comparison {file|escape} @ {rev}:<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ {alltags}
+</h3>
+
+{searchform}
+
+<div class="description">{desc|strip|escape|websub|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th>author</th>
+ <td>{author|obfuscate}</td>
+</tr>
+<tr>
+ <th>date</th>
+ <td class="date age">{date|rfc822date}</td>
+</tr>
+<tr>
+ <th>parents</th>
+ <td>{parent%filerevparent}</td>
+</tr>
+<tr>
+ <th>children</th>
+ <td>{child%filerevchild}</td>
+</tr>
+</table>
+
+<div class="overflow">
+<div class="sourcefirst">   comparison</div>
+<div class="legend">
+  <span class="legendinfo equal">equal</span>
+  <span class="legendinfo delete">deleted</span>
+  <span class="legendinfo insert">inserted</span>
+  <span class="legendinfo replace">replaced</span>
+</div>
+
+<table class="bigtable">
+  <thead class="header">
+    <tr>
+      <th>{leftrev}:{leftnode|short}</th>
+      <th>{rightrev}:{rightnode|short}</th>
+    </tr>
+  </thead>
+  {comparison}
+</table>
+
+</div>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/filediff.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,77 @@
+{header}
+<title>{repo|escape}: {file|escape} diff</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url|urlescape}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
+<li class="active">diff</li>
+<li><a href="{url|urlescape}comparison/{symrev}/{file|urlescape}{sessionvars%urlparameter}">comparison</a></li>
+<li><a href="{url|urlescape}annotate/{symrev}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+<li><a href="{url|urlescape}log/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
+<li><a href="{url|urlescape}raw-file/{symrev}/{file|urlescape}">raw</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>
+ diff {file|escape} @ {rev}:<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ {alltags}
+</h3>
+
+{searchform}
+
+<div class="description">{desc|strip|escape|websub|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th>author</th>
+ <td>{author|obfuscate}</td>
+</tr>
+<tr>
+ <th>date</th>
+ <td class="date age">{date|rfc822date}</td>
+</tr>
+<tr>
+ <th>parents</th>
+ <td>{parent%filerevparent}</td>
+</tr>
+<tr>
+ <th>children</th>
+ <td>{child%filerevchild}</td>
+</tr>
+</table>
+
+<div class="overflow">
+<div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="#">on</a></div>
+<div class="sourcefirst"> line diff</div>
+<div class="stripes2 diffblocks">
+{diff}
+</div>
+</div>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/filelog.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,83 @@
+{header}
+<title>{repo|escape}: {file|escape} history</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url|urlescape}atom-log/tip/{file|urlescape}" title="Atom feed for {repo|escape}:{file}" />
+<link rel="alternate" type="application/rss+xml"
+   href="{url|urlescape}rss-log/tip/{file|urlescape}" title="RSS feed for {repo|escape}:{file}" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file</a></li>
+<li><a href="{url|urlescape}diff/{symrev}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+<li><a href="{url|urlescape}comparison/{symrev}/{file|urlescape}{sessionvars%urlparameter}">comparison</a></li>
+<li><a href="{url|urlescape}annotate/{symrev}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+<li class="active">file log</li>
+<li><a href="{url|urlescape}raw-file/{symrev}/{file|urlescape}">raw</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+<div class="atom-logo">
+<a href="{url|urlescape}atom-log/tip/{file|urlescape}" title="subscribe to atom feed">
+<img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="atom feed" />
+</a>
+</div>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>
+ log {file|escape} @ {rev}:<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ {alltags}
+ {if(linerange,
+' (following lines {linerange}{if(descend, ', descending')} <a href="{url|urlescape}log/{symrev}/{file|urlescape}{sessionvars%urlparameter}">all revisions for this file</a>)')}
+</h3>
+
+{searchform}
+
+<div class="navigate">
+<a href="{url|urlescape}log/{symrev}/{file|urlescape}{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}log/{symrev}/{file|urlescape}{morevars%urlparameter}">more</a>
+| {nav%filenav}</div>
+
+<table class="bigtable">
+<thead>
+ <tr>
+  <th class="age">age</th>
+  <th class="author">author</th>
+  <th class="description">description</th>
+ </tr>
+</thead>
+<tbody class="stripes2">
+{entries%filelogentry}
+</tbody>
+</table>
+
+<div class="navigate">
+<a href="{url|urlescape}log/{symrev}/{file|urlescape}{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}log/{symrev}/{file|urlescape}{morevars%urlparameter}">more</a>
+| {nav%filenav}
+</div>
+
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/filelogentry.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,9 @@
+ <tr>
+  <td class="age">{date|rfc822date}</td>
+  <td class="author">{author|person}</td>
+  <td class="description">
+   <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>
+   {alltags}{rename%filelogrename}
+  </td>
+ </tr>
+ {if(patch, '<tr><td colspan="3">{diff}</td></tr>')}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/filerevision.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,83 @@
+{header}
+<title>{repo|escape}: {node|short} {file|escape}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+<li class="active">file</li>
+<li><a href="{url|urlescape}file/tip/{file|urlescape}{sessionvars%urlparameter}">latest</a></li>
+<li><a href="{url|urlescape}diff/{symrev}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
+<li><a href="{url|urlescape}comparison/{symrev}/{file|urlescape}{sessionvars%urlparameter}">comparison</a></li>
+<li><a href="{url|urlescape}annotate/{symrev}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
+<li><a href="{url|urlescape}log/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file log</a></li>
+<li><a href="{url|urlescape}raw-file/{symrev}/{file|urlescape}">raw</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>
+ view {file|escape} @ {rev}:<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ {alltags}
+</h3>
+
+{searchform}
+
+<div class="description">{desc|strip|escape|websub|nonempty}</div>
+
+<table id="changesetEntry">
+<tr>
+ <th class="author">author</th>
+ <td class="author">{author|obfuscate}</td>
+</tr>
+<tr>
+ <th class="date">date</th>
+ <td class="date age">{date|rfc822date}</td>
+</tr>
+<tr>
+ <th class="author">parents</th>
+ <td class="author">{parent%filerevparent}</td>
+</tr>
+<tr>
+ <th class="author">children</th>
+ <td class="author">{child%filerevchild}</td>
+</tr>
+</table>
+
+<div class="overflow">
+<div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="#">on</a></div>
+<div class="sourcefirst"> line source</div>
+<pre class="sourcelines stripes4 wrap bottomline"
+     data-logurl="{url|urlescape}log/{symrev}/{file|urlescape}"
+     data-selectabletag="SPAN"
+     data-ishead="{ishead}">
+{text%fileline}
+</pre>
+</div>
+
+<script type="text/javascript" src="{staticurl|urlescape}followlines.js"></script>
+
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/footer.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,4 @@
+{motd}
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/graph.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,89 @@
+{header}
+<title>{repo|escape}: revision graph</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}: log" />
+<link rel="alternate" type="application/rss+xml"
+   href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}: log" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+<li class="active">graph</li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+{archives%archiveentry}
+</ul>
+<ul>
+ <li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+<div class="atom-logo">
+<a href="{url|urlescape}atom-log" title="subscribe to atom feed">
+<img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="atom feed" />
+</a>
+</div>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>graph</h3>
+
+{searchform}
+
+<div class="navigate">
+<a href="{url|urlescape}graph/{symrev}{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}graph/{symrev}{morevars%urlparameter}">more</a>
+| rev {rev}: {changenav%navgraph}
+</div>
+
+<noscript><p>The revision graph only works with JavaScript-enabled browsers.</p></noscript>
+
+<div id="wrapper">
+<canvas id="graph"></canvas>
+<ul id="graphnodes" class="stripes2">{nodes%graphentry}</ul>
+</div>
+
+<script type="text/javascript"{if(nonce, ' nonce="{nonce}"')}>
+var data = {jsdata|json};
+var graph = new Graph();
+graph.scale({bg_height});
+graph.render(data);
+</script>
+
+<div class="navigate">
+<a href="{url|urlescape}graph/{symrev}{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}graph/{symrev}{morevars%urlparameter}">more</a>
+| rev {rev}: {changenav%navgraph}
+</div>
+
+<script type="text/javascript"{if(nonce, ' nonce="{nonce}"')}>
+    ajaxScrollInit(
+            '{url|urlescape}graph/%next%{graphvars%urlparameter}',
+            '{nextentry%"{node}"}', <!-- NEXTHASH
+            function (htmlText) \{
+                var m = htmlText.match(/'(\w+)', <!-- NEXTHASH/);
+                return m ? m[1] : null;
+            },
+            '#wrapper',
+            '<div class="%class%" style="text-align: center;">%text%</div>',
+            'graph'
+    );
+</script>
+
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/graphentry.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,9 @@
+<li data-node="{node|short}">
+ <div class="fg">
+  <span class="desc">
+   <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>
+  </span>
+  {alltags}
+  <div class="info"><span class="age">{date|rfc822date}</span>, by {author|person}</div>
+ </div>
+</li>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/header.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,7 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+<head>
+<link rel="icon" href="{staticurl|urlescape}hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow" />
+<link rel="stylesheet" href="{staticurl|urlescape}style-paper.css" type="text/css" />
+<script type="text/javascript" src="{staticurl|urlescape}mercurial.js"></script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/help.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,34 @@
+{header}
+<title>Help: {topic}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+ <li class="active"><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>Help: {topic}</h3>
+{searchform}
+<div id="doc">
+{rstdoc(doc, "html")}
+</div>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/helptopics.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,48 @@
+{header}
+<title>Help: {title}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+{if(subindex,
+  '<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>',
+  '<li class="active">help</li>'
+)}
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+{searchform}
+<table class="bigtable">
+<tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
+{topics % helpentry}
+
+{if(earlycommands, '
+<tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
+{earlycommands % helpentry}
+')}
+
+{if(othercommands, '
+<tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
+{othercommands % helpentry}
+')}
+
+</table>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/index.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,31 @@
+{header}
+<title>Mercurial repositories index</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" width=75 height=90 border=0 alt="mercurial" /></a>
+</div>
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+
+<table class="bigtable">
+    <thead>
+    <tr>
+        <th><a href="?sort={sort_name}">Name</a></th>
+        <th><a href="?sort={sort_description}">Description</a></th>
+        <th><a href="?sort={sort_contact}">Contact</a></th>
+        <th><a href="?sort={sort_lastchange}">Last modified</a></th>
+        <th>&nbsp;</th>
+        <th>&nbsp;</th>
+    </tr>
+    </thead>
+    <tbody class="stripes2">
+    {entries%indexentry}
+    </tbody>
+</table>
+</div>
+</div>
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/manifest.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,56 @@
+{header}
+<title>{repo|escape}: {node|short} {path|escape}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog/{symrev}{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li class="active">browse</li>
+</ul>
+<ul>
+{archives%archiveentry}
+</ul>
+<ul>
+ <li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>
+ directory {path|escape} @ {rev}:<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+ {alltags}
+</h3>
+
+{searchform}
+
+<table class="bigtable">
+<thead>
+<tr>
+  <th class="name">name</th>
+  <th class="size">size</th>
+  <th class="permissions">permissions</th>
+</tr>
+</thead>
+<tbody class="stripes2">
+{ifeq(path, up, '', updirentry)}
+{dentries%direntry}
+{fentries%fileentry}
+</tbody>
+</table>
+</div>
+</div>
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/map	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,307 @@
+default = 'shortlog'
+
+mimetype = 'text/html; charset={encoding}'
+header = header.tmpl
+footer = footer.tmpl
+search = search.tmpl
+
+changelog = shortlog.tmpl
+shortlog = shortlog.tmpl
+shortlogentry = shortlogentry.tmpl
+graph = graph.tmpl
+graphentry = graphentry.tmpl
+help = help.tmpl
+helptopics = helptopics.tmpl
+
+helpentry = '
+  <tr><td>
+    <a href="{url|urlescape}help/{topic|escape}{sessionvars%urlparameter}">
+      {if(basename, '{basename|escape}', '{topic|escape}')}
+    </a>
+  </td><td>
+    {summary|escape}
+  </td></tr>'
+
+naventry = '<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navshortentry = '<a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+navgraphentry = '<a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
+filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
+filedifflink = '<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenodelink = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
+filenolink = '{file|escape} '
+fileellipses = '...'
+diffstatlink = diffstat.tmpl
+diffstatnolink = diffstat.tmpl
+changelogentry = shortlogentry.tmpl
+changeset = changeset.tmpl
+manifest = manifest.tmpl
+
+nav = '{before%naventry} {after%naventry}'
+navshort = '{before%navshortentry}{after%navshortentry}'
+navgraph = '{before%navgraphentry}{after%navgraphentry}'
+filenav = '{before%filenaventry}{after%filenaventry}'
+
+updirentry = '
+  <tr class="fileline">
+    <td class="name">
+      <a href="{url|urlescape}file/{symrev}{up|urlescape}{sessionvars%urlparameter}">[up]</a>
+    </td>
+    <td class="size"></td>
+    <td class="permissions">drwxr-xr-x</td>
+  </tr>'
+
+direntry = '
+  <tr class="fileline">
+    <td class="name">
+      <a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">
+        <img src="{staticurl|urlescape}coal-folder.png" alt="dir."/> {basename|escape}/
+      </a>
+      <a href="{url|urlescape}file/{symrev}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
+        {emptydirs|escape}
+      </a>
+    </td>
+    <td class="size"></td>
+    <td class="permissions">drwxr-xr-x</td>
+  </tr>'
+
+fileentry = '
+  <tr class="fileline">
+    <td class="filename">
+      <a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">
+        <img src="{staticurl|urlescape}coal-file.png" alt="file"/> {basename|escape}
+      </a>
+    </td>
+    <td class="size">{size}</td>
+    <td class="permissions">{permissions|permissions}</td>
+  </tr>'
+
+filerevision = filerevision.tmpl
+fileannotate = fileannotate.tmpl
+filediff = filediff.tmpl
+filecomparison = filecomparison.tmpl
+filelog = filelog.tmpl
+fileline = '
+  <span id="{lineid}">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
+filelogentry = filelogentry.tmpl
+
+annotateline = '
+  <tr id="{lineid}"{ifeq(node, originalnode, ' class="thisrev"')}>
+    <td class="annotate parity{blockparity}">
+      {if(blockhead,
+          '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
+             {rev}
+           </a>')}
+      <div class="annotate-info">
+        <div>
+          <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
+            {node|short}</a>
+          {desc|escape|firstline}
+        </div>
+        <div><em>{author|obfuscate}</em></div>
+        <div>parents: {parents%annotateparent}</div>
+        <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>
+        <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
+      </div>
+    </td>
+    <td class="source followlines-btn-parent"><a href="#{lineid}">{linenumber}</a> {line|escape}</td>
+  </tr>'
+annotateparent = '
+  <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rev}</a>'
+diffblock = '<div class="bottomline inc-lineno"><pre class="sourcelines wrap">{lines}</pre></div>'
+difflineplus = '
+  <span id="{lineid}" class="plusline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
+difflineminus = '
+  <span id="{lineid}" class="minusline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
+difflineat = '
+  <span id="{lineid}" class="atline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
+diffline = '
+  <span id="{lineid}">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
+
+comparisonblock ='
+  <tbody class="block">
+  {lines}
+  </tbody>'
+comparisonline = '
+  <tr id="{lineid}">
+    <td class="source {type}"><a href="#{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
+    <td class="source {type}"><a href="#{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
+  </tr>'
+
+changesetparent = '<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
+
+changesetparentdiff = '
+  {changesetparent}
+  {ifeq(node, basenode, '(current diff)', '({difffrom})')}'
+
+difffrom = '<a href="{url|urlescape}rev/{node|short}:{originalnode|short}{sessionvars%urlparameter}">diff</a>'
+
+filerevparent = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
+filerevchild = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
+
+filerename = '{file|escape}@'
+filelogrename = '
+  <span class="base">
+    base
+    <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+      {file|escape}@{node|short}
+    </a>
+  </span>'
+fileannotateparent = '
+  <tr>
+    <td class="metatag">parent:</td>
+    <td>
+      <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+        {rename%filerename}{node|short}
+      </a>
+    </td>
+  </tr>'
+changesetchild = ' <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
+fileannotatechild = '
+  <tr>
+    <td class="metatag">child:</td>
+    <td>
+      <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
+        {node|short}
+      </a>
+    </td>
+  </tr>'
+tags = tags.tmpl
+tagentry = '
+  <tr class="tagEntry">
+    <td>
+      <a href="{url|urlescape}rev/{tag|revescape}{sessionvars%urlparameter}">
+        {tag|escape}
+      </a>
+    </td>
+    <td class="node">
+      <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
+        {node|short}
+      </a>
+    </td>
+  </tr>'
+bookmarks = bookmarks.tmpl
+bookmarkentry = '
+  <tr class="tagEntry">
+    <td>
+      <a href="{url|urlescape}rev/{bookmark|revescape}{sessionvars%urlparameter}">
+        {bookmark|escape}
+      </a>
+    </td>
+    <td class="node">
+      <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
+        {node|short}
+      </a>
+    </td>
+  </tr>'
+topics = topics.tmpl
+topicentry = '
+  <tr class="tagEntry">
+    <td>
+      <a href="{url|urlescape}shortlog/{topic|revescape}{sessionvars%urlparameter}" class="{status}">
+        {fqbn|escape}
+      </a>
+    </td>
+    <td class="node">
+      <a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
+        {node|short}
+      </a>
+    </td>
+  </tr>'
+branches = branches.tmpl
+branchentry = '
+  <tr class="tagEntry">
+    <td>
+      <a href="{url|urlescape}shortlog/{branch|revescape}{sessionvars%urlparameter}" class="{status}">
+        {branch|escape}
+      </a>
+    </td>
+    <td class="node">
+      <a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
+        {node|short}
+      </a>
+    </td>
+  </tr>'
+phasetag = '{ifeq(phase, 'public', '', '<span class="phase">{phase|escape}</span> ')}'
+topictag = '{if(topic, '<span class="branchname">{topic|escape}</span> ')}'
+obsoletetag = '{if(obsolete, '<span class="obsolete">obsolete</span> ')}'
+instabilitytag = '<span class="instability">{instability|escape}</span> '
+changelogtag = '<span class="tag">{name|escape}</span> '
+changesettag = '<span class="tag">{tag|escape}</span> '
+changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
+changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
+changelogbranchname = '<span class="branchname">{name|escape}</span> '
+alltags = '{phasetag}{obsoletetag}{instabilities%instabilitytag}{inbranch%changelogbranchname}{branches%changelogbranchhead}{topictag}{tags%changelogtag}'
+
+successorlink = '<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
+obsfatesuccessors = '{if(successors, ' as ')}{successors%successorlink}'
+obsfateverb = '{obsfateverb(successors, markers)}'
+obsfateoperations = '{if(obsfateoperations(markers), ' using {join(obsfateoperations(markers), ', ')}')}'
+obsfateusers = '{if(obsfateusers(markers), ' by {join(obsfateusers(markers)%'{user|obfuscate}', ', ')}')}'
+obsfatedate = '{if(obsfatedate(markers), ' {ifeq(min(obsfatedate(markers)), max(obsfatedate(markers)), '<span class="age">{min(obsfatedate(markers))|rfc822date}</span>', 'between <span class="age">{min(obsfatedate(markers))|rfc822date}</span> and <span class="age">{max(obsfatedate(markers))|rfc822date}</span>')}')}'
+obsfateentry = '{obsfateverb}{obsfateoperations}{obsfatesuccessors}{obsfateusers}{obsfatedate}'
+instabilitychangesetlink = '<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
+divergentnode = '{instabilitychangesetlink} ({phase})'
+whyunstableentry = '{instability}: {if(divergentnodes, divergentnodes%divergentnode)} {reason} {instabilitychangesetlink}'
+
+filediffparent = '
+  <tr>
+    <th class="parent">parent {rev}:</th>
+    <td class="parent"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
+  </tr>'
+filediffchild = '
+  <tr>
+    <th class="child">child {rev}:</th>
+    <td class="child"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
+  </td>
+  </tr>'
+
+indexentry = '
+  <tr>
+    <td><a href="{url|urlescape}{sessionvars%urlparameter}">{name|escape}</a></td>
+    <td>{description}</td>
+    <td>{contact|obfuscate}</td>
+    <td class="age">{lastchange|rfc822date}</td>
+    <td class="indexlinks">{archives%indexarchiveentry}</td>
+    <td>
+        {if(isdirectory, '',
+            '<a href="{url|urlescape}atom-log" title="subscribe to repository atom feed">
+                <img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="subscribe to repository atom feed">
+            </a>'
+            )}
+    </td>
+  </tr>\n'
+indexarchiveentry = '<a href="{url|urlescape}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
+index = index.tmpl
+archiveentry = '
+  <li>
+    <a href="{url|urlescape}archive/{symrev}{extension|urlescape}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a>
+  </li>'
+notfound = notfound.tmpl
+error = error.tmpl
+urlparameter = '{separator}{name}={value|urlescape}'
+hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
+breadcrumb = '&gt; <a href="{url|urlescape}">{name|escape}</a> '
+
+searchform = '
+  <form class="search" action="{url|urlescape}log">
+    {sessionvars%hiddenformentry}
+    <p><input name="rev" id="search1" type="text" size="30" value="{query|escape}" /></p>
+    <div id="hint">{searchhint}</div>
+  </form>'
+searchhint = 'Find changesets by keywords (author, files, the commit message), revision
+  number or hash, or <a href="{url|urlescape}help/revsets">revset expression</a>.'
+
+diffoptsform = '
+  <form id="diffopts-form"
+    data-ignorews="{if(get(diffopts, 'ignorews'), '1', '0')}"
+    data-ignorewsamount="{if(get(diffopts, 'ignorewsamount'), '1', '0')}"
+    data-ignorewseol="{if(get(diffopts, 'ignorewseol'), '1', '0')}"
+    data-ignoreblanklines="{if(get(diffopts, 'ignoreblanklines'), '1', '0')}">
+    <span>Ignore whitespace changes - </span>
+    <span>Everywhere:</span>
+    <input id="ignorews-checkbox" type="checkbox" />
+    <span>Within whitespace:</span>
+    <input id="ignorewsamount-checkbox" type="checkbox" />
+    <span>At end of lines:</span>
+    <input id="ignorewseol-checkbox" type="checkbox" />
+  </form>'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/notfound.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,12 @@
+{header}
+<title>Mercurial repository not found</title>
+</head>
+<body>
+
+<h2>Mercurial repository not found</h2>
+
+The specified repository "{repo|escape}" is unknown, sorry.
+
+Please go back to the <a href="{url|urlescape}">main repository list page</a>.
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/search.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,64 @@
+{header}
+<title>{repo|escape}: searching for {query|escape}</title>
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" width=75 height=90 border=0 alt="mercurial"></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>searching for '{query|escape}'</h3>
+
+<p>
+Assuming {modedesc}.
+{if(showforcekw, '<a href="{url|urlescape}log?rev={query|urlescape}&forcekw=1">
+Use {showforcekw}</a> instead.')}
+{if(showunforcekw, '<a href="{url|urlescape}log?rev={query|urlescape}">
+Use {showunforcekw}</a> instead.')}
+</p>
+
+{searchform}
+
+<div class="navigate">
+<a href="{url|urlescape}log{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}log{morevars%urlparameter}">more</a>
+</div>
+
+<table class="bigtable">
+<thead>
+ <tr>
+  <th class="age">age</th>
+  <th class="author">author</th>
+  <th class="description">description</th>
+ </tr>
+</thead>
+<tbody class="stripes2">
+{entries%changelogentry}
+</tbody>
+</table>
+
+<div class="navigate">
+<a href="{url|urlescape}log{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}log{morevars%urlparameter}">more</a>
+</div>
+
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/shortlog.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,89 @@
+{header}
+<title>{repo|escape}: log</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url|urlescape}atom-log" title="Atom feed for {repo|escape}" />
+<link rel="alternate" type="application/rss+xml"
+   href="{url|urlescape}rss-log" title="RSS feed for {repo|escape}" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li class="active">log</li>
+<li><a href="{url|urlescape}graph/{symrev}{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}rev/{symrev}{sessionvars%urlparameter}">changeset</a></li>
+<li><a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
+</ul>
+<ul>
+{archives%archiveentry}
+</ul>
+<ul>
+ <li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+<div class="atom-logo">
+<a href="{url|urlescape}atom-log" title="subscribe to atom feed">
+<img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="atom feed" />
+</a>
+</div>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>log</h3>
+
+{searchform}
+
+<div class="navigate">
+<a href="{url|urlescape}shortlog/{symrev}{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}shortlog/{symrev}{morevars%urlparameter}">more</a>
+| rev {rev}: {changenav%navshort}
+</div>
+
+<table class="bigtable">
+<thead>
+ <tr>
+  <th class="age">age</th>
+  <th class="author">author</th>
+  <th class="description">description</th>
+ </tr>
+</thead>
+<tbody class="stripes2">
+{entries%shortlogentry}
+</tbody>
+</table>
+
+<div class="navigate">
+<a href="{url|urlescape}shortlog/{symrev}{lessvars%urlparameter}">less</a>
+<a href="{url|urlescape}shortlog/{symrev}{morevars%urlparameter}">more</a>
+| rev {rev}: {changenav%navshort}
+</div>
+
+<script type="text/javascript"{if(nonce, ' nonce="{nonce}"')}>
+    ajaxScrollInit(
+            '{url|urlescape}shortlog/%next%{sessionvars%urlparameter}',
+            '{nextentry%"{node}"}', <!-- NEXTHASH
+            function (htmlText) \{
+                var m = htmlText.match(/'(\w+)', <!-- NEXTHASH/);
+                return m ? m[1] : null;
+            },
+            '.bigtable > tbody',
+            '<tr class="%class%">\\
+            <td colspan="3" style="text-align: center;">%text%</td>\\
+            </tr>'
+    );
+</script>
+
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/shortlogentry.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,8 @@
+ <tr>
+  <td class="age">{date|rfc822date}</td>
+  <td class="author">{author|person}</td>
+  <td class="description">
+   <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{desc|strip|firstline|escape|nonempty}</a>
+   {alltags}
+  </td>
+ </tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/tags.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,53 @@
+{header}
+<title>{repo|escape}: tags</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url|urlescape}atom-tags" title="Atom feed for {repo|escape}: tags" />
+<link rel="alternate" type="application/rss+xml"
+   href="{url|urlescape}rss-tags" title="RSS feed for {repo|escape}: tags" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li class="active">tags</li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li><a href="{url|urlescape}topics{sessionvars%urlparameter}">topics</a></li>
+</ul>
+<ul>
+<li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+<div class="atom-logo">
+<a href="{url|urlescape}atom-tags" title="subscribe to atom feed">
+<img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="atom feed" />
+</a>
+</div>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>tags</h3>
+
+{searchform}
+
+<table class="bigtable">
+<thead>
+<tr>
+ <th>tag</th>
+ <th>node</th>
+</tr>
+</thead>
+<tbody class="stripes2">
+{entries%tagentry}
+</tbody>
+</table>
+</div>
+</div>
+
+{footer}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/paper-extended/topics.tmpl	Fri May 30 18:01:26 2025 +0200
@@ -0,0 +1,54 @@
+{header}
+<title>{repo|escape}: topics</title>
+<link rel="alternate" type="application/atom+xml"
+   href="{url|urlescape}atom-topics" title="Atom feed for {repo|escape}: topics" />
+<link rel="alternate" type="application/rss+xml"
+   href="{url|urlescape}rss-topics" title="RSS feed for {repo|escape}: topics" />
+</head>
+<body>
+
+<div class="container">
+<div class="menu">
+<div class="logo">
+<a href="{logourl}">
+<img src="{staticurl|urlescape}{logoimg}" alt="mercurial" /></a>
+</div>
+<ul>
+<li><a href="{url|urlescape}shortlog{sessionvars%urlparameter}">log</a></li>
+<li><a href="{url|urlescape}graph{sessionvars%urlparameter}">graph</a></li>
+<li><a href="{url|urlescape}tags{sessionvars%urlparameter}">tags</a></li>
+<li><a href="{url|urlescape}branches{sessionvars%urlparameter}">branches</a></li>
+<li class="active">topics</li>
+</ul>
+<ul>
+ <li><a href="{url|urlescape}help{sessionvars%urlparameter}">help</a></li>
+</ul>
+<div class="atom-logo">
+<a href="{url|urlescape}atom-topics" title="subscribe to atom feed">
+<img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="atom feed" />
+</a>
+</div>
+</div>
+
+<div class="main">
+<h2 class="breadcrumb"><a href="/">Mercurial</a> {pathdef%breadcrumb}</h2>
+<h3>topics</h3>
+
+{searchform}
+
+<table class="bigtable">
+<thead>
+<tr>
+ <th>topic</th>
+ <th>node</th>
+</tr>
+</thead>
+<tbody class="stripes2">
+{entries % topicentry}
+</tbody>
+</table>
+</div>
+</div>
+
+{footer}
+