More bs5 templates

- Legacy-Id: 19715
This commit is contained in:
Lars Eggert 2021-11-30 14:42:13 +00:00
parent c65f68130a
commit 9a21fca6c1
48 changed files with 1617 additions and 1321 deletions

View file

@ -48,4 +48,4 @@ def email_person_link(email, **kwargs):
name = email.person.name if email.person.alias_set.filter(name=email.person.name).exists() else ''
plain_name = email.person.plain_name()
email = email.address
return {'name': name, 'plain_name': plain_name, 'email': email, 'title': title, 'class': cls}
return {'name': name, 'plain_name': plain_name, 'email': email, 'title': title, 'class': cls}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

1
ietf/static/js/flot.js Normal file
View file

@ -0,0 +1 @@
import "~/node_modules/flot";

View file

@ -0,0 +1 @@
import "~/node_modules/highcharts/modules/export-data";

View file

@ -43,7 +43,6 @@ jQuery.ajaxSetup({
$(document)
.ready(function () {
$('[title][title!=""]')
.not("th")
.attr("data-bs-toggle", "tooltip")
.tooltip();
});
@ -128,7 +127,7 @@ $(document)
.attr("data-bs-offset", 0)
.attr("tabindex", 0)
.after($(`
<div class="col-md-2 small">
<div class="col-xl-2 small">
<nav id="righthand-nav" class="position-fixed navbar navbar-light bg-light overflow-auto" style="height: 70vh;">
<!--<a class="navbar-brand" href="#">Navbar</a>-->
</nav>

View file

@ -39,7 +39,14 @@ $(document)
$(header_row)
.children("[data-sort]")
.addClass("sort");
.addClass("sort")
.each((i, e) => {
if (fields[i] == "date" || fields[i] == "num") {
// magic
$(e)
.addClass("text-end");
}
});
if ($(header_row)
.text()
@ -77,15 +84,15 @@ $(document)
var list_instance = [];
var internal_table = [];
var pagination = $(table)
.children("tbody")
.length == 1;
// var pagination = $(table)
// .children("tbody")
// .length == 1;
// list.js cannot deal with tables with multiple tbodys,
// so maintain separate internal "tables" for
// sorting/searching and update the DOM based on them
$(table)
.children("tbody")
.children("tbody, tfoot")
.addClass("list")
.each(function () {
// add the required classes to the cells
@ -97,7 +104,7 @@ $(document)
.each((i, e) => {
$(e)
.addClass(fields[i]);
if (fields[i] == "date") {
if (fields[i] == "date" || fields[i] == "num") {
// magic
$(e)
.addClass("text-end");
@ -113,6 +120,13 @@ $(document)
var tbody = $(this)
.clone();
if ($(tbody)
.find("tr")
.length == 0) {
console.log("Skipping empty tbody");
return;
}
var parent = $(table)
.clone()
.empty()

View file

@ -0,0 +1,9 @@
$(document)
.ready(function () {
if (window.timeSeriesData && window.timeSeriesOptions) {
var placeholder = $(".stats-time-graph");
placeholder.height(Math.round(placeholder.width() * 1 / 3));
$.plot(placeholder, window.timeSeriesData, window.timeSeriesOptions);
}
});

View file

@ -1,11 +1,12 @@
{# bs5ok #}
{# Copyright The IETF Trust 2007, All Rights Reserved #}
{% extends "base.html" %}
{% load static %}
{% block title %}API Notes{% endblock %}
{% block content %}
<h2>Datatracker API Notes</h2>
<h1>Datatracker API Notes</h1>
<div class="bio-text">
<h3 id="framework" class="anchor-target">Framework API</h3>
<h2 id="framework" class="anchor-target">Framework API</h2>
<p>
This section describes the autogenerated read-only API towards the database tables. See also
the
@ -19,56 +20,62 @@
to generate an API which mirrors the Django ORM (Object Relational Mapping)
for the database. Each Django model class maps down to the SQL database
tables and up to the API. The Django models classes are defined in the
models.py files of the datatracker:
</p>
<p>
<a href="http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/doc/models.py">
https://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/doc/models.py
</a>
<br>
<a href="http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/group/models.py">
https://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/group/models.py
</a>
<br>
<a href="http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/iesg/models.py">
http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/iesg/models.py
</a>
<br>
&hellip;
<code>models.py</code> files of the datatracker:
</p>
<ul>
<li>
<a href="http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/doc/models.py">
https://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/doc/models.py
</a>
</li>
<li>
<a href="http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/group/models.py">
https://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/group/models.py
</a>
</li>
<li>
<a href="http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/iesg/models.py">
http://svn.ietf.org/svn/tools/ietfdb/trunk/ietf/iesg/models.py
</a>
</li>
<li>&hellip;</li>
</ul>
<p>
The API top endpoint is at
<a href="https://datatracker.ietf.org/api/v1/">https://datatracker.ietf.org/api/v1/</a>
. The top
endpoint lists inferior endpoints, and thus permits some autodiscovery,
but there's really no substitute for looking at the actual ORM model classes.
Comparing a class in models.py with the equivalent endpoint may give
some clue (note that in the case of Group, it's a subclass of GroupInfo):
</p>
<p>
<a href="https://datatracker.ietf.org/api/v1/group/group/">https://datatracker.ietf.org/api/v1/group/group/</a>
<br>
<a href="https://trac.ietf.org/trac/ietfdb/browser/trunk/ietf/group/models.py">
https://trac.ietf.org/trac/ietfdb/browser/trunk/ietf/group/models.py
</a>
Comparing a class in <code>models.py</code> with the equivalent endpoint may give
some clue (note that in the case of Group, it's a subclass of <code>GroupInfo</code>):
</p>
<ul>
<li>
<a href="https://datatracker.ietf.org/api/v1/group/group/">https://datatracker.ietf.org/api/v1/group/group/</a>
</li>
<li>
<a href="https://trac.ietf.org/trac/ietfdb/browser/trunk/ietf/group/models.py">
https://trac.ietf.org/trac/ietfdb/browser/trunk/ietf/group/models.py
</a>
</li>
</ul>
<p>
Data is currently provided in JSON and XML format. Adding new formats is
fairly easy, if it should be found desriable.
fairly easy, if it should be found desirable.
</p>
<h4 id="framework-documents" class="anchor-target">Framework API: Documents</h4>
<h3 id="framework-documents" class="anchor-target">Framework API: Documents</h3>
<p>
Documents are listed at
<a href="https://datatracker.ietf.org/api/v1/doc/document/">/api/v1/doc/document/</a>
.
</p>
<p>
In general, individual database objects are represented in the api with a path
In general, individual database objects are represented in the API with a path
composed of the model collection, the object name, and the object key. Most
objects have simple numerical keys, but documents have the document name as
key. Take draft-ietf-eppext-keyrelay. Documents have a model 'Document' which
is described in the 'doc' models.py file. Assembling the path components
'doc', 'document' (lowercase!) and 'draft-ietf-eppext-keyrelay', we get the
key. Take <code>draft-ietf-eppext-keyrelay</code>. Documents have a model <code>Document</code> which
is described in the <code>doc</code> <code>models.py</code> file. Assembling the path components
<code>doc</code>, <code>document</code> (lowercase!) and <code>draft-ietf-eppext-keyrelay</code>, we get the
URL:
</p>
<p>
@ -92,58 +99,56 @@
</p>
<ul>
<li>
If a document has an rfc-editor state, you can select for it by asking for e.g.
If a document has an rfc-editor state, you can select for it by asking for, e.g.,
<a href="https://datatracker.ietf.org/api/v1/doc/document/?limit=0&name__contains=-v6ops-&states__type__slug__in=draft-rfceditor">
v6ops documents which match 'states__type__slug__in=draft-rfceditor'
v6ops documents which match <code>states__type__slug__in=draft-rfceditor</code>
</a>
</li>
<li>
If a document has an IESG state, you can select for it by asking for e.g.
If a document has an IESG state, you can select for it by asking for, e.g.,
<a href="https://datatracker.ietf.org/api/v1/doc/document/?name__contains=-v6ops&states__type__slug__in=draft-iesg">
v6ops documents which match 'states__type__slug__in=draft-iesg'
v6ops documents which match <code>states__type__slug__in=draft-iesg</code>
</a>
</li>
<li>
If a document has a WG state, you can select for it by asking for
documents which match 'states__type__slug__in=draft-stream-ietf'
documents which match <code>states__type__slug__in=draft-stream-ietf</code>
(but without additional filters, that's going to be a lot of documents)
</li>
<li>
States which match 'states__type__slug__in=draft' describe the basic
States which match <code>states__type__slug__in=draft</code> describe the basic
Active/Expired/Dead whatever state of the draft.
</li>
</ul>
<p>
You could use this in at least two alternative ways:
</p>
<p>
You could either fetch and remember the different state groups of interest to you
with queries like
</p>
<pre class="text-wrap">
$ curl 'https://datatracker.ietf.org/api/v1/doc/state/?format=json&limit=0&type__slug__in=draft-rfceditor'
$ curl 'https://datatracker.ietf.org/api/v1/doc/state/?format=json&limit=0&type__slug__in=draft-iesg'
$ curl 'https://datatracker.ietf.org/api/v1/doc/state/?format=json&limit=0&type__slug__in=draft-stream-ietf'
</pre>
<p>
and then match the listed "resource_uri" of the results to the states listed for each
document when you ask for
</p>
<pre class="text-wrap">
$ curl 'https://datatracker.ietf.org/api/v1/doc/document/?limit=0&name__contains=-v6ops-'
</pre>
<p>
Or alternatively you could do a series of queries asking for matches to the RFC Editor
state first, then the IESG state, then the Stream state, and exclude earlier hits:
</p>
<pre class="text-wrap">
$ curl 'https://datatracker.ietf.org/api/v1/doc/document/?limit=0&name__contains=-v6ops-&states__type__slug__in=draft-rfceditor' ...
$ curl 'https://datatracker.ietf.org/api/v1/doc/document/?limit=0&name__contains=-v6ops-&states__type__slug__in=draft-iesg' ...
</pre>
<p>
etc.
</p>
<h3 id="simplified-documents" class="anchor-target">Simplified documents API</h3>
<ol>
<li>
You could either fetch and remember the different state groups of interest to you
with queries like
<pre>
$ curl 'https://datatracker.ietf.org/api/v1/doc/state/?format=json&limit=0&type__slug__in=draft-rfceditor'
$ curl 'https://datatracker.ietf.org/api/v1/doc/state/?format=json&limit=0&type__slug__in=draft-iesg'
$ curl 'https://datatracker.ietf.org/api/v1/doc/state/?format=json&limit=0&type__slug__in=draft-stream-ietf'
</pre>
and then match the listed "resource_uri" of the results to the states listed for each
document when you ask for
<pre>
$ curl 'https://datatracker.ietf.org/api/v1/doc/document/?limit=0&name__contains=-v6ops-'
</pre>
</li>
<li>
Or alternatively you could do a series of queries asking for matches to the RFC Editor
state first, then the IESG state, then the Stream state, and exclude earlier hits:
<pre>
$ curl 'https://datatracker.ietf.org/api/v1/doc/document/?limit=0&name__contains=-v6ops-&states__type__slug__in=draft-rfceditor' ...
$ curl 'https://datatracker.ietf.org/api/v1/doc/document/?limit=0&name__contains=-v6ops-&states__type__slug__in=draft-iesg' ...
</pre>
etc.
</li>
</ol>
<h2 id="simplified-documents" class="anchor-target">Simplified Documents API</h2>
<p>
A simplified Documents API, intended for cases where only a limited set of
document attributes are necessary for an application is
@ -163,179 +168,174 @@
<p>
The simplified document API takes no parameters, and is invoked with a HTTP GET.
</p>
<h3 id="iesg-position-api" class="anchor-target">IESG ballot position API</h3>
<h2 id="iesg-position-api" class="anchor-target">IESG Ballot Position API</h2>
<p>
A simplified IESG ballot position interface, intended for automation, is
available at <code>{% url 'ietf.doc.views_ballot.api_set_position' %}
</code>. Access is limited to area directors.
</p>
<p>
The interface requires the use of a personal API key, which can be created at
<a href="{% url 'ietf.ietfauth.views.apikey_index' %}">{% url 'ietf.ietfauth.views.apikey_index' %}</a>
</p>
<p>
The ballot position API takes the following parameters:
</p>
<ul>
<li>
<code>apikey</code> (required) which is the personal API key hash
</li>
<li>
<code>doc</code> (required) which is the balloted document name
</li>
<li>
<code>position</code> (required) which is the position slug, one of:
<span class="samp">yes, noobj, block, discuss, abstain, recuse, norecord</span>
.
</li>
<li>
<code>discuss</code> (required if position is 'discuss') which is the discuss text
</li>
<li>
<code>comment</code> (optional) which is comment text
</li>
</ul>
<p>
It returns an appropriate http result code, and a brief explanatory text message.
</p>
<p>
Here is an example:
</p>
<pre class="text-wrap">
$ curl -S -F "apikey=AwAAABVR3D5GHkVMhspKSxBCVknGMmqikNIhT85kSnghjaV_pYy26WV92mm-jpdi" -F "doc=draft-ietf-lamps-eai-addresses" -F "position=noobj" -F "comment=Comment text" https://datatracker.ietf.org/api/iesg/position
available at <code>{% url 'ietf.doc.views_ballot.api_set_position' %}</code>. Access is limited to area directors.
</p>
<p>
The interface requires the use of a personal API key, which can be created at
<a href="{% url 'ietf.ietfauth.views.apikey_index' %}">{% url 'ietf.ietfauth.views.apikey_index' %}</a>
</p>
<p>
The ballot position API takes the following parameters:
</p>
<ul>
<li>
<code>apikey</code> (required) which is the personal API key hash
</li>
<li>
<code>doc</code> (required) which is the balloted document name
</li>
<li>
<code>position</code> (required) which is the position slug, one of:
<code>yes</code>, <code>noobj</code>, <code>block</code>, <code>discuss</code>, <code>abstain</code>, <code>recuse</code>, <code>norecord</code>
.
</li>
<li>
<code>discuss</code> (required if position is <code>discuss</code>) which is the discuss text
</li>
<li>
<code>comment</code> (optional) which is comment text
</li>
</ul>
<p>
It returns an appropriate http result code, and a brief explanatory text message.
</p>
<p>
Here is an example:
</p>
<pre>
$ curl -S -F "apikey=AwAAABVR3D5GHkVMhspKSxBCVknGMmqikNIhT85kSnghjaV_pYy26WV92mm-jpdi" -F "doc=draft-ietf-lamps-eai-addresses" -F "position=noobj" -F "comment=Comment text" https://datatracker.ietf.org/api/iesg/position
Done
</pre>
<h3 id="session-video-url-api" class="anchor-target">Set session video URL</h3>
<p>
This interface is intended for Meetecho, to provide a way to set the
URL of a video recording for a given session. It is available at
<code>{% url 'ietf.meeting.views.api_set_session_video_url' %}</code>.
Access is limited to recording managers.
</p>
<p>
The interface requires the use of a personal API key, which can be created at
<a href="{% url 'ietf.ietfauth.views.apikey_index' %}">{% url 'ietf.ietfauth.views.apikey_index' %}</a>
</p>
<p>
The ballot position API takes the following parameters:
</p>
<ul>
<li>
<code>apikey</code> (required) which is the personal API key hash
</li>
<li>
<code>meeting</code> (required) which is the meeting number
</li>
<li>
<code>group</code> (required) which is the group acronym
</li>
<li>
<code>item</code> (required) which is the chronological sequence number of the session (1 for a group's first session, 2 for the second, etc.)
</li>
<li>
<code>url</code> (required) which is the url that points to the video recording
</li>
</ul>
<p>
It returns an appropriate http result code, and a brief explanatory text message.
</p>
<p>
Here is an example:
</p>
<pre class="text-wrap">
$ curl -S -F "apikey=DgAAAMLSi3coaE5TjrRs518xO8eBRlCmFF3eQcC8_SjUTtRGLGiJh7-1SYPT5WiS" -F "meeting=101" -F "group=mptcp" -F "item=1" -F "url=https://foo.example/beer/mptcp" https://datatracker.ietf.org/api/meeting/session/video/url
</pre>
<h2 id="session-video-url-api" class="anchor-target">Set Session Video URL</h2>
<p>
This interface is intended for Meetecho, to provide a way to set the
URL of a video recording for a given session. It is available at
<code>{% url 'ietf.meeting.views.api_set_session_video_url' %}</code>.
Access is limited to recording managers.
</p>
<p>
The interface requires the use of a personal API key, which can be created at
<a href="{% url 'ietf.ietfauth.views.apikey_index' %}">{% url 'ietf.ietfauth.views.apikey_index' %}</a>
</p>
<p>
The ballot position API takes the following parameters:
</p>
<ul>
<li>
<code>apikey</code> (required) which is the personal API key hash
</li>
<li>
<code>meeting</code> (required) which is the meeting number
</li>
<li>
<code>group</code> (required) which is the group acronym
</li>
<li>
<code>item</code> (required) which is the chronological sequence number of the session (1 for a group's first session, 2 for the second, etc.)
</li>
<li>
<code>url</code> (required) which is the url that points to the video recording
</li>
</ul>
<p>
It returns an appropriate http result code, and a brief explanatory text message.
</p>
<p>
Here is an example:
</p>
<pre>
$ curl -S -F "apikey=DgAAAMLSi3coaE5TjrRs518xO8eBRlCmFF3eQcC8_SjUTtRGLGiJh7-1SYPT5WiS" -F "meeting=101" -F "group=mptcp" -F "item=1" -F "url=https://foo.example/beer/mptcp" https://datatracker.ietf.org/api/meeting/session/video/url
Done
</pre>
<h3 id="openid-connect" class="anchor-target">OpenID Connect</h3>
<p>
The datatracker supports
<a href="https://openid.net/connect/">
OpenID Connect
</a>
, but
not dynamic registration. The OpenID Connect Issuer is
<code> {{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.api.urls.oidc_issuer' %} </code>
</p>
<h3 id="datatracker-version" class="anchor-target">
Datatracker Version
</h3>
<p>
The datatracker version and release/patch date is available as a JSON blob at
<code>
<a href="{% url 'ietf.api.views.version' %}">
{% url 'ietf.api.views.version' %}
</pre>
<h2 id="openid-connect" class="anchor-target">OpenID Connect</h2>
<p>
The datatracker supports
<a href="https://openid.net/connect/">OpenID Connect</a>
, but
not dynamic registration. The OpenID Connect Issuer is
<code> {{ settings.IDTRACKER_BASE_URL }}{% url 'ietf.api.urls.oidc_issuer' %} </code>
</p>
<h2 id="datatracker-version" class="anchor-target">Datatracker Version</h2>
<p>
The datatracker version and release/patch date is available as a JSON blob at
<code>
<a href="{% url 'ietf.api.views.version' %}">
{% url 'ietf.api.views.version' %}
</a>
</code>.
</p>
<h2 id="personal-api-keys" class="anchor-target">
Personal API Keys
</h2>
<p>
The datatracker has some API endpoints that uses Personal API keys,
rather than having general access or requiring username/password
login, see for example details for
<code>{% url 'ietf.doc.views_ballot.api_set_position' %}</code>
<a href="#iesg-position-api">
above
</a>
</code>.
</p>
<h3 id="personal-api-keys" class="anchor-target">
Personal API Keys
</h3>
<p>
The datatracker has some API endpoints that uses Personal API keys,
rather than having general access or requiring username/password
login, see for example details for
<code>{% url 'ietf.doc.views_ballot.api_set_position' %}</code>
<a href="#iesg-position-api">
above
</a>
.
Personal API keys are available from your
<a href="{% url 'ietf.ietfauth.views.apikey_index' %}">
Account API Keys
</a>
page when you are logged in.
</p>
<p>
Personal API keys have some characteristics you should be aware of:
</p>
<ul>
<li>
Each API key is valid only for a specific endpoint. If you try to use a key for
a different API endpoint than it's created for, it will not work.
</li>
<li>
The API keys will cause you to be given access with the datatracker
roles you have, thus giving you appropriate access to the various
API endpoints according to the role limitations indicated for each
endpoint.
</li>
<li>
An API key will only give you access to its related endpoint if you have logged
in to the datatracker using your regular login and password during the last
{{ settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS }} days. If you receive the
error message "<code>Too long since last regular login</code>" you should do
a regular login in order to activate access.
</li>
</ul>
<h3 id="signing-keys" class="anchor-target">
Signing Keys
</h3>
<p>
When sending notifications to other APIs, the datatracker may sign
information with a
<a href="https://datatracker.ietf.org/doc/html/rfc7515">
RFC
7515: JSON Web Signature (JWS)
</a>
, using a public/private keypair with
this public key:
</p>
<p>
<code>{{ key.export_public }}</code>
</p>
<p>
or alternatively:
</p>
<pre class="text-wrap">{{ key.export_to_pem }}</pre>
<p>
To verify a signature and get the verified data using Python with the
<a href="https://jwcrypto.readthedocs.io/en/latest/">
jwcrypto
</a>
module,
you could do:
</p>
<pre class="text-wrap">
.
Personal API keys are available from your
<a href="{% url 'ietf.ietfauth.views.apikey_index' %}">
Account API Keys
</a>
page when you are logged in.
</p>
<p>
Personal API keys have some characteristics you should be aware of:
</p>
<ul>
<li>
Each API key is valid only for a specific endpoint. If you try to use a key for
a different API endpoint than it's created for, it will not work.
</li>
<li>
The API keys will cause you to be given access with the datatracker
roles you have, thus giving you appropriate access to the various
API endpoints according to the role limitations indicated for each
endpoint.
</li>
<li>
An API key will only give you access to its related endpoint if you have logged
in to the datatracker using your regular login and password during the last
{{ settings.UTILS_APIKEY_GUI_LOGIN_LIMIT_DAYS }} days. If you receive the
error message "<code>Too long since last regular login</code>" you should do
a regular login in order to activate access.
</li>
</ul>
<h2 id="signing-keys" class="anchor-target">
Signing Keys
</h2>
<p>
When sending notifications to other APIs, the datatracker may sign
information with a
<a href="https://datatracker.ietf.org/doc/html/rfc7515">
RFC
7515: JSON Web Signature (JWS)
</a>
, using a public/private keypair with
this public key:
</p>
<p>
<code>{{ key.export_public }}</code>
</p>
<p>
or alternatively:
</p>
<pre>{{ key.export_to_pem }}</pre>
<p>
To verify a signature and get the verified data using Python with the
<a href="https://jwcrypto.readthedocs.io/en/latest/">
jwcrypto
</a>
module,
you could do:
</p>
<pre>
from jwcrypto import jwk, jws
# ... receive json web signed data as 'data', used below ...
@ -346,6 +346,6 @@ jwstoken = jws.JWS()
jwstoken.deserialize(data)
jwstoken.verify(key)
payload = jwstoken.payload
</pre>
</div>
</pre>
</div>
{% endblock %}

View file

@ -104,7 +104,7 @@
</ul>
</div>
{% endif %}
<div class="col mx-3" id="content">
<div class="col overflow-hidden mx-3" id="content">
{% for message in messages %}
<div class="alert
{% if message.level_tag %}

View file

@ -1,192 +1,314 @@
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% origin %}
{% load ietf_filters %}
<li class="nav-item dropdown">
{% if flavor == "top" %}
<a href="#" class="nav-link dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<a href="#"
class="nav-link dropdown-toggle"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
{% if user.is_authenticated %}
{{ user }}
{% else %}
User
{% endif %}
</a>
<ul class="dropdown-menu {% if flavor == 'top' %}mt-n1{% else %}ms-n1{% endif %}">
{% else %}
<span class="fw-bolder">User</span>
{% endif %}
{% if request.get_full_path == "/accounts/logout/" %}
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" rel="nofollow" href="/accounts/login{% if "/accounts/logout/" not in request.get_full_path %}/?next={{request.get_full_path|urlencode}}{% endif %}">
Sign in
</a>
</li>
{% else %}
{% if user.is_authenticated %}
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" rel="nofollow" href="/accounts/logout/">
Sign out
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" rel="nofollow" href="/accounts/profile/">
Account info
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="/person/{{user.person.name|urlencode}}">
Public profile page
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{%url "ietf.cookies.views.preferences" %}" rel="nofollow">
Preferences
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{%url "ietf.ietfauth.views.apikey_index" %}" rel="nofollow">
API keys
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" rel="nofollow" href="/accounts/password/">
Change password
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" rel="nofollow" href="/accounts/username/">
Change username
</a>
</li>
<ul class="dropdown-menu
{% if flavor == 'top' %}
mt-n1
{% else %}
ms-n1
{% endif %}">
{% else %}
<span class="fw-bolder">User</span>
{% endif %}
{% if request.get_full_path == "/accounts/logout/" %}
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" rel="nofollow" href="/accounts/login/?next={{request.get_full_path|urlencode}}">
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
rel="nofollow"
href="/accounts/login
{% if "/accounts/logout/" not in request.get_full_path %}
/?next={{ request.get_full_path|urlencode }}
{% endif %}">
Sign in
</a>
</li>
{% else %}
{% if user.is_authenticated %}
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
rel="nofollow"
href="/accounts/logout/">
Sign out
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
rel="nofollow"
href="/accounts/profile/">
Account info
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="/person/{{ user.person.name|urlencode }}">
Public profile page
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.cookies.views.preferences" %}"
rel="nofollow">
Preferences
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.ietfauth.views.apikey_index" %}"
rel="nofollow">
API keys
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
rel="nofollow"
href="/accounts/password/">
Change password
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
rel="nofollow"
href="/accounts/username/">
Change username
</a>
</li>
{% else %}
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
rel="nofollow"
href="/accounts/login/?next={{ request.get_full_path|urlencode }}">
Sign in
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
rel="nofollow"
href="/accounts/reset/">
Password reset
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.cookies.views.preferences" %}"
rel="nofollow">
Preferences
</a>
</li>
{% endif %}
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" rel="nofollow" href="/accounts/reset/">
Password reset
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{%url "ietf.cookies.views.preferences" %}" rel="nofollow">
Preferences
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url 'personal-information' %}">
Handling of personal information
</a>
</li>
{% endif %}
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url 'personal-information' %}">Handling of personal information
</a>
</li>
{% endif %}
{% if not request.user.is_authenticated %}
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.ietfauth.views.create_account" %}">
New account
</a>
</li>
{% endif %}
{% if user|has_role:"Reviewer" %}
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.ietfauth.views.review_overview" %}">
My reviews
</a>
</li>
{% endif %}
{% if user|has_role:"Area Director" %}
{% if flavor == "top" %}<li class="divider"></li>{% endif %}
<li {%if flavor == "top" %}class="dropdown-header"{% else %}class="nav-header"{% endif %}>
AD dashboard
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url 'ietf.doc.views_search.docs_for_ad' name=user.person.full_name_as_key %}">
My docs
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.iesg.views.agenda_documents" %}">
Next telechat
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.iesg.views.discusses" %}">
Discusses
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.iesg.views.milestones_needing_review" %}">
Milestone review
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.doc.views_search.drafts_in_last_call" %}">
Last Call docs
</a>
</li>
{% endif %}
{% if user|has_role:"Secretariat" %}
{% if flavor == "top" %}<li class="divider"></li>{% endif %}
<li {%if flavor == "top" %}class="dropdown-header"{% else %}class="nav-header"{% endif %}>
IETF secretariat
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="/admin/iesg/telechatdate/">
Telechat dates
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="/admin/iesg/telechatagendaitem/">
Management items
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.iesg.views.milestones_needing_review" %}">
Milestones
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.sync.views.discrepancies" %}">
Sync discrepancies
</a>
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.ietfauth.views.add_account_whitelist" %}">
Account whitelist
</a>
</li>
{% endif %}
{% if user|has_role:"IANA" %}
{% if flavor == "top" %}<li class="divider"></li>{% endif %}
<li {%if flavor == "top" %}class="dropdown-header"{% else %}class="nav-header"{% endif %}>
IANA
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.sync.views.discrepancies" %}">
Sync discrepancies
</a>
</li>
{% endif %}
{% if user|has_role:"RFC Editor" %}
{% if flavor == "top" %}<li class="divider"></li>{% endif %}
<li {%if flavor == "top" %}class="dropdown-header"{% else %}class="nav-header"{% endif %}>
RFC Editor
</li>
<li>
<a class="dropdown-item {% if flavor != 'top' %}text-wrap link-primary{% endif %}" href="{% url "ietf.sync.views.discrepancies" %}">
Sync discrepancies
</a>
</li>
{% endif %}
{% if flavor == "top" %}</ul>{% endif %}
</li>
{% if not request.user.is_authenticated %}
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.ietfauth.views.create_account" %}">
New account
</a>
</li>
{% endif %}
{% if user|has_role:"Reviewer" %}
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.ietfauth.views.review_overview" %}">
My reviews
</a>
</li>
{% endif %}
{% if user|has_role:"Area Director" %}
{% if flavor == "top" %}<li class="dropdown-divider"></li>{% endif %}
<li {% if flavor == "top" %}class="dropdown-header"{% else %}class="nav-item fw-bolder"{% endif %}>AD dashboard</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url 'ietf.doc.views_search.docs_for_ad' name=user.person.full_name_as_key %}">
My docs
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.iesg.views.agenda_documents" %}">
Next telechat
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.iesg.views.discusses" %}">
Discusses
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.iesg.views.milestones_needing_review" %}">
Milestone review
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.doc.views_search.drafts_in_last_call" %}">
Last Call docs
</a>
</li>
{% endif %}
{% if user|has_role:"Secretariat" %}
{% if flavor == "top" %}<li class="dropdown-divider"></li>{% endif %}
<li {% if flavor == "top" %}class="dropdown-header"{% else %}class="nav-item fw-bolder"{% endif %}>
IETF secretariat
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="/admin/iesg/telechatdate/">
Telechat dates
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="/admin/iesg/telechatagendaitem/">
Management items
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.iesg.views.milestones_needing_review" %}">
Milestones
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.sync.views.discrepancies" %}">
Sync discrepancies
</a>
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.ietfauth.views.add_account_whitelist" %}">
Account whitelist
</a>
</li>
{% endif %}
{% if user|has_role:"IANA" %}
{% if flavor == "top" %}
<li class="dropdown-divider">
</li>
{% endif %}
<li {% if flavor == "top" %}class="dropdown-header"{% else %}class="nav-item fw-bolder"{% endif %}>
IANA
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.sync.views.discrepancies" %}">
Sync discrepancies
</a>
</li>
{% endif %}
{% if user|has_role:"RFC Editor" %}
{% if flavor == "top" %}
<li class="dropdown-divider">
</li>
{% endif %}
<li {% if flavor == "top" %}class="dropdown-header"{% else %}class="nav-item fw-bolder"{% endif %}>
RFC Editor
</li>
<li>
<a class="dropdown-item
{% if flavor != 'top' %}
text-wrap link-primary
{% endif %}"
href="{% url "ietf.sync.views.discrepancies" %}">
Sync discrepancies
</a>
</li>
{% endif %}
{% if flavor == "top" %}</ul>{% endif %}
</li>

View file

@ -1,62 +1,152 @@
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% extends "base.html" %}
{% load origin %}
{% block title %}User settings{% endblock title %}
{% block title %}
User settings
{% endblock title %}
{% block content %}
{% origin %}
<h1>User settings</h1>
<p>
The following settings are implemented using cookies, so if you have
cookies disabled then you will not be able to change the settings
(everything still continues to work by using default settings).
</p>
<h3>How many days is considered "new"?</h3>
<p>This setting affects how many days are considered "new enough" to get the special highlighting in the documents table. The default setting is {{ defaults.new_enough }} days.</p>
<p class="btn-group d-flex">
<a class="btn btn-outline-primary {% if new_enough == '7' %}active{% endif %}" href="/accounts/settings/new_enough/7">7 days</a>
<a class="btn btn-outline-primary {% if new_enough == '14' %}active{% endif %}" href="/accounts/settings/new_enough/14">14 days</a>
<a class="btn btn-outline-primary {% if new_enough == '21' %}active{% endif %}" href="/accounts/settings/new_enough/21">21 days</a>
<a class="btn btn-outline-primary {% if new_enough == '30' %}active{% endif %}" href="/accounts/settings/new_enough/30">30 days</a>
<a class="btn btn-outline-primary {% if new_enough == '60' %}active{% endif %}" href="/accounts/settings/new_enough/60">60 days</a>
<a class="btn btn-outline-primary {% if new_enough == '90' %}active{% endif %}" href="/accounts/settings/new_enough/90">90 days</a>
<h2>How many days is considered "new"?</h2>
<p>
This setting affects how many days are considered "new enough" to get the special highlighting in the documents table. The default setting is {{ defaults.new_enough }} days.
</p>
<h3>How many days is considered "soon"?</h3>
<p>This setting tells what is considered "soon" when showing documents that are going to be expire soon. The Default setting is {{ defaults.expires_soon }} days.</p>
<p class="btn-group d-flex">
<a class="btn btn-outline-primary {% if expires_soon == '7' %}active{% endif %}" href="/accounts/settings/expires_soon/7">7 days</a>
<a class="btn btn-outline-primary {% if expires_soon == '14' %}active{% endif %}" href="/accounts/settings/expires_soon/14">14 days</a>
<a class="btn btn-outline-primary {% if expires_soon == '21' %}active{% endif %}" href="/accounts/settings/expires_soon/21">21 days</a>
<a class="btn btn-outline-primary {% if expires_soon == '30' %}active{% endif %}" href="/accounts/settings/expires_soon/30">30 days</a>
<a class="btn btn-outline-primary {% if expires_soon == '60' %}active{% endif %}" href="/accounts/settings/expires_soon/60">60 days</a>
<a class="btn btn-outline-primary {% if expires_soon == '90' %}active{% endif %}" href="/accounts/settings/expires_soon/90">90 days</a>
<a class="btn btn-outline-primary
{% if new_enough == '7' %}
active
{% endif %}"
href="/accounts/settings/new_enough/7">
7 days
</a>
<a class="btn btn-outline-primary
{% if new_enough == '14' %}
active
{% endif %}"
href="/accounts/settings/new_enough/14">
14 days
</a>
<a class="btn btn-outline-primary
{% if new_enough == '21' %}
active
{% endif %}"
href="/accounts/settings/new_enough/21">
21 days
</a>
<a class="btn btn-outline-primary
{% if new_enough == '30' %}
active
{% endif %}"
href="/accounts/settings/new_enough/30">
30 days
</a>
<a class="btn btn-outline-primary
{% if new_enough == '60' %}
active
{% endif %}"
href="/accounts/settings/new_enough/60">
60 days
</a>
<a class="btn btn-outline-primary
{% if new_enough == '90' %}
active
{% endif %}"
href="/accounts/settings/new_enough/90">
90 days
</a>
</p>
<h2>How many days is considered "soon"?</h2>
<p>
This setting tells what is considered "soon" when showing documents that are going to be expire soon. The Default setting is {{ defaults.expires_soon }} days.
</p>
<h3>Show full document text by default?</h3>
<p>Show the full text immediately on the document page instead of only showing beginning of it. This defaults to {{ defaults.full_draft }}.</p>
<p class="btn-group d-flex">
<a class="btn btn-outline-primary {% if full_draft == 'off' %}active{% endif %}" href="/accounts/settings/full_draft/off">Off</a>
<a class="btn btn-outline-primary {% if full_draft == 'on' %}active{% endif %}" href="/accounts/settings/full_draft/on">On</a>
<a class="btn btn-outline-primary
{% if expires_soon == '7' %}
active
{% endif %}"
href="/accounts/settings/expires_soon/7">
7 days
</a>
<a class="btn btn-outline-primary
{% if expires_soon == '14' %}
active
{% endif %}"
href="/accounts/settings/expires_soon/14">
14 days
</a>
<a class="btn btn-outline-primary
{% if expires_soon == '21' %}
active
{% endif %}"
href="/accounts/settings/expires_soon/21">
21 days
</a>
<a class="btn btn-outline-primary
{% if expires_soon == '30' %}
active
{% endif %}"
href="/accounts/settings/expires_soon/30">
30 days
</a>
<a class="btn btn-outline-primary
{% if expires_soon == '60' %}
active
{% endif %}"
href="/accounts/settings/expires_soon/60">
60 days
</a>
<a class="btn btn-outline-primary
{% if expires_soon == '90' %}
active
{% endif %}"
href="/accounts/settings/expires_soon/90">
90 days
</a>
</p>
<h2>Show full document text by default?</h2>
<p>
Show the full text immediately on the document page instead of only showing beginning of it. This defaults to {{ defaults.full_draft }}.
</p>
<h3>Show the left-hand menu?</h3>
<p>Show the left-hand menu on all regular pages? This defaults to {{ defaults.left_menu }}.</p>
<p class="btn-group d-flex">
<a class="btn btn-outline-primary {% if left_menu == 'off' %}active{% endif %}" href="/accounts/settings/left_menu/off">Off</a>
<a class="btn btn-outline-primary {% if left_menu == 'on' %}active{% endif %}" href="/accounts/settings/left_menu/on">On</a>
<a class="btn btn-outline-primary
{% if full_draft == 'off' %}
active
{% endif %}"
href="/accounts/settings/full_draft/off">
Off
</a>
<a class="btn btn-outline-primary
{% if full_draft == 'on' %}
active
{% endif %}"
href="/accounts/settings/full_draft/on">
On
</a>
</p>
{% endblock content %}
<h2>Show the left-hand menu?</h2>
<p>
Show the left-hand menu on all regular pages? This defaults to {{ defaults.left_menu }}.
</p>
<p class="btn-group d-flex">
<a class="btn btn-outline-primary
{% if left_menu == 'off' %}
active
{% endif %}"
href="/accounts/settings/left_menu/off">
Off
</a>
<a class="btn btn-outline-primary
{% if left_menu == 'on' %}
active
{% endif %}"
href="/accounts/settings/left_menu/on">
On
</a>
</p>
{% endblock content %}

View file

@ -1,9 +1,9 @@
{# bs5ok #}
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load static %}
{% load ietf_filters %}
{% block js %}
<script src="{% static 'ietf/js/highcharts-highstock.js' %}"></script>
<script src="{% static 'ietf/js/highcharts-exporting.js' %}"></script>
@ -22,14 +22,8 @@
});
</script>
{% endblock %}
{% block title %}
Document Statistics
{% endblock %}
{% block title %}Document Statistics{% endblock %}
{% block content %}
{% origin %}
<div id="chart" style="width:100%; height:400px; " class="panel card-body"></div>
<div id="chart"></div>
{% endblock %}

View file

@ -1,32 +1,31 @@
{# bs5ok #}
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% block title %}E-mail sending failed{% endblock %}
{% block content %}
{% origin %}
<h1>E-mail sending failed</h1>
<p class="alert alert-warning">
Sorry, the site needed to send an E-Mail message to complete this
action, and that attempt failed. Please reload this page later
to try again, or, if this condition persists, please send an
e-mail to <a href="mailto:webmaster@ietf.org">webmaster@ietf.org</a>.
e-mail to
<a href="mailto:webmaster@ietf.org">webmaster@ietf.org</a>
.
</p>
{% if debug %}
<hr>
<h3>Debug information, please forward when reporting this error:</h3>
<ul>
<li>Exception: {{ exception|escape }}</li>
<li>Detail: {{ args|escape }}</li>
<li>Traceback:
<li>
Traceback:
<pre>
{{ traceback|escape }}
</pre>
</li>
</ul>
{% endif %}
{% endblock %}
{% endblock %}

View file

@ -1,36 +1,25 @@
{# bs5ok #}
{% extends "base.html" %}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load static %}
{% load django_bootstrap5 %}
{% block title %}{{ title|striptags }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" href="{% static 'ietf/css/datepicker.css' %}">
{% endblock %}
{% block content %}
{% origin %}
<h1>{{ title|safe }}</h1>
<p>
{{ description|safe }}
</p>
<form method="post" class="show-required">
{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" name="{{button|slugify}}" class="btn btn-primary">{{ button }}</button>
{% bootstrap_form form layout='horizontal' %}
<button type="submit" name="{{ button|slugify }}" class="btn btn-primary">{{ button }}</button>
</form>
{% endblock %}
{% block js %}
<script src="{% static 'ietf/js/datepicker.js' %}"></script>
{% endblock %}
{% endblock %}

View file

@ -1,19 +1,18 @@
{# Copyright The IETF Trust 2018-2018, All Rights Reserved #}
{% extends "base.html" %}
{# bs5ok #}
{% load origin %}
{% block title %}Personal Information in the Datatracker{% endblock title %}
{% block title %}
Personal Information in the Datatracker
{% endblock title %}
{% block content %}
{% origin %}
<h1>Personal Information in the Datatracker</h1>
<p>
<a href="https://datatracker.ietf.org/doc/html/rfc3935">RFC 3935, "A Mission Statement for the IETF"</a> lays out
<a href="https://datatracker.ietf.org/doc/html/rfc3935">RFC 3935, "A Mission Statement for the IETF"</a>
lays out
the goal and the mission of the IETF as follows
</p>
<pre>
The goal of the IETF is to make the Internet work better.
@ -22,31 +21,30 @@
design, use, and manage the Internet in such a way as to make the
Internet work better. These documents include protocol standards,
best current practices, and informational documents of various kinds.
</pre>
</pre>
{% comment %}
The following text has been reviewed by legal counsel (Thomas Zych)
on Thu, 26 Apr 2018 17:24:03 -0400
*** DO NOT CHANGE WITHOUT LEGAL REVIEW ***
{% endcomment %}
{% endcomment %}
<p>
In order to fulfil its mission, the IETF provides various ways to distribute
In order to fulfill its mission, the IETF provides various ways to distribute
and discuss Internet-Drafts, and otherwise process them until there is
consensus that they are ready for publication.
</p>
<p>
This makes the information in the content of the draft documents, as well
as contributions related to the draft documents and their processing as
laid out in the "<a href="https://www.ietf.org/about/note-well/">Note
Well</a>" statement, of legitimate interest to the IETF when it pursues
laid out in the
<a href="https://www.ietf.org/about/note-well/">"Note Well"</a>
statement, of legitimate interest to the IETF when it pursues
its mission; not only in general terms, but specifically under Article
6(1)&nbsp;f) of
<a href="https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679#d1e1888-1-1">
EU's General Data Protection Regulation </a>.
EU's General Data Protection Regulation
</a>
.
</p>
<p>
The datatracker treats all personal information derived from draft documents and
documents published as RFC, as well as personal information derived from
@ -56,7 +54,6 @@
contact information for IETF roles such as Working Group chairs, secretaries,
Area Directors and other roles.
</p>
<p>
There is however additional personal information held in the datatracker that
is used for other purposes. This information requires the consent of the
@ -64,28 +61,27 @@
through various means, and the person it relates to may at any time request
its correction or removal. This includes:
</p>
<ul>
<li>Personal photograph or other likeness;</li>
<li>Personal biography;</li>
<li>Personal email addresses not derived from IETF contributions; and </li>
<li>Personal email addresses not derived from IETF contributions; and</li>
<li>Personal account login information</li>
<li>Personal notification subscriptions</li>
</ul>
<p>
Most of this information can be edited on the individual's
<a href="/accounts/profile/">Account Info</a> page by the individual
<a href="/accounts/profile/">Account Info</a>
page by the individual
after logging in to the account. If the datatracker holds such
information about a person, and they don't have an account, a request to
the <a href="mailto:{{ settings.SECRETARIAT_ACTION_EMAIL }}">IETF secretariat</a> to change
the
<a href="mailto:{{ settings.SECRETARIAT_ACTION_EMAIL }}">IETF secretariat</a>
to change
or remove the information will be honoured to the extent feasible and
legally permitted.
</p>
<p>
Please also see the IETF's overall
<a href="https://www.ietf.org/privacy-statement/">Statement concerning personal data</a>
<a href="https://www.ietf.org/privacy-statement/">Statement concerning personal data.</a>
</p>
{% endblock content %}

View file

@ -1,48 +1,44 @@
{% extends "base.html" %}
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin static %}
{% block pagehead %}
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
{% endblock %}
{% block title %} Document state index{% endblock %}
{% block title %}Document state index{% endblock %}
{% block content %}
{% origin %}
<h1>Document state index</h1>
<p>Document state information is available for the following document and document state groups:</p>
<p>
Document state information is available for the following document and document state groups.
</p>
<table class="table table-sm table-striped tablesorter">
<thead>
<tr>
<th>Document</th>
<th>State groups</th>
<th data-sort="document">Document</th>
<th data-sort="state">State groups</th>
</tr>
</thead>
<tbody>
{% for type in types %}
{% if type.stategroups != None %}
<tr>
<td><a href="{% url 'ietf.help.views.state' doc=type.slug %}">{{type.slug}}</a></td>
<td>
<a href="{% url 'ietf.help.views.state' doc=type.slug %}">{{ type.slug }}</a>
</td>
<td>
{% for group in type.stategroups %}
<a href="{% url 'ietf.help.views.state' doc=type.slug type=group %}">{{ group }}</a>{% if not forloop.last %}, {% endif %}
{# djlint:off #}
<a href="{% url 'ietf.help.views.state' doc=type.slug type=group %}">{{ group }}</a>{% if not forloop.last %},{% endif %}
{# djlint:on #}
{% endfor %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block js %}
<script src="{% static "ietf/js/list.js" %}"></script>
{% endblock %}
{% endblock %}

View file

@ -1,18 +1,14 @@
{% extends "base.html" %}
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin static %}
{% block pagehead %}
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
{% endblock %}
{% block title %} {{type.label|cut:"state"|cut:"state"}} states{% endblock %}
{% block title %}{{ type.label|cut:"state"|cut:"state" }} states{% endblock %}
{% block content %}
{% origin %}
<h1>{{type.label|cut:"state"|cut:"State"}} states</h1>
<h1>{{ type.label|cut:"state"|cut:"State" }} states</h1>
<table class="table table-sm table-striped tablesorter">
<thead>
<tr>
@ -21,20 +17,23 @@
<th data-sort="next">Next states</th>
</tr>
</thead>
<tbody>
{% for state in states %}
<tr>
<th>{{ state.name }}</th>
<td>{{ state.desc|safe }}</td>
<td><ul>{% for s in state.next_states.all %}<li>{{ s.name }}</li>{%endfor%}</ul></td>
<td>
<ul>
{% for s in state.next_states.all %}
<li>{{ s.name }}</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block js %}
<script src="{% static "ietf/js/list.js" %}"></script>
{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
{% comment %}bs5ok{% endcomment %}
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin static %}
{% load ballot_icon %}

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
{% comment %}bs5ok{% endcomment %}
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin static %}
{% load ballot_icon %}

View file

@ -1,4 +1,4 @@
{% comment %}bs5ok{% endcomment %}
{# bs5ok #}
{% comment %}
Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>

View file

@ -1,4 +1,4 @@
{% comment %}bs5ok{% endcomment %}
{# bs5ok #}
<ul class="nav nav-tabs my-3">
<li class="nav-item">
<a class="nav-link

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
{% comment %}bs5ok{% endcomment %}
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin static %}
{% load ballot_icon %}

View file

@ -1,5 +1,5 @@
{% extends "base.html" %}
{% comment %}bs5ok{% endcomment %}
{# bs5ok #}
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin static %}
{% load ietf_filters %}

View file

@ -1,17 +1,22 @@
{# Copyright The IETF Trust 2020, All Rights Reserved #}{% spaceless %}
{# bs5ok #}
{# Copyright The IETF Trust 2020, All Rights Reserved #}
{% spaceless %}
<span class="text-nowrap">
{% if email %}
<a {% if title %}title="{{ title }}"{% endif %} href="{% url 'ietf.person.views.profile' email_or_name=email %}">
<span class="{{class}}">{{ plain_name }}</span>
</a>&nbsp;<a href="mailto:{{ email|urlencode }}">
<span class="bi bi-envelope tiny"></span>
<a {% if title %}title="{{ title }}"{% endif %}
href="{% url 'ietf.person.views.profile' email_or_name=email %}">
<span class="{{ class }}">{{ name }}</span>
</a>&nbsp;
<a href="mailto:{{ email|urlencode }}">
<span class="bi bi-envelope"></span>
</a>
{% elif name %}
<a {% if title %}title="{{ title }}"{% endif %} href="{% url 'ietf.person.views.profile' email_or_name=name %}">
<span class="{{class}}">{{ plain_name }}</span>
<a {% if title %}title="{{ title }}"{% endif %}
href="{% url 'ietf.person.views.profile' email_or_name=name %}">
<span class="{{ class }}">{{ name }}</span>
</a>
{% else %}
<span class="{{class}}">{{ plain_name }}</span>
<span class="{{ class }}">{{ name }}</span>
{% endif %}
</span>
{% endspaceless %}

View file

@ -1,23 +1,14 @@
{# bs5ok #}
{# Copyright The IETF Trust 2017, All Rights Reserved #}
{% extends "base.html" %}
{% load origin %}
{% load ietf_filters static django_bootstrap5 %}
{% block title %}Release Statistics{% endblock %}
{% block pagehead %}
{% endblock %}
{% block pagehead %}{% endblock %}
{% block content %}
{% origin %}
<h1>Release Statistics</h1>
<div id="coverage-chart">
</div>
<div id="coverage-chart"></div>
<script id="coverage-data">
var coverageChartConf = {
chart: {
@ -72,10 +63,7 @@
series: {{ coverage_chart_data }}
};
</script>
<div id="frequency-chart">
</div>
<div id="frequency-chart"></div>
<script id="frequency-data">
var frequencyChartConf = {
chart: {
@ -116,10 +104,7 @@
series: {{ frequency_chart_data }}
};
</script>
{% endblock %}
{% block js %}
<script src="{% static 'ietf/js/highcharts-highcharts.js' %}"></script>
<script src="{% static 'ietf/js/highcharts-exporting.js' %}"></script>
@ -130,4 +115,4 @@
Highcharts.chart('frequency-chart', window.frequencyChartConf);
});
</script>
{% endblock %}
{% endblock %}

View file

@ -1,101 +1,84 @@
{# bs5ok #}
{% extends "base.html" %}
{% load origin %}
{% load ietf_filters static django_bootstrap5 %}
{% load ietf_filters static %}
{% block title %}{{ stats_title }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" href="{% static 'ietf/css/datepicker.css' %}">
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
{% endblock %}
{% block content %}
{% origin %}
<h1>Draft/RFC statistics</h1>
<div class="stats-options well">
<div>
Documents:
<div class="btn-group buttonlist">
{% for slug, label, url in possible_document_stats_types %}
<a class="btn btn-outline-primary {% if slug == stats_type %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div>
Authors:
<div class="btn-group buttonlist">
{% for slug, label, url in possible_author_stats_types %}
<a class="btn btn-outline-primary {% if slug == stats_type %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div>
Yearly:
<div class="btn-group buttonlist">
{% for slug, label, url in possible_yearly_stats_types %}
<a class="btn btn-outline-primary {% if slug == stats_type %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<h2>Options</h2>
<div>
Document type:
<div class="btn-group buttonlist">
{% for slug, label, url in possible_document_types %}
<a class="btn btn-outline-primary {% if slug == document_type %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
Time:
<div class="btn-group buttonlist">
{% for slug, label, url in possible_time_choices %}
<a class="btn btn-outline-primary {% if slug == time_choice %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Documents:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_document_stats_types %}
<a class="btn btn-outline-primary
{% if slug == stats_type %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div class="alert alert-info ">
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Authors:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_author_stats_types %}
<a class="btn btn-outline-primary
{% if slug == stats_type %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Yearly:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_yearly_stats_types %}
<a class="btn btn-outline-primary
{% if slug == stats_type %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<h2>Options</h2>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Document type:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_document_types %}
<a class="btn btn-outline-primary
{% if slug == document_type %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Time:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_time_choices %}
<a class="btn btn-outline-primary
{% if slug == time_choice %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div class="alert alert-info my-5">
<b>Please Note:</b> The author information in the datatracker about RFCs
with numbers lower than about 1300 and drafts from before 2001 is
unreliable and in many cases absent. For this reason, statistics on these
pages does not show correct author stats for corpus selections that involve such
documents.
<!--
<br/>
<br/>
The reason for this situation is that Datatracker is primarily focused on
managing workflow, not trying to provide history from the beginning of
time. The Tools Team has talked about ways to crowd source this
information, but the tooling to allow people with Datatracker accounts
enter the author data is likely to be quite a bit of work, and is not
imminent.
-->
</div>
<div class="document-stats">
{% include content_template %}
</div>
{% include content_template %}
{% endblock %}
{% block js %}
<script src="{% static 'ietf/js/highcharts-highcharts.js' %}"></script>
<script src="{% static 'ietf/js/highcharts-exporting.js' %}"></script>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -30,7 +31,7 @@
var s = '<b>' + this.points[0].key + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -40,15 +41,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Affiliation</th>
<th>Percentage of authors</th>
<th>Authors</th>
<th data-sort="affiliation">Affiliation</th>
<th data-sort="num">Percentage of authors</th>
<th data-sort="num">Authors</th>
</tr>
</thead>
<tbody>
@ -61,48 +60,50 @@
{% endfor %}
</tbody>
</table>
<p>The statistics are based entirely on the author affiliation
<p>
The statistics are based entirely on the author affiliation
provided with each draft. Since this may vary across documents, an
author may be counted with more than one affiliation, making the
total sum more than 100%.</p>
<h3>Affiliation Aliases</h3>
<p>In generating the above statistics, some heuristics have been
applied to determine the affiliations of each author.</p>
total sum more than 100%.
</p>
<h2>Affiliation Aliases</h2>
<p>
In generating the above statistics, some heuristics have been
applied to determine the affiliations of each author.
</p>
{% if request.GET.showaliases %}
<p><a href="{{ hide_aliases_url }}" class="btn btn-primary">Hide generated aliases</a></p>
<p>
<a href="{{ hide_aliases_url }}" class="btn btn-primary">Hide generated aliases</a>
</p>
{% if request.user.is_staff %}
<p>Note: since you're an admin, you can <a href="{% url "admin:stats_affiliationalias_add" %}">add an extra known alias</a> or see the <a href="{% url "admin:stats_affiliationalias_changelist" %}">existing known aliases</a> and <a href="{% url "admin:stats_affiliationignoredending_changelist" %}">generally ignored endings</a>.</p>
<p>
Note: since you're an admin, you can
<a href="{% url "admin:stats_affiliationalias_add" %}">add an extra known alias</a>
or see the
<a href="{% url "admin:stats_affiliationalias_changelist" %}">existing known aliases</a>
and
<a href="{% url "admin:stats_affiliationignoredending_changelist" %}">generally ignored endings</a>
.
</p>
{% endif %}
{% if alias_data %}
<table class="table table-sm">
<table class="table table-sm table-striped tablesorter">
<thead>
<tr>
<th>Affiliation</th>
<th>Alias</th>
<th data-sort="affiliation">Affiliation</th>
<th data-sort="alias">Alias</th>
</tr>
</thead>
{% for name, alias in alias_data %}
<tr>
<td>
{% ifchanged %}
{{ name|default:"(unknown)" }}
{% endifchanged %}
</td>
<td>{{ name|default:"(unknown)" }}</td>
<td>{{ alias }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% else %}
<p><a href="{{ show_aliases_url }}" class="btn btn-primary">Show generated aliases</a></p>
{% endif %}
<p>
<a href="{{ show_aliases_url }}" class="btn btn-primary">Show generated aliases</a>
</p>
{% endif %}

View file

@ -1,3 +1,4 @@
{# bs5ok #}
{% load origin %}{% origin %}
<div id="chart"></div>
@ -46,14 +47,14 @@
};
</script>
<h3>Data</h3>
<h2>Data</h2>
<table class="table table-sm stats-data">
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Citations</th>
<th>Percentage of authors</th>
<th>Authors</th>
<th data-sort="num">Citations</th>
<th data-sort="num">Percentage of authors</th>
<th data-sort="authors">Authors</th>
</tr>
</thead>
<tbody>
@ -67,4 +68,4 @@
</tbody>
</table>
<p>Note that the citation counts do not exclude self-references.</p>
<p>Note that the citation counts do not exclude self-references.</p>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -30,7 +31,7 @@
var s = '<b>' + this.points[0].key + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -40,15 +41,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Continent</th>
<th>Percentage of authors</th>
<th>Authors</th>
<th data-sort="continent">Continent</th>
<th data-sort="num">Percentage of authors</th>
<th data-sort="num">Authors</th>
</tr>
</thead>
<tbody>
@ -61,8 +60,9 @@
{% endfor %}
</tbody>
</table>
<p>The statistics are based entirely on the author addresses provided
with each draft. Since this varies across documents, a travelling
<p>
The statistics are based entirely on the author addresses provided
with each draft. Since this varies across documents, a traveling
author may be counted in more than country, making the total sum
more than 100%.</p>
more than 100%.
</p>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -30,7 +31,7 @@
var s = '<b>' + this.points[0].key + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -40,90 +41,92 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Country</th>
<th>Percentage of authors</th>
<th>Authors</th>
<th data-sort="country">Country</th>
<th class="text-end" data-sort="percentage">Percentage of authors</th>
<th class="text-end" data-sort="authors">Authors</th>
</tr>
</thead>
<tbody>
{% for country, percentage, count, names in table_data %}
<tr>
<td>{{ country|default:"(unknown)" }}</td>
<td>{{ percentage|floatformat:2 }}%</td>
<td>{% include "stats/includes/number_with_details_cell.html" %}</td>
<td class="text-end">{{ percentage|floatformat:2 }}%</td>
<td class="text-end">{% include "stats/includes/number_with_details_cell.html" %}</td>
</tr>
{% endfor %}
</tbody>
</table>
<p>The statistics are based entirely on the author addresses provided
with each draft. Since this varies across documents, a travelling
<p>
The statistics are based entirely on the author addresses provided
with each draft. Since this varies across documents, a traveling
author may be counted in more than country, making the total sum
more than 100%.</p>
<p>In case no country information is found for an author in the time
period, the author is counted as (unknown).</p>
<p>EU (European Union) is not a country, but has been added for reference, as the sum of
more than 100%.
</p>
<p>
In case no country information is found for an author in the time
period, the author is counted as (unknown).
</p>
<p>
EU (European Union) is not a country, but has been added for reference, as the sum of
all current EU member countries:
{% for c in eu_countries %}{{ c.name }}{% if not forloop.last %}, {% endif %}{% endfor %}.</p>
<h3>Country Aliases</h3>
<p>In generating the above statistics, some heuristics have been
applied to figure out which country each author is from.</p>
{% for c in eu_countries %}
{{ c.name }}
{% if not forloop.last %},{% endif %}
{% endfor %}
.
</p>
<h2>Country Aliases</h2>
<p>
In generating the above statistics, some heuristics have been
applied to figure out which country each author is from.
</p>
{% if request.GET.showaliases %}
<p><a href="{{ hide_aliases_url }}" class="btn btn-primary">Hide generated aliases</a></p>
<p>
<a href="{{ hide_aliases_url }}" class="btn btn-primary">Hide generated aliases</a>
</p>
{% if request.user.is_staff %}
<p>Note: since you're an admin, some extra links are visible. You
<p class="alert alert-info">
Note: since you're an admin, some extra links are visible. You
can either correct a document author entry directly in case the
information is obviously missing or add an alias if an unknown
<a href="{% url "admin:name_countryname_changelist" %}">country name</a>
is being used.
</p>
{% endif %}
{% if alias_data %}
<table class="table table-sm">
<table class="table table-sm table-striped tablesorter">
<thead>
<th>Country</th>
<th>Alias</th>
<th></th>
<th data-sort="country">Country</th>
<th data-sort="alias">Alias</th>
</thead>
{% for name, alias, country in alias_data %}
<tr>
<td>
{% ifchanged %}
{% if country and request.user.is_staff %}
<a href="{% url "admin:name_countryname_change" country.pk %}">
{% endif %}
{% if country and request.user.is_staff %}
<a href="{% url "admin:name_countryname_change" country.pk %}">{{ name|default:"(unknown)" }}</a>
{% else %}
{{ name|default:"(unknown)" }}
{% if country and request.user.is_staff %}
</a>
{% endif %}
{% endifchanged %}
{% endif %}
</td>
<td>{{ alias }}</td>
<td>
{{ alias }}
{% if request.user.is_staff and name != "EU" %}
<a href="{% url "admin:doc_documentauthor_changelist" %}?country={{ alias|urlencode }}">Matching authors</a>
<a class="float-end btn btn-primary btn-sm"
href="{% url "admin:doc_documentauthor_changelist" %}?country={{ alias|urlencode }}">
Matching authors
</a>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% else %}
<p><a href="{{ show_aliases_url }}" class="btn btn-primary">Show generated aliases</a></p>
<p>
<a href="{{ show_aliases_url }}" class="btn btn-primary">Show generated aliases</a>
</p>
{% endif %}

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -36,7 +37,7 @@
var s = '<b>' + this.x + ' ' + (this.x == 1 ? "{{ doc_label }}" : '{{ doc_label }}s') + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y.toFixed(1) + '%';
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y.toFixed(1) + '%';
});
return s;
@ -46,15 +47,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Documents</th>
<th>Percentage of authors</th>
<th>Authors</th>
<th data-sort="num">Documents</th>
<th data-sort="num">Percentage of authors</th>
<th data-sort="num">Authors</th>
</tr>
</thead>
<tbody>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -35,7 +36,7 @@
var s = '<b>' + ' h-index ' + this.x + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y.toFixed(1) + '%';
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y.toFixed(1) + '%';
});
return s;
@ -45,15 +46,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>h-index</th>
<th>Percentage of authors</th>
<th>Authors</th>
<th data-sort="num">h-index</th>
<th data-sort="num">Percentage of authors</th>
<th data-sort="Authors">Authors</th>
</tr>
</thead>
<tbody>
@ -66,13 +65,18 @@
{% endfor %}
</tbody>
</table>
<p>Hirsch index or h-index is a
<a href="https://www.wikipedia.org/wiki/H-index">measure of the
productivity and impact of the publications of an author</a>. An
<p>
Hirsch index or h-index is a
<a href="https://www.wikipedia.org/wiki/H-index">
measure of the
productivity and impact of the publications of an author
</a>
. An
author with an h-index of 5 has had 5 publications each cited at
least 5 times - to increase the index to 6, the 5 publications plus
1 more would have to have been cited at least 6 times, each. Thus a
high h-index requires many highly-cited publications.</p>
<p>Note that the h-index calculations do not exclude self-references.</p>
high h-index requires many highly-cited publications.
</p>
<p>
Note that the h-index calculations do not exclude self-references.
</p>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -35,7 +36,7 @@
var s = '<b>' + this.x + ' ' + (this.x == 1 ? "author" : 'authors') + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y.toFixed(1) + '%';
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y.toFixed(1) + '%';
});
return s;
@ -45,15 +46,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Authors</th>
<th>Percentage of {{ doc_label }}s</th>
<th>{{ doc_label|capfirst }}s</th>
<th data-sort="num">Authors</th>
<th data-sort="num">Percentage of {{ doc_label }}s</th>
<th data-sort="num">{{ doc_label|capfirst }}s</th>
</tr>
</thead>
<tbody>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -31,7 +32,7 @@
var s = '<b>' + this.points[0].key + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -41,15 +42,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Format</th>
<th>Percentage of {{ doc_label }}s</th>
<th>{{ doc_label|capfirst }}s</th>
<th data-sort="format">Format</th>
<th data-sort="num">Percentage of {{ doc_label }}s</th>
<th data-sort="label">{{ doc_label|capfirst }}s</th>
</tr>
</thead>
<tbody>
@ -61,4 +60,4 @@
</tr>
{% endfor %}
</tbody>
</table>
</table>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -31,7 +32,7 @@
var s = '<b>' + this.points[0].key + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -41,15 +42,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Formal language</th>
<th>Percentage of {{ doc_label }}s</th>
<th>{{ doc_label|capfirst }}s</th>
<th data-sort="formal">Formal language</th>
<th data-sort="num">Percentage of {{ doc_label }}s</th>
<th data-sort="num">{{ doc_label|capfirst }}s</th>
</tr>
</thead>
<tbody>
@ -61,4 +60,4 @@
</tr>
{% endfor %}
</tbody>
</table>
</table>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -29,7 +30,7 @@
var s = '<b>' + this.x + ' ' + (this.x == 1 ? "page" : 'pages') + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -39,15 +40,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Pages</th>
<th>Percentage of {{ doc_label }}s</th>
<th>{{ doc_label|capfirst }}s</th>
<th data-sort="num">Pages</th>
<th data-sort="num">Percentage of {{ doc_label }}s</th>
<th data-sort="num">{{ doc_label|capfirst }}s</th>
</tr>
</thead>
<tbody>
@ -59,4 +58,4 @@
</tr>
{% endfor %}
</tbody>
</table>
</table>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -29,7 +30,7 @@
var s = '<b>' + this.x + ' - ' + (this.x + {{ bin_size }} - 1) + ' ' + (this.x == 1 ? "word" : 'words') + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -39,15 +40,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data">
<h2>Data</h2>
<table class="table table-sm table-striped tablesorter stats-data">
<thead>
<tr>
<th>Words</th>
<th>Percentage of {{ doc_label }}s</th>
<th>{{ doc_label|capfirst }}s</th>
<th data-sort="num">Words</th>
<th data-sort="num">Percentage of {{ doc_label }}s</th>
<th data-sort="num">{{ doc_label|capfirst }}s</th>
</tr>
</thead>
<tbody>
@ -59,4 +58,4 @@
</tr>
{% endfor %}
</tbody>
</table>
</table>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -40,7 +41,7 @@
var s = '<b>' + this.x + '</b>';
$.each(this.points, function () {
s += '<br/>' + this.series.name + ': ' + this.y;
s += '<br />' + this.series.name + ': ' + this.y;
});
return s;
@ -49,4 +50,4 @@
},
series: {{ chart_data }}
};
</script>
</script>

View file

@ -1,8 +1,10 @@
{% load person_filters %}{% if content_limit and count <= content_limit %}
{# bs5ok #}
{% load person_filters %}
{% if content_limit and count <= content_limit %}
{% for n in names %}
{% with n|person_by_name as person %}
{% if person %}
<a href="{{ person.get_absolute_url }}">{{ n }}</a>
{% person_link person %}
{% else %}
{{ n }}
{% endif %}
@ -10,6 +12,5 @@
{% endwith %}
{% endfor %}
{% else %}
{# <a class="popover-details" href="" data-elements="{% for n in names|slice:":20" %}{{ n }}{% if not forloop.last %}|{% endif %}{% endfor %}" data-sliced="{% if count > 20 %}1{% endif %}">{{ count }}</a> #}
{{ count }}
{% endif %}
{% endif %}

View file

@ -1,20 +1,25 @@
{# bs5ok #}
{% extends "base.html" %}
{% load origin %}
{% load ietf_filters static django_bootstrap5 %}
{% load ietf_filters static %}
{% block content %}
{% origin %}
<h1>{% block title %}Statistics{% endblock %}</h1>
<p>Statistics on...</p>
<h1>
{% block title %}Statistics{% endblock %}
</h1>
<p>
Statistics on...
</p>
<ul>
<li><a href="{% url "ietf.stats.views.document_stats" %}">Drafts/RFCs (authors, countries, formats, ...)</a></li>
<li><a href="{% url "ietf.stats.views.meeting_stats" %}">Meeting attendance</a></li>
<li><a rel="nofollow" href="{% url "ietf.stats.views.review_stats" %}">Reviews of drafts in review teams</a> (requires login)</li>
<li>
<a href="{% url "ietf.stats.views.document_stats" %}">Drafts/RFCs (authors, countries, formats, ...)</a>
</li>
<li>
<a href="{% url "ietf.stats.views.meeting_stats" %}">Meeting attendance</a>
</li>
<li>
<a rel="nofollow" href="{% url "ietf.stats.views.review_stats" %}">Reviews of drafts in review teams</a>
(requires login)
</li>
</ul>
{% endblock %}
{% endblock %}

View file

@ -1,25 +1,30 @@
{# bs5ok #}
{% extends "base.html" %}
{% load origin %}
{% load ietf_filters static django_bootstrap5 %}
{% load ietf_filters static %}
{% block pagehead %}
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
{% endblock %}
{% block content %}
{% origin %}
<h1>{% block title %}Countries known to the Datatracker{% endblock %}</h1>
<p>In case you think a country or an alias is missing from the list, you can <a href="mailto:{{ settings.SECRETARIAT_ACTION_EMAIL }}">file a ticket</a>.</p>
<h1>
{% block title %}Countries known to the Datatracker{% endblock %}
</h1>
<p>
In case you think a country or an alias is missing from the list, you can
<a href="mailto:{{ settings.SECRETARIAT_ACTION_EMAIL }}">file a ticket</a>
.
</p>
{% if request.user.is_staff %}
<p>Note: since you're an admin, the country names are linked to their corresponding admin page.</p>
<p>
Note: since you're an admin, the country names are linked to their corresponding admin page.
</p>
{% endif %}
<table class="table table-sm table-striped">
<table class="table table-sm table-striped tablesorter">
<thead>
<tr>
<th>Name</th>
<th>Aliases (lowercase aliases are matched case-insensitive)</th>
<th data-sort="name">Name</th>
<th data-sort="aliases">Aliases (lowercase aliases are matched case-insensitive)</th>
</tr>
</thead>
<tbody>
@ -28,20 +33,21 @@
<td>
{% if request.user.is_staff %}
<a href="{% url "admin:name_countryname_change" c.pk %}">
{% endif %}
{{ c.name }}
{% if request.user.is_staff %}
</a>
{% endif %}
</td>
<td>
{% for a in c.aliases %}
{{ a.alias }}{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% endif %}
{{ c.name }}
{% if request.user.is_staff %}</a>{% endif %}
</td>
<td>
{% for a in c.aliases %}
{{ a.alias }}
{% if not forloop.last %},{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block js %}
<script src="{% static "ietf/js/list.js" %}"></script>
{% endblock %}

View file

@ -1,49 +1,38 @@
{# bs5ok #}
{% extends "base.html" %}
{% load origin %}
{% load ietf_filters static django_bootstrap5 %}
{% block title %}{{ stats_title }}{% endblock %}
{% block pagehead %}
<link rel="stylesheet" href="{% static 'ietf/css/datepicker.css' %}">
<link rel="stylesheet" href="{% static 'ietf/css/list.css' %}">
{% endblock %}
{% block content %}
{% origin %}
<h1>Meeting Statistics</h1>
{% if meeting %}
<p>
<a href="{% url "ietf.stats.views.meeting_stats" %}">&laquo; Back to overview</a>
</p>
{% endif %}
<div class="stats-options well">
<div>
Attendees:
<div class="btn-group">
{% for slug, label, url in possible_stats_types %}
<a class="btn btn-primary {% if slug == stats_type %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Attendees:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_stats_types %}
<a class="btn btn-outline-primary
{% if slug == stats_type %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div class="document-stats">
{% include content_template %}
</div>
<div class="document-stats">{% include content_template %}</div>
{% endblock %}
{% block js %}
<script src="{% static 'ietf/js/highcharts-highcharts.js' %}"></script>
<script src="{% static 'ietf/js/highcharts-exporting.js' %}"></script>
<script src="{% static 'highcharts/modules/export-data.js' %}"></script>
<script src="{% static 'ietf/js/highcharts-export-data.js' %}"></script>
<script src="{% static 'ietf/js/highcharts-offline-exporting.js' %}"></script>
<script src="{% static 'ietf/js/stats.js' %}"></script>
<script src="{% static "ietf/js/list.js" %}"></script>
{% endblock %}
{% endblock %}

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -30,7 +31,7 @@
var s = '<b>' + this.points[0].key + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -40,15 +41,13 @@
series: {{ chart_data }}
};
</script>
<h3>Data</h3>
<table class="table table-sm stats-data tablesorter">
<h2>Data</h2>
<table class="table table-sm table-striped stats-data tablesorter">
<thead>
<tr>
<th>Continent</th>
<th>Percentage of attendees</th>
<th>Attendees</th>
<th data-soort="continent">Continent</th>
<th data-soort="num">Percentage of attendees</th>
<th data-soort="num">Attendees</th>
</tr>
</thead>
<tbody>
@ -60,4 +59,4 @@
</tr>
{% endfor %}
</tbody>
</table>
</table>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart"></div>
<script>
var chartConf = {
chart: {
@ -30,7 +31,7 @@
var s = '<b>' + this.points[0].key + '</b>';
$.each(this.points, function () {
s += '<br/>' + chartConf.yAxis.title.text + ': ' + this.y;
s += '<br />' + chartConf.yAxis.title.text + ': ' + this.y;
});
return s;
@ -40,9 +41,7 @@
series: {{ chart_data }}
};
</script>
<div id="pie-chart"></div>
<script>
var pieChartConf = {
chart: {
@ -70,9 +69,7 @@
}]
};
</script>
<h3>Data</h3>
<h2>Data</h2>
<table class="table table-sm stats-data tablesorter">
<thead>
<tr>
@ -91,8 +88,12 @@
{% endfor %}
</tbody>
</table>
<p>EU (European Union) is not a country, but has been added for reference, as the sum of
<p>
EU (European Union) is not a country, but has been added for reference, as the sum of
all current EU member countries:
{% for c in eu_countries %}{{ c.name }}{% if not forloop.last %}, {% endif %}{% endfor %}.
</p>
{% for c in eu_countries %}
{{ c.name }}
{% if not forloop.last %},{% endif %}
{% endfor %}
.
</p>

View file

@ -1,6 +1,7 @@
{% load origin %}{% origin %}
{# bs5ok #}
{% load origin %}
{% origin %}
<div id="chart" class="chart-{{ stats_type }}"></div>
<script>
var chartConf = {
@ -32,8 +33,8 @@
tooltip: {
formatter: function () {
var s = '<b>' + this.point.name + '</b>';
s += '<br/>' + this.point.date;
s += '<br/>' + this.series.name + '<br/> Attendees: ' + this.y;
s += '<br />' + this.point.date;
s += '<br />' + this.series.name + '<br /> Attendees: ' + this.y;
return s;
},
shared: false
@ -68,7 +69,7 @@
var s = '<b>' + "IETF " + this.x + '</b>';
$.each(this.points, function () {
s += '<br/>' + this.series.name + ': ' + this.y;
s += '<br />' + this.series.name + ': ' + this.y;
});
return s;
@ -118,34 +119,36 @@
series: {{ chart_data }}
};
</script>
{% if table_data %}
<h3>Data</h3>
<table class="table table-sm stats-data tablesorter">
<h2>Data</h2>
<table class="table table-sm table-striped stats-data tablesorter">
<thead>
<tr>
<th>Meeting</th>
<th>Date</th>
<th>City</th>
<th>Country</th>
<th>Continent</th>
<th>Attendees</th>
<th data-sort="num">Meeting</th>
<th data-sort="date">Date</th>
<th data-sort="city">City</th>
<th data-sort="country">Country</th>
<th data-sort="continent">Continent</th>
<th data-sort="num">Attendees</th>
</tr>
</thead>
<tbody>
{% for meeting, url, count, country in table_data %}
<tr>
{% if meeting.get_number > 71 %}
<td><a href="{{ url }}">{{ meeting.number }}</a></td>
<td>{{ meeting.date }} </td>
<td><a href="{{ url }}">{{ meeting.city }}</a></td>
<td>
<a href="{{ url }}">{{ meeting.number }}</a>
</td>
<td>{{ meeting.date }}</td>
<td>
<a href="{{ url }}">{{ meeting.city }}</a>
</td>
<td>{{ country.name }}</td>
<td>{{ country.continent }}</td>
<td>{% include "stats/includes/number_with_details_cell.html" %}</td>
{% else %}
<td>{{ meeting.number }}</td>
<td>{{ meeting.date }} </td>
<td>{{ meeting.date }}</td>
<td>{{ meeting.city }}</td>
<td>{{ country.name }}</td>
<td>{{ country.continent }}</td>
@ -155,5 +158,4 @@
{% endfor %}
</tbody>
</table>
{% endif %}
{% endif %}

View file

@ -1,17 +1,14 @@
{# bs5ok #}
{% extends "base.html" %}
{% load origin %}{% origin %}
{% load origin %}
{% origin %}
{% load ietf_filters static django_bootstrap5 %}
{% block pagehead %}
<link rel="stylesheet" href="{% static "ietf/css/list.css" %}">
<link rel="stylesheet" href="{% static 'ietf/css/datepicker.css' %}">
{% endblock %}
{% block content %}
{% origin %}
<h1>
{% block title %}
{% if level == "team" %}
@ -21,120 +18,174 @@
{% endif %}
{% endblock %}
</h1>
{% if level == "reviewer" %}
<p><a href="{{ team_level_url }}">&laquo; Back to teams</a></p>
<p>
<a href="{{ team_level_url }}">&laquo; Back to teams</a>
</p>
{% endif %}
<div class="stats-options well">
<div>
Show:
<div class="btn-group">
{% for slug, label, url in possible_stats_types %}
<a class="btn btn-primary {% if slug == stats_type %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div>
Count:
<div class="btn-group">
{% for slug, label, url in possible_count_choices %}
<a class="btn btn-primary {% if slug == count %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<form class="form-inline date-range">
Request time:
<input class="form-control" type="text" name="from" value="{{ from_date }}" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-autoclose="1" data-date-end-date="{{ today.isoformat }}" data-date-start-view="months">
-
<input class="form-control" type="text" name="to" value="{{ to_date }}" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-autoclose="1" data-date-end-date="{{ today.isoformat }}" data-date-start-view="months">
{% for name, value in request.GET.iteritems %}
{% if name != "from" and name != "to" %}
<input type="hidden" name="{{ name }}" value="{{ value }}">
{% endif %}
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Show:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_stats_types %}
<a class="btn btn-outline-primary
{% if slug == stats_type %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
<button class="btn btn-primary" type="submit">Set</button>
</form>
{% if stats_type == "time" %}
<hr>
<div>
Team:
<div class="btn-group">
{% for slug, label, url in possible_teams %}
<a class="btn btn-primary {% if slug in selected_teams %}active{% endif %}" href="{{ url }}">{{ label }}</a>
</div>
</div>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Count:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_count_choices %}
<a class="btn btn-outline-primary
{% if slug == count %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<form class="date-range">
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Request time:</label>
<div class="col-sm-10">
<div class="input-group">
<input class="form-control"
type="text"
name="from"
value="{{ from_date }}"
data-provide="datepicker"
data-date-format="yyyy-mm-dd"
data-date-autoclose="1"
data-date-orientation="auto bottom"
data-date-end-date="{{ today.isoformat }}"
data-date-start-view="months">
<span class="input-group-text" id="basic-addon2">&mdash;</span>
<input class="form-control"
type="text"
name="to"
value="{{ to_date }}"
data-provide="datepicker"
data-date-format="yyyy-mm-dd"
data-date-autoclose="1"
data-date-orientation="auto bottom"
data-date-end-date="{{ today.isoformat }}"
data-date-start-view="months">
{% for name, value in request.GET.iteritems %}
{% if name != "from" and name != "to" %}<input type="hidden" name="{{ name }}" value="{{ value }}">{% endif %}
{% endfor %}
<button class="btn btn-primary" type="submit">Set</button>
</div>
</div>
</div>
</form>
{% if stats_type == "time" %}
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Team:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_teams %}
<a class="btn btn-outline-primary
{% if slug in selected_teams %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
{% if selected_teams %}
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Completion:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_completion_types %}
<a class="btn btn-outline-primary
{% if slug == selected_completion_type %}
active
{% endif %}"
href="{{ url }}">
{{ label }}
</a>
{% endfor %}
</div>
</div>
{% if selected_teams %}
<div>
Completion:
<div class="btn-group">
{% for slug, label, url in possible_completion_types %}
<a class="btn btn-primary {% if slug == selected_completion_type %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">Result:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_results %}
<a class="btn btn-outline-primary
{% if slug == selected_result %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
<div>
Result:
<div class="btn-group">
{% for slug, label, url in possible_results %}
<a class="btn btn-primary {% if slug == selected_result %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
<div class="row my-3">
<label class="fw-bold col-sm-2 col-form-label">State:</label>
<div class="btn-group col-sm-10">
{% for slug, label, url in possible_states %}
<a class="btn btn-outline-primary
{% if slug == selected_state %}
active
{% endif %}"
href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
<div>
State:
<div class="btn-group">
{% for slug, label, url in possible_states %}
<a class="btn btn-primary {% if slug == selected_state %}active{% endif %}" href="{{ url }}">{{ label }}</a>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% endif %}
</div>
{% endif %}
{% if stats_type == "completion" %}
<h3>Completion status and completion time</h3>
<table class="review-stats table tablesorter">
<h2>Completion status and completion time</h2>
<table class="review-stats table table-sm table-striped tablesorter">
<thead>
<th>
<th data-sort="{{ level }}">
{% if level == "team" %}
Team
{% elif level == "reviewer" %}
Reviewer
{% endif %}
</th>
<th title="Requests that are currently requested or accepted by reviewer">Open in time</th>
<th title="Requests that are currently requested or accepted by reviewer and past the deadline">Open late</th>
<th title="Requests that have been completed partially or completely">Completed in time</th>
<th title="Requests that have been completed partially or completely past the deadline">Completed late</th>
<th title="Requests that are rejected by the reviewer, withdrawn, overtaken by events or with no response from reviewer">Not completed</th>
<th title="Average time between assignment and completion for completed reviews, in days">Avg. compl. days{% if count == "pages" %}/page{% endif %}</th>
<th data-sort="num"
title="Requests that are currently requested or accepted by reviewer">Open in time</th>
<th data-sort="num"
title="Requests that are currently requested or accepted by reviewer and past the deadline">
Open late
</th>
<th data-sort="num"
title="Requests that have been completed partially or completely">Completed in time</th>
<th data-sort="num"
title="Requests that have been completed partially or completely past the deadline">
Completed late
</th>
<th data-sort="num"
title="Requests that are rejected by the reviewer, withdrawn, overtaken by events or with no response from reviewer">
Not completed
</th>
<th data-sort="num"
title="Average time between assignment and completion for completed reviews, in days">
Avg. compl. days
{% if count == "pages" %}/page{% endif %}
</th>
</thead>
<tbody>
{% for row in data %}
<tr {% if row.obj == "Totals" %}class="totals"{% endif %}>
{% for row in data %}
{% if forloop.first %}
<tbody>
{% elif forloop.last %}
</tbody>
<tfoot>
{% endif %}
<tr>
<td>{{ row.obj }}</td>
<td>{{ row.open_in_time }}</td>
<td>{{ row.open_late }}</td>
<td>{{ row.completed_in_time }}</td>
<td>{{ row.completed_late }}</td>
<td>{{ row.not_completed }}</td>
<td>
{{ row.completed_late }}
</td>
<td>
{{ row.not_completed }}
</td>
<td>
{% if row.average_assignment_to_closure_days != None %}
{{ row.average_assignment_to_closure_days|floatformat }}
@ -142,78 +193,99 @@
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% elif stats_type == "results" %}
<h3>Results of completed reviews</h3>
<table class="review-stats table tablesorter">
<thead>
<th>
{% if level == "team" %}
Team
{% elif level == "reviewer" %}
Reviewer
{% endif %}
</th>
{% for r in results %}
<th>{{ r.name }}</th>
{% endfor %}
</thead>
<tbody>
</foot>
</table>
{% elif stats_type == "results" %}
<h2>
Results of completed reviews
</h2>
<table class="review-stats table table-sm table-striped tablesorter">
<thead>
<th data-sort="{{ level }}">
{% if level == "team" %}
Team
{% elif level == "reviewer" %}
Reviewer
{% endif %}
</th>
{% for r in results %}
<th data-sort="num">
{{ r.name }}
</th>
{% endfor %}
</thead>
{% for row in data %}
<tr {% if row.obj == "Totals" %}class="totals"{% endif %}>
<td>{{ row.obj }}</td>
{% for c in row.result_list %}
<td>{{ c }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% elif stats_type == "states" %}
<h3>Specific request states</h3>
<table class="review-stats table tablesorter">
<thead>
<th>
{% if level == "team" %}
Team
{% elif level == "reviewer" %}
Reviewer
{% endif %}
</th>
{% for s in states %}
<th>{{ s.name }}</th>
{% endfor %}
</thead>
<tbody>
{% if forloop.first %}
<tbody>
{% elif forloop.last %}
</tbody>
<tfoot>
{% endif %}
<tr>
<td>
{{ row.obj }}
</td>
{% for c in row.result_list %}
<td>
{{ c }}
</td>
{% endfor %}
</tr>
{% endfor %}
</tfoot>
</table>
{% elif stats_type == "states" %}
<h2>
Specific request states
</h2>
<table class="review-stats table table-sm table-striped tablesorter">
<thead>
<th data-sort="{{ level }}">
{% if level == "team" %}
Team
{% elif level == "reviewer" %}
Reviewer
{% endif %}
</th>
{% for s in states %}
<th data-sort="num">
{{ s.name }}
</th>
{% endfor %}
</thead>
{% for row in data %}
<tr {% if row.obj == "Totals" %}class="totals"{% endif %}>
<td>{{ row.obj }}</td>
{% for c in row.state_list %}
<td>{{ c }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% elif stats_type == "time" and selected_teams %}
<h3>Counts per month</h3>
<div class="stats-time-graph"></div>
<script>
{% if forloop.first %}
<tbody>
{% elif forloop.last %}
</tbody>
<tfoot>
{% endif %}
<tr>
<td>
{{ row.obj }}
</td>
{% for c in row.state_list %}
<td>
{{ c }}
</td>
{% endfor %}
</tr>
{% endfor %}
</tfoot>
</table>
{% elif stats_type == "time" and selected_teams %}
<h2>
Counts per month
</h2>
<div class="stats-time-graph">
</div>
<script>
var timeSeriesData = {{ data|safe }};
console.log(timeSeriesData);
var timeSeriesOptions = {
xaxis: {
mode: "time",
timeBase: "milliseconds",
tickLength: 0
},
yaxis: {
@ -223,41 +295,47 @@
stack: true,
bars: {
show: true,
barWidth: 20 * 24 * 60 * 60 * 1000,
align: "center",
lineWidth: 1,
fill: 0.6
}
}
};
</script>
{% endif %}
{% if stats_type != "time" %}
<p class="text-muted text-end">
Note:
{% if level == "team" %}
teams
{% elif level == "reviewer" %}
reviewers
{% endif %}
with no requests in the period are omitted.
</p>
{% endif %}
{% if level == "team" and stats_type != "time" %}
<h2>
Statistics for Individual Reviewers
</h2>
<div class="row row-cols-1 row-cols-md-4">
{% for t in teams %}
<a class="" href="{{ t.reviewer_stats_url }}">
{{ t.name }}
</a>
{% endfor %}
</div>
{% endif %}
{% endblock %}
{% block js %}
<script src="{% static "ietf/js/list.js" %}">
</script>
{% endif %}
{% if stats_type != "time" %}
<p class="text-muted text-right">Note: {% if level == "team" %}teams{% elif level == "reviewer" %}reviewers{% endif %}
with no requests in the period are omitted.</p>
{% endif %}
{% if level == "team" and stats_type != "time" %}
<p>Statistics for individual reviewers:</p>
<div class="review-stats-teams">
{% for t in teams %}
<a href="{{ t.reviewer_stats_url }}">{{ t.name }}</a>
{% endfor %}
</div>
{% endif %}
{% endblock %}
{% block js %}
<script src="{% static "ietf/js/list.js" %}"></script>
<script src="{% static 'ietf/js/datepicker.js' %}"></script>
{% if stats_type == "time" %}
<script src="{% static 'flot/jquery.flot.min.js' %}"></script>
<script src="{% static 'flot/jquery.flot.time.min.js' %}"></script>
<script src="{% static 'flot/jquery.flot.stack.min.js' %}"></script>
<script src="{% static 'ietf/js/review-stats.js' %}"></script>
{% endif %}
{% endblock %}
<script src="{% static 'ietf/js/datepicker.js' %}">
</script>
{% if stats_type == "time" %}
<script src="{% static 'ietf/js/flot.js' %}">
</script>
<script src="{% static 'ietf/js/review-stats.js' %}">
</script>
{% endif %}
{% endblock %}

285
package-lock.json generated
View file

@ -12,6 +12,7 @@
"bootstrap-datepicker": "^1.9.0",
"bootstrap-icons": "^1.7.0",
"d3": "^3.5.17",
"flot": "^4.2.2",
"highcharts": "^9.3.1",
"jquery": "^3.6.0",
"js-cookie": "^3.0.1",
@ -1792,9 +1793,9 @@
}
},
"node_modules/@parcel/watcher": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.3.tgz",
"integrity": "sha512-PHh5PArr3nYGYVj9z/NSfDmmKEBNrg2bzoFgxzjTRBBxPUKx039x3HF6VGLFIfrghjJxcYn/IeSpdVwfob7KFA==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz",
"integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@ -1834,9 +1835,9 @@
}
},
"node_modules/@popperjs/core": {
"version": "2.10.2",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz",
"integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
@ -1867,9 +1868,9 @@
}
},
"node_modules/@types/node": {
"version": "16.11.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.10.tgz",
"integrity": "sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA==",
"version": "16.11.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.11.tgz",
"integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==",
"dev": true
},
"node_modules/@types/parse-json": {
@ -2778,9 +2779,9 @@
"dev": true
},
"node_modules/core-js": {
"version": "3.19.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.19.1.tgz",
"integrity": "sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg==",
"version": "3.19.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.19.2.tgz",
"integrity": "sha512-ciYCResnLIATSsXuXnIOH4CbdfgV+H1Ltg16hJFN7/v6OxqnFr/IFGeLacaZ+fHLAm0TBbXwNK9/DNBzBUrO/g==",
"dev": true,
"hasInstallScript": true,
"funding": {
@ -3092,12 +3093,12 @@
}
},
"node_modules/cssnano": {
"version": "5.0.11",
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.11.tgz",
"integrity": "sha512-5SHM31NAAe29jvy0MJqK40zZ/8dGlnlzcfHKw00bWMVFp8LWqtuyPSFwbaoIoxvt71KWJOfg8HMRGrBR3PExCg==",
"version": "5.0.12",
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.12.tgz",
"integrity": "sha512-U38V4x2iJ3ijPdeWqUrEr4eKBB5PbEKsNP5T8xcik2Au3LeMtiMHX0i2Hu9k51FcKofNZumbrcdC6+a521IUHg==",
"dev": true,
"dependencies": {
"cssnano-preset-default": "^5.1.7",
"cssnano-preset-default": "^5.1.8",
"is-resolvable": "^1.1.0",
"lilconfig": "^2.0.3",
"yaml": "^1.10.2"
@ -3114,9 +3115,9 @@
}
},
"node_modules/cssnano-preset-default": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.7.tgz",
"integrity": "sha512-bWDjtTY+BOqrqBtsSQIbN0RLGD2Yr2CnecpP0ydHNafh9ZUEre8c8VYTaH9FEbyOt0eIfEUAYYk5zj92ioO8LA==",
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.8.tgz",
"integrity": "sha512-zWMlP0+AMPBVE852SqTrP0DnhTcTA2C1wAF92TKZ3Va+aUVqLIhkqKlnJIXXdqXD7RN+S1ujuWmNpvrJBiM/vg==",
"dev": true,
"dependencies": {
"css-declaration-sorter": "^6.0.3",
@ -3144,7 +3145,7 @@
"postcss-normalize-url": "^5.0.3",
"postcss-normalize-whitespace": "^5.0.1",
"postcss-ordered-values": "^5.0.2",
"postcss-reduce-initial": "^5.0.1",
"postcss-reduce-initial": "^5.0.2",
"postcss-reduce-transforms": "^5.0.1",
"postcss-svgo": "^5.0.3",
"postcss-unique-selectors": "^5.0.2"
@ -3224,9 +3225,9 @@
}
},
"node_modules/debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
@ -3480,9 +3481,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.3.tgz",
"integrity": "sha512-hfpppjYhqIZB8jrNb0rNceQRkSnBN7QJl3W26O1jUv3F3BkQknqy1YTqVXkFnIcFtBc3Qnv5M7r5Lez2iOLgZA==",
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz",
"integrity": "sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw==",
"dev": true
},
"node_modules/elliptic": {
@ -4224,6 +4225,11 @@
"integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==",
"dev": true
},
"node_modules/flot": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/flot/-/flot-4.2.2.tgz",
"integrity": "sha512-Strct/A27o0TA25X7Z0pxKhwK4djiP1Kjeqj0tkiqrkRu1qYPqfbp5BYuxEL8CWDNtj85Uc0PnG2E2plo1+VMg=="
},
"node_modules/follow-redirects": {
"version": "1.14.5",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
@ -4602,9 +4608,9 @@
}
},
"node_modules/highcharts": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/highcharts/-/highcharts-9.3.1.tgz",
"integrity": "sha512-T5BjvY2CDtqlKRbid1Jd22psBp8tV9+7fm+x7h+EZuXF0OVDLR5128sRuC6WCWVss4cTVzS6PKnlnXKfYskIhw=="
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/highcharts/-/highcharts-9.3.2.tgz",
"integrity": "sha512-I/48gNMvs3hZxZnPRUqLbnlrGZJJ7YPPVr1+fYeZ35p4pSZAOwTmAGbptrjBr7JlF52HmJH9zMbt/I4TPLu9Pg=="
},
"node_modules/highlight.js": {
"version": "10.4.1",
@ -4833,6 +4839,12 @@
"node": ">= 4"
}
},
"node_modules/immutable": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
"integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
"dev": true
},
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -5501,9 +5513,9 @@
"dev": true
},
"node_modules/json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
"dev": true
},
"node_modules/json-schema-traverse": {
@ -5543,18 +5555,18 @@
}
},
"node_modules/jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
"dev": true,
"engines": [
"node >=0.6.0"
],
"dependencies": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"json-schema": "0.4.0",
"verror": "1.10.0"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/levn": {
@ -6353,9 +6365,9 @@
"dev": true
},
"node_modules/postcss": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.1.tgz",
"integrity": "sha512-WqLs/TTzXdG+/A4ZOOK9WDZiikrRaiA+eoEb/jz2DT9KUhMNHgP7yKPO8vwi62ZCsb703Gwb7BMZwDzI54Y2Ag==",
"version": "8.4.4",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.4.tgz",
"integrity": "sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==",
"dev": true,
"dependencies": {
"nanoid": "^3.1.30",
@ -7233,12 +7245,12 @@
}
},
"node_modules/postcss-reduce-initial": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz",
"integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==",
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz",
"integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==",
"dev": true,
"dependencies": {
"browserslist": "^4.16.0",
"browserslist": "^4.16.6",
"caniuse-api": "^3.0.0"
},
"engines": {
@ -7310,9 +7322,9 @@
}
},
"node_modules/postcss-value-parser": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
},
"node_modules/posthtml": {
@ -7353,9 +7365,9 @@
}
},
"node_modules/preact": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.6.1.tgz",
"integrity": "sha512-ydCg+ISIq70vqiThvNWStZWLRjR9U2awP/JAmGdWUKm9+Tyuy+MqVdAIyEByeIspAVtD4GWC/SJtxO8XD4knVA==",
"version": "10.6.2",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.6.2.tgz",
"integrity": "sha512-ppDjurt75nSxyikpyali+uKwRl8CK9N6ntOPovGIEGQagjMLVzEgVqFEsUUyUrqyE9Ch90KE0jmFc9q2QcPLBA==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
@ -7427,27 +7439,27 @@
"dev": true
},
"node_modules/purgecss": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-4.0.3.tgz",
"integrity": "sha512-PYOIn5ibRIP34PBU9zohUcCI09c7drPJJtTDAc0Q6QlRz2/CHQ8ywGLdE7ZhxU2VTqB7p5wkvj5Qcm05Rz3Jmw==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-4.1.3.tgz",
"integrity": "sha512-99cKy4s+VZoXnPxaoM23e5ABcP851nC2y2GROkkjS8eJaJtlciGavd7iYAw2V84WeBqggZ12l8ef44G99HmTaw==",
"dev": true,
"dependencies": {
"commander": "^6.0.0",
"glob": "^7.0.0",
"postcss": "^8.2.1",
"postcss-selector-parser": "^6.0.2"
"commander": "^8.0.0",
"glob": "^7.1.7",
"postcss": "^8.3.5",
"postcss-selector-parser": "^6.0.6"
},
"bin": {
"purgecss": "bin/purgecss.js"
}
},
"node_modules/purgecss/node_modules/commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"dev": true,
"engines": {
"node": ">= 6"
"node": ">= 12"
}
},
"node_modules/qs": {
@ -7803,12 +7815,13 @@
"dev": true
},
"node_modules/sass": {
"version": "1.43.5",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.43.5.tgz",
"integrity": "sha512-WuNm+eAryMgQluL7Mbq9M4EruyGGMyal7Lu58FfnRMVWxgUzIvI7aSn60iNt3kn5yZBMR7G84fAGDcwqOF5JOg==",
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.44.0.tgz",
"integrity": "sha512-0hLREbHFXGQqls/K8X+koeP+ogFRPF4ZqetVB19b7Cst9Er8cOR0rc6RU7MaI4W1JmUShd1BPgPoeqmmgMMYFw==",
"dev": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0"
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0"
},
"bin": {
"sass": "sass.js"
@ -10126,9 +10139,9 @@
}
},
"@parcel/watcher": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.3.tgz",
"integrity": "sha512-PHh5PArr3nYGYVj9z/NSfDmmKEBNrg2bzoFgxzjTRBBxPUKx039x3HF6VGLFIfrghjJxcYn/IeSpdVwfob7KFA==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz",
"integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==",
"dev": true,
"requires": {
"node-addon-api": "^3.2.1",
@ -10150,9 +10163,9 @@
}
},
"@popperjs/core": {
"version": "2.10.2",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz",
"integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ=="
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
"integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ=="
},
"@swc/helpers": {
"version": "0.2.14",
@ -10176,9 +10189,9 @@
}
},
"@types/node": {
"version": "16.11.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.10.tgz",
"integrity": "sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA==",
"version": "16.11.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.11.tgz",
"integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw==",
"dev": true
},
"@types/parse-json": {
@ -10909,9 +10922,9 @@
}
},
"core-js": {
"version": "3.19.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.19.1.tgz",
"integrity": "sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg==",
"version": "3.19.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.19.2.tgz",
"integrity": "sha512-ciYCResnLIATSsXuXnIOH4CbdfgV+H1Ltg16hJFN7/v6OxqnFr/IFGeLacaZ+fHLAm0TBbXwNK9/DNBzBUrO/g==",
"dev": true
},
"core-util-is": {
@ -11163,21 +11176,21 @@
"dev": true
},
"cssnano": {
"version": "5.0.11",
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.11.tgz",
"integrity": "sha512-5SHM31NAAe29jvy0MJqK40zZ/8dGlnlzcfHKw00bWMVFp8LWqtuyPSFwbaoIoxvt71KWJOfg8HMRGrBR3PExCg==",
"version": "5.0.12",
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.12.tgz",
"integrity": "sha512-U38V4x2iJ3ijPdeWqUrEr4eKBB5PbEKsNP5T8xcik2Au3LeMtiMHX0i2Hu9k51FcKofNZumbrcdC6+a521IUHg==",
"dev": true,
"requires": {
"cssnano-preset-default": "^5.1.7",
"cssnano-preset-default": "^5.1.8",
"is-resolvable": "^1.1.0",
"lilconfig": "^2.0.3",
"yaml": "^1.10.2"
}
},
"cssnano-preset-default": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.7.tgz",
"integrity": "sha512-bWDjtTY+BOqrqBtsSQIbN0RLGD2Yr2CnecpP0ydHNafh9ZUEre8c8VYTaH9FEbyOt0eIfEUAYYk5zj92ioO8LA==",
"version": "5.1.8",
"resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.8.tgz",
"integrity": "sha512-zWMlP0+AMPBVE852SqTrP0DnhTcTA2C1wAF92TKZ3Va+aUVqLIhkqKlnJIXXdqXD7RN+S1ujuWmNpvrJBiM/vg==",
"dev": true,
"requires": {
"css-declaration-sorter": "^6.0.3",
@ -11205,7 +11218,7 @@
"postcss-normalize-url": "^5.0.3",
"postcss-normalize-whitespace": "^5.0.1",
"postcss-ordered-values": "^5.0.2",
"postcss-reduce-initial": "^5.0.1",
"postcss-reduce-initial": "^5.0.2",
"postcss-reduce-transforms": "^5.0.1",
"postcss-svgo": "^5.0.3",
"postcss-unique-selectors": "^5.0.2"
@ -11268,9 +11281,9 @@
}
},
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
"dev": true,
"requires": {
"ms": "2.1.2"
@ -11465,9 +11478,9 @@
}
},
"electron-to-chromium": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.3.tgz",
"integrity": "sha512-hfpppjYhqIZB8jrNb0rNceQRkSnBN7QJl3W26O1jUv3F3BkQknqy1YTqVXkFnIcFtBc3Qnv5M7r5Lez2iOLgZA==",
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz",
"integrity": "sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw==",
"dev": true
},
"elliptic": {
@ -12050,6 +12063,11 @@
"integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==",
"dev": true
},
"flot": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/flot/-/flot-4.2.2.tgz",
"integrity": "sha512-Strct/A27o0TA25X7Z0pxKhwK4djiP1Kjeqj0tkiqrkRu1qYPqfbp5BYuxEL8CWDNtj85Uc0PnG2E2plo1+VMg=="
},
"follow-redirects": {
"version": "1.14.5",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
@ -12325,9 +12343,9 @@
}
},
"highcharts": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/highcharts/-/highcharts-9.3.1.tgz",
"integrity": "sha512-T5BjvY2CDtqlKRbid1Jd22psBp8tV9+7fm+x7h+EZuXF0OVDLR5128sRuC6WCWVss4cTVzS6PKnlnXKfYskIhw=="
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/highcharts/-/highcharts-9.3.2.tgz",
"integrity": "sha512-I/48gNMvs3hZxZnPRUqLbnlrGZJJ7YPPVr1+fYeZ35p4pSZAOwTmAGbptrjBr7JlF52HmJH9zMbt/I4TPLu9Pg=="
},
"highlight.js": {
"version": "10.4.1",
@ -12499,6 +12517,12 @@
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"immutable": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
"integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
"dev": true
},
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -12986,9 +13010,9 @@
"dev": true
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
"dev": true
},
"json-schema-traverse": {
@ -13025,14 +13049,14 @@
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
"dev": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"json-schema": "0.4.0",
"verror": "1.10.0"
}
},
@ -13663,9 +13687,9 @@
"dev": true
},
"postcss": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.1.tgz",
"integrity": "sha512-WqLs/TTzXdG+/A4ZOOK9WDZiikrRaiA+eoEb/jz2DT9KUhMNHgP7yKPO8vwi62ZCsb703Gwb7BMZwDzI54Y2Ag==",
"version": "8.4.4",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.4.tgz",
"integrity": "sha512-joU6fBsN6EIer28Lj6GDFoC/5yOZzLCfn0zHAn/MYXI7aPt4m4hK5KC5ovEZXy+lnCjmYIbQWngvju2ddyEr8Q==",
"dev": true,
"requires": {
"nanoid": "^3.1.30",
@ -14313,12 +14337,12 @@
}
},
"postcss-reduce-initial": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz",
"integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==",
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz",
"integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==",
"dev": true,
"requires": {
"browserslist": "^4.16.0",
"browserslist": "^4.16.6",
"caniuse-api": "^3.0.0"
}
},
@ -14363,9 +14387,9 @@
}
},
"postcss-value-parser": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
},
"posthtml": {
@ -14397,9 +14421,9 @@
}
},
"preact": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.6.1.tgz",
"integrity": "sha512-ydCg+ISIq70vqiThvNWStZWLRjR9U2awP/JAmGdWUKm9+Tyuy+MqVdAIyEByeIspAVtD4GWC/SJtxO8XD4knVA=="
"version": "10.6.2",
"resolved": "https://registry.npmjs.org/preact/-/preact-10.6.2.tgz",
"integrity": "sha512-ppDjurt75nSxyikpyali+uKwRl8CK9N6ntOPovGIEGQagjMLVzEgVqFEsUUyUrqyE9Ch90KE0jmFc9q2QcPLBA=="
},
"prelude-ls": {
"version": "1.2.1",
@ -14460,21 +14484,21 @@
"dev": true
},
"purgecss": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-4.0.3.tgz",
"integrity": "sha512-PYOIn5ibRIP34PBU9zohUcCI09c7drPJJtTDAc0Q6QlRz2/CHQ8ywGLdE7ZhxU2VTqB7p5wkvj5Qcm05Rz3Jmw==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/purgecss/-/purgecss-4.1.3.tgz",
"integrity": "sha512-99cKy4s+VZoXnPxaoM23e5ABcP851nC2y2GROkkjS8eJaJtlciGavd7iYAw2V84WeBqggZ12l8ef44G99HmTaw==",
"dev": true,
"requires": {
"commander": "^6.0.0",
"glob": "^7.0.0",
"postcss": "^8.2.1",
"postcss-selector-parser": "^6.0.2"
"commander": "^8.0.0",
"glob": "^7.1.7",
"postcss": "^8.3.5",
"postcss-selector-parser": "^6.0.6"
},
"dependencies": {
"commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"dev": true
}
}
@ -14727,12 +14751,13 @@
"dev": true
},
"sass": {
"version": "1.43.5",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.43.5.tgz",
"integrity": "sha512-WuNm+eAryMgQluL7Mbq9M4EruyGGMyal7Lu58FfnRMVWxgUzIvI7aSn60iNt3kn5yZBMR7G84fAGDcwqOF5JOg==",
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.44.0.tgz",
"integrity": "sha512-0hLREbHFXGQqls/K8X+koeP+ogFRPF4ZqetVB19b7Cst9Er8cOR0rc6RU7MaI4W1JmUShd1BPgPoeqmmgMMYFw==",
"dev": true,
"requires": {
"chokidar": ">=3.0.0 <4.0.0"
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0"
}
},
"saxes": {

View file

@ -7,6 +7,7 @@
"bootstrap-datepicker": "^1.9.0",
"bootstrap-icons": "^1.7.0",
"d3": "^3.5.17",
"flot": "^4.2.2",
"highcharts": "^9.3.1",
"jquery": "^3.6.0",
"js-cookie": "^3.0.1",
@ -21,34 +22,37 @@
"parcel": "^2.0.0"
},
"source": [
"ietf/static/js/ietf.js",
"ietf/static/js/list.js",
"ietf/static/js/document_timeline.js",
"ietf/static/js/d3.js",
"ietf/static/js/fullcalendar.js",
"ietf/static/js/datepicker.js",
"ietf/static/js/highcharts-highcharts.js",
"ietf/static/js/highcharts-highstock.js",
"ietf/static/js/highcharts-exporting.js",
"ietf/static/js/highcharts-offline-exporting.js",
"ietf/static/js/moment.js",
"ietf/static/js/agenda_filter.js",
"ietf/static/js/agenda_materials.js",
"ietf/static/js/agenda_timezone.js",
"ietf/static/js/agenda_personalize.js",
"ietf/static/js/timezone.js",
"ietf/static/js/room_params.js",
"ietf/static/js/week-view.js",
"ietf/static/js/doc-search.js",
"ietf/static/js/stats.js",
"ietf/static/js/moment-timezone-with-data-10-year-range.js",
"ietf/static/css/ietf.scss",
"ietf/static/css/list.scss",
"ietf/static/images/ietflogo-small-transparent.png",
"ietf/static/images/ietflogo.png",
"ietf/static/images/apple-touch-icon.png",
"ietf/static/images/ietf-icon-red3.png",
"ietf/static/images/nopictureavailable.jpg"
"ietf/static/images/ietflogo-small-transparent.png",
"ietf/static/images/ietflogo.png",
"ietf/static/images/nopictureavailable.jpg",
"ietf/static/js/agenda_filter.js",
"ietf/static/js/agenda_materials.js",
"ietf/static/js/agenda_personalize.js",
"ietf/static/js/agenda_timezone.js",
"ietf/static/js/d3.js",
"ietf/static/js/datepicker.js",
"ietf/static/js/doc-search.js",
"ietf/static/js/document_timeline.js",
"ietf/static/js/flot.js",
"ietf/static/js/fullcalendar.js",
"ietf/static/js/highcharts-export-data.js",
"ietf/static/js/highcharts-exporting.js",
"ietf/static/js/highcharts-highcharts.js",
"ietf/static/js/highcharts-highstock.js",
"ietf/static/js/highcharts-offline-exporting.js",
"ietf/static/js/ietf.js",
"ietf/static/js/list.js",
"ietf/static/js/moment-timezone-with-data-10-year-range.js",
"ietf/static/js/moment.js",
"ietf/static/js/review-stats.js",
"ietf/static/js/room_params.js",
"ietf/static/js/stats.js",
"ietf/static/js/timezone.js",
"ietf/static/js/week-view.js"
],
"targets": {
"default": {