Compare commits

...

7 commits

Author SHA1 Message Date
famfo fe49225c9f
Merge 0a76482118 into 7066694571 2026-01-21 23:56:49 +00:00
Kévin Commaille 7066694571
Spec for MSC3824: OAuth 2.0 aware clients (#2272)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Spec / Create release (push) Has been cancelled
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
2026-01-21 10:55:59 +00:00
Kévin Commaille c8c2110c3b
Spec Account management for OAuth 2.0 API (#2270)
Some checks are pending
Spec / 🔎 Validate OpenAPI specifications (push) Waiting to run
Spec / 🔎 Check Event schema examples (push) Waiting to run
Spec / 🔎 Check OpenAPI definitions examples (push) Waiting to run
Spec / 🔎 Check JSON Schemas inline examples (push) Waiting to run
Spec / ⚙️ Calculate baseURL for later jobs (push) Waiting to run
Spec / 🐍 Build OpenAPI definitions (push) Blocked by required conditions
Spec / 📢 Run towncrier for changelog (push) Waiting to run
Spec / 📖 Build the spec (push) Blocked by required conditions
Spec / 🔎 Validate generated HTML (push) Blocked by required conditions
Spec / 📖 Build the historical backup spec (push) Blocked by required conditions
Spec / Create release (push) Blocked by required conditions
Spell Check / Spell Check with Typos (push) Waiting to run
* Spec Account management for OAuth 2.0 API

As per MSC4191.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add changelog

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Fix field name

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Bump Matrix version

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Apply suggestions from code review

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Remove justification

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add fields to example

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Use definition shortcode for account management server metadata

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Use definition shortcode for account management URL query parameters

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Apply suggestion for account management actions

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Add copyright and license

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Remove enum for actions

It doesn't make sense to have the action schema in a separate file now
that only the `type` is shared.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

* Use "server" instead of "homeserver"

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>

---------

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2026-01-20 11:06:45 -07:00
Kévin Commaille 2a3841347e
Spec Additional Error Codes for submitToken endpoint (#2277)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Spec / Create release (push) Has been cancelled
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2026-01-16 17:18:15 +00:00
Kévin Commaille c47fa4d093
Bump docsy to v0.13.0 (#2287)
Some checks are pending
Spec / 🔎 Validate OpenAPI specifications (push) Waiting to run
Spec / 🔎 Check Event schema examples (push) Waiting to run
Spec / 🔎 Check OpenAPI definitions examples (push) Waiting to run
Spec / 🔎 Check JSON Schemas inline examples (push) Waiting to run
Spec / ⚙️ Calculate baseURL for later jobs (push) Waiting to run
Spec / 🐍 Build OpenAPI definitions (push) Blocked by required conditions
Spec / 📢 Run towncrier for changelog (push) Waiting to run
Spec / 📖 Build the spec (push) Blocked by required conditions
Spec / 🔎 Validate generated HTML (push) Blocked by required conditions
Spec / 📖 Build the historical backup spec (push) Blocked by required conditions
Spec / Create release (push) Blocked by required conditions
Spell Check / Spell Check with Typos (push) Waiting to run
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2026-01-15 17:01:07 +00:00
Johannes Marbach fa78688f57
Spec for MSC4356: Recently used emoji (#2291)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Spec / Create release (push) Has been cancelled
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
2026-01-14 09:15:24 +00:00
Kévin Commaille 2cc7e13c09
Remove unused CSS files (#2290)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Spec / Create release (push) Has been cancelled
2026-01-09 11:19:51 +00:00
64 changed files with 841 additions and 1257 deletions

View file

@ -1,8 +1,9 @@
name: "Spec"
env:
HUGO_VERSION: 0.148.1
HUGO_VERSION: 0.153.3
PYTHON_VERSION: 3.13
NODE_VERSION: 24
on:
push:
@ -27,7 +28,7 @@ jobs:
- name: " Setup Node"
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: ${{ env.NODE_VERSION }}
- name: "🔎 Run validator"
run: |
npx @redocly/cli@latest lint data/api/*/*.yaml
@ -201,7 +202,7 @@ jobs:
- name: " Setup Node"
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: ${{ env.NODE_VERSION }}
- name: " Setup Hugo"
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
with:
@ -288,7 +289,7 @@ jobs:
- name: " Setup Node"
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: ${{ env.NODE_VERSION }}
- name: " Setup Hugo"
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
with:

View file

@ -50,7 +50,7 @@ function getHeadings() {
let headings = [];
// First get the anchors in the ToC.
const toc_anchors = document.querySelectorAll("#toc nav a");
const toc_anchors = document.querySelectorAll("#TableOfContents a");
for (const anchor of toc_anchors) {
// Then get the heading from its selector in the anchor's href.
@ -59,7 +59,7 @@ function getHeadings() {
console.error("Got ToC anchor without href");
continue;
}
const heading = document.querySelector(selector);
if (!heading) {
console.error("Heading not found for selector:", selector);
@ -122,13 +122,13 @@ function getCurrentHeading(headings, headerOffset) {
*/
function selectTocEntry(id) {
// Deselect previously selected entries.
const activeEntries = document.querySelectorAll("#toc nav a.active");
const activeEntries = document.querySelectorAll("#TableOfContents a.active");
for (const activeEntry of activeEntries) {
activeEntry.classList.remove('active');
}
// Find the new entry and select it.
const newEntry = document.querySelector(`#toc nav a[href="#${id}"]`);
const newEntry = document.querySelector(`#TableOfContents a[href="#${id}"]`);
if (!newEntry) {
console.error("ToC entry not found for ID:", id);
return;

View file

@ -76,52 +76,126 @@ Custom SCSS for the Matrix spec
scroll-behavior: smooth;
overscroll-behavior: contain;
&>.td-sidebar-nav__section {
& > .td-sidebar-nav__section {
margin-top: 1rem;
}
.td-sidebar-nav__section .ul-1 ul {
padding-left: 0;
}
/* This is to make the width of the items that have sub-items (like room versions)
the same as the width of items that don't (like changelog) */
.pr-md-3, .px-md-3 {
padding-right: 0 !important;
}
.ul-1 > li > a {
padding-left: 1rem !important;
}
.ul-2 > li > a {
padding-left: 2rem !important;
}
a.td-sidebar-link.tree-root {
color: $gray-800;
font-weight: $font-weight-bold;
font-size: 1.3rem;
margin-bottom: 0;
border-bottom: none;
}
a, a.td-sidebar-link {
color: $gray-800;
font-weight: $font-weight-normal;
padding-top: .2rem;
padding-bottom: .2rem;
display: block;
transition: all 100ms ease-in-out;
&:hover {
background-color: $secondary-lighter-background;
color: $gray-800;
.ul-1 ul {
padding-left: 0;
}
&.active, &active:hover {
background-color: $secondary-background;
/* This is to make the width of the items that have sub-items (like room versions)
the same as the width of items that don't (like changelog) */
.pr-md-3, .px-md-3 {
padding-right: 0 !important;
}
.ul-1 > li > a {
padding-left: 1rem !important;
}
.ul-2 > li > a {
padding-left: 2rem !important;
}
}
/* Styles for the table of contents */
& > .td-toc {
padding-top: 1rem;
padding-left: 1.5rem;
/* Add border above the toc */
border-top: 1px solid var(--bs-tertiary-color);
ol {
padding-left: 1rem;
counter-reset: section;
list-style-type: none;
}
#TableOfContents {
/* Remove the space between the title and the ToC */
margin-top: 0;
&>ol>li {
margin-bottom: .5rem;
&>a {
font-weight: $font-weight-bold;
}
}
ol {
padding-left: 0;
}
&>ol>li>a {
padding-left: 1rem;
}
&>ol>li>ol>li>a {
padding-left: 2rem;
}
&>ol>li>ol>li>ol>li>a {
padding-left: 3rem;
}
&>ol>li>ol>li>ol>li>ol>li>a {
padding-left: 4rem;
}
&>ol>li>ol>li>ol>li>ol>li>ol>li>a {
padding-left: 5rem;
}
}
li a:before {
counter-increment: section;
content: counters(section, ".") " ";
}
.td-toc-title {
font-weight: $font-weight-bold;
font-size: 1.3rem;
/* Remove the border under the title */
border-bottom: 0;
/* Remove the space under the title */
margin-bottom: 0;
/* Fix the top of page link color */
a, a:hover {
color: $secondary;
}
}
}
/* Apply the same style to links in the navigation and in the ToC */
& > .td-sidebar-nav__section, & > .td-toc #TableOfContents {
li a.td-sidebar-link.tree-root {
color: $gray-800;
font-weight: $font-weight-bold;
font-size: 1.3rem;
margin-bottom: 0;
border-bottom: none;
}
li a, li a.td-sidebar-link {
color: $gray-800;
font-weight: $font-weight-normal;
padding-top: .2rem;
padding-bottom: .2rem;
transition: all 100ms ease-in-out;
&:hover {
background-color: $secondary-lighter-background;
color: $gray-800;
}
&.active, &active:hover {
background-color: $secondary-background;
}
}
}
}
@ -199,64 +273,6 @@ Custom SCSS for the Matrix spec
scroll-margin-top: 5.5rem;
}
/* Styles for the table of contents */
#toc {
padding-top: .5rem;
padding-left: 1.5rem;
ol {
padding-left: 1rem;
counter-reset: section;
list-style-type: none;
}
#TableOfContents {
&>ol>li {
margin-bottom: .5rem;
&>a {
font-weight: $font-weight-bold;
}
}
ol {
padding-left: 0;
}
&>ol>li>a {
padding-left: 1rem;
}
&>ol>li>ol>li>a {
padding-left: 2rem;
}
&>ol>li>ol>li>ol>li>a {
padding-left: 3rem;
}
&>ol>li>ol>li>ol>li>ol>li>a {
padding-left: 4rem;
}
&>ol>li>ol>li>ol>li>ol>li>ol>li>a {
padding-left: 5rem;
}
}
li a:before {
counter-increment: section;
content: counters(section, ".") " ";
}
#toc-title {
font-weight: $font-weight-bold;
font-size: 1.3rem;
}
}
.endpoints-toc {
summary {
cursor: pointer;

View file

@ -18,6 +18,7 @@ $primary: #FFF;
$secondary: #0098D4;
$dark: #333;
$gray-100: #FBFBFB;
$code-color: #005b7f;
$secondary-background: #E5F5FB;
$secondary-lighter-background: #F4FAFC;

View file

@ -0,0 +1 @@
Add the account management capabilities for the OAuth 2.0 authentication API, as per [MSC4191](https://github.com/matrix-org/matrix-spec-proposals/pull/4191).

View file

@ -0,0 +1 @@
Add OAuth 2.0 aware clients, as per [MSC3824](https://github.com/matrix-org/matrix-spec-proposals/pull/3824).

View file

@ -0,0 +1,3 @@
The optional `submit_url` response parameter of the `/requestToken` endpoints uses the same request
and response parameters and error codes as the Identity Service API's `POST /_matrix/identity/v2/validate/email/submitToken`,
as per [MSC4183](https://github.com/matrix-org/matrix-spec-proposals/pull/4183).

View file

@ -0,0 +1 @@
Add `m.recent_emoji` account data event to track recently used emoji as per [MSC4356](https://github.com/matrix-org/matrix-spec-proposals/pull/4356).

View file

@ -0,0 +1,3 @@
Clarify the error codes that can be returned with a 400 HTTP status code by the `POST /_matrix/identity/v2/validate/email/submitToken`
and `POST /_matrix/identity/v2/validate/msisdn/submitToken` endpoints, introducing the `M_TOKEN_INCORRECT`
error code, as per [MSC4183](https://github.com/matrix-org/matrix-spec-proposals/pull/4183).

View file

@ -0,0 +1 @@
Upgrade to docsy v0.13.0.

View file

@ -0,0 +1 @@
Remove unused leftover CSS files.

View file

@ -166,3 +166,11 @@ sidebar_menu_compact = true
mediaType = "text/markdown"
isPlainText = true
baseName = "checklist"
# Add font media types for downloading KaTeX fonts.
# See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#create-media-types-for-katex-fonts
[mediaTypes]
[mediaTypes.'font/woff']
suffixes = ['woff']
[mediaTypes.'font/woff2']
suffixes = ['woff2']

View file

@ -480,6 +480,13 @@ Currently the OAuth 2.0 API doesn't cover all the use cases of the legacy API,
such as automated applications that cannot use a web browser.
{{% /boxes/note %}}
{{% boxes/note %}}
{{% added-in v="1.18" %}}
A compatibility feature, called [OAuth 2.0 aware clients](#oauth-20-aware-clients),
is available to ease the transition to the OAuth 2.0 API for clients that only
support the legacy API.
{{% /boxes/note %}}
### Authentication API discovery
To discover if a homeserver supports the legacy API, the [`GET /login`](#get_matrixclientv3login)
@ -645,7 +652,7 @@ manage their account like [changing their password](#password-management),
[deactivating their account](#account-deactivation).
With the OAuth 2.0 API, all account management is done via the homeserver's web
UI.
UI that can be accessed by users via the [account management URL](#oauth-20-account-management).
### Legacy API
@ -1612,6 +1619,73 @@ MAY reject weak passwords with an error code `M_WEAK_PASSWORD`.
{{% http-api spec="client-server" api="account_deactivation" %}}
#### OAuth 2.0 aware clients
{{% added-in v="1.18" %}}
This is a compatibility feature to aide clients in the transition to the OAuth
2.0 API. It allows clients that only support the legacy API to make some
less-invasive changes to improve the user experience when talking to a
homeserver that is using the OAuth 2.0 API without actually having to implement
the full OAuth 2.0 API.
##### Client behaviour
For a client to be considered fully OAuth 2.0 aware it MUST:
* Support the [`m.login.sso` authentication flow](#client-login-via-sso).
* Where a `oauth_aware_preferred` value of `true` is present on an `m.login.sso`
flow, *only* offer that auth flow to the user.
* Append `action=login` or `action=register` parameters to the [SSO redirect
endpoints](#get_matrixclientv3loginssoredirect). The client might determine
the value to use based on whether the user clicked a "Login" or "Register"
button.
* Check and honour the [`m.3pid_changes` capability](#m3pid_changes-capability)
so that the user is not offered the ability to add or remove 3PIDs if the
homeserver says the capability is not available.
* Determine if the homeserver is using the OAuth 2.0 API by using
[server metadata discovery](#get_matrixclientv1auth_metadata) from the OAuth
2.0 API.
* If a homeserver is using the OAuth 2.0 API as discovered in the previous step
then the client MUST redirect users to manage their account at the [account
management URL](#oauth-20-account-management), if available, instead of
providing a native UI using the legacy API endpoints.
* If the user wishes to deactivate their account then the client MUST refer
them to the account management URL.
* If the user wishes to sign out a device other than its own then the client
MUST deep link the user to the account management URL by adding the
`action=org.matrix.device_delete` and `device_id=<device_id>` parameters so
that the web UI knows that the user wishes to sign out a device and which
one it is.
Optionally, an OAuth 2.0 aware client MAY:
* Label the SSO button as "Continue" rather than "SSO" when
`oauth_aware_preferred` is `true`. This is because after redirect the server
may then offer a password and/or further upstream IdPs.
* Pass other [account management URL parameters](#account-management-url-parameters)
for context when linking to the account web UI.
##### Server behaviour
For a homeserver to provide support for OAuth 2.0 aware clients it MUST:
* Support the [OAuth 2.0 API](#oauth-20-api).
* Provide an implementation of the [`m.login.sso` authentication flow](#client-login-via-sso)
from the legacy API.
* If password authentication was previously enabled on the homeserver then
provide an implementation of the [`m.login.password` authentication flow](#legacy-login)
from the legacy API.
* Indicate that the `m.login.sso` flow is preferred by setting
`oauth_aware_preferred` to `true`.
* Support a value for the `action` param on the [SSO redirect endpoints](#get_matrixclientv3loginssoredirect).
Additionally, the homeserver SHOULD:
* Advertise the [account management URL](#oauth-20-account-management) in the
[server metadata](#get_matrixclientv1auth_metadata).
### OAuth 2.0 API
{{% added-in v="1.15" %}}
@ -2271,6 +2345,46 @@ The server SHOULD return one of the following responses:
- For other errors, the server returns a `400 Bad Request` response with error
details
#### Account management {id="oauth-20-account-management"}
{{% added-in v="1.18" %}}
All account management is done via the homeserver's web UI.
This specification defines extensions to the [OAuth Authorization Server
Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata)
to offer clients a way to deep-link to the account management capabilities of
the homeserver to allow the user to complete the account management operations
in a browser.
##### Account management URL discovery
The [OAuth 2.0 authorization server metadata](#server-metadata-discovery) is
extended to include the following **optional** fields.
{{% definition path="schemas/oauth2-account-management-server-metadata" %}}
##### Account management URL parameters
The account management URL MAY accept the following minimum query parameters.
{{% definition path="schemas/oauth2-account-management-url" %}}
##### Account management URL actions
Account management actions are unique to the application. They SHOULD follow the
[Common Namespaced Identifier Grammar](/appendices/#common-namespaced-identifier-grammar)
where feasible. The Matrix-specific actions are:
| Action | Description |
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| `org.matrix.profile` | The user wishes to view/edit their profile (name, avatar, contact details). |
| `org.matrix.devices_list` | The user wishes to view a list of their devices. |
| `org.matrix.device_view` | The user wishes to view the details of a specific device. A `device_id` SHOULD be provided. |
| `org.matrix.device_delete` | The user wishes to delete/log out a specific device. A `device_id` SHOULD be provided. |
| `org.matrix.account_deactivate` | The user wishes to deactivate their account. |
| `org.matrix.cross_signing_reset` | The user wishes to reset their cross-signing identity. Servers SHOULD use this action in the URL of the [`m.oauth`](#oauth-authentication) UIA type. |
### Account moderation
#### Account locking
@ -3898,6 +4012,7 @@ that profile.
| [Guest Access](#guest-access) | Optional | Optional | Optional | Optional | Optional |
| [Moderation Policy Lists](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional |
| [OpenID](#openid) | Optional | Optional | Optional | Optional | Optional |
| [Recently used emoji](#recently-used-emoji) | Optional | Optional | Optional | Optional | Optional |
| [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional |
| [Reporting Content](#reporting-content) | Optional | Optional | Optional | Optional | Optional |
| [Rich replies](#rich-replies) | Optional | Optional | Optional | Optional | Optional |
@ -3999,5 +4114,6 @@ systems.
{{% cs-module name="Spaces" filename="spaces" %}}
{{% cs-module name="Event replacements" filename="event_replacements" %}}
{{% cs-module name="Event annotations and reactions" filename="event_annotations" %}}
{{% cs-module name="Recently used emoji" filename="recent_emoji" %}}
{{% cs-module name="Threading" filename="threading" %}}
{{% cs-module name="Reference relations" filename="reference_relations" %}}

View file

@ -0,0 +1,40 @@
### Recently used emoji
{{% added-in v="1.18" %}}
This module enables clients to track a user's cumulated emoji usage across different
devices. The data is stored in the [`m.recent_emoji`](#mrecent_emoji)
global [account data](#client-config) and can, among other things, be used to
generate recommendations in emoji pickers.
#### Events
{{% event event="m.recent_emoji" %}}
#### Client behaviour
What exactly constitutes trackable emoji usage is left as an implementation detail
for clients. It is RECOMMENDED to include sending emoji in both messages and
annotations.
When an emoji is used, the sending client moves (or adds) it to the beginning of
the `recent_emoji` array and increments (or initializes) its counter. This keeps
the array ordered by last usage time which facilitates evaluating the data. How
exactly the client evaluates and uses the collected data is deliberately left
unspecified.
To prevent excessive growth of the event as new emoji are being used, clients
SHOULD limit the length of the `recent_emoji` array by dropping elements from
its end. A RECOMMENDED maximum length is 100 emoji.
To enable future extension, clients MUST tolerate and preserve array elements
within `recent_emoji` regardless of whether they understand or support the
contained `emoji` value. This means ignoring entries with unrecognised values
of `emoji` when deciding what to display to the user while retaining them when
modifying the array (unless the modification is for truncation).
To prevent undefined behavior, clients SHOULD remove array elements that
don't conform to the event schema such as elements with negative counters.

View file

@ -35,6 +35,14 @@ paths:
Unlike other endpoints, this endpoint does not take an `id_access_token`
parameter because the homeserver is expected to sign the request to the
identity server instead.
{{% boxes/warning %}}
{{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients)
MUST NOT use this endpoint when the server supports the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
Instead they MUST refer the user to the [account management URL](/client-server-api/#oauth-20-account-management),
if available, and MAY use the `action=org.matrix.account_deactivate`
parameter.
{{% /boxes/warning %}}
security:
- {}
- accessTokenQuery: []

View file

@ -0,0 +1,29 @@
# Copyright 2026 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
title: Recent Emoji
type: object
properties:
emoji:
type: string
description: The Unicode emoji as string.
example: 🚀
total:
type: number
description: |-
The number of times the emoji has been used.
MUST be non-negative and smaller than 2^53.
required:
- emoji
- total

View file

@ -24,16 +24,23 @@ properties:
submit_url:
type: string
format: uri
x-changedInMatrixVersion:
"1.18": |-
The URL has the same request and response parameters and error codes as
the Identity Service API's endpoint.
description: |-
An optional field containing a URL where the client must submit the
validation token to, with identical parameters to the Identity Service
API's `POST /validate/email/submitToken` endpoint (without the requirement
for an access token). The homeserver must send this token to the user (if
applicable), who should then be prompted to provide it to the client.
validation token, with identical request and response parameters and error
codes to the Identity Service API's
[`POST /validate/email/submitToken`](/identity-service-api/#post_matrixidentityv2validateemailsubmittoken)
and [`POST /validate/msisdn/submitToken`](/identity-service-api/#post_matrixidentityv2validatemsisdnsubmittoken)
endpoints (without the requirement for an access token). The homeserver
must send this token to the user (if applicable), who should then be
prompted to provide it to the client.
If this field is not present, the client can assume that verification
will happen without the client's involvement provided the homeserver
advertises this specification version in the `/versions` response
(ie: r0.5.0).
advertises a sufficiently recent version in the [`GET /versions`](/client-server-api/#get_matrixclientversions)
response (ie: r0.5.0).
example: "https://example.org/path/to/submitToken"
required: ['sid']

View file

@ -86,5 +86,13 @@ properties:
brand usage as intended by the server.
example: "github"
required: ['id', 'name']
oauth_aware_preferred:
type: boolean
x-addedInMatrixVersion: "1.18"
description: |
Whether the `m.login.sso` flow is preferred over other flows. If this is `true`,
[OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients) MUST only
offer this flow to the user.
example: true
required: ['type']

View file

@ -170,6 +170,13 @@ paths:
When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
{{% /boxes/warning %}}
{{% boxes/warning %}}
{{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients)
MUST NOT use this endpoint when the server supports the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
Instead they MUST refer the user to the [account management URL](/client-server-api/#oauth-20-account-management),
if available, with the `action=org.matrix.device_delete` and `device_id={deviceId}` parameters.
{{% /boxes/warning %}}
operationId: deleteDevice
security:
- accessTokenQuery: []
@ -232,6 +239,13 @@ paths:
When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
{{% /boxes/warning %}}
{{% boxes/warning %}}
{{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients)
MUST NOT use this endpoint when the server supports the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
Instead they MUST refer the user to the [account management URL](/client-server-api/#oauth-20-account-management),
if available.
{{% /boxes/warning %}}
operationId: deleteDevices
security:
- accessTokenQuery: []

View file

@ -139,6 +139,32 @@ paths:
items:
type: string
description: A prompt value that the server supports.
account_management_uri:
x-addedInMatrixVersion: "1.18"
type: string
format: uri
description: |-
The URL where the user is able to access the account management capabilities
of the homeserver.
This is an extension [defined in this specification](/client-server-api/#oauth-20-account-management).
account_management_actions_supported:
x-addedInMatrixVersion: "1.18"
type: array
description: |-
List of actions that the account management URL supports.
This is an extension [defined in this specification](/client-server-api/#oauth-20-account-management).
items:
type: string
enum:
- "org.matrix.profile"
- "org.matrix.devices_list"
- "org.matrix.device_view"
- "org.matrix.device_delete"
- "org.matrix.account_deactivate"
- "org.matrix.cross_signing_reset"
description: An action that the account management URL supports.
required:
- issuer
- authorization_endpoint
@ -159,6 +185,15 @@ paths:
"grant_types_supported": ["authorization_code", "refresh_token"],
"response_modes_supported": ["query", "fragment"],
"code_challenge_methods_supported": ["S256"],
"account_management_uri": "https://account.example.com/manage",
"account_management_actions_supported": [
"org.matrix.profile",
"org.matrix.devices_list",
"org.matrix.device_view",
"org.matrix.device_delete",
"org.matrix.account_deactivate",
"org.matrix.cross_signing_reset",
],
}
tags:
- Session management

View file

@ -72,6 +72,15 @@ paths:
`inhibit_login` parameter is not set to `true`, the server MUST return a
400 HTTP status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code.
{{% /boxes/note %}}
{{% boxes/warning %}}
{{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients)
MUST NOT use this endpoint when the server offers the [`m.login.sso`
authentication flow](/client-server-api/#client-login-via-sso) with
`oauth_aware_preferred` set to `true`. Instead they MUST use the
[`/login/sso/redirect`](/client-server-api/#get_matrixclientv3loginssoredirect)
endpoint, adding the `action=register` parameter.
{{% /boxes/warning %}}
operationId: register
parameters:
- in: query

View file

@ -37,6 +37,22 @@ paths:
required: true
schema:
type: string
- in: query
name: action
x-addedInMatrixVersion: "1.18"
description: |-
The action that the user wishes to take at the SSO redirect.
The following values are supported:
* `login`: the SSO redirect is for the purposes of signing an
existing user in.
* `register`: the SSO redirect is for the purpose of registering a
new user account.
schema:
type: string
enum:
- login
- register
responses:
"302":
description: A redirect to the SSO interface.
@ -75,6 +91,22 @@ paths:
required: true
schema:
type: string
- in: query
name: action
x-addedInMatrixVersion: "1.18"
description: |-
The action that the user wishes to take at the SSO redirect.
The following values are supported:
* `login`: the SSO redirect is for the purposes of signing an
existing user in.
* `register`: the SSO redirect is for the purpose of registering a
new user account.
schema:
type: string
enum:
- login
- register
responses:
"302":
description: A redirect to the SSO interface.

View file

@ -153,6 +153,24 @@ paths:
value: {
"success": true
}
"400":
description: |
An error occurred. Some possible errors are:
- {{% added-in v="1.18" %}} `M_TOKEN_INCORRECT`: The token that the user entered to validate the session is
incorrect.
- {{% added-in v="1.18" %}} `M_INVALID_PARAM`: One of the supplied parameters is not valid.
- {{% added-in v="1.18" %}} `M_SESSION_EXPIRED`: The validation session in question has expired.
content:
application/json:
schema:
$ref: ../client-server/definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOKEN_INCORRECT",
"error": "The token is incorrect"
}
"403":
description: |
The user must do something in order to use this endpoint. One example

View file

@ -155,6 +155,24 @@ paths:
value: {
"success": true
}
"400":
description: |
An error occurred. Some possible errors are:
- {{% added-in v="1.18" %}} `M_TOKEN_INCORRECT`: The token that the user entered to validate the session is
incorrect.
- {{% added-in v="1.18" %}} `M_INVALID_PARAM`: One of the supplied parameters is not valid.
- {{% added-in v="1.18" %}} `M_SESSION_EXPIRED`: The validation session in question has expired.
content:
application/json:
schema:
$ref: ../client-server/definitions/errors/error.yaml
examples:
response:
value: {
"errcode": "M_TOKEN_INCORRECT",
"error": "The token is incorrect"
}
"403":
description: |
The user must do something in order to use this endpoint. One example

View file

@ -0,0 +1,16 @@
{
"$ref": "core/event.json",
"type": "m.recent_emoji",
"content": {
"recent_emoji": [{
"emoji": "🤔",
"total": 19
}, {
"emoji": "👍",
"total": 7
}, {
"emoji": "😅",
"total": 84
}]
}
}

View file

@ -0,0 +1,29 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"title": "Recent Emoji Event",
"description": "Lets clients maintain a list of recently used emoji.",
"allOf": [{
"$ref": "core-event-schema/event.yaml"
}],
"properties": {
"type": {
"type": "string",
"enum": ["m.recent_emoji"]
},
"content": {
"type": "object",
"properties": {
"recent_emoji": {
"description": "The list of recently used emoji. Elements in the list are ordered descendingly by last usage time.",
"type": "array",
"items": {
"$ref": "../../api/client-server/definitions/recent_emoji.yaml"
},
}
},
"required": ["recent_emoji"]
}
},
"required": ["type", "content"]
}

View file

@ -0,0 +1,30 @@
# Copyright 2026 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
title: OAuth 2.0 Server Metadata Account Management Extension
properties:
account_management_uri:
type: string
format: uri
description: |-
The URL where the user is able to access the account management capabilities of the
server.
account_management_actions_supported:
type: array
description: |-
List of [actions](/client-server-api/#account-management-url-actions) that the account
management URL supports.
items:
type: string
description: An action that the account management URL supports.

View file

@ -0,0 +1,29 @@
# Copyright 2026 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
type: object
title: OAuth 2.0 Account Management URL Query Parameters
properties:
action:
type: string
description: |-
The action that the user wishes to take. Must match one of the actions advertised by the
server in [`account_management_actions_supported`](/client-server-api/#account-management-url-discovery).
device_id:
type: string
description: |-
For Matrix-specific actions, the user's device ID. Actions which don't support the device ID
will ignore it.
If the `org.matrix.device_view` or `org.matrix.device_delete` actions are advertised as
supported by the server then the server SHOULD support the `device_id` parameter.

2
go.mod
View file

@ -2,4 +2,4 @@ module github.com/matrix-org/matrix-spec
go 1.12
require github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af // indirect
require github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a // indirect

6
go.sum
View file

@ -1,4 +1,4 @@
github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af h1:XghgUC0H5BoGrvtT9/oWBUi+5Zux875qRHhpAZ0RURI=
github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af/go.mod h1:4/t21g/nPraob/DVMm3jrk26k0CDL5I7Mxf+ar0IAgs=
github.com/twbs/bootstrap v5.3.6+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a h1:WB3unuZJy7ewAf33sxbtEwYnC+i+Jt1sJpAR3BtzvEo=
github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a/go.mod h1:mdn1m5HJug6ZddQgrOyCrXNegbtdl5evHiqqbEQLzdI=
github.com/twbs/bootstrap v5.3.8+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=

View file

@ -5,15 +5,7 @@
We use it to send the delimited passthrough element through KaTeX to render maths
in the Olm / Megolm spec.
See: https://gohugo.io/functions/transform/tomath/#step-2
See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#add-passthrough-render-hook
*/ -}}
{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }}
{{- with try (transform.ToMath .Inner $opts) }}
{{- with .Err }}
{{- errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }}
{{- else }}
{{- .Value }}
{{- $.Page.Store.Set "hasMath" true }}
{{- end }}
{{- end -}}
{{ partial "scripts/math.html" . }}

View file

@ -1,28 +1,35 @@
{{/*
A copy of the breadcrumb.html partial in Docsy, modified
to:
A copy of the breadcrumb.html partial in Docsy, modified to:
* show the breadcrumbs by default by removing the `td-breadcrumbs__single`
class
* omit breadcrumbs when this is the homepage
* otherwise, include the homepage in the breadcrumbs
*/}}
{{ if not .IsHome }}
{{ if not .IsHome -}}
<nav aria-label="breadcrumb" class="td-breadcrumbs">
<ol class="breadcrumb">
{{ template "breadcrumbnav" (dict "p1" . "p2" .) }}
</ol>
</nav >
{{ end }}
<ol class="breadcrumb">
{{- template "breadcrumbnav" (dict "p1" . "p2" .) }}
</ol>
</nav>
{{ end -}}
{{ define "breadcrumbnav" }}
{{ if .p1.Parent }}
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }}
{{ else if not .p1.IsHome }}
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
{{ end }}
{{ $isActive := eq .p1 .p2 }}
<li class="breadcrumb-item{{ if $isActive }} active{{ end }}" {{ if $isActive }}aria-current="page"{{ end }}>
<a href="{{ .p1.RelPermalink }}">{{ .p1.LinkTitle }}</a>
</li>
{{ end }}
{{- define "breadcrumbnav" -}}
{{ if .p1.Parent -}}
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) -}}
{{ else if not .p1.IsHome -}}
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) -}}
{{ end -}}
{{ $isActive := eq .p1 .p2 }}
<li class="breadcrumb-item{{ if $isActive }} active{{ end }}"
{{- if $isActive }}aria-current="page"{{ end }}>
{{ if $isActive -}}
{{ .p1.LinkTitle -}}
{{ else -}}
<a href="{{ .p1.RelPermalink }}">{{ .p1.LinkTitle }}</a>
{{- end -}}
</li>
{{- end -}}

View file

@ -1,8 +1,11 @@
{{- /*
A version of the navbar.html partial in Docsy, only modified
to include the spec version, which is calculated using an
inline `version-string` partial.
A copy of the navbar.html partial in Docsy, modified to:
* remove `data-bs-theme` at L20, otherwise the title disappears on hover.
* replace the site title with "specification" at L31.
* include the spec version from the config at L34-35, which is calculated
using an inline `version-string` partial.
*/ -}}
@ -13,8 +16,8 @@
{{ $baseURL := urls.Parse $.Site.Params.Baseurl -}}
<nav class="td-navbar js-navbar-scroll
{{- if $cover }} td-navbar-cover {{- end }}" data-bs-theme="light">
<div class="container-fluid flex-column flex-md-row">
{{- if $cover }} td-navbar-cover {{- end }}">
<div class="td-navbar-container container-fluid flex-column flex-md-row">
<a class="navbar-brand" href="{{ .Site.Home.RelPermalink }}">
{{- /**/ -}}
<span class="navbar-brand__logo navbar-logo">
@ -32,7 +35,8 @@
<span class="navbar-version"> &mdash; {{ partial "version-string" . }}</span>
{{- /**/ -}}
</a>
<div class="td-navbar-nav-scroll ms-md-auto" id="main_navbar">
<div class="td-navbar-nav-scroll td-navbar-nav-scroll--indicator" id="main_navbar">
<div class="scroll-indicator scroll-left"></div>
<ul class="navbar-nav">
{{ $p := . -}}
{{ range .Site.Menus.main -}}
@ -58,39 +62,41 @@
</li>
{{ end -}}
{{ if .Site.Params.versions -}}
<li class="nav-item dropdown d-none d-lg-block">
<li class="nav-item dropdown d-none d-lg-block td-navbar__version-menu">
{{ partial "navbar-version-selector.html" . -}}
</li>
{{ end -}}
{{ if (gt (len .Site.Home.Translations) 0) -}}
<li class="nav-item dropdown d-none d-lg-block">
<li class="nav-item td-navbar__lang-menu">
{{ partial "navbar-lang-selector.html" . -}}
</li>
{{ end -}}
{{ if .Site.Params.ui.showLightDarkModeMenu -}}
<li class="td-light-dark-menu nav-item dropdown">
{{- $darkMode := partialCached "dark-mode-config.html" "dark-mode-global" -}}
{{ if $darkMode.showMenu -}}
<li class="nav-item td-navbar__light-dark-menu">
{{ partial "theme-toggler" . }}
</li>
{{ end -}}
</ul>
<div class="scroll-indicator scroll-right"></div>
</div>
<div class="d-none d-lg-block">
<div class="d-none d-lg-block td-navbar__search">
{{ partial "search-input.html" . }}
</div>
</div>
</nav>
{{ define "_partials/version-string" }}
{{ $ret := "unstable version"}}
{{- define "_partials/version-string" -}}
{{ $ret := "unstable version" -}}
{{ $status := .Site.Params.version.status }}
{{ $status := .Site.Params.version.status -}}
{{ if ne $status "unstable"}}
{{ $path := path.Join "changelogs" }}
{{ if ne $status "unstable" -}}
{{ $path := path.Join "changelogs" -}}
{{/* produces a string similar to "version v1.5" */}}
{{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" }}
{{ end }}
{{/* produces a string similar to "version v1.5" */ -}}
{{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" -}}
{{ end -}}
{{ return $ret }}
{{ end }}
{{ return $ret -}}
{{- end -}}

View file

@ -1,37 +1,57 @@
{{- /*
A modified version of the siderbar-tree.html partial in Docsy, adding:
* The "toc.html" partial at L45.
A copy of the siderbar-tree.html partial in Docsy, modified to:
* Ignore the `sidebarRoot` parameter, because of this regression:
<https://github.com/google/docsy/issues/2426>
* Add the "toc.html" partial at L68.
*/ -}}
{{/* We cache this partial for bigger sites and set the active class client side. */ -}}
{{ $sidebarCacheLimit := .Site.Params.ui.sidebar_cache_limit | default 2000 -}}
{{ $shouldDelayActive := ge (len .Site.Pages) $sidebarCacheLimit -}}
{{ $context := .context -}}
{{ $sidebarRoot := .sidebarRoot -}}
{{ $sidebarRootID := .sidebarRootID -}}
{{ $cacheSidebar := .cacheSidebar -}}
{{ with $context -}}
{{/* When the sidebar is cached, "active" class is set client side. */ -}}
{{ $shouldDelayActive := $cacheSidebar -}}
<div id="td-sidebar-menu" class="td-sidebar__inner{{ if $shouldDelayActive }} d-none{{ end }}">
{{ if not .Site.Params.ui.sidebar_search_disable -}}
<form class="td-sidebar__search d-flex align-items-center">
{{ partial "search-input.html" . }}
<button class="btn btn-link td-sidebar__toggle d-md-none p-0 ms-3 fas fa-bars" type="button" data-bs-toggle="collapse" data-bs-target="#td-section-nav" aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
<button class="btn btn-link td-sidebar__toggle" type="button" {{/**/ -}}
data-bs-toggle="collapse" data-bs-target="#td-section-nav" {{/**/ -}}
aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
</button>
</form>
{{ else -}}
{{- else -}}
<div id="content-mobile">
<form class="td-sidebar__search d-flex align-items-center">
{{ partial "search-input.html" . }}
<button class="btn btn-link td-sidebar__toggle d-md-none p-0 ms-3 fas fa-bars" type="button" data-bs-toggle="collapse" data-bs-target="#td-section-nav" aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
<button class="btn btn-link td-sidebar__toggle" type="button" {{/**/ -}}
data-bs-toggle="collapse" data-bs-target="#td-section-nav" {{/**/ -}}
aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
</button>
</form>
</div>
<div id="content-desktop"></div>
{{ end -}}
{{- end }}
{{/* */ -}}
<nav class="td-sidebar-nav collapse
{{- if .Site.Params.ui.sidebar_search_disable }} td-sidebar-nav--search-disabled{{ end -}}
{{- if .Site.Params.ui.sidebar_menu_foldable }} foldable-nav{{ end -}}
" id="td-section-nav">
{{ if (gt (len .Site.Home.Translations) 0) -}}
<div class="td-sidebar-nav__section nav-item dropdown d-block d-lg-none">
{{- if .Site.Params.ui.sidebar_search_disable }} td-sidebar-nav--search-disabled{{ end -}}
{{- if .Site.Params.ui.sidebar_menu_foldable }} foldable-nav{{ end }}" {{/**/ -}}
id="td-section-nav"
{{- if .Site.Params.ui.sidebar_root_enabled }} data-sidebar-root-id="{{ $sidebarRootID }}"{{ end -}}
>
{{ if and .Site.Params.ui.sidebar_lang_menu (gt (len .Site.Home.Translations) 0) -}}
<div class="td-sidebar-nav__section nav-item d-block d-lg-none">
{{ partial "navbar-lang-selector.html" . }}
</div>
{{ end -}}
@ -45,44 +65,129 @@
{{ partial "toc.html" . }}
</nav>
</div>
{{- end }}{{/* with $context */ -}}
{{ define "section-tree-nav-section" -}}
{{ $s := .section -}}
{{ $p := .page -}}
{{ $shouldDelayActive := .shouldDelayActive -}}
{{ $sidebarMenuTruncate := .sidebarMenuTruncate -}}
{{ $treeRoot := cond (eq .ulNr 0) true false -}}
{{ $ulNr := .ulNr -}}
{{ $ulShow := .ulShow -}}
{{ $active := and (not $shouldDelayActive) (eq $s $p) -}}
{{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}}
{{ $show := cond (or (lt $ulNr $ulShow) $activePath (and (not $shouldDelayActive) (eq $s.Parent $p.Parent)) (and (not $shouldDelayActive) (eq $s.Parent $p)) (not $p.Site.Params.ui.sidebar_menu_compact) (and (not $shouldDelayActive) ($p.IsDescendant $s.Parent))) true false -}}
{{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}}
{{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}}
{{ $pages := $pages_tmp | first $sidebarMenuTruncate -}}
{{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}}
{{ if gt $truncatedEntryCount 0 -}}
{{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s"
$truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}}
{{ end -}}
{{ $withChild := gt (len $pages) 0 -}}
{{ $manualLink := cond (isset $s.Params "manuallink") $s.Params.manualLink ( cond (isset $s.Params "manuallinkrelref") (relref $s $s.Params.manualLinkRelref) $s.RelPermalink) -}}
{{ $manualLinkTitle := cond (isset $s.Params "manuallinktitle") $s.Params.manualLinkTitle $s.Title -}}
<li class="td-sidebar-nav__section-title td-sidebar-nav__section{{ if $withChild }} with-child{{ else }} without-child{{ end }}{{ if $activePath }} active-path{{ end }}{{ if (not (or $show $p.Site.Params.ui.sidebar_menu_foldable )) }} collapse{{ end }}" id="{{ $mid }}-li">
{{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}}
<input type="checkbox" id="{{ $mid }}-check"{{ if $activePath}} checked{{ end }}/>
<label for="{{ $mid }}-check"><a href="{{ $manualLink }}"{{ if ne $s.LinkTitle $manualLinkTitle }} title="{{ $manualLinkTitle }}"{{ end }}{{ with $s.Params.manualLinkTarget }} target="{{ . }}"{{ if eq . "_blank" }} rel="noopener"{{ end }}{{ end }} class="align-left ps-0 {{ if $active}} active{{ end }} td-sidebar-link{{ if $s.IsPage }} td-sidebar-link__page{{ else }} td-sidebar-link__section{{ end }}{{ if $treeRoot }} tree-root{{ end }}" id="{{ $mid }}">{{ with $s.Params.Icon}}<i class="{{ . }}"></i>{{ end }}<span class="{{ if $active }}td-sidebar-nav-active-item{{ end }}">{{ $s.LinkTitle }}</span></a></label>
{{ else -}}
<a href="{{ $manualLink }}"{{ if ne $s.LinkTitle $manualLinkTitle }} title="{{ $manualLinkTitle }}"{{ end }}{{ with $s.Params.manualLinkTarget }} target="{{ . }}"{{ if eq . "_blank" }} rel="noopener"{{ end }}{{ end }} class="align-left ps-0{{ if $active}} active{{ end }} td-sidebar-link{{ if $s.IsPage }} td-sidebar-link__page{{ else }} td-sidebar-link__section{{ end }}{{ if $treeRoot }} tree-root{{ end }}" id="{{ $mid }}">{{ with $s.Params.Icon}}<i class="{{ . }}"></i>{{ end }}<span class="{{ if $active }}td-sidebar-nav-active-item{{ end }}">{{ $s.LinkTitle }}</span></a>
{{- end }}
{{- if $withChild }}
{{- $ulNr := add $ulNr 1 }}
<ul class="ul-{{ $ulNr }}{{ if (gt $ulNr 1)}} foldable{{end}}">
{{ range $pages -}}
{{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}}
{{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }}
{{/* cSpell:ignore manuallink manuallinkrelref manuallinktitle */ -}}
{{ $s := .section -}}
{{ $p := .page -}}
{{ $shouldDelayActive := .shouldDelayActive -}}
{{ $sidebarMenuTruncate := .sidebarMenuTruncate -}}
{{ $treeRoot := cond (eq .ulNr 0) true false -}}
{{ $ulNr := .ulNr -}}
{{ $ulShow := .ulShow -}}
{{ $active := and (not $shouldDelayActive) (eq $s $p) -}}
{{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}}
{{ $show := cond
(or
(lt $ulNr $ulShow)
$activePath
(and (not $shouldDelayActive) (eq $s.Parent $p.Parent))
(and (not $shouldDelayActive) (eq $s.Parent $p))
(not $p.Site.Params.ui.sidebar_menu_compact)
(and (not $shouldDelayActive) ($p.IsDescendant $s.Parent))
)
true false
-}}
{{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}}
{{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}}
{{ $pages := $pages_tmp | first $sidebarMenuTruncate -}}
{{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}}
{{ if gt $truncatedEntryCount 0 -}}
{{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s"
$truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}}
{{ end -}}
{{ $withChild := gt (len $pages) 0 -}}
{{ $manualLink :=
cond
(isset $s.Params "manuallink")
$s.Params.manualLink
(cond
(isset $s.Params "manuallinkrelref")
(relref $s $s.Params.manualLinkRelref)
$s.RelPermalink
)
-}}
{{ $manualLinkTitle :=
cond
(isset $s.Params "manuallinktitle")
$s.Params.manualLinkTitle
$s.Title
-}}
{{ if and $treeRoot (eq $s.Params.sidebar_root_for "self") -}}
{{ with $s.Parent -}}
{{ $manualLink = .RelPermalink -}}
{{ end -}}
{{ end -}}
<li class="td-sidebar-nav__section-title td-sidebar-nav__section
{{- if $withChild }} with-child{{ else }} without-child{{ end -}}
{{ if $activePath }} active-path{{ end -}}
{{ if (not (or $show $p.Site.Params.ui.sidebar_menu_foldable )) }} collapse{{ end -}}
" {{/**/ -}}
id="{{ $mid }}-li" {{- /**/ -}}
>
{{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}}
<input type="checkbox" id="{{ $mid }}-check"{{ if $activePath}} checked{{ end }}/>
<label for="{{ $mid }}-check">{{/**/ -}}
<a href="{{ $manualLink }}"
{{- if ne $s.LinkTitle $manualLinkTitle }} {{/**/ -}}
title="{{ $manualLinkTitle }}"
{{- end -}}
{{ with $s.Params.manualLinkTarget }} {{/**/ -}}
target="{{ . }}"
{{- if eq . "_blank" }} rel="noopener"{{ end -}}
{{ end }} {{/**/ -}}
class="align-left ps-0 {{ if $active}} active{{ end }} td-sidebar-link
{{- if $s.IsPage }} td-sidebar-link__page
{{- else }} td-sidebar-link__section
{{- end }}
{{- if $treeRoot }} tree-root{{ end }}" {{/**/ -}}
id="{{ $mid }}" {{- /**/ -}}
>
{{- with $s.Params.Icon -}}
<i class="{{ . }}"></i>
{{- end -}}
<span class="{{ if $active }}td-sidebar-nav-active-item{{ end }}">
{{- $s.LinkTitle -}}
</span> {{- /**/ -}}
</a> {{- /**/ -}}
</label>
{{ else -}}
<a href="{{ $manualLink }}"
{{- if ne $s.LinkTitle $manualLinkTitle }} title="{{ $manualLinkTitle }}"{{ end -}}
{{ with $s.Params.manualLinkTarget }} {{/**/ -}}
target="{{ . }}"
{{- if eq . "_blank" }} rel="noopener"{{ end -}}
{{ end }} {{/**/ -}}
class="align-left ps-0
{{- if $active}} active{{ end }} {{/**/ -}}
td-sidebar-link
{{- if $s.IsPage }} td-sidebar-link__page{{ else }} td-sidebar-link__section{{ end }}
{{- if $treeRoot }} tree-root{{ end }}" {{/**/ -}}
id="{{ $mid }}" {{- /**/ -}}
>
{{- with $s.Params.Icon -}}
<i class="{{ . }}"></i>
{{- end -}}
<span class="
{{- if $active }}td-sidebar-nav-active-item{{ end -}}
{{- if and $s.Params.sidebar_root_for site.Params.ui.sidebar_root_enabled }} td-sidebar-root-up-icon{{ end -}}
">
{{- $s.LinkTitle -}}
</span></a>
{{- end -}}
{{ if $withChild -}}
{{ $ulNr := add $ulNr 1 }}
<ul class="ul-{{ $ulNr }}{{ if (gt $ulNr 1)}} foldable{{end}}">
{{ range $pages -}}
{{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}}
{{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }}
{{- end }}
{{- end }}
</ul>
{{- end }}
{{- end }}
</ul>
{{- end }}
</li>
{{- end -}}
</li>
{{- end }}

View file

@ -1,15 +1,29 @@
{{/*
A modified version of the toc.html partial in Docsy.
A copy of the toc.html partial in Docsy, modified to:
*/}}
{{ $page := .Params }}
* show the page's title instead of "on this page"
*/ -}}
{{/*
Always render the td-toc element. ScrollSpy is counting on it to exist,
even if it's empty.
cSpell:ignore notoc
*/ -}}
<div class="td-toc" data-proofer-ignore>
{{ if not .Params.notoc -}}
{{ with .TableOfContents -}}
<hr>
<div id="toc">
<a id="toc-title" href="#">{{ $page.Title }}</a>
{{ . }}
{{ $toc := .TableOfContents -}}
{{ if and $toc (ne $toc `<nav id="TableOfContents"></nav>`) -}}
<div class="td-toc-title">
<span class="td-toc-title__text">{{ .Params.Title }}</span>
<a class="td-toc-title__link" title="{{ i18n "toc_top_of_page" }}" href="#"></a>
</div>
{{ $toc | safeHTML }}
{{ end -}}
{{ end -}}
</div>
{{/* */ -}}

View file

@ -1,11 +1,14 @@
{{/*
A copy of the baseof.html partial in Docsy, modified
to remove the right-hand column from the layout.
A copy of the baseof.html partial in Docsy, modified to:
*/}}
* generate a static file `versions.json` that can be used to populate the
version picker.
* remove the right-hand column from the layout.
{{/* Generate a static file versions.json that can be used to populate the version picker */}}
*/ -}}
{{/* Generate a static file versions.json that can be used to populate the version picker */ -}}
{{ if .IsHome }}
{{- /* Load all changelog subpages, sorted by release date */ -}}
{{ $changelog := site.GetPage "changelog" }}
@ -28,20 +31,18 @@
<html itemscope itemtype="http://schema.org/WebPage"
{{- with .Site.Language.LanguageDirection }} dir="{{ . }}" {{- end -}}
{{ with .Site.Language.Lang }} lang="{{ . }}" {{- end }} {{/**/ -}}
class="no-js">
class="no-js"
{{- $darkMode := partialCached "dark-mode-config.html" "dark-mode-global" -}}
{{- if $darkMode.enable }} data-theme-init{{ end }}>
<head>
{{ partial "head.html" . }}
{{ if .Page.Store.Get "hasMath" }}
<link href="{{ relURL "css/katex.min.css" }}" rel="preload" as="style">
<link href="{{ relURL "css/katex.min.css" }}" rel="stylesheet">
{{ end }}
</head>
<body class="td-{{ .Kind }}{{ with .Page.Params.body_class }} {{ . }}{{ end }}">
<header>
{{ partial "navbar.html" . }}
</header>
<div class="container-fluid td-outer">
<div class="td-main">
<div class="td-main" {{- partialCached "td/scrollspy-attr.txt" . .Section | safeHTMLAttr }}>
<div class="row flex-xl-nowrap">
<aside class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none">
{{ partial "sidebar.html" . }}

View file

@ -1,572 +0,0 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
img {
border: 0;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- general body styles --------------------------------------------------- */
a.headerlink {
visibility: hidden;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
div.document p.caption {
text-align: inherit;
}
div.document td {
text-align: left;
}
.field-list ul {
padding-left: 1em;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
.align-left {
text-align: left;
}
.align-center {
clear: both;
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
background-color: #ffe;
width: 40%;
float: right;
}
p.sidebar-title {
font-weight: bold;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.document p.centered {
text-align: center;
margin-top: 25px;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border: 0;
border-collapse: collapse;
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.field-list td, table.field-list th {
border: 0 !important;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
table.colwidths-auto caption {
font-family: 'Inconsolata', monospace;
font-weight: 800;
font-size: 120%;
padding: 5px;
text-align: left;
margin-bottom: 2px;
}
.section ol, .section li {
margin: 0px 0px 0px 30px !important;
}
p.httpheaders {
font-weight: 800;
font-size: 120%;
padding: 5px;
text-align: left;
margin-bottom: 2px;
}
table.colwidths-auto {
width:100%;
margin-top: 20px;
}
table.colwidths-auto tr td:nth-child(1) {
width: 15%;
}
table.colwidths-auto tr td:nth-child(2) {
width: 15%;
font-family: 'Inconsolata', monospace;
}
table.colwidths-auto tr td:nth-child(3) {
width: 70%;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
dl {
margin-bottom: 15px;
}
dd p {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dt:target, .highlighted {
background-color: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.refcount {
color: #060;
}
.optional {
font-size: 1.3em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
/* -- proposals page -------------------------------------------------------- */
#tables-of-tracked-proposals h2 {
padding-left: 10px;
position: -webkit-sticky;
position: sticky;
}
/* Move sticky headers below header bar on desktop */
@media all and (min-width:980px) {
#tables-of-tracked-proposals h2 {
top: 52px;
}
}
/* Sticky headers stick to the top on mobile */
@media all and (min-width:0px) and (max-width: 980px) {
#tables-of-tracked-proposals h2 {
top: 0px;
}
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
}
tt.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
tt.descclassname {
background-color: transparent;
}
tt.xref, a tt {
background-color: transparent;
font-weight: bold;
}
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.document div.math p {
text-align: center;
}
span.eqno {
float: right;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

View file

@ -1,4 +0,0 @@
blockquote {
margin: 20px 0 30px;
padding-left: 20px;
}

View file

@ -1,16 +0,0 @@
pre.code .comment, code .comment { color: green }
pre.code .keyword, code .keyword { color: darkred; font-weight: bold }
pre.code .name.builtin, code .name.builtin { color: darkred; font-weight: bold }
pre.code .name.tag, code .name.tag { color: darkgreen }
pre.code .literal, code .literal { color: darkblue }
pre.code .literal.number, code .literal.number { color: blue }
/* HTTP Methods have class "name function" */
pre.code.http .name.function, code.http .name.function { color: black; font-weight: bold }
/* HTTP Paths have class "name namespace" */
pre.code.http .name.namespace, code.http .name.namespace { color: darkgreen }
/* HTTP "HTTP" strings have class "keyword reserved" */
pre.code.http .keyword.reserved, code.http .keyword.reserved { color: black; font-weight: bold }
/* HTTP Header names have class "name attribute" */
pre.code.http .name.attribute, code.http .name.attribute { color: black; font-weight: bold }

View file

@ -1,295 +0,0 @@
/*
* nature.css_t
* ~~~~~~~~~~~~
*
* Sphinx stylesheet -- nature theme.
*
* :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- page layout ----------------------------------------------------------- */
body {
font-family: Arial, sans-serif;
font-size: 100%;
/*background-color: #111;*/
color: #555;
margin: 0;
padding: 0;
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
hr {
border: 1px solid #B1B4B6;
}
/*
div.document {
background-color: #eee;
}
*/
div.document {
background-color: #ffffff;
color: #3E4349;
padding: 0 30px 30px 30px;
font-size: 0.9em;
}
div.footer {
color: #555;
width: 100%;
padding: 13px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: #444;
text-decoration: underline;
}
div.related {
background-color: #6BA81E;
line-height: 32px;
color: #fff;
text-shadow: 0px 1px 0 #444;
font-size: 0.9em;
}
div.related a {
color: #E2F3CC;
}
div.sphinxsidebar {
font-size: 0.75em;
line-height: 1.5em;
}
div.sphinxsidebarwrapper{
padding: 20px 0;
}
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Arial, sans-serif;
color: #222;
font-size: 1.2em;
font-weight: normal;
margin: 0;
padding: 5px 10px;
background-color: #ddd;
text-shadow: 1px 1px 0 white
}
div.sphinxsidebar h4{
font-size: 1.1em;
}
div.sphinxsidebar h3 a {
color: #444;
}
div.sphinxsidebar p {
color: #888;
padding: 5px 20px;
}
div.sphinxsidebar p.topless {
}
div.sphinxsidebar ul {
margin: 10px 20px;
padding: 0;
color: #000;
}
div.sphinxsidebar a {
color: #444;
}
div.sphinxsidebar input {
border: 1px solid #ccc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar input[type=text]{
margin-left: 20px;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: #005B81;
text-decoration: none;
}
a:hover {
color: #E32E00;
text-decoration: underline;
}
div.document h1,
div.document h2,
div.document h3,
div.document h4,
div.document h5,
div.document h6 {
font-family: Arial, sans-serif;
background-color: #BED4EB;
font-weight: normal;
color: #212224;
margin: 30px 0px 10px 0px;
padding: 5px 0 5px 10px;
text-shadow: 0px 1px 0 white
}
div.document h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }
div.document h2 { font-size: 150%; background-color: #C8D5E3; }
div.document h3 { font-size: 120%; background-color: #D8DEE3; }
div.document h4 { font-size: 110%; background-color: #D8DEE3; }
div.document h5 { font-size: 100%; background-color: #D8DEE3; }
div.document h6 { font-size: 100%; background-color: #D8DEE3; }
a.headerlink {
color: #c60f0f;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: #c60f0f;
color: white;
}
div.document p, div.document dd, div.document li {
line-height: 1.5em;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.highlight{
background-color: white;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 10px;
background-color: White;
color: #222;
line-height: 1.2em;
border: 1px solid #C6C9CB;
font-size: 1.1em;
margin: 1.5em 0 1.5em 0;
-webkit-box-shadow: 1px 1px 1px #d8d8d8;
-moz-box-shadow: 1px 1px 1px #d8d8d8;
}
tt {
background-color: #ecf0f3;
color: #222;
/* padding: 1px 2px; */
font-size: 1.1em;
font-family: monospace;
}
.viewcode-back {
font-family: Arial, sans-serif;
}
div.viewcode-block:target {
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
ul li dd {
margin-top: 0;
}
ul li dl {
margin-bottom: 0;
}
li dl dd {
margin-bottom: 0;
}
dd ul {
padding-left: 0;
}
li dd ul {
margin-bottom: 0;
}
table {
margin-top: 10px;
margin-bottom: 10px;
border: 0;
border-collapse: collapse;
}
td[colspan]:not([colspan="1"]) {
background: #eeeeee;
text-transform: capitalize;
}
thead {
background: #eeeeee;
}
div.admonition-rationale {
background-color: #efe;
border: 1px solid #ccc;
}
div.admonition-example {
background-color: #eef;
border: 1px solid #ccc;
}
div#table-of-contents ul {
list-style-type: none;
}

View file

@ -1,83 +0,0 @@
/*
Original styles generated from:
pygmentize -f html -S colorful -a pre.code > ./scripts/css/pygments.css
Rules for which we don't want the syntax highlighter to kick in are commented
out at the bottom.
Windows users: if you regenerate this file, you'll need to re-save it as utf-8
to make docutils happy.
*/
/* DIFFS */
pre.code .gd { color: #A00000 } /* Generic.Deleted */
pre.code .gi { color: #00A000 } /* Generic.Inserted */
/* UNUSED */
/*pre.code .hll { background-color: #ffffcc }*/
/*pre.code { background: #ffffff; }*/
/*pre.code .c { color: #888888 } !* Comment *!*/
/*pre.code .err { color: #FF0000; background-color: #FFAAAA } !* Error *!*/
/*pre.code .k { color: #008800; font-weight: bold } !* Keyword *!*/
/*pre.code .o { color: #333333 } !* Operator *!*/
/*pre.code .ch { color: #888888 } !* Comment.Hashbang *!*/
/*pre.code .cm { color: #888888 } !* Comment.Multiline *!*/
/*pre.code .cp { color: #557799 } !* Comment.Preproc *!*/
/*pre.code .cpf { color: #888888 } !* Comment.PreprocFile *!*/
/*pre.code .c1 { color: #888888 } !* Comment.Single *!*/
/*pre.code .cs { color: #cc0000; font-weight: bold } !* Comment.Special *!*/
/*pre.code .ge { font-style: italic } !* Generic.Emph *!*/
/*pre.code .gr { color: #FF0000 } !* Generic.Error *!*/
/*pre.code .gh { color: #000080; font-weight: bold } !* Generic.Heading *!*/
/*pre.code .go { color: #888888 } !* Generic.Output *!*/
/*pre.code .gp { color: #c65d09; font-weight: bold } !* Generic.Prompt *!*/
/*pre.code .gs { font-weight: bold } !* Generic.Strong *!*/
/*pre.code .gu { color: #800080; font-weight: bold } !* Generic.Subheading *!*/
/*pre.code .gt { color: #0044DD } !* Generic.Traceback *!*/
/*pre.code .kc { color: #008800; font-weight: bold } !* Keyword.Constant *!*/
/*pre.code .kd { color: #008800; font-weight: bold } !* Keyword.Declaration *!*/
/*pre.code .kn { color: #008800; font-weight: bold } !* Keyword.Namespace *!*/
/*pre.code .kp { color: #003388; font-weight: bold } !* Keyword.Pseudo *!*/
/*pre.code .kr { color: #008800; font-weight: bold } !* Keyword.Reserved *!*/
/*pre.code .kt { color: #333399; font-weight: bold } !* Keyword.Type *!*/
/*pre.code .m { color: #6600EE; font-weight: bold } !* Literal.Number *!*/
/*pre.code .s { background-color: #fff0f0 } !* Literal.String *!*/
/*pre.code .na { color: #0000CC } !* Name.Attribute *!*/
/*pre.code .nb { color: #007020 } !* Name.Builtin *!*/
/*pre.code .nc { color: #BB0066; font-weight: bold } !* Name.Class *!*/
/*pre.code .no { color: #003366; font-weight: bold } !* Name.Constant *!*/
/*pre.code .nd { color: #555555; font-weight: bold } !* Name.Decorator *!*/
/*pre.code .ni { color: #880000; font-weight: bold } !* Name.Entity *!*/
/*pre.code .ne { color: #FF0000; font-weight: bold } !* Name.Exception *!*/
/*pre.code .nf { color: #0066BB; font-weight: bold } !* Name.Function *!*/
/*pre.code .nl { color: #997700; font-weight: bold } !* Name.Label *!*/
/*pre.code .nn { color: #0e84b5; font-weight: bold } !* Name.Namespace *!*/
/*pre.code .nt { color: #007700 } !* Name.Tag *!*/
/*pre.code .nv { color: #996633 } !* Name.Variable *!*/
/*pre.code .ow { color: #000000; font-weight: bold } !* Operator.Word *!*/
/*pre.code .w { color: #bbbbbb } !* Text.Whitespace *!*/
/*pre.code .mb { color: #6600EE; font-weight: bold } !* Literal.Number.Bin *!*/
/*pre.code .mf { color: #6600EE; font-weight: bold } !* Literal.Number.Float *!*/
/*pre.code .mh { color: #005588; font-weight: bold } !* Literal.Number.Hex *!*/
/*pre.code .mi { color: #0000DD; font-weight: bold } !* Literal.Number.Integer *!*/
/*pre.code .mo { color: #4400EE; font-weight: bold } !* Literal.Number.Oct *!*/
/*pre.code .sa { background-color: #fff0f0 } !* Literal.String.Affix *!*/
/*pre.code .sb { background-color: #fff0f0 } !* Literal.String.Backtick *!*/
/*pre.code .sc { color: #0044DD } !* Literal.String.Char *!*/
/*pre.code .dl { background-color: #fff0f0 } !* Literal.String.Delimiter *!*/
/*pre.code .sd { color: #DD4422 } !* Literal.String.Doc *!*/
/*pre.code .s2 { background-color: #fff0f0 } !* Literal.String.Double *!*/
/*pre.code .se { color: #666666; font-weight: bold; background-color: #fff0f0 } !* Literal.String.Escape *!*/
/*pre.code .sh { background-color: #fff0f0 } !* Literal.String.Heredoc *!*/
/*pre.code .si { background-color: #eeeeee } !* Literal.String.Interpol *!*/
/*pre.code .sx { color: #DD2200; background-color: #fff0f0 } !* Literal.String.Other *!*/
/*pre.code .sr { color: #000000; background-color: #fff0ff } !* Literal.String.Regex *!*/
/*pre.code .s1 { background-color: #fff0f0 } !* Literal.String.Single *!*/
/*pre.code .ss { color: #AA6600 } !* Literal.String.Symbol *!*/
/*pre.code .bp { color: #007020 } !* Name.Builtin.Pseudo *!*/
/*pre.code .fm { color: #0066BB; font-weight: bold } !* Name.Function.Magic *!*/
/*pre.code .vc { color: #336699 } !* Name.Variable.Class *!*/
/*pre.code .vg { color: #dd7700; font-weight: bold } !* Name.Variable.Global *!*/
/*pre.code .vi { color: #3333BB } !* Name.Variable.Instance *!*/
/*pre.code .vm { color: #996633 } !* Name.Variable.Magic *!*/
/*pre.code .il { color: #0000DD; font-weight: bold } !* Literal.Number.Integer.Long *!*/

View file

@ -1,4 +0,0 @@
/* Column with header cells */
table.docutils tbody th.stub {
background: #eeeeee;
}

View file

@ -1,41 +0,0 @@
#!/bin/bash
#
# Download the KaTeX fonts and CSS, and copy them into `static`.
set -e
root=$(dirname "$0")/..
# Check that the caller supplied a version.
version=$1
if [[ -z $1 || $1 = "-h" || $1 = "--help" ]]; then
>&2 echo "Usage: download-katex-assets.sh VERSION (e.g. v0.16.23)"
>&2 echo
>&2 echo "Downloads KaTeX fonts and CSS from the specified release"
>&2 echo "on GitHub and puts the files into static/."
exit 1
fi
# Create a temporary directory and register a handler to clean it up on exit.
tmp_dir=$(mktemp -d)
clean_up () {
rm -rf "$tmp_dir"
}
trap clean_up EXIT
# Fetch the release archive.
archive=$tmp_dir/katex.tar.gz
url=https://github.com/KaTeX/KaTeX/releases/download/$version/katex.tar.gz
echo "GET $url"
curl -L --output "$archive" "$url"
# Unpack the archive.
tar -xzvf "$archive" -C "$tmp_dir"
# Move the CSS file into place.
install -vm644 "$tmp_dir/katex/katex.min.css" "$root/static/css/katex.min.css"
# Remove any existing fonts and move the new ones into place.
rm -rvf "$root"/static/css/fonts/KaTeX*
while IFS= read -r -d '' file; do
install -vm644 "$file" "$root/static/css/fonts"
done < <(find "$tmp_dir/katex/fonts" -maxdepth 1 -name "KaTeX*.woff2" -print0)

File diff suppressed because one or more lines are too long