Skip to content

feat(site): add live presets to the installation guide and CLI - #1919

Draft
decepulis wants to merge 5 commits into
mainfrom
claude/live-presets-install-guide-tlcckz
Draft

feat(site): add live presets to the installation guide and CLI#1919
decepulis wants to merge 5 commits into
mainfrom
claude/live-presets-install-guide-tlcckz

Conversation

@decepulis

@decepulis decepulis commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Adds live-video and live-audio to the installation guide's use-case picker and to @videojs/cli docs how-to/installation via --preset live-video|live-audio. The presets already shipped in @videojs/html and @videojs/react; only the install surfaces were missing them. Follow-up commits then gave live full CDN parity and made the live skins ejectable.

What changed

PresetsUseCase gains live-video and live-audio. Both surfaces list them in Video → Audio → Live Video → Live Audio → Background Video order, and each offers the usual default / minimal / headless skins.

Media source types — the live use cases offer streaming sources only: hls, dash, mux-video for live video and mux-audio for live audio. A progressive file can't carry a live presentation, so offering one would generate a player that never reports live-edge state. Live use cases also default to a live demo source (VJS10_DEMO_LIVE, the same stream the sandbox uses) instead of the on-demand asset.

Codegen refactor — the preset group now comes from the use case rather than the skin, via getPresetGroup. Tags and import paths compose uniformly as {group}-player / {group}-skin / {group}-minimal-skin, which is what lets five presets share one code path instead of three special cases. React skin components follow LiveVideoSkin / MinimalLiveVideoSkin. Output for the three pre-existing use cases is byte-identical through this refactor — background included, where the subpath (background) and tag prefix (background-video) differ.

CDN paritytsdown.cdn.config.ts previously published only live-video and live-video-minimal. It now publishes all five variants for each live group (default, minimal, headless, and the two -ui bundles the ejected snippets load), matching the non-live groups: 21 preset bundles total. Eight new side-effect entries under packages/html/src/cdn/.

CDN support used to be a renderer-only question; it now also considers the preset and skin, so a preset in the picker without a published bundle degrades to a package manager instead of emitting a script tag that 404s:

  • generateCdnCode returns null for a combination with no bundle, and getCdnUnsupportedReason reports whether the preset or the renderer is the cause.
  • The install page hides the CDN tab and names the reason; the CLI rejects --install-method cdn with the same distinction.
  • With every live variant now shipping, the 'preset' branch is a guard rather than a live path — no preset the picker offers hits it.

CDN drift guard — the gating set above is hand-written, and nothing tied it to what the CDN config publishes, so dropping a preset from the config would silently leave the page emitting a 404 script tag. A new check:workspace check (11 of 11) asserts the set is a subset of the configured presets and that every configured preset has an entry file. It's the cheap counterpart to what build-cdn-manifest.ts does for media subpaths by reading build output.

CLI media validation--media was validated against every renderer, so --preset live-audio --media html5-video would generate a live player pointed at a progressive file. It now validates against VALID_RENDERERS[useCase], matching what the interactive prompt and the install page's dropdown already offered.

Ejectable live skinsbuild-ejected-skins.ts had no live coverage, so customize-skins.mdx gains four sections and the generator goes 16 → 32 entries (HTML/React × css/tailwind × default/minimal × live video/audio). Live entries differ from their non-live counterparts in three ways: they use the live-video/live-audio subpaths, tags, and feature sets; they emit a live source and poster; and they use a media element plus its CDN media bundle (hlsjs-video, mux-audio) rather than a bare <video>, since a live presentation is HLS and a bare <video> only plays HLS in Safari.

Verification

  • pnpm -F site test — 555 passed; pnpm -F @videojs/cli test — 80 passed. Installation-utils coverage went 83 → 126.
  • New tests cover live tags/imports/skins for both frameworks, the live source default, the streaming-only renderer lists, URL detection under live use cases, every CDN gating branch, and the CLI's per-preset media validation.
  • Traced every generated identifier to real source rather than trusting the codegen: the live-* element tag names in packages/html/src/define/, the four React skin exports in packages/react/src/presets/live-*/, and the liveVideoFeatures/liveAudioFeatures chain (@videojs/react@videojs/core/domstore/featurespresets). The bundle-size report independently confirms the same paths ship as artifacts.
  • Inspected the generated ejected output: HTML live entries emit cdn/live-video-ui.js + cdn/media/hlsjs-video.js inside <live-video-player>; React live entries emit liveVideoFeatures from @videojs/react/live-video into LiveVideoPlayer.tsx and <HlsJsVideo src={src} playsInline />. Netlify's full site build passing matters here, since EjectedSkin.astro returns silently on an unknown id.
  • Verified picker order and all four live CDN snippets in a browser against a locally served site (with cdn-media.json generated — without it every CDN tab hides and the check is vacuous).
  • Verified the new drift check by fault injection rather than trusting a green run: it catches a gated name the config doesn't publish, a configured preset with no entry file, and a rename of either parsed identifier.
  • pnpm typecheck, pnpm check:workspace (11 passed), biome check — all clean.
  • astro check: reproduced the CI job (build:packagesapi-docsejected-skinsastro check --minimumSeverity warning) for 0 errors, 0 warnings across 569 files.

Known gaps

  • live-video + dash still defaults to the on-demand .mpd sample — the one place a live preset generates a non-live source. We don't host a live manifest; livesim2.dashif.org/livesim2/testpic_2s/Manifest.mpd is verified type="dynamic" if we want a third-party placeholder.
  • live-audio can only express a Mux stream — a live HLS audio stream on another host has no representable renderer, even though simple-hls-audio-only ships a CDN media bundle. default-audio has the same gap, so this isn't new.
  • Live placeholder durability — if that playback ID stops streaming, the live install and ejected snippets silently show a dead player, and no test would catch it.
  • The 16 Tailwind ejected-skin entries are generated but unreferenced, pending Docs: Add Tailwind as a Supported Style for Documentation #840.

Add `live-video` and `live-audio` to the installation guide's use-case
picker and to `@videojs/cli docs how-to/installation` via
`--preset live-video|live-audio`.

The live use cases offer streaming media only — hls, dash, and mux-video
for live video, mux-audio for live audio. A progressive file can't carry
a live presentation, so offering one would generate a player that never
reports live-edge state. Live use cases also default to a live demo
source instead of the on-demand asset.

Derive the preset group from the use case rather than the skin, so tags
and import paths compose as `<group>-player` / `<group>-skin` /
`<group>-minimal-skin` across all five presets.

`@videojs/html` publishes CDN bundles for `live-video` and
`live-video-minimal` only, so CDN gating now also considers the
preset/skin: the install page hides the CDN tab and names the reason,
and the CLI rejects `--install-method cdn` for live audio and headless
live players.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7asb81fZMvvhpsKEFTQww
@netlify

netlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit de1c7b4
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6a7115515edd5f0007e05bbc
😎 Deploy Preview https://deploy-preview-1919--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview Aug 3, 2026 10:25pm

Request Review

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Initial Lazy
/video (default) 53.76 kB 53.52 kB
/video (default + hls) 189.69 kB 53.52 kB
/video (minimal) 53.66 kB 53.52 kB
/video (minimal + hls) 189.50 kB 53.52 kB
/audio (default) 46.16 kB 53.52 kB
/audio (minimal) 42.47 kB 53.52 kB
/background 5.00 kB 53.52 kB
Media (12)
Entry Initial Lazy
/media/background-video 1.14 kB
/media/container 2.58 kB 53.52 kB
/media/dash-video 211.14 kB
/media/google-cast 6.46 kB
/media/hlsjs-video 137.92 kB
/media/mux-audio 138.88 kB
/media/mux-data 153.96 kB
/media/mux-video 139.06 kB
/media/native-hls-video 5.34 kB
/media/simple-hls-audio-only 19.92 kB
/media/simple-hls-video 24.27 kB
/media/vimeo-video 12.31 kB
Players (5)
Entry Initial Lazy
/video/player 8.98 kB 53.52 kB
/audio/player 6.20 kB 53.52 kB
/background/player 4.72 kB 53.52 kB
/live-video/player 8.39 kB 53.52 kB
/live-audio/player 6.21 kB 53.52 kB
Skins (30)
Entry Type Initial Lazy
/video/minimal-skin.css css 5.93 kB
/video/skin.css css 5.93 kB
/video/minimal-skin js 53.68 kB 53.52 kB
/video/minimal-skin.tailwind js 54.28 kB 53.52 kB
/video/skin js 53.84 kB 53.52 kB
/video/skin.tailwind js 54.44 kB 53.52 kB
/audio/minimal-skin.css css 4.12 kB
/audio/skin.css css 4.06 kB
/audio/minimal-skin js 42.51 kB 53.52 kB
/audio/minimal-skin.tailwind js 42.98 kB 53.52 kB
/audio/skin js 46.03 kB 53.52 kB
/audio/skin.tailwind js 46.53 kB 53.52 kB
/background/skin.css css 133 B
/background/skin js 1.14 kB
/live-video/minimal-skin.css css 5.93 kB
/live-video/skin.css css 5.93 kB
/live-video/minimal-skin js 50.02 kB 53.52 kB
/live-video/minimal-skin.tailwind js 50.61 kB 53.52 kB
/live-video/skin js 52.34 kB 53.52 kB
/live-video/skin.tailwind js 52.92 kB 53.52 kB
/live-audio/minimal-skin.css css 4.12 kB
/live-audio/skin.css css 4.06 kB
/live-audio/minimal-skin js 34.68 kB 53.52 kB
/live-audio/minimal-skin.tailwind js 34.12 kB 53.52 kB
/live-audio/skin js 38.31 kB 53.52 kB
/live-audio/skin.tailwind js 37.96 kB 53.52 kB
/global.css css 183 B
/shared.css css 104 B
/tailwind.css css 161 B
/skin-element js 1.46 kB
UI Components (39)
Entry Initial
/ui/airplay-button 2.57 kB
/ui/alert-dialog 2.89 kB
/ui/alert-dialog-close 2.56 kB
/ui/alert-dialog-description 2.51 kB
/ui/alert-dialog-title 2.53 kB
/ui/audio-track-radio-group 3.08 kB
/ui/buffering-indicator 2.78 kB
/ui/captions-button 2.68 kB
/ui/captions-radio-group 3.08 kB
/ui/cast-button 2.63 kB
/ui/compounds 3.28 kB
/ui/controls 3.01 kB
/ui/error-dialog 3.02 kB
/ui/fullscreen-button 2.63 kB
/ui/hotkey 2.60 kB
/ui/menu 3.04 kB
/ui/mute-button 2.70 kB
/ui/pip-button 2.60 kB
/ui/play-button 2.66 kB
/ui/playback-rate-button 2.71 kB
/ui/playback-rate-radio-group 2.85 kB
/ui/popover 3.22 kB
/ui/poster 2.42 kB
/ui/quality-radio-group 3.00 kB
/ui/seek-button 2.59 kB
/ui/seek-indicator 2.83 kB
/ui/seek-indicator-value 470 B
/ui/slider 3.04 kB
/ui/status-announcer 2.47 kB
/ui/status-indicator 2.64 kB
/ui/status-indicator-value 421 B
/ui/thumbnail 2.64 kB
/ui/time 3.01 kB
/ui/time-slider 3.04 kB
/ui/tooltip 3.00 kB
/ui/volume-indicator 2.54 kB
/ui/volume-indicator-fill 373 B
/ui/volume-indicator-value 426 B
/ui/volume-slider 3.04 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Initial Lazy
/video (default) 42.49 kB 53.52 kB
/video (default + hls) 177.04 kB 53.52 kB
/video (minimal) 42.75 kB 53.52 kB
/video (minimal + hls) 177.57 kB 53.52 kB
/audio (default) 34.68 kB 53.52 kB
/audio (minimal) 34.74 kB 53.52 kB
/background 581 B
Media (11)
Entry Initial
/media/background-video 394 B
/media/dash-video 209.54 kB
/media/google-cast 5.35 kB
/media/hlsjs-video 136.40 kB
/media/mux-audio 137.23 kB
/media/mux-data 152.93 kB
/media/mux-video 137.38 kB
/media/native-hls-video 3.54 kB
/media/simple-hls-audio-only 18.18 kB
/media/simple-hls-video 22.64 kB
/media/vimeo-video 10.46 kB
Skins (27)
Entry Type Initial Lazy
/tailwind.css css 161 B
/video/minimal-skin.css css 5.82 kB
/video/skin.css css 5.82 kB
/video/minimal-skin js 42.70 kB 53.52 kB
/video/minimal-skin.tailwind js 48.90 kB 53.52 kB
/video/skin js 42.43 kB 53.52 kB
/video/skin.tailwind js 48.62 kB 53.52 kB
/audio/minimal-skin.css css 3.98 kB
/audio/skin.css css 3.92 kB
/audio/minimal-skin js 34.66 kB 53.52 kB
/audio/minimal-skin.tailwind js 37.19 kB 53.52 kB
/audio/skin js 34.58 kB 53.52 kB
/audio/skin.tailwind js 38.97 kB 53.52 kB
/background/skin.css css 90 B
/background/skin js 272 B
/live-video/minimal-skin.css css 5.82 kB
/live-video/skin.css css 5.82 kB
/live-video/minimal-skin js 37.58 kB 53.52 kB
/live-video/minimal-skin.tailwind js 43.78 kB 53.52 kB
/live-video/skin js 37.55 kB 53.52 kB
/live-video/skin.tailwind js 43.83 kB 53.52 kB
/live-audio/minimal-skin.css css 3.98 kB
/live-audio/skin.css css 3.92 kB
/live-audio/minimal-skin js 25.04 kB 53.52 kB
/live-audio/minimal-skin.tailwind js 28.31 kB 53.52 kB
/live-audio/skin js 25.09 kB 53.52 kB
/live-audio/skin.tailwind js 28.53 kB 53.52 kB
UI Components (33)
Entry Initial
/ui/airplay-button 2.53 kB
/ui/alert-dialog 2.77 kB
/ui/audio-track 2.49 kB
/ui/buffering-indicator 2.64 kB
/ui/captions-button 2.59 kB
/ui/captions-radio-group 2.45 kB
/ui/cast-button 2.56 kB
/ui/controls 2.70 kB
/ui/error-dialog 2.64 kB
/ui/fullscreen-button 2.59 kB
/ui/gesture 2.59 kB
/ui/hotkey 2.54 kB
/ui/live-button 2.53 kB
/ui/menu 2.78 kB
/ui/mute-button 2.56 kB
/ui/pip-button 2.62 kB
/ui/play-button 2.57 kB
/ui/playback-rate 2.63 kB
/ui/playback-rate-button 2.60 kB
/ui/popover 3.28 kB
/ui/poster 2.66 kB
/ui/quality 2.45 kB
/ui/seek-button 2.53 kB
/ui/seek-indicator 2.80 kB
/ui/slider 2.62 kB
/ui/status-announcer 2.44 kB
/ui/status-indicator 2.48 kB
/ui/thumbnail 2.65 kB
/ui/time 2.44 kB
/ui/time-slider 2.65 kB
/ui/tooltip 3.26 kB
/ui/volume-indicator 2.47 kB
/ui/volume-slider 2.61 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (75)
Entry Initial Lazy
. 11.46 kB
/dom 18.32 kB
/i18n 3.07 kB 53.52 kB
/i18n/locales/all 32.44 kB
/i18n/locales/ar 1.14 kB
/i18n/locales/az 1.04 kB
/i18n/locales/bg 1.21 kB
/i18n/locales/bn 1.23 kB
/i18n/locales/bs 951 B
/i18n/locales/ca 1.00 kB
/i18n/locales/cs 1022 B
/i18n/locales/cy 977 B
/i18n/locales/da 943 B
/i18n/locales/de 1.02 kB
/i18n/locales/el 1.40 kB
/i18n/locales/en 732 B
/i18n/locales/es 959 B
/i18n/locales/et 1019 B
/i18n/locales/eu 983 B
/i18n/locales/fa 1.14 kB
/i18n/locales/fi 997 B
/i18n/locales/fr 1.01 kB
/i18n/locales/gd 1.03 kB
/i18n/locales/gl 960 B
/i18n/locales/he 1.06 kB
/i18n/locales/hi 1.24 kB
/i18n/locales/hr 986 B
/i18n/locales/hu 1.02 kB
/i18n/locales/id 868 B
/i18n/locales/it 978 B
/i18n/locales/ja 1.12 kB
/i18n/locales/ko 1.08 kB
/i18n/locales/lt 986 B
/i18n/locales/lv 1.02 kB
/i18n/locales/mr 1.24 kB
/i18n/locales/nb 928 B
/i18n/locales/ne 1.23 kB
/i18n/locales/nl 967 B
/i18n/locales/nn 931 B
/i18n/locales/oc 1.01 kB
/i18n/locales/pl 1.06 kB
/i18n/locales/pt 988 B
/i18n/locales/pt-BR 988 B
/i18n/locales/pt-PT 953 B
/i18n/locales/ro 1.01 kB
/i18n/locales/ru 1.29 kB
/i18n/locales/sk 1.03 kB
/i18n/locales/sl 987 B
/i18n/locales/sr 1017 B
/i18n/locales/sv 962 B
/i18n/locales/te 1.26 kB
/i18n/locales/th 1.22 kB
/i18n/locales/tr 1.01 kB
/i18n/locales/uk 1.32 kB
/i18n/locales/vi 1.03 kB
/i18n/locales/zh 977 B
/i18n/locales/zh-CN 977 B
/i18n/locales/zh-TW 972 B
/i18n/text/airplay 101 B
/i18n/text/buttons 137 B
/i18n/text/captions 93 B
/i18n/text/cast 114 B
/i18n/text/common 90 B
/i18n/text/container 75 B
/i18n/text/errors 277 B
/i18n/text/fullscreen 98 B
/i18n/text/live 126 B
/i18n/text/menu 249 B
/i18n/text/pip 101 B
/i18n/text/playback 80 B
/i18n/text/seek 105 B
/i18n/text/slider 65 B
/i18n/text/status 222 B
/i18n/text/time 214 B
/i18n/text/volume 133 B
🏷️ @videojs/element — no changes
Entries (2)
Entry Initial
. 996 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Initial
. 1.39 kB
/html 696 B
/react 361 B
🔧 @videojs/utils — no changes
Entries (13)
Entry Initial
/array 104 B
/dom 3.16 kB
/events 319 B
/function 327 B
/i18n 44 B
/jwt 176 B
/object 505 B
/predicate 265 B
/percent 281 B
/string 239 B
/style 190 B
/time 900 B
/number 158 B
📦 @videojs/media — no changes
Entries (14)
Entry Initial
. 959 B
/dom/audio-host 1.11 kB
/dom/custom-media-element 2.09 kB
/dom/dash 208.99 kB
/dom/google-cast 4.06 kB
/dom/hls-js 136.00 kB
/dom/media-host 1.21 kB
/dom/media-played-ranges 576 B
/dom/mux 159.38 kB
/dom/native-hls 3.02 kB
/dom/simple-hls 22.09 kB
/dom/simple-hls-audio-only 17.73 kB
/dom/video-host 1.40 kB
/dom/vimeo 9.88 kB
📦 @videojs/spf — no changes
Entries (5)
Entry Initial
. 4.46 kB
/dom 6.50 kB
/hls 18.74 kB
/media-tracks 504 B
/background-video 13.42 kB

ℹ️ How to interpret

JS sizes are initial static graph totals (minified + brotli). Lazy dynamic chunks are shown separately when present.

Icon Meaning
No change
🔺 Increased ≤ 10%
🔴 Increased > 10%
🔽 Decreased
🆕 New (no baseline)

Run pnpm size locally to check current initial sizes.

Add the four missing live CDN entries so `live-video` and `live-audio`
cover the same default / minimal / headless matrix as `video` and
`audio`: `live-video-headless`, `live-audio`, `live-audio-minimal`, and
`live-audio-headless`.

Every preset the installation guide offers now ships a CDN bundle, so the
guide no longer steers live audio or headless live players away from CDN.
The preset-level gate stays in place — the published-bundle set is
explicit rather than derived, so a preset added to the picker without a
matching CDN entry still degrades to a package manager instead of
emitting a script tag that 404s.

Also reorder the presets to video, audio, live video, live audio,
background video across the picker, the CLI prompt, the `--preset` flag
help, and the CDN entry list.

Note: `live-video-ui`, `live-video-minimal-ui`, `live-audio-ui`, and
`live-audio-minimal-ui` are still missing relative to video/audio. Those
serve ejected light-DOM layouts rather than the installation guide, and
the live UI entries register a different element set, so they are left
for a follow-up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7asb81fZMvvhpsKEFTQww
The interactive prompt only offers renderers valid for the selected
preset, and the install page's dropdown does the same, but the flag path
validated `--media` against every known renderer. That let
`--preset live-audio --media html5-video` generate a "live" player
pointed at a progressive file — a combination the UI cannot produce.

Validate the resolved renderer against `VALID_RENDERERS[useCase]` after
option resolution, so it covers both the flag path and a mixed
flags-plus-prompts run. The error names the `--preset` flag value rather
than the internal use-case id, and lists the media types that are valid.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7asb81fZMvvhpsKEFTQww
Add live skins to the eject flow. `build-ejected-skins.ts` covered only
default/minimal video and audio, so the customize-skins page had no live
entries — the live presets could be installed but not ejected.

Adds all 16 live variants (default/minimal x video/audio x
HTML/React x CSS/Tailwind, 32 entries total) and the four CDN `-ui`
bundles they need: `live-video-ui`, `live-video-minimal-ui`,
`live-audio-ui`, `live-audio-minimal-ui`. The live UI define modules
already existed and register a different element set than their non-live
counterparts, so `video-ui` was not a substitute.

Derive the package subpath, tag prefix, feature set, and component name
from the skin's live-ness rather than assuming video/audio, so live
snippets emit `<live-video-player>`, `liveVideoFeatures`, and
`LiveVideoPlayer.tsx`.

Live snippets also need a live source: a bare `<video>` plays HLS only in
Safari, and an on-demand file would leave the Live button permanently
behind live. Live entries therefore use a media element plus its CDN
media bundle — `hlsjs-video` for live video and `mux-audio` for live
audio, matching the installation guide's live defaults — pointed at the
live demo stream and its thumbnail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7asb81fZMvvhpsKEFTQww
The install page hides its CDN tab based on CDN_PRESET_BUNDLES, a
hand-written set of bundle names. Nothing tied that set to what
tsdown.cdn.config.ts actually publishes, so dropping a preset from the
config would leave the page emitting a script tag that 404s — the same
class of drift build-cdn-manifest.ts avoids for media subpaths by
reading build output.

Add a check:workspace check that the set is a subset of the configured
presets, and that every configured preset has an entry file. Verified by
fault injection: it catches an unpublished gated name, a configured
preset with no entry file, and a rename of either parsed identifier.

Also drop the unreachable `background` entry from the set —
getCdnFileName resolves background before consulting it — and hoist
getPresetLabel's background guard above the work it skips.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7asb81fZMvvhpsKEFTQww
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants