Files
dependabot[bot] 611e6a210e Bump the npm_and_yarn group across 1 directory with 3 updates (#8067)
Bumps the npm_and_yarn group with 3 updates in the /utils/vscode
directory:
[@azure/msal-node](https://github.com/AzureAD/microsoft-authentication-library-for-js),
[qs](https://github.com/ljharb/qs) and
[undici](https://github.com/nodejs/undici).

Updates `@azure/msal-node` from 5.1.4 to 7.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/releases">@​azure/msal-node's
releases</a>.</em></p>
<blockquote>
<h2><code>@​azure/msal-node</code> v7.1.2</h2>
<h2>7.1.2</h2>
<p>Tue, 27 Oct 2026 18:15:10 GMT</p>
<h3>Patches</h3>
<ul>
<li>Bump <code>@​azure/msal-common</code> to v16.15.0 (beachball)</li>
</ul>
<h2><code>@​azure/msal-node</code> v7.1.1</h2>
<h2>7.1.1</h2>
<p>Wed, 21 Oct 2026 18:37:17 GMT</p>
<h3>Patches</h3>
<ul>
<li>Bump <code>@​azure/msal-common</code> to v16.14.3 (beachball)</li>
</ul>
<h2><code>@​azure/msal-node</code> v7.1.0</h2>
<h2>7.1.0</h2>
<p>Tue, 13 Oct 2026 22:26:37 GMT</p>
<h3>Minor changes</h3>
<ul>
<li>Sanitize authorization code payloads and reject unsupported
instance-aware inputs for confidential clients. <a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/pull/8901">#8901</a>
(<a href="mailto:hemoral@microsoft.com">hemoral@microsoft.com</a>)</li>
</ul>
<h2><code>@​azure/msal-node</code> v7.0.2</h2>
<h2>7.0.2</h2>
<p>Tue, 13 Oct 2026 19:04:36 GMT</p>
<h3>Patches</h3>
<ul>
<li>Sanitize authorization code payloads and reject unsupported
instance-aware inputs for confidential clients. <a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/pull/8901">#8901</a>
(<a
href="mailto:rginsburg@microsoft.com">rginsburg@microsoft.com</a>)</li>
</ul>
<h2><code>@​azure/msal-node</code> v7.0.1</h2>
<h2>7.0.1</h2>
<p>Fri, 02 Oct 2026 19:03:42 GMT</p>
<h3>Patches</h3>
<ul>
<li>Bump <code>@​azure/msal-common</code> to v16.14.2 (beachball)</li>
</ul>
<h2><code>@​azure/msal-node</code> v7.0.0</h2>
<h2>7.0.0</h2>
<p>Wed, 23 Sep 2026 15:49:44 GMT</p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/96488ec6e583adbfd2940374c62d9c70e4327165"><code>96488ec</code></a>
Clarify authority discovery trust model (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8938">#8938</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/95e5031808e1e290468a7d9d783fdeea1d7ec3a4"><code>95e5031</code></a>
Handle response headers case-insensitively (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8916">#8916</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/01b6a8fdda1bf6373ca87085df47ba392eab3f57"><code>01b6a8f</code></a>
Introduce &quot;popup origin check done&quot; param (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8793">#8793</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/0f98b8ca3718486015e2b13600943e92fd10d1fb"><code>0f98b8c</code></a>
Improve redirect response URL cleanup (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8918">#8918</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/4cf9a6156da7967efbaac18501a8de94269a38b1"><code>4cf9a61</code></a>
Post-release PR (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8925">#8925</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/16a4714f38ba2844f34d154dd59dd8f1402457c9"><code>16a4714</code></a>
Fix web silent-request deduplication for refresh policies and extra
parameter...</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/bd8b2cdfb4d476b008442902fd799d321f1c5b2b"><code>bd8b2cd</code></a>
Fallback from EAR to auth code flow in Safari (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8903">#8903</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/a9a1221ac325f30e73fd4d6cfbb4c0636a3ffcbe"><code>a9a1221</code></a>
Native Auth V2 entry and validation fixes (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8898">#8898</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/8bd17ffb63577f2b0ccd9013b20a3ab93b8e08e7"><code>8bd17ff</code></a>
chore: update basic-ftp to patched 6.2.2 (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8915">#8915</a>)</li>
<li><a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/commit/4d1e6f9516df2d0d21b8537010bbd8afd5bffe4c"><code>4d1e6f9</code></a>
build(deps): bump dorny/paths-filter from 3.0.4 to 4.0.3 (<a
href="https://redirect.github.com/AzureAD/microsoft-authentication-library-for-js/issues/8841">#8841</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/AzureAD/microsoft-authentication-library-for-js/compare/msal-node-v5.1.4...msal-node-v7.1.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `qs` from 6.15.2 to 6.17.1
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ljharb/qs/blob/main/CHANGELOG.md">qs's
changelog</a>.</em></p>
<blockquote>
<h2><strong>6.17.1</strong></h2>
<ul>
<li>[Fix] <code>parse</code>: <code>interpretNumericEntities</code>:
decode code points above U+FFFF as surrogate pairs (<a
href="https://redirect.github.com/ljharb/qs/issues/640">#640</a>)</li>
<li>[Fix] <code>parse</code>: respect <code>plainObjects</code> for
<code>[]</code> with <code>parseArrays: false</code> (<a
href="https://redirect.github.com/ljharb/qs/issues/639">#639</a>)</li>
<li>[Fix] <code>utils</code>: <code>merge</code>: count the elements of
a sparse array against <code>arrayLimit</code>, not its holes</li>
<li>[Fix] <code>parse</code>: guard bracket-wrapped prototype keys at
depth 0 (<a
href="https://redirect.github.com/ljharb/qs/issues/638">#638</a>)</li>
<li>[Refactor] <code>parse</code>: extract wrapping-bracket stripping
helper</li>
<li>[readme] document that <code>depth: 0</code> and <code>depth:
false</code> keep keys flat</li>
<li>[Tests] <code>parse</code>: pin depth-0 bracket stripping and
prototype keys kept by
<code>allowPrototypes</code>/<code>plainObjects</code></li>
</ul>
<h2><strong>6.17.0</strong></h2>
<ul>
<li>[New] <code>stringify</code>: add <code>WHATWG</code> format (<a
href="https://redirect.github.com/ljharb/qs/issues/623">#623</a>)</li>
<li>[Fix] <code>stringify</code>: do not sort the caller's
<code>filter</code> array in place (<a
href="https://redirect.github.com/ljharb/qs/issues/637">#637</a>)</li>
<li>[Fix] <code>parse</code>: copy an own <code>__proto__</code> key as
data (<a
href="https://redirect.github.com/ljharb/qs/issues/636">#636</a>)</li>
<li>[Fix] <code>parse</code>: decode percent-encoded dots
case-insensitively (<a
href="https://redirect.github.com/ljharb/qs/issues/635">#635</a>)</li>
<li>[Fix] <code>stringify</code>: encode keys when
<code>allowEmptyArrays</code> is set (<a
href="https://redirect.github.com/ljharb/qs/issues/561">#561</a>)</li>
<li>[Fix] <code>parse</code>: preserve comma arrays when interpreting
numeric entities (<a
href="https://redirect.github.com/ljharb/qs/issues/630">#630</a>)</li>
<li>[Fix] <code>parse</code>: allow scalar fields with a zero array
limit (<a
href="https://redirect.github.com/ljharb/qs/issues/627">#627</a>)</li>
<li>[Fix] <code>parse</code>: do not count an existing comma array
toward <code>arrayLimit</code> when <code>duplicates</code> discards or
replaces it</li>
<li>[Fix] <code>utils</code>: <code>encode</code>: encode lone
surrogates as U+FFFD instead of consuming the next code unit (<a
href="https://redirect.github.com/ljharb/qs/issues/624">#624</a>)</li>
<li>[eslint] fix indentation</li>
<li>[readme] document the encoder's <code>format</code> argument</li>
<li>[meta] add changelog acknowledgement</li>
<li>[meta] fix changelog indents</li>
<li>[Dev Deps] update <code>eslint</code>, <code>evalmd</code>,
<code>npmignore</code></li>
<li>[Tests] <code>stringify</code>: pin <code>allowEmptyArrays</code>
output for keys that need no encoding</li>
<li>[Tests] <code>stringify</code>: pin <code>sort</code> order for
nested keys selected by an array <code>filter</code></li>
<li>[Tests] <code>parse</code>: cover
<code>interpretNumericEntities</code> across value shapes, keys, and the
charset sentinel</li>
<li>[Tests] <code>parse</code>: cover more input that builds no array at
a zero or negative <code>arrayLimit</code></li>
<li>[Tests] <code>parse</code>: cover <code>comma</code> with a zero or
negative <code>arrayLimit</code>, and combining a full comma array</li>
<li>[Tests] <code>parse</code>: pin the behavior of a zero or negative
<code>arrayLimit</code></li>
<li>[Tests] <code>utils</code>/<code>stringify</code>: pin
<code>~</code>, <code>*</code>, and parens encoding in RFC3986 and
RFC1738</li>
</ul>
<h2><strong>6.16.2</strong></h2>
<ul>
<li>[Fix] <code>stringify</code>: encode keys when
<code>allowEmptyArrays</code> is set (<a
href="https://redirect.github.com/ljharb/qs/issues/561">#561</a>)</li>
<li>[meta] use double quotes for better OS support</li>
<li>[Dev Deps] update <code>evalmd</code>, <code>npmignore</code></li>
<li>[Tests] <code>stringify</code>: pin <code>allowEmptyArrays</code>
output for keys that need no encoding</li>
</ul>
<h2><strong>6.16.1</strong></h2>
<ul>
<li>[Fix] <code>parse</code>: do not mutate an object input</li>
<li>[Fix] <code>stringify</code>: stop re-encoding structural separator
dots when <code>encodeDotInKeys</code> is set (<a
href="https://redirect.github.com/ljharb/qs/issues/564">#564</a>)</li>
<li>[Fix] <code>stringify</code>: <code>arrayFormat: 'comma'</code>:
pass the full encoder arguments with <code>encodeValuesOnly</code></li>
<li>[Fix] <code>utils</code>: encode <code>+</code> as <code>%2B</code>
in iso-8859-1 mode so values round-trip (<a
href="https://redirect.github.com/ljharb/qs/issues/565">#565</a>)</li>
<li>[Fix] parse: only convert top-level dots to brackets when allowDots
is on (<a
href="https://redirect.github.com/ljharb/qs/issues/621">#621</a>)</li>
<li>[Fix] <code>stringify</code>: ignore inherited array format names
(<a
href="https://redirect.github.com/ljharb/qs/issues/622">#622</a>)</li>
<li>[Fix] <code>stringify</code>: <code>arrayFormat: 'comma'</code>: do
not throw on elements with no callable <code>toString</code></li>
<li>[Fix] <code>utils</code>: <code>merge</code>: seed an overflow
container's index from its own keys, not just the source</li>
<li>[Fix] <code>utils</code>: <code>merge</code>: keep a
<code>strictMerge</code> conflict container's index and
<code>arrayLimit</code> correct</li>
<li>[Fix] <code>parse</code>: only treat <code>[]</code> as array syntax
when it ends the key</li>
<li>[Perf] <code>decode</code>: skip decoders when there is no percent
sign (<a
href="https://redirect.github.com/ljharb/qs/issues/583">#583</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ljharb/qs/commit/43baea4655cb9b543fb1c5cc0db95cde42852140"><code>43baea4</code></a>
v6.17.1</li>
<li><a
href="https://github.com/ljharb/qs/commit/54623b64dcef77a436b834b0413cf4cbb6bc6927"><code>54623b6</code></a>
[Fix] <code>parse</code>: <code>interpretNumericEntities</code>: decode
code points above U+FFFF as...</li>
<li><a
href="https://github.com/ljharb/qs/commit/7924b65958d41cd91dbaf688f61e7029673eb33f"><code>7924b65</code></a>
[Fix] <code>parse</code>: respect <code>plainObjects</code> for
<code>[]</code> with <code>parseArrays: false</code></li>
<li><a
href="https://github.com/ljharb/qs/commit/7d4b440de3c028e8497544d0474d5264d9d2bad9"><code>7d4b440</code></a>
[readme] document that <code>depth: 0</code> and <code>depth:
false</code> keep keys flat</li>
<li><a
href="https://github.com/ljharb/qs/commit/101492a5c4d9cb72f6510ecc15483759ec8e45fa"><code>101492a</code></a>
[Fix] <code>utils</code>: <code>merge</code>: count the elements of a
sparse array against `arrayLi...</li>
<li><a
href="https://github.com/ljharb/qs/commit/42eccf0f6292c502fb4bc175191f0812d5476769"><code>42eccf0</code></a>
[Fix] <code>parse</code>: guard bracket-wrapped prototype keys at depth
0</li>
<li><a
href="https://github.com/ljharb/qs/commit/ae0b5c7481fcc6483c4d8ff875e290b2387f87b6"><code>ae0b5c7</code></a>
[Refactor] <code>parse</code>: extract wrapping-bracket stripping
helper</li>
<li><a
href="https://github.com/ljharb/qs/commit/6459f9fc5e5036cfdb6e120fcb94df8e48f584df"><code>6459f9f</code></a>
[Tests] <code>parse</code>: pin depth-0 bracket stripping and prototype
keys kept by `al...</li>
<li><a
href="https://github.com/ljharb/qs/commit/cb6855c1eb72eb0a3ef549b3cf9fce904e6263ec"><code>cb6855c</code></a>
Merge backport release tags v6.12.6–v6.16.2 into main</li>
<li><a
href="https://github.com/ljharb/qs/commit/136912a619c2d81c090ca196ea02b6c193580d1d"><code>136912a</code></a>
v6.16.2</li>
<li>Additional commits viewable in <a
href="https://github.com/ljharb/qs/compare/v6.15.2...v6.17.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `undici` from 7.30.0 to 7.30.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nodejs/undici/releases">undici's
releases</a>.</em></p>
<blockquote>
<h2>v7.30.1</h2>
<h2>Security fixes</h2>
<h3>High severity</h3>
<h4>Denial of service via TLS 1.2 certificate-changing
renegotiation</h4>
<p><strong>CVE-2026-87018 · <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-qrxm-fqhp-jwvm">GHSA-qrxm-fqhp-jwvm</a></strong></p>
<p>A malicious or compromised HTTPS server could crash the Node.js
process by initiating TLS 1.2 renegotiation and presenting a different,
CA-trusted certificate whose hostname did not match the requested host.
The resulting socket error reached an assertion in undici's HTTP/1.1 and
HTTP/2 connection handling. This release handles post-connect
certificate errors without terminating the process.</p>
<h4>TLS certificate validation bypass through dropped <code>Agent</code>
options</h4>
<p><strong>CVE-2026-109383 · <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-2m5v-pch6-74hx">GHSA-2m5v-pch6-74hx</a></strong></p>
<p><code>Agent</code> used a JSON-based clone for constructor options,
which silently removed function-valued TLS options such as
<code>checkServerIdentity</code>. Applications relying on custom
certificate or public-key verification could therefore accept a
certificate that the callback was intended to reject. This release
preserves TLS options when creating per-origin dispatchers.</p>
<h4>Cache poisoning and cross-user disclosure through cross-origin
redirects</h4>
<p><strong>CVE-2026-109829 · <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-4w7w-5xrc-9h26">GHSA-4w7w-5xrc-9h26</a></strong></p>
<p>When an originless <code>Agent</code> combined redirect and
shared-cache interceptors as <code>compose(redirect(), cache())</code>,
a response from a cross-origin redirect could be stored under the
original URL. This could allow persistent cache poisoning or disclosure
of user-specific responses to later callers. This release verifies the
response origin before caching and preserves redirect-hop cache-control
policy.</p>
<h4>Denial of service through excessive <code>Content-Encoding</code>
values</h4>
<p><strong>CVE-2026-109869 · <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-xjj6-f33q-929c">GHSA-xjj6-f33q-929c</a></strong></p>
<p>A malicious HTTP server could crash the Node.js process by returning
more than five content codings and closing the connection before sending
the body. Although <code>fetch()</code> rejected the response, an error
from an orphaned internal stream could remain unhandled. This release
validates the content-encoding chain before creating the body stream and
aborts oversized chains safely.</p>
<h3>Medium severity</h3>
<h4>Denial of service through the <code>decompress</code>
interceptor</h4>
<p><strong>CVE-2026-87029 · <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-55wc-3pg8-jfw6">GHSA-55wc-3pg8-jfw6</a></strong></p>
<p>An exception thrown by a downstream response handler from an
asynchronous decompression callback could escape as an uncaught
exception. A server could trigger this when <code>decompress</code> was
composed with a handler such as <code>dump</code> with a size limit.
This release converts downstream handler exceptions into per-request
errors.</p>
<h4>Subresource Integrity bypass with non-lowercase algorithm
tokens</h4>
<p><strong>CVE-2026-109841 · <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-f72v-6w45-q472">GHSA-f72v-6w45-q472</a></strong></p>
<p><code>fetch()</code> treated valid mixed-case or uppercase SRI
algorithm tokens, such as <code>SHA256</code>, as unknown and could
accept a response whose body did not match the configured digest. This
release normalizes algorithm tokens before validation and digest
selection.</p>
<h4>Denial of service through unbounded EventSource parser state</h4>
<p><strong>CVE-2026-109924 · <a
href="https://github.com/nodejs/undici/security/advisories/GHSA-4qv8-2p9j-2685">GHSA-4qv8-2p9j-2685</a></strong></p>
<p>A malicious Server-Sent Events endpoint could exhaust process memory
by sending many tiny <code>data:</code> fields without completing an
event, or by splitting an unfinished line across many chunks. This
release bounds retained EventSource parser state, including field
counts, buffered chunks, unfinished-line length, and retained field
data.</p>
<h4>Denial of service through unbounded automatic WebSocket PONG
buffering</h4>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nodejs/undici/commit/7507102a675b082a71437f0a00681e537875556c"><code>7507102</code></a>
Bumped v7.30.1 (<a
href="https://redirect.github.com/nodejs/undici/issues/6022">#6022</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/7d60c7b6ee342d3b5489beef02a88e3da72d6463"><code>7d60c7b</code></a>
[v7.x] fix(cookies): backport <a
href="https://redirect.github.com/nodejs/undici/issues/5663">#5663</a>,
<a
href="https://redirect.github.com/nodejs/undici/issues/5808">#5808</a>
and <a
href="https://redirect.github.com/nodejs/undici/issues/5832">#5832</a>
(<a
href="https://redirect.github.com/nodejs/undici/issues/6019">#6019</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/0227d5de51ed14d88a95e2cd4c01abddfce9b5fc"><code>0227d5d</code></a>
fix: avoid unbounded recursion in Set-Cookie attribute parser (<a
href="https://redirect.github.com/nodejs/undici/issues/5757">#5757</a>)
(<a
href="https://redirect.github.com/nodejs/undici/issues/5997">#5997</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/53944624462b6797560288c55dbd8c66857bb495"><code>5394462</code></a>
fix(websocket): bound automatic PONG writes under backpressure</li>
<li><a
href="https://github.com/nodejs/undici/commit/299162740d5f39120092277e70efacb4d151c1c6"><code>2991627</code></a>
fix(eventsource): bound retained SSE parser state</li>
<li><a
href="https://github.com/nodejs/undici/commit/18bc8a1e09d15bc45815154a289dcf6fd5254d00"><code>18bc8a1</code></a>
fix(sri): accept non-lowercase algorithm tokens</li>
<li><a
href="https://github.com/nodejs/undici/commit/63cba7712ca012b2603c6aeeb4c72d8692332cd0"><code>63cba77</code></a>
fix(decompress): converge downstream handler throws to per-request
errors</li>
<li><a
href="https://github.com/nodejs/undici/commit/07ded4941b1e72afec862958c3b8ddf468f3b429"><code>07ded49</code></a>
fix(fetch): abort excessive content encoding responses</li>
<li><a
href="https://github.com/nodejs/undici/commit/b20b82ad80a405a12b6ce1f341bcd418de390aa0"><code>b20b82a</code></a>
fix(cache): prevent cross-origin redirect cache confusion</li>
<li><a
href="https://github.com/nodejs/undici/commit/04cb74b1db131ff8f5b4557dce811cbf5f4664b4"><code>04cb74b</code></a>
fix: preserve Agent connection options</li>
<li>Additional commits viewable in <a
href="https://github.com/nodejs/undici/compare/v7.30.0...v7.30.1">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-11-01 01:25:31 +00:00
..

Carbon Language

This extension provides support for the Carbon Language.

This extension is currently experimental, and being developed alongside Carbon.

Quickstart

  1. Download and install a carbon release.
    • By default, the extension will look for carbon under ./bazel-bin. This is for developers actively working on Carbon and running VS Code inside a carbon-lang clone.
  2. Install the Carbon Language extension.
  3. Configure the installed path to carbon.

Configuration

The configuration is under carbon.*. At present, the only configuration is the path to the carbon binary. This looks like:

"carbon.carbonPath": "/path/to/carbon"

Communication

See Carbon's collaboration systems. We're most active on Discord and have a #editor-integrations channel. We'll also respond to questions on GitHub Discussions.

Documentation

Carbon currently only has project-level documentation. See the GitHub repository.