diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..d079320fc0089792fda7151a5caa51a08cb62721 100644 --- a/.gitattributes +++ b/.gitattributes @@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text *tfevents* filter=lfs diff=lfs merge=lfs -text +trackio/assets/badge.png filter=lfs diff=lfs merge=lfs -text +trackio/assets/trackio_logo_old.png filter=lfs diff=lfs merge=lfs -text diff --git a/trackio/CHANGELOG.md b/trackio/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..2179b8efd767a42bc64e037511301835a71c4354 --- /dev/null +++ b/trackio/CHANGELOG.md @@ -0,0 +1,356 @@ +# trackio + +## 0.30.2 + +### Features + +- [#614](https://github.com/gradio-app/trackio/pull/614) [`eba80c7`](https://github.com/gradio-app/trackio/commit/eba80c7464af250519a90b8ac3179ff6652b651a) - Render logbooks as single-page documents with section navigation and contextual resources. Thanks @abidlabs! +- [#612](https://github.com/gradio-app/trackio/pull/612) [`2c1b943`](https://github.com/gradio-app/trackio/commit/2c1b9436b093e9f9335c99c10fe4b6afa622e314) - Warn that logbook open is experimental. Thanks @abidlabs! +- [#611](https://github.com/gradio-app/trackio/pull/611) [`96b1d94`](https://github.com/gradio-app/trackio/commit/96b1d94def7596aa1302864cbfc57942dd63822b) - Logbook: auto-capture output artifacts and live-embedded dashboard cells. Thanks @abidlabs! + +## 0.30.1 + +### Features + +- [#609](https://github.com/gradio-app/trackio/pull/609) [`2ed1295`](https://github.com/gradio-app/trackio/commit/2ed12959c73aa9c04ca1096cf7a8315ce2886ed1) - Serve live logbook preview from open. Thanks @abidlabs! + +## 0.30.0 + +### Features + +- [#603](https://github.com/gradio-app/trackio/pull/603) [`a793fd8`](https://github.com/gradio-app/trackio/commit/a793fd88827482134bce295c6228e117de64566a) - Move default artifact downloads under `./.trackio/artifact-downloads/` so materialized files stay out of the project root. Thanks @abidlabs! +- [#604](https://github.com/gradio-app/trackio/pull/604) [`dd3b8ee`](https://github.com/gradio-app/trackio/commit/dd3b8eeef4e0da8bf0df6238617e20ae81f3e564) - docs: clarify artifact types. Thanks @abidlabs! +- [#586](https://github.com/gradio-app/trackio/pull/586) [`7db4c3b`](https://github.com/gradio-app/trackio/commit/7db4c3b6de6ff4903daf7dabed8842f212c8b7fd) - artifact tracking API — `log_artifact`, `use_artifact`, and an `Artifact` class for versioned, named file collections with aliases, content-addressed deduplication, and producer/consumer run lineage; works offline and syncs blobs to Hugging Face Spaces/Datasets. Thanks @Saba9! +- [#597](https://github.com/gradio-app/trackio/pull/597) [`5ba561e`](https://github.com/gradio-app/trackio/commit/5ba561e1b4023abdf63624f4fb396367ed6e9e76) - Add experiment logbooks: shareable static-Space lab notebooks. Thanks @abidlabs! + +## 0.29.0 + +### Features + +- [#593](https://github.com/gradio-app/trackio/pull/593) [`ca4722c`](https://github.com/gradio-app/trackio/commit/ca4722c19d2219a3a78b5977149873b9dff73f34) - Add CLI command to list Trackio Spaces. Thanks @abidlabs! + +## 0.28.1 + +### Features + +- [#589](https://github.com/gradio-app/trackio/pull/589) [`5e9905d`](https://github.com/gradio-app/trackio/commit/5e9905d7815bb063f2d9bb38aa76177405c5e2b4) - Reduce Metrics page log payloads by requesting scalar-only metrics and add URL x-axis initialization/fallback handling. Thanks @evalstate! +- [#590](https://github.com/gradio-app/trackio/pull/590) [`56493a6`](https://github.com/gradio-app/trackio/commit/56493a6e9a0114b8655ab44b8c3dec7bae2a5df5) - Use TRACKIO_WRITE_TOKEN for server write token. Thanks @abidlabs! + +## 0.28.0 + +### Features + +- [#582](https://github.com/gradio-app/trackio/pull/582) [`d9dabb5`](https://github.com/gradio-app/trackio/commit/d9dabb5bda8147ad7c9203646358bd0880fa6521) - Add JSONL inbox fragments: durable logging when the Space is unreachable and on network filesystems. Thanks @abidlabs! + +## 0.27.0 + +### Features + +- [#567](https://github.com/gradio-app/trackio/pull/567) [`8c0ce21`](https://github.com/gradio-app/trackio/commit/8c0ce21ff9746d7c6a250684b1b5f0f3f04e0520) - Add CPU, RAM, disk, network and sensor metrics monitoring for non-Apple devices. Thanks @yannsadowski! +- [#571](https://github.com/gradio-app/trackio/pull/571) [`57bc7df`](https://github.com/gradio-app/trackio/commit/57bc7df27ecd7b3ff543dbd2bff5c94182bfb69e) - Fix IndexError when importing CSV with no numeric metric columns. Thanks @Ckal! +- [#577](https://github.com/gradio-app/trackio/pull/577) [`db0e730`](https://github.com/gradio-app/trackio/commit/db0e730463103142688c1c0efef9ff68a52e281d) - Sort and paginate media items. Thanks @abidlabs! +- [#576](https://github.com/gradio-app/trackio/pull/576) [`6f635e2`](https://github.com/gradio-app/trackio/commit/6f635e22553ce2deaece6a0d6289475ab8683040) - Render plot/metric titles as searchable DOM text. Thanks @abidlabs! +- [#579](https://github.com/gradio-app/trackio/pull/579) [`cf7759e`](https://github.com/gradio-app/trackio/commit/cf7759efaab73ce1e98a8a2355dc1f65d54bc775) - Merge image viewer with current media page, credit to @catwell. Thanks @abidlabs! + +## 0.26.0 + +### Features + +- [#553](https://github.com/gradio-app/trackio/pull/553) [`06011ac`](https://github.com/gradio-app/trackio/commit/06011acc9c73341fd234f9cd8eaf96d5a34ad8ce) - fix: serve static-Space assets at /static/trackio. Thanks @abidlabs! +- [#563](https://github.com/gradio-app/trackio/pull/563) [`551569c`](https://github.com/gradio-app/trackio/commit/551569c16fb56ec63249ebdc28348d326ccf7126) - Fix Traces UI a bit. Thanks @abidlabs! +- [#550](https://github.com/gradio-app/trackio/pull/550) [`5690acd`](https://github.com/gradio-app/trackio/commit/5690acda5da303c63ad332451afeab3e9750fd1a) - fix: keep sparse metrics sparse through smoothing. Thanks @abidlabs! +- [#551](https://github.com/gradio-app/trackio/pull/551) [`0ef7266`](https://github.com/gradio-app/trackio/commit/0ef72660695cf932f3906ddbf33d41d087280a22) - add "group by" dropdown to sidebar. Thanks @Saba9! +- [#538](https://github.com/gradio-app/trackio/pull/538) [`a15c1a8`](https://github.com/gradio-app/trackio/commit/a15c1a8877c07514e0596630bb7c7299299994a9) - Subdue empty dashboard tabs. Thanks @abidlabs! +- [#559](https://github.com/gradio-app/trackio/pull/559) [`0b53a41`](https://github.com/gradio-app/trackio/commit/0b53a413909598f92138b6b6395a91c2d5034faf) - Store traces separately from metrics. Thanks @abidlabs! +- [#556](https://github.com/gradio-app/trackio/pull/556) [`d110001`](https://github.com/gradio-app/trackio/commit/d110001dbd9f6b262dfe41f2b702e3a71aa0cfc9) - fix: keep selected x-axis option in dropdown and dismiss dropdown on re-click. Thanks @Saba9! +- [#560](https://github.com/gradio-app/trackio/pull/560) [`aee2923`](https://github.com/gradio-app/trackio/commit/aee2923d3ada4f74d62d065c16f1f6a56a295e48) - Paginate Traces tab with step filter. Thanks @abidlabs! + +### Fixes + +- [#540](https://github.com/gradio-app/trackio/pull/540) [`0b674ac`](https://github.com/gradio-app/trackio/commit/0b674ac6438738de89bc5b3fb700ccfd8a39368c) - raise default metrics sampling cap from 1500 to 3000 so client-side smoothing on the Metrics tab runs over higher-resolution data. Thanks @edbeeching! + +## 0.25.1 + +### Features + +- [#535](https://github.com/gradio-app/trackio/pull/535) [`d7f1b27`](https://github.com/gradio-app/trackio/commit/d7f1b27a98f185d2d97ef54975d5865e0b5243c9) - Avoid HF token leaks in static snapshots. Thanks @abidlabs! + +## 0.25.0 + +### Features + +- [#533](https://github.com/gradio-app/trackio/pull/533) [`08bc5eb`](https://github.com/gradio-app/trackio/commit/08bc5eb090525d3ff5f7fa4233c30c42162aa74c) - Fix Windows-only emoji mojibake when uploading Space README. Thanks @tomaarsen! +- [#518](https://github.com/gradio-app/trackio/pull/518) [`e7ed176`](https://github.com/gradio-app/trackio/commit/e7ed176da53d8b49290fddd890b3d18c0b9b958f) - Traces in Trackio. Thanks @abidlabs! +- [#531](https://github.com/gradio-app/trackio/pull/531) [`27a50a3`](https://github.com/gradio-app/trackio/commit/27a50a37362020304b774344b4c774ff548985b6) - Add configurable custom frontends for Trackio. Thanks @abidlabs! + +## 0.24.2 + +### Features + +- [#527](https://github.com/gradio-app/trackio/pull/527) [`7d1c0b9`](https://github.com/gradio-app/trackio/commit/7d1c0b9c37ce9a9845e6bbe6c083da9d36084caf) - Fix dashboard UX issues: smoothing in share URL, run selection, and run filtering. Thanks @abidlabs! +- [#526](https://github.com/gradio-app/trackio/pull/526) [`643878a`](https://github.com/gradio-app/trackio/commit/643878a82985fab9e6675f769ff0107cb46e042a) - Add emoji to README and deploy README content. Thanks @qgallouedec! +- [#529](https://github.com/gradio-app/trackio/pull/529) [`a77972b`](https://github.com/gradio-app/trackio/commit/a77972b68541ebe9e056824e69c9bbca3979ece4) - Remove pydub dependency. Thanks @abidlabs! + +## 0.24.1 + +### Features + +- [#524](https://github.com/gradio-app/trackio/pull/524) [`65a6897`](https://github.com/gradio-app/trackio/commit/65a6897561b465fc8f05550562f8da1ba3c99060) - Fix `trackio skills add`. Thanks @abidlabs! +- [#522](https://github.com/gradio-app/trackio/pull/522) [`05aaca7`](https://github.com/gradio-app/trackio/commit/05aaca7f166bf7667b60b40656d677532a4bdd6e) - relax `starlette` dependency and fix import style. Thanks @abidlabs! +- [#525](https://github.com/gradio-app/trackio/pull/525) [`32c05c5`](https://github.com/gradio-app/trackio/commit/32c05c5d5e3aa84ca7099a6fa08a9093ccd4b95f) - Restore sidebar share and embed snippets, and fix query parameter regression. Thanks @abidlabs! + +## 0.24.0 + +### Features + +- [#502](https://github.com/gradio-app/trackio/pull/502) [`3b397df`](https://github.com/gradio-app/trackio/commit/3b397dfbaff9de137b088f3cad528117e14faab1) - Add docs on SQL & Parquet schema / format, as well as a new CLI command: `trackio query project --project PROJECT --sql SQL_QUERY`. Thanks @abidlabs! +- [#506](https://github.com/gradio-app/trackio/pull/506) [`498bbc4`](https://github.com/gradio-app/trackio/commit/498bbc47f66cc90cc5776f363d001a5571941c00) - Scope bucket sync to trackio/ subtree to avoid walking the HF cache. Thanks @abidlabs! +- [#505](https://github.com/gradio-app/trackio/pull/505) [`8e26ab9`](https://github.com/gradio-app/trackio/commit/8e26ab93b5d9caa2f81334f6fff42fb9cefbb232) - Add an `id` field to `Run` which is used internally, allowing users to have multiple runs with the same run name. Thanks @abidlabs! +- [#517](https://github.com/gradio-app/trackio/pull/517) [`29e1034`](https://github.com/gradio-app/trackio/commit/29e1034b795567ec5ed6d19c5a946915a6498e2a) - Fix static exports, Space bucket handling, and other misc issues. Thanks @abidlabs! +- [#489](https://github.com/gradio-app/trackio/pull/489) [`1b96db3`](https://github.com/gradio-app/trackio/commit/1b96db39c8fd4326e621ee2336b0fca4f263a18a) - Remove `gradio` dependency in `trackio` -- only `gradio_client` is needed locally anymore. Also lazily import `pandas` and remove it as a dependency. Thanks @abidlabs! +- [#513](https://github.com/gradio-app/trackio/pull/513) [`d54d290`](https://github.com/gradio-app/trackio/commit/d54d290fcb1bb08358b558a43a962f78abe990ea) - Reduce HF Spaces 429s: polling tuning and batched metric logs API. Thanks @abidlabs! +- [#516](https://github.com/gradio-app/trackio/pull/516) [`afe2959`](https://github.com/gradio-app/trackio/commit/afe295988928a3ea3ded38bdb5bb05cca85d3c74) - Fix run list order and legend overflow. Thanks @abidlabs! +- [#515](https://github.com/gradio-app/trackio/pull/515) [`0a242b8`](https://github.com/gradio-app/trackio/commit/0a242b85127b02f532b24c7fd2bb046580cc7641) - Add Gradio-compatible /gradio_api routes on Spaces. Thanks @abidlabs! +- [#510](https://github.com/gradio-app/trackio/pull/510) [`60bbc86`](https://github.com/gradio-app/trackio/commit/60bbc86b4e7f880de72075e5bf31b093709bb5a4) - Add server_url and TRACKIO_SERVER_URL for self-hosted servers; space_id and TRACKIO_SPACE_ID take precedence when both are set. Thanks @abidlabs! +- [#509](https://github.com/gradio-app/trackio/pull/509) [`21c099a`](https://github.com/gradio-app/trackio/commit/21c099aa830a278973fab4c7c58a0139f417caa4) - Fix: Open browser with write_token so trackio show allows mutations. Thanks @abidlabs! + +## 0.23.0 + +### Features + +- [#494](https://github.com/gradio-app/trackio/pull/494) [`e8a897d`](https://github.com/gradio-app/trackio/commit/e8a897d2266d9b2558f72d768b0b21f4d0a8781b) - Add a settings/CLI page to Trackio. Thanks @abidlabs! +- [#481](https://github.com/gradio-app/trackio/pull/481) [`882647e`](https://github.com/gradio-app/trackio/commit/882647ec1599cf04500d03b5ca75ddc2733682e2) - Add multi-GPU system metrics support. Thanks @Saba9! +- [#485](https://github.com/gradio-app/trackio/pull/485) [`46a3cc3`](https://github.com/gradio-app/trackio/commit/46a3cc3758719e171417612efee102a487e71ebd) - Fix/remove flaky E2E space tests. Thanks @abidlabs! +- [#501](https://github.com/gradio-app/trackio/pull/501) [`06ea885`](https://github.com/gradio-app/trackio/commit/06ea8852f5e40ab3f1cf629a0a01af5c17f847a1) - Fix SQLite corruption on bucket-mounted Spaces. Thanks @abidlabs! +- [#496](https://github.com/gradio-app/trackio/pull/496) [`af23d74`](https://github.com/gradio-app/trackio/commit/af23d74438b146c4a3512ace15ea984656e943ed) - Prevent trackio errors from crashing the user's training loop. Thanks @abidlabs! + +## 0.22.0 + +### Features + +- [#484](https://github.com/gradio-app/trackio/pull/484) [`cc05ada`](https://github.com/gradio-app/trackio/commit/cc05ada8e89773f3a894af99b801ef680f64418f) - Fix duplicate columns in parquet export. Thanks @abidlabs! +- [#487](https://github.com/gradio-app/trackio/pull/487) [`853f764`](https://github.com/gradio-app/trackio/commit/853f7646a70d12633afaa4f69db86425aa665413) - Relax `PIL` dependency and remove `plotly` as it's no longer used. Thanks @abidlabs! + +## 0.21.2 + +### Features + +- [#482](https://github.com/gradio-app/trackio/pull/482) [`f62180a`](https://github.com/gradio-app/trackio/commit/f62180a0218bc99a259d5ca110a0384a6cae11c8) - Use server-side bucket copy when freezing Spaces. Thanks @abidlabs! + +## 0.21.1 + +### Features + +- [#475](https://github.com/gradio-app/trackio/pull/475) [`fcb476c`](https://github.com/gradio-app/trackio/commit/fcb476cd37a40923e9679aaf966f41d582a878a8) - Tweaks. Thanks @abidlabs! +- [#477](https://github.com/gradio-app/trackio/pull/477) [`7d52dfd`](https://github.com/gradio-app/trackio/commit/7d52dfdce5b6eff6a34501a6d5a620220663cf09) - Fix `.sync()` and add `.freeze()` as a separate methods. Thanks @abidlabs! + +## 0.21.0 + +### Features + +- [#467](https://github.com/gradio-app/trackio/pull/467) [`f357deb`](https://github.com/gradio-app/trackio/commit/f357debf78957e4c1f2b901bee4f77cf397298b4) - Allow logged metrics as x-axis choices. Thanks @abidlabs! +- [#474](https://github.com/gradio-app/trackio/pull/474) [`655673d`](https://github.com/gradio-app/trackio/commit/655673d4c6b7c8b7ee8f87f2589f2dbbc3d2ef91) - Fix file descriptor leak from `sqlite3.connect`. Thanks @abidlabs! +- [#470](https://github.com/gradio-app/trackio/pull/470) [`bea8c9d`](https://github.com/gradio-app/trackio/commit/bea8c9dcae0b59d071b6c779c97ee525c9bbf6e7) - Restores tooltips to line plots and fixes the call to uses TTL instead of OAuth. Thanks @abidlabs! +- [#471](https://github.com/gradio-app/trackio/pull/471) [`246fce0`](https://github.com/gradio-app/trackio/commit/246fce0a01619e1c2c538c67b3e460883334d500) - Deprecate dataset backend in favor of buckets. Thanks @abidlabs! +- [#465](https://github.com/gradio-app/trackio/pull/465) [`3e11174`](https://github.com/gradio-app/trackio/commit/3e1117438bb8168b802245a33059affa558ae519) - Use HF buckets as backend. Thanks @abidlabs! +- [#469](https://github.com/gradio-app/trackio/pull/469) [`915d170`](https://github.com/gradio-app/trackio/commit/915d17045133172b59195acfdcc70709229668aa) - Make static Spaces work with Buckets and also allow conversion from Gradio SDK to Static Spaces. Thanks @abidlabs! + +## 0.20.2 + +### Features + +- [#464](https://github.com/gradio-app/trackio/pull/464) [`c89ebb3`](https://github.com/gradio-app/trackio/commit/c89ebb3b50f695bc7f16cbc6f46dce86f79a01e9) - Improve rendering of curves. Thanks @abidlabs! +- [#462](https://github.com/gradio-app/trackio/pull/462) [`9160b78`](https://github.com/gradio-app/trackio/commit/9160b78ff6f258f0b87a4f34a24e7d0b5dfbf2fb) - Refactor plot title to display only the metric name without the path. Thanks @qgallouedec! + +## 0.20.1 + +### Features + +- [#454](https://github.com/gradio-app/trackio/pull/454) [`22881db`](https://github.com/gradio-app/trackio/commit/22881dbbbb6b81197a00a19853771007093d61e4) - Bar chart single point. Thanks @abidlabs! +- [#455](https://github.com/gradio-app/trackio/pull/455) [`f8db51a`](https://github.com/gradio-app/trackio/commit/f8db51a20ca61ef703f3f2c2ee1ebd9c4f239cf2) - Adds a static Trackio mode via `trackio.sync(sdk="static")` and support for the `TRACKIO_SPACE_ID` environment variable. Thanks @abidlabs! + +## 0.20.0 + +### Features + +- [#450](https://github.com/gradio-app/trackio/pull/450) [`b0571ef`](https://github.com/gradio-app/trackio/commit/b0571ef6207a1ce346696f858ad2b7b584dd194f) - Use Svelte source for Gradio components directly in Trackio dashboard. Thanks @abidlabs! + +## 0.19.0 + +### Features + +- [#445](https://github.com/gradio-app/trackio/pull/445) [`cef4a58`](https://github.com/gradio-app/trackio/commit/cef4a583cb76f4091fc6c0e5783124ee84f8e243) - Add remote HF Space support to CLI. Thanks @abidlabs! +- [#444](https://github.com/gradio-app/trackio/pull/444) [`358f2a9`](https://github.com/gradio-app/trackio/commit/358f2a9ca238ee8b90b5a8c96220da287e0698fb) - Fix alerts placeholder flashing on reports page. Thanks @abidlabs! + +## 0.18.0 + +### Features + +- [#435](https://github.com/gradio-app/trackio/pull/435) [`4a47112`](https://github.com/gradio-app/trackio/commit/4a471128e18a39e45fad48a67fd711c5ae9e4aed) - feat: allow hiding section header accordions. Thanks @Saba9! +- [#439](https://github.com/gradio-app/trackio/pull/439) [`18e9650`](https://github.com/gradio-app/trackio/commit/18e96503d5a3a7cf926e92782d457e23c19942bd) - Add alerts with webhooks, CLI, and documentation. Thanks @abidlabs! +- [#438](https://github.com/gradio-app/trackio/pull/438) [`0875ccd`](https://github.com/gradio-app/trackio/commit/0875ccd3d8a41b1376f64030f21cfe8cdcc73b05) - Add "share this view" functionality. Thanks @qgallouedec! +- [#409](https://github.com/gradio-app/trackio/pull/409) [`9282403`](https://github.com/gradio-app/trackio/commit/9282403d8896d48679b0f888208a7ba5bdd4271a) - Add Apple Silicon GPU and system monitoring support. Thanks @znation! +- [#434](https://github.com/gradio-app/trackio/pull/434) [`4193223`](https://github.com/gradio-app/trackio/commit/41932230a3a2e1c16405dba08ecba5a42f11d1a8) - fix: table slider crash. Thanks @Saba9! + +### Fixes + +- [#441](https://github.com/gradio-app/trackio/pull/441) [`3a2d11d`](https://github.com/gradio-app/trackio/commit/3a2d11dab0b4b37c925abc30ef84b0e2910321ee) - preserve x-axis step when toggling run checkboxes. Thanks @Saba9! + +## 0.17.0 + +### Features + +- [#428](https://github.com/gradio-app/trackio/pull/428) [`f7dd1ce`](https://github.com/gradio-app/trackio/commit/f7dd1ce2dc8a1936f9983467fcbcf93bfef01e09) - feat: add ability to rename runs. Thanks @Saba9! +- [#437](https://github.com/gradio-app/trackio/pull/437) [`2727c0b`](https://github.com/gradio-app/trackio/commit/2727c0b0755f48f7f186162ea45185c98f6b5516) - Add markdown reports across Trackio. Thanks @abidlabs! +- [#427](https://github.com/gradio-app/trackio/pull/427) [`5aeb9ed`](https://github.com/gradio-app/trackio/commit/5aeb9edcfd2068d309d9d64f172dcbcc327be1ab) - Make Trackio logging much more robust. Thanks @abidlabs! + +## 0.16.1 + +### Features + +- [#431](https://github.com/gradio-app/trackio/pull/431) [`c7ce55b`](https://github.com/gradio-app/trackio/commit/c7ce55b14dd5eb0c2165fb15df17dd60721c9325) - Lazy load the UI when trackio is imported. Thanks @abidlabs! + +## 0.16.0 + +### Features + +- [#426](https://github.com/gradio-app/trackio/pull/426) [`ead4dc8`](https://github.com/gradio-app/trackio/commit/ead4dc8e74ee2d8e47d61bca0a7668456acf49be) - Fix redundant double rendering of group checkboxes. Thanks @abidlabs! +- [#413](https://github.com/gradio-app/trackio/pull/413) [`39c4750`](https://github.com/gradio-app/trackio/commit/39c4750951d554ba6eb4d58847c6bb444b2891a8) - Check `dist-packages` when checking for source installation. Thanks @sergiopaniego! +- [#423](https://github.com/gradio-app/trackio/pull/423) [`2e52ab3`](https://github.com/gradio-app/trackio/commit/2e52ab303e3041718a6a56fbf84d0848aca9ad67) - Fix legend outline visibility issue. Thanks @Raghunath-Balaji! +- [#407](https://github.com/gradio-app/trackio/pull/407) [`c8a384d`](https://github.com/gradio-app/trackio/commit/c8a384ddfe5a295cecf862a26178d40e48acb424) - Fix pytests that were failling locally on MacOS. Thanks @abidlabs! +- [#405](https://github.com/gradio-app/trackio/pull/405) [`35aae4e`](https://github.com/gradio-app/trackio/commit/35aae4e3aa3e2b2888887528478b9dc6a9808bda) - Add conditional padding for HF Space dashboard when not in iframe. Thanks @znation! + +## 0.15.0 + +### Features + +- [#397](https://github.com/gradio-app/trackio/pull/397) [`6b38ad0`](https://github.com/gradio-app/trackio/commit/6b38ad02e5d73a0df49c4eede7e91331282ece04) - Adds `--host` cli option support. Thanks @abidlabs! +- [#396](https://github.com/gradio-app/trackio/pull/396) [`4a4d1ab`](https://github.com/gradio-app/trackio/commit/4a4d1ab85e63d923132a3fa7afa5d90e16431bec) - Fix run selection issue. Thanks @abidlabs! +- [#394](https://github.com/gradio-app/trackio/pull/394) [`c47a3a3`](https://github.com/gradio-app/trackio/commit/c47a3a31f8c4b83bce1aa7fc22eeba3d9021ad3d) - Add wandb-compatible API for trackio. Thanks @abidlabs! +- [#378](https://github.com/gradio-app/trackio/pull/378) [`b02046a`](https://github.com/gradio-app/trackio/commit/b02046a5b0dad7c9854e099a87f884afba4aecb2) - Add JSON export button for line plots and upgrade gradio dependency. Thanks @JamshedAli18! + +## 0.14.2 + +### Features + +- [#386](https://github.com/gradio-app/trackio/pull/386) [`f9452cd`](https://github.com/gradio-app/trackio/commit/f9452cdb8f0819368f3610f7ac0ed08957305275) - Fixing some issues related to deployed Trackio Spaces. Thanks @abidlabs! + +## 0.14.1 + +### Features + +- [#382](https://github.com/gradio-app/trackio/pull/382) [`44fe9bb`](https://github.com/gradio-app/trackio/commit/44fe9bb264fb2aafb0ec302ff15227c045819a2c) - Fix app file path when Trackio is not installed from source. Thanks @abidlabs! +- [#380](https://github.com/gradio-app/trackio/pull/380) [`c3f4cff`](https://github.com/gradio-app/trackio/commit/c3f4cff74bc5676e812773d8571454894fcdc7cc) - Add CLI commands for querying projects, runs, and metrics. Thanks @abidlabs! + +## 0.14.0 + +### Features + +- [#377](https://github.com/gradio-app/trackio/pull/377) [`5c5015b`](https://github.com/gradio-app/trackio/commit/5c5015b68c85c5de51111dad983f735c27b9a05f) - fixed wrapping issue in Runs table. Thanks @gaganchapa! +- [#374](https://github.com/gradio-app/trackio/pull/374) [`388e26b`](https://github.com/gradio-app/trackio/commit/388e26b9e9f24cd7ad203affe9b709be885b3d24) - Save Optimized Parquet files. Thanks @lhoestq! +- [#371](https://github.com/gradio-app/trackio/pull/371) [`fbace9c`](https://github.com/gradio-app/trackio/commit/fbace9cd7732c166f34d268f54b05bb06846cc5d) - Add GPU metrics logging. Thanks @kashif! +- [#367](https://github.com/gradio-app/trackio/pull/367) [`862840c`](https://github.com/gradio-app/trackio/commit/862840c13e30fc960cbee5b9eac4d3c25beba9de) - Add option to only show latest run, and fix the double logo issue. Thanks @abidlabs! + +## 0.13.1 + +### Features + +- [#369](https://github.com/gradio-app/trackio/pull/369) [`767e9fe`](https://github.com/gradio-app/trackio/commit/767e9fe095d7c6ed102016caf927c1517fb8618c) - tiny pr removing unnecessary code. Thanks @abidlabs! + +## 0.13.0 + +### Features + +- [#358](https://github.com/gradio-app/trackio/pull/358) [`073715d`](https://github.com/gradio-app/trackio/commit/073715d1caf8282f68890117f09c3ac301205312) - Improvements to `trackio.sync()`. Thanks @abidlabs! + +## 0.12.0 + +### Features + +- [#357](https://github.com/gradio-app/trackio/pull/357) [`02ba815`](https://github.com/gradio-app/trackio/commit/02ba815358060f1966052de051a5bdb09702920e) - Redesign media and tables to show up on separate page. Thanks @abidlabs! +- [#359](https://github.com/gradio-app/trackio/pull/359) [`08fe9c9`](https://github.com/gradio-app/trackio/commit/08fe9c9ddd7fe99ee811555fdfb62df9ab88e939) - docs: Improve docstrings. Thanks @qgallouedec! + +## 0.11.0 + +### Features + +- [#355](https://github.com/gradio-app/trackio/pull/355) [`ea51f49`](https://github.com/gradio-app/trackio/commit/ea51f4954922f21be76ef828700420fe9a912c4b) - Color code run checkboxes and match with plot lines. Thanks @abidlabs! +- [#353](https://github.com/gradio-app/trackio/pull/353) [`8abe691`](https://github.com/gradio-app/trackio/commit/8abe6919aeefe21fc7a23af814883efbb037c21f) - Remove show_api from demo.launch. Thanks @sergiopaniego! +- [#351](https://github.com/gradio-app/trackio/pull/351) [`8a8957e`](https://github.com/gradio-app/trackio/commit/8a8957e530dd7908d1fef7f2df030303f808101f) - Add `trackio.save()`. Thanks @abidlabs! + +## 0.10.0 + +### Features + +- [#305](https://github.com/gradio-app/trackio/pull/305) [`e64883a`](https://github.com/gradio-app/trackio/commit/e64883a51f7b8b93f7d48b8afe55acdb62238b71) - bump to gradio 6.0, make `trackio` compatible, and fix related issues. Thanks @abidlabs! + +## 0.9.1 + +### Features + +- [#344](https://github.com/gradio-app/trackio/pull/344) [`7e01024`](https://github.com/gradio-app/trackio/commit/7e010241d9a34794e0ce0dc19c1a6f0cf94ba856) - Avoid redundant calls to /whoami-v2. Thanks @Wauplin! + +## 0.9.0 + +### Features + +- [#343](https://github.com/gradio-app/trackio/pull/343) [`51bea30`](https://github.com/gradio-app/trackio/commit/51bea30f2877adff8e6497466d3a799400a0a049) - Sync offline projects to Hugging Face spaces. Thanks @candemircan! +- [#341](https://github.com/gradio-app/trackio/pull/341) [`4fd841f`](https://github.com/gradio-app/trackio/commit/4fd841fa190e15071b02f6fba7683ef4f393a654) - Adds a basic UI test to `trackio`. Thanks @abidlabs! +- [#339](https://github.com/gradio-app/trackio/pull/339) [`011d91b`](https://github.com/gradio-app/trackio/commit/011d91bb6ae266516fd250a349285670a8049d05) - Allow customzing the trackio color palette. Thanks @abidlabs! + +## 0.8.1 + +### Features + +- [#336](https://github.com/gradio-app/trackio/pull/336) [`5f9f51d`](https://github.com/gradio-app/trackio/commit/5f9f51dac8677f240d7c42c3e3b2660a22aee138) - Support a list of `Trackio.Image` in a `trackio.Table` cell. Thanks @abidlabs! + +## 0.8.0 + +### Features + +- [#331](https://github.com/gradio-app/trackio/pull/331) [`2c02d0f`](https://github.com/gradio-app/trackio/commit/2c02d0fd0a5824160528782402bb0dd4083396d5) - Truncate table string values that are greater than 250 characters (configuirable via env variable). Thanks @abidlabs! +- [#324](https://github.com/gradio-app/trackio/pull/324) [`50b2122`](https://github.com/gradio-app/trackio/commit/50b2122e7965ac82a72e6cb3b7d048bc10a2a6b1) - Add log y-axis functionality to UI. Thanks @abidlabs! +- [#326](https://github.com/gradio-app/trackio/pull/326) [`61dc1f4`](https://github.com/gradio-app/trackio/commit/61dc1f40af2f545f8e70395ddf0dbb8aee6b60d5) - Fix: improve table rendering for metrics in Trackio Dashboard. Thanks @vigneshwaran! +- [#328](https://github.com/gradio-app/trackio/pull/328) [`6857cbb`](https://github.com/gradio-app/trackio/commit/6857cbbe557a59a4642f210ec42566d108294e63) - Support trackio.Table with trackio.Image columns. Thanks @abidlabs! +- [#323](https://github.com/gradio-app/trackio/pull/323) [`6857cbb`](https://github.com/gradio-app/trackio/commit/6857cbbe557a59a4642f210ec42566d108294e63) - add Trackio client implementations in Go, Rust, and JS. Thanks @vaibhav-research! + +## 0.7.0 + +### Features + +- [#277](https://github.com/gradio-app/trackio/pull/277) [`db35601`](https://github.com/gradio-app/trackio/commit/db35601b9c023423c4654c9909b8ab73e58737de) - fix: make grouped runs view reflect live updates. Thanks @Saba9! +- [#320](https://github.com/gradio-app/trackio/pull/320) [`24ae739`](https://github.com/gradio-app/trackio/commit/24ae73969b09fb3126acd2f91647cdfbf8cf72a1) - Add additional query parms for xmin, xmax, and smoothing. Thanks @abidlabs! +- [#270](https://github.com/gradio-app/trackio/pull/270) [`cd1dfc3`](https://github.com/gradio-app/trackio/commit/cd1dfc3dc641b4499ac6d4a1b066fa8e2b52c57b) - feature: add support for logging audio. Thanks @Saba9! + +## 0.6.0 + +### Features + +- [#309](https://github.com/gradio-app/trackio/pull/309) [`1df2353`](https://github.com/gradio-app/trackio/commit/1df23534d6c01938c8db9c0f584ffa23e8d6021d) - Add histogram support with wandb-compatible API. Thanks @abidlabs! +- [#315](https://github.com/gradio-app/trackio/pull/315) [`76ba060`](https://github.com/gradio-app/trackio/commit/76ba06055dc43ca8f03b79f3e72d761949bd19a8) - Add guards to avoid silent fails. Thanks @Xmaster6y! +- [#313](https://github.com/gradio-app/trackio/pull/313) [`a606b3e`](https://github.com/gradio-app/trackio/commit/a606b3e1c5edf3d4cf9f31bd50605226a5a1c5d0) - No longer prevent certain keys from being used. Instead, dunderify them to prevent collisions with internal usage. Thanks @abidlabs! +- [#317](https://github.com/gradio-app/trackio/pull/317) [`27370a5`](https://github.com/gradio-app/trackio/commit/27370a595d0dbdf7eebbe7159d2ba778f039da44) - quick fixes for trackio.histogram. Thanks @abidlabs! +- [#312](https://github.com/gradio-app/trackio/pull/312) [`aa0f3bf`](https://github.com/gradio-app/trackio/commit/aa0f3bf372e7a0dd592a38af699c998363830eeb) - Fix video logging by adding TRACKIO_DIR to allowed_paths. Thanks @abidlabs! + +## 0.5.3 + +### Features + +- [#300](https://github.com/gradio-app/trackio/pull/300) [`5e4cacf`](https://github.com/gradio-app/trackio/commit/5e4cacf2e7ce527b4ce60de3a5bc05d2c02c77fb) - Adds more environment variables to allow customization of Trackio dashboard. Thanks @abidlabs! + +## 0.5.2 + +### Features + +- [#293](https://github.com/gradio-app/trackio/pull/293) [`64afc28`](https://github.com/gradio-app/trackio/commit/64afc28d3ea1dfd821472dc6bf0b8ed35a9b74be) - Ensures that the TRACKIO_DIR environment variable is respected. Thanks @abidlabs! +- [#287](https://github.com/gradio-app/trackio/pull/287) [`cd3e929`](https://github.com/gradio-app/trackio/commit/cd3e9294320949e6b8b829239069a43d5d7ff4c1) - fix(sqlite): unify .sqlite extension, allow export when DBs exist, clean WAL sidecars on import. Thanks @vaibhav-research! + +### Fixes + +- [#291](https://github.com/gradio-app/trackio/pull/291) [`3b5adc3`](https://github.com/gradio-app/trackio/commit/3b5adc3d1f452dbab7a714d235f4974782f93730) - Fix the wheel build. Thanks @pngwn! + +## 0.5.1 + +### Fixes + +- [#278](https://github.com/gradio-app/trackio/pull/278) [`314c054`](https://github.com/gradio-app/trackio/commit/314c05438007ddfea3383e06fd19143e27468e2d) - Fix row orientation of metrics plots. Thanks @abidlabs! \ No newline at end of file diff --git a/trackio/__init__.py b/trackio/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bd32b70a68ea8b2006fb8a77c6867647245bba89 --- /dev/null +++ b/trackio/__init__.py @@ -0,0 +1,1208 @@ +import atexit +import glob +import json +import logging +import os +import shutil +import warnings +import webbrowser +from pathlib import Path +from typing import Any + +import huggingface_hub +from gradio_client import handle_file +from huggingface_hub import SpaceStorage +from huggingface_hub.errors import LocalTokenNotFoundError + +from trackio import context_vars, deploy, utils +from trackio.alerts import AlertLevel +from trackio.api import Api +from trackio.apple_gpu import apple_gpu_available +from trackio.apple_gpu import log_apple_gpu as _log_apple_gpu +from trackio.artifact import Artifact +from trackio.cpu import cpu_available +from trackio.cpu import log_cpu as _log_cpu +from trackio.deploy import freeze, sync +from trackio.frontend_config import resolve_frontend_dir +from trackio.gpu import gpu_available +from trackio.gpu import log_gpu as _log_nvidia_gpu +from trackio.histogram import Histogram +from trackio.imports import import_csv, import_tf_events +from trackio.launch import launch_trackio_dashboard +from trackio.markdown import Markdown +from trackio.media import ( + TrackioAudio, + TrackioImage, + TrackioVideo, + get_project_media_path, +) +from trackio.remote_client import RemoteClient +from trackio.run import Run +from trackio.server import TrackioDashboardApp, build_starlette_app_only +from trackio.sqlite_storage import SQLiteStorage +from trackio.table import Table +from trackio.trace import Trace +from trackio.typehints import UploadEntry +from trackio.utils import TRACKIO_DIR, TRACKIO_LOGO_DIR, _emit_nonfatal_warning + +logging.getLogger("httpx").setLevel(logging.WARNING) + +__version__ = json.loads(Path(__file__).parent.joinpath("package.json").read_text())[ + "version" +] + + +class _TupleNoPrint(tuple): + def __repr__(self) -> str: + return "" + + +__all__ = [ + "init", + "log", + "log_system", + "log_gpu", + "log_artifact", + "use_artifact", + "log_cpu", + "finish", + "alert", + "AlertLevel", + "show", + "sync", + "freeze", + "delete_project", + "import_csv", + "import_tf_events", + "save", + "Artifact", + "Image", + "Video", + "Audio", + "Table", + "Trace", + "Histogram", + "Markdown", + "Api", + "TRACKIO_LOGO_DIR", +] + +Audio = TrackioAudio +Image = TrackioImage +Video = TrackioVideo + + +config = {} + +_atexit_registered = False +_spaces_created_this_session: set[str] = set() +_projects_notified_auto_log_hw: set[str] = set() + + +def _cleanup_current_run(): + run = context_vars.current_run.get() + if run is not None: + try: + run.finish() + except Exception: + pass + + +def _safe_get_runs_for_init( + project: str, + space_id: str | None, + server_base_url: str | None, + write_token: str | None, + resume: str, + remote_client: RemoteClient | None = None, + check_existing_for_never: bool = False, +) -> list[str]: + if space_id is not None or server_base_url is not None: + if resume == "never" and not check_existing_for_never: + return [] + if remote_client is not None: + source = space_id or server_base_url + try: + runs = remote_client.predict( + project=project, api_name="/get_runs_for_project" + ) + return runs if isinstance(runs, list) else [] + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not inspect existing runs for project '{project}' on '{source}': {e}. Continuing without resume metadata." + ) + return [] + try: + return SQLiteStorage.get_runs(project) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not inspect existing runs for project '{project}': {e}. Continuing without resume metadata." + ) + return [] + + +def _safe_get_latest_run_for_init( + project: str, + name: str, + space_id: str | None = None, + server_base_url: str | None = None, + write_token: str | None = None, + remote_client: RemoteClient | None = None, +) -> dict | None: + if ( + space_id is not None or server_base_url is not None + ) and remote_client is not None: + source = space_id or server_base_url + try: + runs = remote_client.predict( + project=project, api_name="/get_runs_for_project" + ) + if not isinstance(runs, list): + return None + matches = [r for r in runs if isinstance(r, dict) and r.get("name") == name] + if not matches: + return None + matches.sort(key=lambda r: r.get("created_at") or "", reverse=True) + return matches[0] + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not inspect existing runs for project '{project}' on '{source}': {e}. Continuing without resume metadata." + ) + return None + try: + return SQLiteStorage.get_latest_run_record_by_name(project, name) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not inspect existing runs for project '{project}': {e}. Continuing without resume metadata." + ) + return None + + +def _safe_get_last_step_for_init( + project: str, + run_name: str, + space_id: str | None, + server_base_url: str | None, + write_token: str | None, + resumed: bool, + run_id: str | None = None, + remote_client: RemoteClient | None = None, +) -> int | None: + if not resumed: + return None + if ( + space_id is not None or server_base_url is not None + ) and remote_client is not None: + source = space_id or server_base_url + try: + summary_kwargs: dict[str, Any] = { + "project": project, + "api_name": "/get_run_summary", + } + if run_id is not None: + summary_kwargs["run_id"] = run_id + else: + summary_kwargs["run"] = run_name + summary = remote_client.predict(**summary_kwargs) + if isinstance(summary, dict): + last_step = summary.get("last_step") + return last_step if isinstance(last_step, int) else None + return None + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not recover the previous step for run '{run_name}' on '{source}': {e}. Continuing from step 0." + ) + return None + try: + return SQLiteStorage.get_max_step_for_run(project, run_name, run_id=run_id) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not recover the previous step for run '{run_name}': {e}. Continuing from step 0." + ) + return None + + +def init( + project: str, + name: str | None = None, + group: str | None = None, + space_id: str | None = None, + server_url: str | None = None, + space_storage: SpaceStorage | None = None, + dataset_id: str | None = None, + bucket_id: str | None = None, + config: dict | None = None, + resume: str = "never", + settings: Any = None, + private: bool | None = None, + embed: bool = True, + auto_log_gpu: bool | None = None, + gpu_log_interval: float = 10.0, + auto_log_cpu: bool | None = None, + cpu_log_interval: float = 10.0, + webhook_url: str | None = None, + webhook_min_level: AlertLevel | str | None = None, +) -> Run: + """ + Creates a new Trackio project and returns a [`Run`] object. + + Args: + project (`str`): + The name of the project (can be an existing project to continue tracking or + a new project to start tracking from scratch). + name (`str`, *optional*): + The name of the run (if not provided, a default name will be generated). + group (`str`, *optional*): + The name of the group which this run belongs to in order to help organize + related runs together. You can toggle the entire group's visibility in the + dashboard. + space_id (`str`, *optional*): + If provided, the project will be logged to a Hugging Face Space instead of + a local directory. Should be a complete Space name like + `"username/reponame"` or `"orgname/reponame"`, or just `"reponame"` in which + case the Space will be created in the currently-logged-in Hugging Face + user's namespace. If the Space does not exist, it will be created. If the + Space already exists, the project will be logged to it. Can also be set + via the `TRACKIO_SPACE_ID` environment variable. You cannot log to a + Space that has been **frozen** (converted to the static SDK); use + ``trackio.sync(..., sdk="static")`` only after you are done logging. + Takes precedence over `server_url` and `TRACKIO_SERVER_URL` when more than + one is set. + server_url (`str`, *optional*): + Base URL of a self-hosted Trackio server (``http://`` or ``https://``), or the + write-access URL from ``trackio.show()`` which may include a ``write_token`` query + parameter. The client sends that token on each request (``X-Trackio-Write-Token``); + you can also set ``TRACKIO_WRITE_TOKEN`` instead of embedding the token in the URL. + When set, metrics are sent to that server over HTTP instead of creating or syncing + to a Hugging Face Space. Can also be set via the ``TRACKIO_SERVER_URL`` environment + variable. Ignored when ``space_id`` or ``TRACKIO_SPACE_ID`` is set. + space_storage ([`~huggingface_hub.SpaceStorage`], *optional*): + Choice of persistent storage tier. + dataset_id (`str`, *optional*): + Deprecated. Use `bucket_id` instead. + bucket_id (`str`, *optional*): + The ID of the Hugging Face Bucket to use for metric persistence. By default, + when a `space_id` is provided and `bucket_id` is not explicitly set, a + bucket is auto-generated from the space_id. Buckets provide + S3-like storage without git overhead - the SQLite database is stored directly + via `hf-mount` in the Space. Specify a Bucket with name like + `"username/bucketname"` or just `"bucketname"`. + config (`dict`, *optional*): + A dictionary of configuration options. Provided for compatibility with + `wandb.init()`. + resume (`str`, *optional*, defaults to `"never"`): + Controls how to handle resuming a run. Can be one of: + + - `"must"`: Must resume the run with the given name, raises error if run + doesn't exist + - `"allow"`: Resume the run if it exists, otherwise create a new run + - `"never"`: Never resume a run, always create a new one + private (`bool`, *optional*): + Whether to make the Space private. If None (default), the repo will be + public unless the organization's default is private. This value is ignored + if the repo already exists. + settings (`Any`, *optional*): + Not used. Provided for compatibility with `wandb.init()`. + embed (`bool`, *optional*, defaults to `True`): + If running inside a Jupyter/Colab notebook, whether the dashboard should + automatically be embedded in the cell when trackio.init() is called. For + local runs, this launches a local Trackio dashboard and embeds it. For Space runs, + this embeds the Space URL. In Colab, the local dashboard will be accessible + via a public share URL when `share=True`. + auto_log_gpu (`bool` or `None`, *optional*, defaults to `None`): + Controls automatic GPU metrics logging. If `None` (default), GPU logging + is automatically enabled when `nvidia-ml-py` is installed and an NVIDIA + GPU or Apple M series is detected. Set to `True` to force enable or + `False` to disable. + gpu_log_interval (`float`, *optional*, defaults to `10.0`): + The interval in seconds between automatic GPU metric logs. + Only used when `auto_log_gpu=True`. + auto_log_cpu (`bool` or `None`, *optional*, defaults to `None`): + Controls automatic CPU and RAM metrics logging (utilization, memory, + disk I/O, network I/O, and sensors). If `None` (default), CPU logging + is automatically enabled when `psutil` is installed. Set to `True` to + force enable or `False` to disable. + cpu_log_interval (`float`, *optional*, defaults to `10.0`): + The interval in seconds between automatic CPU metric logs. + Only used when CPU auto-logging is enabled. + webhook_url (`str`, *optional*): + A webhook URL to POST alert payloads to when `trackio.alert()` is + called. Supports Slack and Discord webhook URLs natively (payloads + are formatted automatically). Can also be set via the + `TRACKIO_WEBHOOK_URL` environment variable. Individual alerts can + override this URL by passing `webhook_url` to `trackio.alert()`. + webhook_min_level (`AlertLevel` or `str`, *optional*): + Minimum alert level that should trigger webhook delivery. + For example, `AlertLevel.WARN` sends only `WARN` and `ERROR` + alerts to the webhook destination. Can also be set via + `TRACKIO_WEBHOOK_MIN_LEVEL`. + Returns: + `Run`: A [`Run`] object that can be used to log metrics and finish the run. + """ + SQLiteStorage.validate_project_name(project) + + if settings is not None: + _emit_nonfatal_warning( + "* Warning: settings is not used. Provided for compatibility with wandb.init(). Please create an issue at: https://github.com/gradio-app/trackio/issues if you need a specific feature implemented." + ) + + previous_run = context_vars.current_run.get() + if previous_run is not None: + try: + previous_run.finish() + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not finish the previous run '{previous_run.name}': {e}. Continuing with new run." + ) + context_vars.current_run.set(None) + + bucket_id_was_explicit = bucket_id is not None + space_id, server_url = utils.resolve_space_id_and_server_url(space_id, server_url) + if bucket_id is None and utils.on_spaces(): + bucket_id = os.environ.get("TRACKIO_BUCKET_ID") + if server_url is not None and not server_url.startswith(("http://", "https://")): + raise ValueError( + f"`server_url` must be a full URL starting with http:// or https://, got: {server_url!r}" + ) + server_base_url: str | None = None + write_token_resolved: str | None = None + if server_url is not None: + server_base_url, tok = utils.parse_trackio_server_url(server_url) + write_token_resolved = tok or os.environ.get("TRACKIO_WRITE_TOKEN") + if not write_token_resolved: + raise ValueError( + "Self-hosted logging requires a write token: add write_token to the server URL, " + "or set the TRACKIO_WRITE_TOKEN environment variable." + ) + if server_url is not None and (dataset_id is not None or bucket_id is not None): + raise ValueError( + "`dataset_id` and `bucket_id` are Hugging Face Spaces concepts and are not " + "compatible with `server_url`. Configure storage on the self-hosted server." + ) + if space_id is None and dataset_id is not None: + raise ValueError("Must provide a `space_id` when `dataset_id` is provided.") + if dataset_id is not None and bucket_id is not None: + raise ValueError("Cannot provide both `dataset_id` and `bucket_id`.") + try: + space_id, dataset_id, bucket_id = utils.preprocess_space_and_dataset_ids( + space_id, dataset_id, bucket_id + ) + if ( + space_id is not None + and dataset_id is None + and bucket_id is not None + and not bucket_id_was_explicit + and not utils.on_spaces() + ): + bucket_id = deploy.resolve_auto_bucket_id(space_id, bucket_id) + except LocalTokenNotFoundError as e: + raise LocalTokenNotFoundError( + f"You must be logged in to Hugging Face locally when `space_id` is provided to deploy to a Space. {e}" + ) from e + + if space_id is None and bucket_id is not None: + _emit_nonfatal_warning( + "trackio.init() has `bucket_id` set but `space_id` is None: metrics will be logged " + "locally only. Pass `space_id` to create or use a Hugging Face Space, which will be " + "attached to the Hugging Face Bucket.", + UserWarning, + stacklevel=2, + ) + + if space_id is not None: + deploy.raise_if_space_is_frozen_for_logging(space_id) + + remote_source = space_id or server_base_url + + if remote_source is not None: + url = remote_source + context_vars.current_server.set(url) + if space_id is not None: + context_vars.current_space_id.set(space_id) + context_vars.current_server_write_token.set(None) + else: + context_vars.current_space_id.set(None) + context_vars.current_server_write_token.set(write_token_resolved) + else: + url = None + context_vars.current_server.set(None) + context_vars.current_space_id.set(None) + context_vars.current_server_write_token.set(None) + + _should_embed_local = False + + newly_created_space = False + if space_id is not None and space_id in _spaces_created_this_session: + if deploy.space_is_running(space_id): + _spaces_created_this_session.discard(space_id) + else: + newly_created_space = True + + if ( + context_vars.current_project.get() is None + or context_vars.current_project.get() != project + ): + print(f"* Trackio project initialized: {project}") + + if bucket_id is not None: + if utils.on_spaces(): + os.environ["TRACKIO_BUCKET_ID"] = bucket_id + bucket_url = f"https://huggingface.co/buckets/{bucket_id}" + print( + f"* Trackio metrics will be synced to Hugging Face Bucket: {bucket_url}" + ) + elif dataset_id is not None: + if utils.on_spaces(): + os.environ["TRACKIO_DATASET_ID"] = dataset_id + print( + f"* Trackio metrics will be synced to Hugging Face Dataset: {dataset_id}" + ) + if remote_source is None: + print(f"* Trackio metrics logged to: {TRACKIO_DIR}") + _should_embed_local = embed and utils.is_in_notebook() + if not _should_embed_local: + utils.print_dashboard_instructions(project) + elif server_base_url is not None: + print( + f"* Trackio metrics will be sent to self-hosted server: {server_base_url}" + ) + if utils.is_in_notebook() and embed: + utils.embed_url_in_notebook(server_base_url) + else: + try: + if deploy.create_space_if_not_exists( + space_id, + space_storage, + dataset_id, + bucket_id, + private, + ): + _spaces_created_this_session.add(space_id) + newly_created_space = True + user_name, space_name = space_id.split("/") + space_url = deploy.SPACE_HOST_URL.format( + user_name=user_name, space_name=space_name + ) + if utils.is_in_notebook() and embed: + utils.embed_url_in_notebook(space_url) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not prepare Space '{space_id}': {e}. Logging will continue in local fallback mode until the Space is reachable." + ) + context_vars.current_project.set(project) + + remote_client = None + if space_id is not None and not newly_created_space: + try: + remote_client = RemoteClient( + space_id, + hf_token=huggingface_hub.utils.get_token(), + verbose=False, + ) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not create a remote client for Space '{space_id}': {e}. Continuing with local fallback metadata lookups." + ) + elif server_base_url is not None: + try: + remote_client = RemoteClient( + server_base_url, + hf_token=None, + write_token=write_token_resolved, + verbose=False, + ) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not create a remote client for '{server_base_url}': {e}. Continuing with local fallback metadata lookups." + ) + + existing_run_records = _safe_get_runs_for_init( + project, + space_id, + server_base_url, + write_token_resolved, + resume, + remote_client=remote_client, + check_existing_for_never=name is not None, + ) + existing_runs = [ + r["name"] if isinstance(r, dict) else r for r in existing_run_records + ] + + existing_run = ( + _safe_get_latest_run_for_init( + project, + name, + space_id=space_id, + server_base_url=server_base_url, + write_token=write_token_resolved, + remote_client=remote_client, + ) + if name is not None + else None + ) + resolved_run_id = None + + if resume == "must": + if name is None: + raise ValueError("Must provide a run name when resume='must'") + if existing_run is None: + raise ValueError(f"Run '{name}' does not exist in project '{project}'") + resumed = True + resolved_run_id = existing_run["id"] + elif resume == "allow": + resumed = existing_run is not None + if resumed: + resolved_run_id = existing_run["id"] + elif resume == "never": + resumed = False + else: + raise ValueError("resume must be one of: 'must', 'allow', or 'never'") + + initial_last_step = ( + _safe_get_last_step_for_init( + project, + name, + space_id, + server_base_url, + write_token_resolved, + resumed, + run_id=resolved_run_id, + remote_client=remote_client, + ) + if name is not None + else None + ) + + auto_log_cpu_detected = False + if auto_log_cpu is None: + auto_log_cpu_detected = cpu_available() + auto_log_cpu = auto_log_cpu_detected + + auto_log_gpu_detected = False + nvidia_available = False + apple_available = False + if auto_log_gpu is None: + nvidia_available = gpu_available() + apple_available = apple_gpu_available() + auto_log_gpu_detected = nvidia_available or apple_available + auto_log_gpu = auto_log_gpu_detected + + if project not in _projects_notified_auto_log_hw: + if nvidia_available: + print("* NVIDIA GPU detected, enabling automatic GPU metrics logging") + elif apple_available: + print( + "* Apple Silicon detected, enabling automatic GPU/system metrics logging" + ) + if auto_log_cpu_detected: + print("* psutil detected, enabling automatic CPU/system metrics logging") + if auto_log_gpu_detected or auto_log_cpu_detected: + _projects_notified_auto_log_hw.add(project) + + run = Run( + url=url, + project=project, + client=None, + name=name, + run_id=resolved_run_id, + group=group, + config=config, + space_id=space_id, + bucket_id=bucket_id, + server_base_url=server_base_url, + write_token=write_token_resolved, + existing_runs=existing_runs, + initial_last_step=initial_last_step, + auto_log_gpu=auto_log_gpu, + gpu_log_interval=gpu_log_interval, + auto_log_cpu=auto_log_cpu, + cpu_log_interval=cpu_log_interval, + webhook_url=webhook_url, + webhook_min_level=webhook_min_level, + ) + + if space_id is not None: + try: + SQLiteStorage.set_project_metadata(project, "space_id", space_id) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not persist Space metadata for project '{project}': {e}. Logging will continue." + ) + try: + if SQLiteStorage.has_pending_data(project): + run._has_local_buffer = True + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not inspect pending buffered data for project '{project}': {e}. Logging will continue." + ) + + global _atexit_registered + if not _atexit_registered: + atexit.register(_cleanup_current_run) + _atexit_registered = True + + if resumed: + print(f"* Resumed existing run: {run.name}") + else: + print(f"* Created new run: {run.name}") + + context_vars.current_run.set(run) + globals()["config"] = run.config + + if space_id is not None or server_url is None: + try: + from trackio import logbook as _logbook # noqa: PLC0415 + + _logbook.auto_note_dashboard(project, space_id=space_id) + except Exception: + pass + + if _should_embed_local: + try: + show(project=project, open_browser=False, block_thread=False) + except Exception as e: + _emit_nonfatal_warning( + f"trackio.init() could not auto-launch the dashboard: {e}. Logging will continue." + ) + + return run + + +def log(metrics: dict, step: int | None = None) -> None: + """ + Logs metrics to the current run. + + Args: + metrics (`dict`): + A dictionary of metrics to log. + step (`int`, *optional*): + The step number. If not provided, the step will be incremented + automatically. + """ + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log().") + run.log( + metrics=metrics, + step=step, + ) + + +def log_system(metrics: dict) -> None: + """ + Logs system metrics (GPU, etc.) to the current run using timestamps instead of steps. + + Args: + metrics (`dict`): + A dictionary of system metrics to log. + """ + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log_system().") + run.log_system(metrics=metrics) + + +def log_artifact( + artifact_or_path: Artifact | str | Path, + name: str | None = None, + type: str | None = None, + aliases: list[str] | None = None, +) -> Artifact: + """ + Logs an artifact as an output of the current run. + + Args: + artifact_or_path (`Artifact`, `str`, or `Path`): + The artifact to log (must have at least one file added via + `add_file` or `add_dir`), or a path to a file or directory to + log as a new artifact. + name (`str`, *optional*): + Artifact name when logging a path. Defaults to + `run--`. Must not be passed with an `Artifact`. + type (`str`, *optional*): + Artifact type when logging a path (e.g. `"model"`, `"dataset"`). + Defaults to `"unspecified"`. Must not be passed with an + `Artifact`. + aliases (`list[str]`, *optional*): + Aliases to rotate onto the resulting version, alongside `latest` + (assigned automatically whenever a new version is created). Your + aliases rotate onto the version even when identical content is + de-duplicated. + + Returns: + The logged `Artifact` instance, hydrated with `version`, `aliases`, + `size`, `manifest`, and `project` set. + """ + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log_artifact().") + return run.log_artifact(artifact_or_path, name=name, type=type, aliases=aliases) + + +def use_artifact( + artifact_or_name: Artifact | str, + type: str | None = None, +) -> Artifact: + """ + Fetches an artifact and records it as an input to the current run. + + Args: + artifact_or_name (`Artifact` or `str`): + An already-logged `Artifact`, or an artifact name. A bare name + (`"my-model"`) resolves to `:latest`; you can also pin a version + (`"my-model:v3"`) or resolve an alias (`"my-model:prod"`). + type (`str`, *optional*): + If given, checked against the stored artifact type, raising if it + does not match. + + Returns: + The fetched `Artifact`, hydrated and ready to `download()`. + """ + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.use_artifact().") + return run.use_artifact(artifact_or_name, type=type) + + +def log_gpu(run: Run | None = None, device: int | None = None) -> dict: + """ + Log GPU metrics to the current or specified run as system metrics. + Automatically detects whether an NVIDIA or Apple GPU is available and calls + the appropriate logging method. + + Args: + run: Optional Run instance. If None, uses current run from context. + device: CUDA device index to collect metrics from (NVIDIA GPUs only). + If None, collects from all GPUs visible to this process. + This parameter is ignored for Apple GPUs. + + Returns: + dict: The GPU metrics that were logged. + + Example: + ```python + import trackio + + run = trackio.init(project="my-project") + trackio.log({"loss": 0.5}) + trackio.log_gpu() + trackio.log_gpu(device=0) + ``` + """ + if run is None: + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log_gpu().") + + if gpu_available(): + return _log_nvidia_gpu(run=run, device=device) + elif apple_gpu_available(): + return _log_apple_gpu(run=run) + else: + _emit_nonfatal_warning( + "No GPU detected. Install nvidia-ml-py for NVIDIA GPU support " + "or psutil for Apple Silicon support." + ) + return {} + + +def log_cpu(run: Run | None = None) -> dict: + """ + Log CPU, RAM, disk, network, and sensor metrics to the current or specified run + as system metrics. + + Args: + run: Optional Run instance. If None, uses current run from context. + + Returns: + dict: The CPU and system metrics that were logged. + + Example: + ```python + import trackio + + run = trackio.init(project="my-project") + trackio.log({"loss": 0.5}) + trackio.log_cpu() + ``` + """ + if run is None: + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log_cpu().") + + return _log_cpu(run=run) + + +def finish(): + """ + Finishes the current run. + """ + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.finish().") + try: + run.finish() + finally: + context_vars.current_run.set(None) + + +def alert( + title: str, + text: str | None = None, + level: AlertLevel = AlertLevel.WARN, + webhook_url: str | None = None, +) -> None: + """ + Fires an alert immediately on the current run. The alert is printed to the + terminal, stored in the database, and displayed in the dashboard. If a + webhook URL is configured (via `trackio.init()`, the `TRACKIO_WEBHOOK_URL` + environment variable, or the `webhook_url` parameter here), the alert is + also POSTed to that URL. + + Args: + title (`str`): + A short title for the alert. + text (`str`, *optional*): + A longer description with details about the alert. + level (`AlertLevel`, *optional*, defaults to `AlertLevel.WARN`): + The severity level. One of `AlertLevel.INFO`, `AlertLevel.WARN`, + or `AlertLevel.ERROR`. + webhook_url (`str`, *optional*): + A webhook URL to send this specific alert to. Overrides any + URL set in `trackio.init()` or the `TRACKIO_WEBHOOK_URL` + environment variable. Supports Slack and Discord webhook + URLs natively. + """ + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.alert().") + run.alert(title=title, text=text, level=level, webhook_url=webhook_url) + + +def delete_project(project: str, force: bool = False) -> bool: + """ + Deletes a project by removing its local SQLite database. + + Args: + project (`str`): + The name of the project to delete. + force (`bool`, *optional*, defaults to `False`): + If `True`, deletes the project without prompting for confirmation. + If `False`, prompts the user to confirm before deleting. + + Returns: + `bool`: `True` if the project was deleted, `False` otherwise. + """ + db_path = SQLiteStorage.get_project_db_path(project) + + if not db_path.exists(): + print(f"* Project '{project}' does not exist.") + return False + + if not force: + response = input( + f"Are you sure you want to delete project '{project}'? " + f"This will permanently delete all runs and metrics. (y/N): " + ) + if response.lower() not in ["y", "yes"]: + print("* Deletion cancelled.") + return False + + try: + db_path.unlink() + + for suffix in ("-wal", "-shm"): + sidecar = Path(str(db_path) + suffix) + if sidecar.exists(): + sidecar.unlink() + + for parquet_path in SQLiteStorage._project_parquet_paths(db_path): + if parquet_path.exists(): + parquet_path.unlink() + + for asset_dir in ( + utils.project_artifacts_dir(project), + utils.project_media_dir(project), + ): + if asset_dir.exists(): + shutil.rmtree(asset_dir, ignore_errors=True) + + print(f"* Project '{project}' has been deleted.") + return True + except Exception as e: + print(f"* Error deleting project '{project}': {e}") + return False + + +def save( + glob_str: str | Path, + project: str | None = None, +) -> str: + """ + Saves files to a project (not linked to a specific run). If Trackio is running + locally, the file(s) will be copied to the project's files directory. If Trackio is + running in a Space, the file(s) will be uploaded to the Space's files directory. + + Args: + glob_str (`str` or `Path`): + The file path or glob pattern to save. Can be a single file or a pattern + matching multiple files (e.g., `"*.py"`, `"models/**/*.pth"`). + project (`str`, *optional*): + The name of the project to save files to. If not provided, uses the current + project from `trackio.init()`. If no project is initialized, raises an + error. + + Returns: + `str`: The path where the file(s) were saved (project's files directory). + + Example: + ```python + import trackio + + trackio.init(project="my-project") + trackio.save("config.yaml") + trackio.save("models/*.pth") + ``` + """ + if project is None: + project = context_vars.current_project.get() + if project is None: + raise RuntimeError( + "No project specified. Either call trackio.init() first or provide a " + "project parameter to trackio.save()." + ) + + glob_str = Path(glob_str) + base_path = Path.cwd().resolve() + + matched_files = [] + if glob_str.is_file(): + matched_files = [glob_str.resolve()] + else: + pattern = str(glob_str) + if not glob_str.is_absolute(): + pattern = str((Path.cwd() / glob_str).resolve()) + matched_files = [ + Path(f).resolve() + for f in glob.glob(pattern, recursive=True) + if Path(f).is_file() + ] + + if not matched_files: + raise ValueError(f"No files found matching pattern: {glob_str}") + + current_run = context_vars.current_run.get() + is_local = ( + current_run._is_local + if current_run is not None + else ( + context_vars.current_space_id.get() is None + and context_vars.current_server.get() is None + ) + ) + + if is_local: + for file_path in matched_files: + try: + relative_to_base = file_path.relative_to(base_path) + except ValueError: + relative_to_base = Path(file_path.name) + + if current_run is not None: + current_run._queue_upload( + file_path, + step=None, + relative_path=str(relative_to_base.parent), + use_run_name=False, + ) + else: + media_path = get_project_media_path( + project=project, + run=None, + step=None, + relative_path=str(relative_to_base), + ) + shutil.copy(str(file_path), str(media_path)) + else: + url = context_vars.current_server.get() + + upload_entries = [] + for file_path in matched_files: + try: + relative_to_base = file_path.relative_to(base_path) + except ValueError: + relative_to_base = Path(file_path.name) + + if current_run is not None: + current_run._queue_upload( + file_path, + step=None, + relative_path=str(relative_to_base.parent), + use_run_name=False, + ) + else: + upload_entry: UploadEntry = { + "project": project, + "run": None, + "step": None, + "relative_path": str(relative_to_base), + "uploaded_file": handle_file(file_path), + } + upload_entries.append(upload_entry) + + if upload_entries: + if url is None: + raise RuntimeError( + "No server available. Call trackio.init() before trackio.save() to start the server." + ) + + try: + wt = context_vars.current_server_write_token.get() + if wt is not None: + client = RemoteClient( + url, + hf_token=None, + write_token=wt, + httpx_kwargs={"timeout": 90}, + ) + else: + client = RemoteClient( + url, + hf_token=huggingface_hub.utils.get_token(), + httpx_kwargs={"timeout": 90}, + ) + client.predict( + api_name="/bulk_upload_media", + uploads=upload_entries, + hf_token=huggingface_hub.utils.get_token() if wt is None else None, + ) + except Exception as e: + _emit_nonfatal_warning( + f"Failed to upload files: {e}. " + "Files may not be available in the dashboard." + ) + + return str(utils.project_media_dir(project) / "files") + + +def show( + project: str | None = None, + *, + theme: Any = None, + mcp_server: bool | None = None, + footer: bool = True, + color_palette: list[str] | None = None, + open_browser: bool = True, + block_thread: bool | None = None, + host: str | None = None, + share: bool | None = None, + server_port: int | None = None, + frontend_dir: str | Path | None = None, +): + """ + Launches the Trackio dashboard. + + Args: + project (`str`, *optional*): + The name of the project whose runs to show. If not provided, all projects + will be shown and the user can select one. + theme (`Any`, *optional*): + Ignored. Kept for backward compatibility; Trackio no longer uses Gradio themes. + mcp_server (`bool`, *optional*): + If `True`, the dashboard exposes an MCP server at `/mcp` when the optional + `trackio[mcp]` dependency is installed. If `None` (default), the + `GRADIO_MCP_SERVER` environment variable is used (e.g. on Spaces). + footer (`bool`, *optional*, defaults to `True`): + Whether to include `footer=false` in the write-token URL when `False`. + This can also be controlled via the `footer` query parameter in the URL. + color_palette (`list[str]`, *optional*): + A list of hex color codes to use for plot lines. If not provided, the + `TRACKIO_COLOR_PALETTE` environment variable will be used (comma-separated + hex codes), or if that is not set, the default color palette will be used. + Example: `['#FF0000', '#00FF00', '#0000FF']` + open_browser (`bool`, *optional*, defaults to `True`): + If `True` and not in a notebook, a new browser tab will be opened with the + dashboard. If `False`, the browser will not be opened. + block_thread (`bool`, *optional*): + If `True`, the main thread will be blocked until the dashboard is closed. + If `None` (default behavior), then the main thread will not be blocked if the + dashboard is launched in a notebook, otherwise the main thread will be blocked. + host (`str`, *optional*): + The host to bind the server to. If not provided, defaults to `'127.0.0.1'` + (localhost only). Set to `'0.0.0.0'` to allow remote access. + share (`bool`, *optional*): + If `True`, creates a temporary public URL (Gradio-compatible tunnel). On Colab + or hosted notebooks, defaults to `True` unless overridden. + server_port (`int`, *optional*): + Port to bind. If not set, scans from `GRADIO_SERVER_PORT` (default 7860). + frontend_dir (`str | Path`, *optional*): + Directory containing a custom static frontend. Must contain `index.html`. + If not provided, Trackio checks `TRACKIO_FRONTEND_DIR`, then the persistent + Trackio config, then the bundled frontend. If an explicit `frontend_dir` + points to a missing or empty directory, Trackio copies in the starter + template and serves that directory. + + Returns: + `app`: The dashboard handle (`.close()` stops the server). + `url`: The local URL of the dashboard. + `share_url`: The public share URL, if any. + `full_url`: The full URL including the write token (share URL when sharing, else local). + """ + if theme is not None and theme != "default": + warnings.warn( + "The theme argument is ignored; Trackio no longer depends on Gradio themes.", + UserWarning, + stacklevel=2, + ) + + if color_palette is not None: + os.environ["TRACKIO_COLOR_PALETTE"] = ",".join(color_palette) + + _mcp_server = ( + mcp_server + if mcp_server is not None + else os.environ.get("GRADIO_MCP_SERVER", "False") == "True" + ) + + resolved_frontend = resolve_frontend_dir(frontend_dir, announce=True) + starlette_app, wt = build_starlette_app_only( + mcp_server=_mcp_server, + frontend_dir=str(resolved_frontend.path), + ) + local_url, share_url, _local_api_url, uv_server = launch_trackio_dashboard( + starlette_app, + server_name=host, + server_port=server_port, + share=share, + mcp_server=_mcp_server, + quiet=True, + ) + server = TrackioDashboardApp(starlette_app, uv_server, wt) + + base_root = (share_url or local_url).rstrip("/") + base_url = base_root + "/" + dashboard_url = base_url + if project: + dashboard_url += f"?project={project}" + full_url = utils.get_full_url( + base_root, + project=project, + write_token=wt, + footer=footer, + ) + + if not utils.is_in_notebook(): + print(f"\033[1m\033[38;5;208m* Trackio UI launched at: {dashboard_url}\033[0m") + utils.print_write_token_instructions(full_url) + if open_browser: + webbrowser.open(full_url) + block_thread = block_thread if block_thread is not None else True + else: + utils.embed_url_in_notebook(full_url) + block_thread = block_thread if block_thread is not None else False + + if block_thread: + utils.block_main_thread_until_keyboard_interrupt() + return _TupleNoPrint((server, local_url, share_url, full_url)) diff --git a/trackio/_vendor/__init__.py b/trackio/_vendor/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/trackio/_vendor/gradio_exceptions.py b/trackio/_vendor/gradio_exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..34696b9e534896b66557bab78a2d78709c07e351 --- /dev/null +++ b/trackio/_vendor/gradio_exceptions.py @@ -0,0 +1,6 @@ +class ChecksumMismatchError(Exception): + pass + + +class ShareCertificateWriteError(Exception): + pass diff --git a/trackio/_vendor/networking.py b/trackio/_vendor/networking.py new file mode 100644 index 0000000000000000000000000000000000000000..04ef35763f89eb813059ea6fc91a7316ecd2f2de --- /dev/null +++ b/trackio/_vendor/networking.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +import os +import time +import warnings +from pathlib import Path +from urllib.parse import urlparse, urlunparse + +import httpx + +from trackio._vendor.gradio_exceptions import ShareCertificateWriteError +from trackio._vendor.tunneling import CERTIFICATE_PATH, Tunnel + +GRADIO_API_SERVER = "https://api.gradio.app/v3/tunnel-request" +GRADIO_SHARE_SERVER_ADDRESS = os.getenv("GRADIO_SHARE_SERVER_ADDRESS") + + +def setup_tunnel( + local_host: str, + local_port: int, + share_token: str, + share_server_address: str | None, + share_server_tls_certificate: str | None, +) -> str: + share_server_address = ( + GRADIO_SHARE_SERVER_ADDRESS + if share_server_address is None + else share_server_address + ) + if share_server_address is None: + try: + response = httpx.get(GRADIO_API_SERVER, timeout=30) + payload = response.json()[0] + remote_host, remote_port = payload["host"], int(payload["port"]) + certificate = payload["root_ca"] + except Exception as e: + raise RuntimeError( + "Could not get share link from Gradio API Server." + ) from e + try: + Path(CERTIFICATE_PATH).parent.mkdir(parents=True, exist_ok=True) + with open(CERTIFICATE_PATH, "w") as f: + f.write(certificate) + except Exception as e: + raise ShareCertificateWriteError( + f"{e}. This can happen if the current working directory is read-only." + ) from e + share_server_tls_certificate = CERTIFICATE_PATH + + else: + remote_host, remote_port = share_server_address.split(":") + remote_port = int(remote_port) + tunnel = Tunnel( + remote_host, + remote_port, + local_host, + local_port, + share_token, + share_server_tls_certificate, + ) + address = tunnel.start_tunnel() + return address + + +def url_ok(url: str) -> bool: + try: + for _ in range(5): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + r = httpx.head(url, timeout=3, verify=False) + if r.status_code in (200, 401, 302, 303, 307): + return True + time.sleep(0.500) + except (ConnectionError, httpx.ConnectError, httpx.TimeoutException): + return False + return False + + +def normalize_share_url(share_url: str, share_server_protocol: str) -> str: + parsed_url = urlparse(share_url) + return urlunparse((share_server_protocol,) + parsed_url[1:]) diff --git a/trackio/_vendor/tunneling.py b/trackio/_vendor/tunneling.py new file mode 100644 index 0000000000000000000000000000000000000000..6bd6258ed043ba70b07bb1e928bf009864206000 --- /dev/null +++ b/trackio/_vendor/tunneling.py @@ -0,0 +1,191 @@ +import atexit +import hashlib +import os +import platform +import re +import stat +import subprocess +import sys +import time +from pathlib import Path + +import httpx +from huggingface_hub.constants import HF_HOME + +from trackio._vendor.gradio_exceptions import ChecksumMismatchError + +VERSION = "0.3" +CURRENT_TUNNELS: list["Tunnel"] = [] + +machine = platform.machine() +if machine == "x86_64": + machine = "amd64" +elif machine == "aarch64": + machine = "arm64" + +BINARY_REMOTE_NAME = f"frpc_{platform.system().lower()}_{machine.lower()}" +EXTENSION = ".exe" if os.name == "nt" else "" +BINARY_URL = f"https://cdn-media.huggingface.co/frpc-gradio-{VERSION}/{BINARY_REMOTE_NAME}{EXTENSION}" + +CHECKSUMS = { + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_windows_amd64.exe": "14bc0ea470be5d67d79a07412bd21de8a0a179c6ac1116d7764f68e942dc9ceb", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_amd64": "c791d1f047b41ff5885772fc4bf20b797c6059bbd82abb9e31de15e55d6a57c4", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_arm64": "823ced25104de6dc3c9f4798dbb43f20e681207279e6ab89c40e2176ccbf70cd", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_darwin_amd64": "930f8face3365810ce16689da81b7d1941fda4466225a7bbcbced9a2916a6e15", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_darwin_arm64": "dfac50c690aca459ed5158fad8bfbe99f9282baf4166cf7c410a6673fbc1f327", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_arm": "4b563beb2e36c448cc688174e20b53af38dc1ff2b5e362d4ddd1401f2affbfb7", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_freebsd_386": "cb0a56c764ecf96dd54ed601d240c564f060ee4e58202d65ffca17c1a51ce19c", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_freebsd_amd64": "516d9e6903513869a011ddcd1ec206167ad1eb5dd6640d21057acc258edecbbb", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_386": "4c2f2a48cd71571498c0ac8a4d42a055f22cb7f14b4b5a2b0d584220fd60a283", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_mips": "b309ecd594d4f0f7f33e556a80d4b67aef9319c00a8334648a618e56b23cb9e0", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_mips64": "0372ef5505baa6f3b64c6295a86541b24b7b0dbe4ef28b344992e21f47624b7b", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_riscv64": "1658eed7e8c14ea76e1d95749d58441ce24147c3d559381832c725c29cfc3df3", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_mipsle": "a2aaba16961d3372b79bd7a28976fcd0f0bbaebc2b50d5a7a71af2240747960f", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_windows_386.exe": "721b90550195a83e15f2176d8f85a48d5a25822757cb872e9723d4bccc4e5bb6", + "https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_linux_mips64le": "796481edd609f31962b45cc0ab4c9798d040205ae3bf354ed1b72fb432d796b8", +} + +CHUNK_SIZE = 128 + +BINARY_FILENAME = f"{BINARY_REMOTE_NAME}_v{VERSION}" +BINARY_FOLDER = Path(HF_HOME) / "trackio" / "frpc" +BINARY_PATH = str(BINARY_FOLDER / BINARY_FILENAME) + +TUNNEL_TIMEOUT_SECONDS = 30 +TUNNEL_ERROR_MESSAGE = ( + "Could not create share URL. " + "Please check the appended log from frpc for more information:" +) + +CERTIFICATE_PATH = ".trackio/certificate.pem" + + +class Tunnel: + def __init__( + self, + remote_host: str, + remote_port: int, + local_host: str, + local_port: int, + share_token: str, + share_server_tls_certificate: str | None, + ): + self.proc = None + self.url = None + self.remote_host = remote_host + self.remote_port = remote_port + self.local_host = local_host + self.local_port = local_port + self.share_token = share_token + self.share_server_tls_certificate = share_server_tls_certificate + + @staticmethod + def download_binary(): + if not Path(BINARY_PATH).exists(): + Path(BINARY_FOLDER).mkdir(parents=True, exist_ok=True) + resp = httpx.get(BINARY_URL, timeout=30) + + if resp.status_code == 403: + raise OSError( + f"Cannot set up a share link as this platform is incompatible. Please " + f"create a GitHub issue with information about your platform: {platform.uname()}" + ) + + resp.raise_for_status() + + with open(BINARY_PATH, "wb") as file: + file.write(resp.content) + st = os.stat(BINARY_PATH) + os.chmod(BINARY_PATH, st.st_mode | stat.S_IEXEC) + + if BINARY_URL in CHECKSUMS: + sha = hashlib.sha256() + with open(BINARY_PATH, "rb") as f: + for chunk in iter(lambda: f.read(CHUNK_SIZE * sha.block_size), b""): + sha.update(chunk) + calculated_hash = sha.hexdigest() + + if calculated_hash != CHECKSUMS[BINARY_URL]: + raise ChecksumMismatchError() + + def start_tunnel(self) -> str: + self.download_binary() + self.url = self._start_tunnel(BINARY_PATH) + return self.url + + def kill(self): + if self.proc is not None: + print(f"Killing tunnel {self.local_host}:{self.local_port} <> {self.url}") + self.proc.terminate() + self.proc = None + + def _start_tunnel(self, binary: str) -> str: + CURRENT_TUNNELS.append(self) + command = [ + binary, + "http", + "-n", + self.share_token, + "-l", + str(self.local_port), + "-i", + self.local_host, + "--uc", + "--sd", + "random", + "--ue", + "--server_addr", + f"{self.remote_host}:{self.remote_port}", + "--disable_log_color", + ] + if self.share_server_tls_certificate is not None: + command.extend( + [ + "--tls_enable", + "--tls_trusted_ca_file", + self.share_server_tls_certificate, + ] + ) + self.proc = subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + atexit.register(self.kill) + return self._read_url_from_tunnel_stream() + + def _read_url_from_tunnel_stream(self) -> str: + start_timestamp = time.time() + + log = [] + url = "" + + def _raise_tunnel_error(): + log_text = "\n".join(log) + print(log_text, file=sys.stderr) + raise ValueError(f"{TUNNEL_ERROR_MESSAGE}\n{log_text}") + + while url == "": + if time.time() - start_timestamp >= TUNNEL_TIMEOUT_SECONDS: + _raise_tunnel_error() + + assert self.proc is not None # noqa: S101 + if self.proc.stdout is None: + continue + + line = self.proc.stdout.readline() + line = line.decode("utf-8") + + if line == "": + continue + + log.append(line.strip()) + + if "start proxy success" in line: + result = re.search("start proxy success: (.+)\n", line) + if result is None: + _raise_tunnel_error() + else: + url = result.group(1) + elif "login to server failed" in line: + _raise_tunnel_error() + + return url diff --git a/trackio/alerts.py b/trackio/alerts.py new file mode 100644 index 0000000000000000000000000000000000000000..646b9786eacb91fca5270189a78280293e045fc0 --- /dev/null +++ b/trackio/alerts.py @@ -0,0 +1,184 @@ +import json +import logging +import ssl +import urllib.request +from enum import Enum + +try: + import certifi + + _SSL_CONTEXT = ssl.create_default_context(cafile=certifi.where()) +except ImportError: + _SSL_CONTEXT = None + +logger = logging.getLogger(__name__) + + +class AlertLevel(str, Enum): + INFO = "info" + WARN = "warn" + ERROR = "error" + + +ALERT_LEVEL_ORDER = { + AlertLevel.INFO: 0, + AlertLevel.WARN: 1, + AlertLevel.ERROR: 2, +} + +ALERT_COLORS = { + AlertLevel.INFO: "\033[94m", + AlertLevel.WARN: "\033[93m", + AlertLevel.ERROR: "\033[91m", +} +RESET_COLOR = "\033[0m" + +LEVEL_EMOJI = { + AlertLevel.INFO: "ℹ️", + AlertLevel.WARN: "⚠️", + AlertLevel.ERROR: "🚨", +} + + +def format_alert_terminal( + level: AlertLevel, title: str, text: str | None, step: int | None +) -> str: + color = ALERT_COLORS.get(level, "") + step_str = f" (step {step})" if step is not None else "" + if text: + return f"{color}[TRACKIO {level.value.upper()}]{RESET_COLOR} {title}: {text}{step_str}" + return f"{color}[TRACKIO {level.value.upper()}]{RESET_COLOR} {title}{step_str}" + + +def _is_slack_url(url: str) -> bool: + return "hooks.slack.com" in url + + +def _is_discord_url(url: str) -> bool: + return "discord.com/api/webhooks" in url or "discordapp.com/api/webhooks" in url + + +def _build_slack_payload( + level: AlertLevel, + title: str, + text: str | None, + project: str, + run: str, + step: int | None, +) -> dict: + emoji = LEVEL_EMOJI.get(level, "") + step_str = f" • Step {step}" if step is not None else "" + header = f"{emoji} *[{level.value.upper()}] {title}*" + context = f"Project: {project} • Run: {run}{step_str}" + blocks = [ + {"type": "section", "text": {"type": "mrkdwn", "text": header}}, + ] + if text: + blocks.append({"type": "section", "text": {"type": "mrkdwn", "text": text}}) + blocks.append( + {"type": "context", "elements": [{"type": "mrkdwn", "text": context}]} + ) + return {"blocks": blocks} + + +def _build_discord_payload( + level: AlertLevel, + title: str, + text: str | None, + project: str, + run: str, + step: int | None, +) -> dict: + color_map = { + AlertLevel.INFO: 3447003, + AlertLevel.WARN: 16776960, + AlertLevel.ERROR: 15158332, + } + emoji = LEVEL_EMOJI.get(level, "") + step_str = f" • Step {step}" if step is not None else "" + embed = { + "title": f"{emoji} [{level.value.upper()}] {title}", + "color": color_map.get(level, 0), + "footer": {"text": f"Project: {project} • Run: {run}{step_str}"}, + } + if text: + embed["description"] = text + return {"embeds": [embed]} + + +def _build_generic_payload( + level: AlertLevel, + title: str, + text: str | None, + project: str, + run: str, + step: int | None, + timestamp: str | None, +) -> dict: + return { + "level": level.value, + "title": title, + "text": text, + "project": project, + "run": run, + "step": step, + "timestamp": timestamp, + } + + +def parse_alert_level(level: AlertLevel | str) -> AlertLevel: + if isinstance(level, AlertLevel): + return level + normalized = level.lower().strip() + try: + return AlertLevel(normalized) + except ValueError as e: + allowed = ", ".join(lvl.value for lvl in AlertLevel) + raise ValueError( + f"Invalid alert level '{level}'. Expected one of: {allowed}." + ) from e + + +def resolve_webhook_min_level( + webhook_min_level: AlertLevel | str | None, +) -> AlertLevel | None: + if webhook_min_level is None: + return None + return parse_alert_level(webhook_min_level) + + +def should_send_webhook( + level: AlertLevel, webhook_min_level: AlertLevel | None +) -> bool: + if webhook_min_level is None: + return True + return ALERT_LEVEL_ORDER[level] >= ALERT_LEVEL_ORDER[webhook_min_level] + + +def send_webhook( + url: str, + level: AlertLevel, + title: str, + text: str | None, + project: str, + run: str, + step: int | None, + timestamp: str | None = None, +) -> None: + if _is_slack_url(url): + payload = _build_slack_payload(level, title, text, project, run, step) + elif _is_discord_url(url): + payload = _build_discord_payload(level, title, text, project, run, step) + else: + payload = _build_generic_payload( + level, title, text, project, run, step, timestamp + ) + + data = json.dumps(payload).encode("utf-8") + req = urllib.request.Request( + url, data=data, headers={"Content-Type": "application/json"} + ) + try: + urllib.request.urlopen(req, timeout=10, context=_SSL_CONTEXT) + except Exception as e: + logger.warning(f"Failed to send webhook to {url}: {e}") diff --git a/trackio/api.py b/trackio/api.py new file mode 100644 index 0000000000000000000000000000000000000000..8ae640e5cb7c8be650e1bc92f31ac5975d7ca280 --- /dev/null +++ b/trackio/api.py @@ -0,0 +1,95 @@ +from typing import Iterator + +from trackio.sqlite_storage import SQLiteStorage + + +class Run: + def __init__(self, project: str, name: str, run_id: str | None = None): + self.project = project + self.name = name + self._id = run_id or name + self._config = None + + @property + def id(self) -> str: + return self._id + + @property + def config(self) -> dict | None: + if self._config is None: + self._config = SQLiteStorage.get_run_config( + self.project, self.name, run_id=self.id + ) + return self._config + + def alerts(self, level: str | None = None, since: str | None = None) -> list[dict]: + return SQLiteStorage.get_alerts( + self.project, run_name=self.name, run_id=self.id, level=level, since=since + ) + + def delete(self) -> bool: + return SQLiteStorage.delete_run(self.project, self.name, run_id=self.id) + + def move(self, new_project: str) -> bool: + success = SQLiteStorage.move_run( + self.project, self.name, new_project, run_id=self.id + ) + if success: + self.project = new_project + return success + + def rename(self, new_name: str) -> "Run": + SQLiteStorage.rename_run(self.project, self.name, new_name, run_id=self.id) + self.name = new_name + return self + + def __repr__(self) -> str: + return f"" + + +class Runs: + def __init__(self, project: str): + self.project = project + self._runs = None + + def _load_runs(self): + if self._runs is None: + records = SQLiteStorage.get_run_records(self.project) + self._runs = [ + Run(self.project, str(record["name"]), run_id=str(record["id"])) + for record in records + ] + + def __iter__(self) -> Iterator[Run]: + self._load_runs() + return iter(self._runs) + + def __getitem__(self, index: int) -> Run: + self._load_runs() + return self._runs[index] + + def __len__(self) -> int: + self._load_runs() + return len(self._runs) + + def __repr__(self) -> str: + self._load_runs() + return f"" + + +class Api: + def runs(self, project: str) -> Runs: + if not SQLiteStorage.get_project_db_path(project).exists(): + raise ValueError(f"Project '{project}' does not exist") + return Runs(project) + + def alerts( + self, + project: str, + run: str | None = None, + level: str | None = None, + since: str | None = None, + ) -> list[dict]: + if not SQLiteStorage.get_project_db_path(project).exists(): + raise ValueError(f"Project '{project}' does not exist") + return SQLiteStorage.get_alerts(project, run_name=run, level=level, since=since) diff --git a/trackio/apple_gpu.py b/trackio/apple_gpu.py new file mode 100644 index 0000000000000000000000000000000000000000..3373bf6ddc8dcde19b2d6b15e7ce46e86df00dc1 --- /dev/null +++ b/trackio/apple_gpu.py @@ -0,0 +1,206 @@ +import platform +import subprocess +import sys +import threading +import warnings +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from trackio.run import Run + +psutil: Any = None +PSUTIL_AVAILABLE = False +_monitor_lock = threading.Lock() + + +def _ensure_psutil(): + global PSUTIL_AVAILABLE, psutil + if PSUTIL_AVAILABLE: + return psutil + try: + import psutil as _psutil + + psutil = _psutil + PSUTIL_AVAILABLE = True + return psutil + except ImportError: + raise ImportError( + "psutil is required for Apple Silicon monitoring. " + "Install it with: pip install psutil" + ) + + +def is_apple_silicon() -> bool: + """Check if running on Apple Silicon (M1/M2/M3/M4).""" + if platform.system() != "Darwin": + return False + + try: + result = subprocess.run( + ["sysctl", "-n", "machdep.cpu.brand_string"], + capture_output=True, + text=True, + timeout=1, + ) + cpu_brand = result.stdout.strip() + return "Apple" in cpu_brand + except Exception: + return False + + +def get_gpu_info() -> dict[str, Any]: + """Get Apple GPU information using ioreg.""" + try: + result = subprocess.run( + ["ioreg", "-r", "-d", "1", "-w", "0", "-c", "IOAccelerator"], + capture_output=True, + text=True, + timeout=2, + ) + + if result.returncode == 0 and result.stdout: + lines = result.stdout.strip().split("\n") + for line in lines: + if "IOAccelerator" in line and "class" in line: + return {"detected": True, "type": "Apple GPU"} + else: + print("Error collecting Apple GPU info. ioreg stdout was:", file=sys.stderr) + print(result.stdout, file=sys.stderr) + print("ioreg stderr was:", file=sys.stderr) + print(result.stderr, file=sys.stderr) + + result = subprocess.run( + ["system_profiler", "SPDisplaysDataType"], + capture_output=True, + text=True, + timeout=3, + ) + + if result.returncode == 0 and "Apple" in result.stdout: + for line in result.stdout.split("\n"): + if "Chipset Model:" in line: + model = line.split(":")[-1].strip() + return {"detected": True, "type": model} + + except Exception: + pass + + return {"detected": False} + + +def apple_gpu_available() -> bool: + """ + Check if Apple GPU monitoring is available. + + Returns True if running on Apple Silicon (M-series chips) and psutil is installed. + """ + try: + _ensure_psutil() + return is_apple_silicon() + except ImportError: + return False + except Exception: + return False + + +def collect_apple_metrics(include_cpu_metrics: bool = True) -> dict: + """ + Collect system metrics for Apple Silicon. + + Returns: + Dictionary of system metrics including CPU, memory, and GPU info. + """ + metrics = {} + + if include_cpu_metrics: + from trackio.cpu import collect_cpu_metrics + + metrics.update(collect_cpu_metrics(include_static=True)) + + gpu_info = get_gpu_info() + if gpu_info.get("detected"): + metrics["gpu/detected"] = 1 + + return metrics + + +class AppleGpuMonitor: + def __init__( + self, run: "Run", interval: float = 10.0, include_cpu_metrics: bool = True + ): + self._run = run + self._interval = interval + self._include_cpu_metrics = include_cpu_metrics + self._stop_flag = threading.Event() + self._thread: "threading.Thread | None" = None + + def start(self): + if not is_apple_silicon(): + warnings.warn( + "auto_log_gpu=True but not running on Apple Silicon. " + "Apple GPU logging disabled." + ) + return + + if not PSUTIL_AVAILABLE: + try: + _ensure_psutil() + except ImportError: + warnings.warn( + "auto_log_gpu=True but psutil not installed. " + "Install with: pip install psutil" + ) + return + + self._thread = threading.Thread(target=self._monitor_loop, daemon=True) + self._thread.start() + + def stop(self): + self._stop_flag.set() + if self._thread is not None: + self._thread.join(timeout=2.0) + + def _monitor_loop(self): + while not self._stop_flag.is_set(): + try: + metrics = collect_apple_metrics( + include_cpu_metrics=self._include_cpu_metrics + ) + if metrics: + self._run.log_system(metrics) + except Exception: + pass + + self._stop_flag.wait(timeout=self._interval) + + +def log_apple_gpu(run: "Run | None" = None) -> dict: + """ + Log Apple Silicon system metrics to the current or specified run. + + Args: + run: Optional Run instance. If None, uses current run from context. + + Returns: + dict: The system metrics that were logged. + + Example: + ```python + import trackio + + run = trackio.init(project="my-project") + trackio.log({"loss": 0.5}) + trackio.log_apple_gpu() + ``` + """ + from trackio import context_vars + + if run is None: + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log_apple_gpu().") + + metrics = collect_apple_metrics() + if metrics: + run.log_system(metrics) + return metrics diff --git a/trackio/artifact.py b/trackio/artifact.py new file mode 100644 index 0000000000000000000000000000000000000000..ba969d71b65fc839dc54cd1d742d1e356522a536 --- /dev/null +++ b/trackio/artifact.py @@ -0,0 +1,353 @@ +import os +import shutil +import uuid +from pathlib import Path + +import httpx +from huggingface_hub.utils import get_token + +from trackio import cas, utils +from trackio.remote_client import _merge_client_headers, _resolve_src_url +from trackio.typehints import Manifest, Sha256Digest + + +def _materialize(blob: Path, dst: Path, size: int) -> None: + """Copy `blob` to `dst` unless `dst` already matches the blob's size and + mtime. + """ + dst.parent.mkdir(parents=True, exist_ok=True) + blob_stat = blob.stat() + if dst.is_file(): + dst_stat = dst.stat() + if dst_stat.st_size == size and dst_stat.st_mtime_ns == blob_stat.st_mtime_ns: + return + partial = dst.parent / f"{dst.name}.partial.{uuid.uuid4().hex}" + try: + shutil.copyfile(blob, partial) + os.utime(partial, ns=(blob_stat.st_atime_ns, blob_stat.st_mtime_ns)) + os.replace(partial, dst) + except Exception: + partial.unlink(missing_ok=True) + raise + + +def _fetch_blob_from_remote( + remote_source: dict, + project: str, + digest: Sha256Digest, + target_path: Path, +) -> None: + space_id = remote_source.get("space_id") + src = space_id or remote_source.get("server_base_url") + if not src: + raise RuntimeError( + "Artifact has _remote_source set but neither space_id nor " + "server_base_url is populated." + ) + base_url = _resolve_src_url(src).rstrip("/") + url = f"{base_url}/artifact_blob/{utils.canonical_project_name(project)}/{digest}" + headers = _merge_client_headers( + get_token() if space_id else None, + remote_source.get("write_token"), + ) + with httpx.stream( + "GET", + url, + headers=headers, + timeout=httpx.Timeout(connect=10.0, read=300.0, write=10.0, pool=10.0), + ) as response: + if response.status_code == 404: + raise FileNotFoundError( + f"Artifact blob {digest} not available on remote at {url}" + ) + response.raise_for_status() + cas.stage_blob_from_chunks( + response.iter_bytes(), + claimed_digest=digest, + target_path=target_path, + ) + + +class Artifact: + """ + A versioned, named bundle of files attached to a project. + + Construct an `Artifact`, add files to it with `add_file` / `add_dir`, then + persist it with `trackio.log_artifact`. Logging freezes the artifact and + populates its read-only `version`, `aliases`, `size`, and `manifest`. + + Args: + name (`str`): + Artifact name, unique within the project. Must match + `^[A-Za-z0-9._-]+$` (letters, digits, dot, underscore, hyphen). + type (`str`): + Free-form category such as `"model"` or `"dataset"`, used to group + artifacts. + description (`str`, *optional*): + Human-readable description of the artifact. + metadata (`dict`, *optional*): + Arbitrary JSON-serializable metadata stored alongside the version. + """ + + def __init__( + self, + name: str, + type: str, + description: str | None = None, + metadata: dict | None = None, + ): + cas.validate_artifact_name(name) + self._name = name + self._type = type + self._description = description + self._metadata: dict = dict(metadata) if metadata else {} + self._pending_files: list[tuple[Path, str]] = [] + self._logged = False + self._version: int | None = None + self._aliases: tuple[str, ...] = () + self._size: int | None = None + self._manifest: Manifest | None = None + self._manifest_digest: Sha256Digest | None = None + self._project: str | None = None + self._remote_source: dict | None = None + + @property + def name(self) -> str: + """Artifact name, unique within its project.""" + return self._name + + @property + def type(self) -> str: + """Free-form category such as `"model"` or `"dataset"`.""" + return self._type + + @property + def description(self) -> str | None: + """Human-readable description, or None if unset.""" + return self._description + + @description.setter + def description(self, value: str | None) -> None: + self._description = value + + @property + def metadata(self) -> dict: + """Live, mutable metadata dict; assignments like `art.metadata["k"] = v` + made before logging are preserved.""" + return self._metadata + + @metadata.setter + def metadata(self, value: dict | None) -> None: + self._metadata = dict(value) if value else {} + + @property + def version(self) -> str | None: + """Version string in `"v"` form (e.g. `"v3"`), or None if the + artifact has not been logged or fetched yet.""" + return None if self._version is None else f"v{self._version}" + + @property + def aliases(self) -> tuple[str, ...]: + """Aliases pointing at this version, e.g. `("latest", "prod")`.""" + return self._aliases + + @property + def size(self) -> int | None: + """Total size of the artifact's files in bytes, or None if not yet logged.""" + return self._size + + @property + def manifest(self) -> Manifest | None: + """List of file entries (each with `path`, `digest`, and `size`) + describing the artifact's contents, or None if not yet logged or + fetched. Returns a fresh copy on each access.""" + return None if self._manifest is None else [dict(e) for e in self._manifest] + + @property + def manifest_digest(self) -> Sha256Digest | None: + """Digest over the manifest (file paths plus their content), used to + de-duplicate re-logged content; None until logged or fetched.""" + return self._manifest_digest + + @property + def digest(self) -> Sha256Digest | None: + """Alias of `manifest_digest`.""" + return self._manifest_digest + + @property + def qualified_name(self) -> str: + """`"/:v"` for a logged or fetched artifact.""" + if self._project is None or self._version is None: + raise RuntimeError( + "Artifact has no qualified name until it is logged or fetched." + ) + return f"{self._project}/{self._name}:v{self._version}" + + @property + def project(self) -> str | None: + """Project the artifact belongs to, or None until logged or fetched.""" + return self._project + + def wait(self, timeout: int | None = None) -> "Artifact": + """No-op: trackio logs artifacts synchronously, so the artifact is + already committed by the time `log_artifact` returns.""" + if not self._logged: + raise RuntimeError( + "Cannot wait on an Artifact that has not been logged; " + "call log_artifact first." + ) + return self + + def add_file(self, local_path: str | Path, name: str | None = None) -> None: + """Stage a single file for inclusion in the artifact. + + Args: + local_path (`str` or `Path`): + Path to an existing regular file to add. + name (`str`, *optional*): + Logical path the file is stored under inside the artifact. + Defaults to the file's basename. + """ + if self._logged: + raise RuntimeError( + "Cannot add files to an Artifact that has already been logged or fetched." + ) + src = Path(local_path).resolve() + if not src.is_file(): + raise ValueError(f"Not a regular file: {local_path}") + logical = cas.validate_logical_path(name if name is not None else src.name) + self._pending_files.append((src, logical)) + + def add_dir(self, local_dir: str | Path, name: str | None = None) -> None: + """Stage every regular file under a directory, recursively. + + Symlinks are skipped. + + Args: + local_dir (`str` or `Path`): + Path to an existing directory whose files are added. + name (`str`, *optional*): + Logical path prefix for the added files. Defaults to no prefix, + so files keep their paths relative to `local_dir`. + """ + if self._logged: + raise RuntimeError( + "Cannot add files to an Artifact that has already been logged or fetched." + ) + root = Path(local_dir).resolve() + if not root.is_dir(): + raise ValueError(f"Not a directory: {local_dir}") + prefix = cas.validate_logical_path(name.rstrip("/")) + "/" if name else "" + for dirpath, dirnames, filenames in os.walk(root, followlinks=False): + dirnames.sort() + for filename in sorted(filenames): + entry = Path(dirpath) / filename + if entry.is_symlink() or not entry.is_file(): + continue + rel = entry.relative_to(root).as_posix() + logical = cas.validate_logical_path(prefix + rel) + self._pending_files.append((entry, logical)) + + def _build_manifest(self, project: str) -> Manifest: + if not self._pending_files: + raise ValueError( + f"Artifact {self._name!r} has no files; call add_file/add_dir first." + ) + cas.assert_manifest_paths_compatible( + logical for _, logical in self._pending_files + ) + + entries: Manifest = [] + for src, logical in self._pending_files: + digest, size = cas.stage_blob_into_project(src, project) + entries.append({"path": logical, "digest": digest, "size": size}) + return entries + + def _hydrate_from_db( + self, + *, + project: str, + version: int, + aliases: list[str], + manifest: Manifest, + manifest_digest: Sha256Digest, + size_bytes: int, + description: str | None = None, + metadata: dict | None = None, + ) -> None: + if description is not None: + self._description = description + if metadata is not None: + self._metadata = dict(metadata) + self._project = project + self._version = version + self._aliases = tuple(aliases) + self._manifest = [dict(e) for e in manifest] + self._manifest_digest = manifest_digest + self._size = size_bytes + self._logged = True + + def download(self, root: str | Path | None = None) -> str: + """Materialize the artifact's files into a local directory. + + Files are copied from Trackio's content-addressed cache (and fetched + from the remote when missing locally), so repeated calls are cheap and + idempotent. + + Args: + root (`str` or `Path`, *optional*): + Directory to write the files into. Defaults to + `./.trackio/artifact-downloads//_v/`, + keyed by project so same-named artifacts from different projects + never collide, and by the resolved version so a moving alias + like `latest` never leaves behind stale files from a previous + version. + + Returns: + The absolute path to the download directory, as a string. + """ + if not self._logged: + raise RuntimeError( + "Cannot download an Artifact that has not been logged or fetched." + ) + if self._manifest is None or self._project is None or self._version is None: + raise RuntimeError("Artifact is missing manifest, project, or version.") + + if root is None: + project = utils.canonical_project_name(self._project) + root_path = ( + Path.cwd() + / ".trackio" + / "artifact-downloads" + / project + / f"{self._name}_v{self._version}" + ) + else: + root_path = Path(root) + root_path.mkdir(parents=True, exist_ok=True) + + for entry in self._manifest: + digest = cas.validate_digest(entry["digest"]) + logical = cas.validate_logical_path(entry["path"]) + blob = cas.blob_path(self._project, digest) + if not blob.is_file(): + if self._remote_source is None: + raise FileNotFoundError( + f"Artifact blob {digest} not available locally or " + "remotely. The producer machine may not have shipped " + "this blob yet." + ) + _fetch_blob_from_remote( + self._remote_source, self._project, digest, blob + ) + _materialize(blob, root_path / logical, entry["size"]) + + return str(root_path) + + def __repr__(self) -> str: + parts: list[str] = [f"name={self._name!r}", f"type={self._type!r}"] + if self._version is not None: + parts.append(f"version=v{self._version}") + if self._aliases: + parts.append(f"aliases={list(self._aliases)!r}") + return f"Artifact({', '.join(parts)})" diff --git a/trackio/asgi_app.py b/trackio/asgi_app.py new file mode 100644 index 0000000000000000000000000000000000000000..027ae1dcf1efcbb5b0a4a363f22dae54a249f6b6 --- /dev/null +++ b/trackio/asgi_app.py @@ -0,0 +1,535 @@ +from __future__ import annotations + +import inspect +import json +import logging +import math +import secrets +import tempfile +import threading +from collections.abc import Callable +from pathlib import Path +from typing import Any, get_args, get_origin +from urllib.parse import unquote + +from starlette.applications import Starlette +from starlette.requests import Request +from starlette.responses import FileResponse, JSONResponse, Response, StreamingResponse +from starlette.routing import Route + +from trackio import utils +from trackio.exceptions import TrackioAPIError +from trackio.remote_client import HTTP_API_VERSION + +logger = logging.getLogger("trackio.asgi_app") + +_PACKAGE_JSON_PATH = Path(__file__).parent / "package.json" +_TRACKIO_PACKAGE_VERSION = json.loads(_PACKAGE_JSON_PATH.read_text())["version"] + + +def _normalize_allowed_file_roots( + allowed_file_roots: list[str | Path] | None, +) -> tuple[Path, ...]: + roots = [] + for root in allowed_file_roots or []: + roots.append(Path(root).resolve()) + return tuple(roots) + + +def _is_allowed_file_path(path: Path, allowed_roots: tuple[Path, ...]) -> bool: + resolved_path = path.resolve(strict=False) + for root in allowed_roots: + try: + resolved_path.relative_to(root) + return True + except ValueError: + continue + return False + + +def _json_safe(data: Any) -> Any: + if data is None or isinstance(data, (str, bool, int)): + return data + if isinstance(data, float): + return data if math.isfinite(data) else None + if isinstance(data, dict): + return {k: _json_safe(v) for k, v in data.items()} + if isinstance(data, (list, tuple)): + return [_json_safe(v) for v in data] + if hasattr(data, "item"): + try: + return _json_safe(data.item()) + except Exception: + pass + return str(data) + + +def register_uploaded_temp_file(request: Request, file_path: str | Path) -> None: + resolved_path = Path(file_path).resolve(strict=False) + with request.app.state.uploaded_temp_files_lock: + request.app.state.uploaded_temp_files.add(resolved_path) + + +def consume_uploaded_temp_file(request: Request, file_data: Any) -> Path: + file_path = file_data.get("path") if isinstance(file_data, dict) else None + if not isinstance(file_path, str) or not file_path: + raise TrackioAPIError("Expected uploaded file metadata with a valid path.") + + resolved_path = Path(file_path).resolve(strict=False) + with request.app.state.uploaded_temp_files_lock: + if resolved_path not in request.app.state.uploaded_temp_files: + raise TrackioAPIError( + "Uploaded file was not created by this Trackio server." + ) + request.app.state.uploaded_temp_files.remove(resolved_path) + + if not resolved_path.is_file(): + raise TrackioAPIError("Uploaded file is missing.") + + return resolved_path + + +def cleanup_uploaded_temp_file(file_path: str | Path) -> None: + try: + Path(file_path).unlink(missing_ok=True) + except Exception: + pass + + +def _invoke_handler( + fn: Any, + request: Request, + args: list[Any] | None = None, + kwargs: dict[str, Any] | None = None, +) -> Any: + sig = inspect.signature(fn) + params = list(sig.parameters.values()) + positional_args: list[Any] = [] + keyword_args: dict[str, Any] = {} + args = list(args or []) + kwargs = dict(kwargs or {}) + data_index = 0 + + for param in params: + if param.name == "request": + keyword_args["request"] = request + elif param.kind == inspect.Parameter.VAR_POSITIONAL: + positional_args.extend(args[data_index:]) + data_index = len(args) + elif param.kind == inspect.Parameter.VAR_KEYWORD: + keyword_args.update(kwargs) + kwargs.clear() + elif param.name in kwargs: + keyword_args[param.name] = kwargs.pop(param.name) + elif param.kind in ( + inspect.Parameter.POSITIONAL_ONLY, + inspect.Parameter.POSITIONAL_OR_KEYWORD, + ) and data_index < len(args): + positional_args.append(args[data_index]) + data_index += 1 + elif param.default is inspect.Signature.empty and param.kind not in ( + inspect.Parameter.VAR_POSITIONAL, + inspect.Parameter.VAR_KEYWORD, + ): + raise TrackioAPIError(f"Missing required parameter: {param.name}") + + return fn(*positional_args, **keyword_args) + + +async def version_handler(request: Request) -> Response: + mcp_enabled = bool(getattr(request.app.state, "mcp_enabled", False)) + return JSONResponse( + { + "version": _TRACKIO_PACKAGE_VERSION, + "api_version": HTTP_API_VERSION, + "api_transport": "http", + "mcp_enabled": mcp_enabled, + "mcp_path": "/mcp" if mcp_enabled else None, + } + ) + + +def _json_schema_and_python_type(annotation: Any) -> tuple[dict[str, Any], str]: + if annotation is inspect.Parameter.empty: + return {"type": "object"}, "Any" + origin = get_origin(annotation) + args = get_args(annotation) + if origin is not None and args: + non_none = tuple(a for a in args if a is not type(None)) + if len(non_none) == 1 and len(args) > 1: + return _json_schema_and_python_type(non_none[0]) + if origin is list: + inner, py_inner = _json_schema_and_python_type( + args[0] if args else inspect.Parameter.empty + ) + return {"type": "array", "items": inner}, f"list[{py_inner}]" + if origin is dict: + return {"type": "object"}, "dict" + if annotation in (str, bytes): + return {"type": "string"}, "str" + if annotation is int: + return {"type": "integer"}, "int" + if annotation is float: + return {"type": "number"}, "float" + if annotation is bool: + return {"type": "boolean"}, "bool" + name = getattr(annotation, "__name__", None) + if name: + return {"type": "object"}, name + return {"type": "object"}, "Any" + + +def build_gradio_api_info(api_registry: dict[str, Any]) -> dict[str, Any]: + named_endpoints: dict[str, Any] = {} + for name in sorted(api_registry.keys()): + fn = api_registry[name] + if not callable(fn): + continue + sig = inspect.signature(fn) + parameters: list[dict[str, Any]] = [] + for pname, param in sig.parameters.items(): + if pname == "request": + continue + jtype, pytype = _json_schema_and_python_type(param.annotation) + has_default = param.default is not inspect.Parameter.empty + parameters.append( + { + "label": pname, + "parameter_name": pname, + "parameter_has_default": has_default, + "parameter_default": None if not has_default else param.default, + "type": jtype, + "python_type": {"type": pytype, "description": ""}, + "component": "Api", + "example_input": None, + } + ) + ret_ann = sig.return_annotation + if ret_ann is inspect.Signature.empty: + ret_ann = Any + rjtype, rpytype = _json_schema_and_python_type(ret_ann) + returns = [ + { + "label": "result", + "type": rjtype, + "python_type": {"type": rpytype, "description": ""}, + "component": "Api", + } + ] + named_endpoints[f"/{name}"] = { + "parameters": parameters, + "returns": returns, + "api_visibility": "public", + } + return {"named_endpoints": named_endpoints, "unnamed_endpoints": {}} + + +_MAX_GRADIO_CALL_EVENTS = 256 + + +def _hf_token_value_is_unset(value: Any) -> bool: + if value is None: + return True + if isinstance(value, str) and value.strip() == "": + return True + return False + + +def _authorization_bearer_token(request: Request) -> str | None: + auth = request.headers.get("authorization") or request.headers.get("Authorization") + if not auth: + return None + parts = auth.split() + if len(parts) != 2 or parts[0].lower() != "bearer": + return None + tok = parts[1].strip() + return tok or None + + +def _maybe_apply_hf_token_from_authorization( + request: Request, fn: Any, args: list[Any], kwargs: dict[str, Any] +) -> None: + if not utils.on_spaces(): + return + token = _authorization_bearer_token(request) + if not token: + return + sig = inspect.signature(fn) + if "hf_token" not in sig.parameters: + return + params = [p for p in sig.parameters.values() if p.name != "request"] + names = [p.name for p in params] + if "hf_token" not in names: + return + idx = names.index("hf_token") + if "hf_token" in kwargs: + if _hf_token_value_is_unset(kwargs["hf_token"]): + kwargs["hf_token"] = token + return + if idx < len(args): + if _hf_token_value_is_unset(args[idx]): + args[idx] = token + return + kwargs["hf_token"] = token + + +def _store_gradio_call_result( + request: Request, event_id: str, api_name: str, data: Any +) -> None: + with request.app.state.gradio_call_events_lock: + d = request.app.state.gradio_call_events + while len(d) >= _MAX_GRADIO_CALL_EVENTS: + d.pop(next(iter(d))) + d[event_id] = {"api_name": api_name, "data": data} + + +async def run_api_request(request: Request, api_name: str) -> Response: + api_registry = request.app.state.api_registry + fn = api_registry.get(api_name) + if fn is None: + return JSONResponse({"error": f"Unknown API: {api_name}"}, status_code=404) + + try: + body = await request.json() + except Exception: + body = {} + + args: list[Any] = [] + kwargs: dict[str, Any] = {} + if isinstance(body, dict): + if "args" in body or "kwargs" in body: + args = body.get("args") or [] + kwargs = body.get("kwargs") or {} + elif "data" in body and isinstance(body["data"], list): + args = body["data"] + else: + kwargs = body + elif isinstance(body, list): + args = body + elif body is not None: + args = [body] + + if not isinstance(args, list): + args = [args] + if not isinstance(kwargs, dict): + kwargs = {} + + _maybe_apply_hf_token_from_authorization(request, fn, args, kwargs) + + try: + result = _invoke_handler(fn, request, args=args, kwargs=kwargs) + return JSONResponse({"data": _json_safe(result)}) + except TrackioAPIError as e: + return JSONResponse({"error": str(e)}, status_code=400) + except Exception as e: + return JSONResponse({"error": str(e)}, status_code=500) + + +async def api_handler(request: Request) -> Response: + return await run_api_request(request, request.path_params["api_name"]) + + +async def gradio_api_info_handler(request: Request) -> Response: + return JSONResponse( + build_gradio_api_info(request.app.state.api_registry), + headers={"Cache-Control": "no-store"}, + ) + + +async def gradio_call_post_handler(request: Request) -> Response: + api_name = request.path_params["api_name"] + resp = await run_api_request(request, api_name) + if resp.status_code != 200: + return resp + body = json.loads(bytes(resp.body).decode()) + event_id = secrets.token_urlsafe(16) + _store_gradio_call_result(request, event_id, api_name, body["data"]) + return JSONResponse({"event_id": event_id}) + + +async def gradio_call_poll_handler(request: Request) -> Response: + api_name = request.path_params["api_name"] + event_id = request.path_params["event_id"] + with request.app.state.gradio_call_events_lock: + event = request.app.state.gradio_call_events.pop(event_id, None) + if event is None: + logger.info("gradio_api poll: unknown or expired event_id") + return JSONResponse({"error": "Unknown or expired event_id"}, status_code=404) + if event.get("api_name") != api_name: + logger.info( + "gradio_api poll: api_name mismatch (path=%r, stored=%r)", + api_name, + event.get("api_name"), + ) + with request.app.state.gradio_call_events_lock: + d = request.app.state.gradio_call_events + while len(d) >= _MAX_GRADIO_CALL_EVENTS: + d.pop(next(iter(d))) + d[event_id] = event + return JSONResponse({"error": "Unknown or expired event_id"}, status_code=404) + + data = event["data"] + payload = json.dumps(_json_safe([data])) + + async def sse() -> Any: + yield f"event: complete\ndata: {payload}\n\n" + + return StreamingResponse( + sse(), + media_type="text/event-stream", + headers={ + "Cache-Control": "no-store", + "X-Accel-Buffering": "no", + }, + ) + + +async def upload_handler(request: Request) -> Response: + upload_authorizer = getattr(request.app.state, "upload_authorizer", None) + if callable(upload_authorizer): + try: + upload_authorizer(request) + except TrackioAPIError as e: + return JSONResponse({"error": str(e)}, status_code=400) + + form = await request.form() + uploads = form.getlist("files") + saved_paths = [] + for upload in uploads: + suffix = Path(getattr(upload, "filename", "") or "").suffix + with tempfile.NamedTemporaryFile( + delete=False, + prefix="trackio-upload-", + suffix=suffix, + ) as tmp: + tmp.write(await upload.read()) + register_uploaded_temp_file(request, tmp.name) + saved_paths.append(tmp.name) + return JSONResponse({"paths": saved_paths}) + + +async def gradio_upload_alias_handler(request: Request) -> Response: + return await upload_handler(request) + + +_DISALLOWED_FILE_SUFFIXES = frozenset( + {".db", ".db-journal", ".db-wal", ".db-shm", ".sqlite", ".sqlite3"} +) + + +async def file_handler(request: Request) -> Response: + fs_path = request.query_params.get("path") + if fs_path is None: + return Response("Missing path", status_code=400) + fp = Path(unquote(fs_path)).resolve(strict=False) + if fp.suffix.lower() in _DISALLOWED_FILE_SUFFIXES: + return Response("Not found", status_code=404) + if _is_allowed_file_path(fp, (utils.ARTIFACTS_DIR.resolve(),)): + return Response("Not found", status_code=404) + allowed_roots = getattr(request.app.state, "allowed_file_roots", ()) + if fp.is_file() and _is_allowed_file_path(fp, allowed_roots): + return FileResponse(str(fp)) + return Response("Not found", status_code=404) + + +async def artifact_blob_handler(request: Request) -> Response: + from trackio import cas # noqa: PLC0415 + from trackio import server as _server # noqa: PLC0415 + + project = request.path_params.get("project") + digest = request.path_params.get("digest") + try: + project = _server._validate_project_name(project) + digest = _server._validate_sha256_digest(digest) + except TrackioAPIError: + return Response("Not found", status_code=404) + try: + _server.assert_can_stage_upload(request) + except TrackioAPIError: + return Response("Forbidden", status_code=403) + blob = cas.blob_path(project, digest) + if not blob.is_file(): + return Response("Not found", status_code=404) + return FileResponse(str(blob)) + + +def create_trackio_starlette_app( + oauth_routes: list[Route], + api_registry: dict[str, Any], + extra_routes: list[Any] | None = None, + mcp_lifespan: Any = None, + mcp_enabled: bool = False, + allowed_file_roots: list[str | Path] | None = None, + upload_authorizer: Callable[[Request], None] | None = None, +) -> Starlette: + routes: list[Any] = list(oauth_routes) + routes.extend( + [ + Route("/version", endpoint=version_handler, methods=["GET"]), + Route("/api/upload", endpoint=upload_handler, methods=["POST"]), + Route("/api/{api_name:str}", endpoint=api_handler, methods=["POST"]), + Route("/file", endpoint=file_handler, methods=["GET"]), + Route( + "/artifact_blob/{project:str}/{digest:str}", + endpoint=artifact_blob_handler, + methods=["GET"], + ), + ] + ) + if utils.on_spaces(): + routes.extend( + [ + Route( + "/gradio_api/info", + endpoint=gradio_api_info_handler, + methods=["GET"], + ), + Route( + "/gradio_api/info/", + endpoint=gradio_api_info_handler, + methods=["GET"], + ), + Route( + "/gradio_api/upload", + endpoint=gradio_upload_alias_handler, + methods=["POST"], + ), + Route( + "/gradio_api/upload/", + endpoint=gradio_upload_alias_handler, + methods=["POST"], + ), + Route( + "/gradio_api/call/{api_name:str}", + endpoint=gradio_call_post_handler, + methods=["POST"], + ), + Route( + "/gradio_api/call/{api_name:str}/", + endpoint=gradio_call_post_handler, + methods=["POST"], + ), + Route( + "/gradio_api/call/{api_name:str}/{event_id:str}", + endpoint=gradio_call_poll_handler, + methods=["GET"], + ), + Route( + "/gradio_api/call/{api_name:str}/{event_id:str}/", + endpoint=gradio_call_poll_handler, + methods=["GET"], + ), + ] + ) + routes.extend(extra_routes or []) + app = Starlette(routes=routes, lifespan=mcp_lifespan) + app.state.api_registry = api_registry + app.state.mcp_enabled = mcp_enabled + app.state.allowed_file_roots = _normalize_allowed_file_roots(allowed_file_roots) + app.state.upload_authorizer = upload_authorizer + app.state.uploaded_temp_files = set() + app.state.uploaded_temp_files_lock = threading.Lock() + if utils.on_spaces(): + app.state.gradio_call_events = {} + app.state.gradio_call_events_lock = threading.Lock() + return app diff --git a/trackio/assets/badge.png b/trackio/assets/badge.png new file mode 100644 index 0000000000000000000000000000000000000000..03e0340873223b3ecb45f3ebf09512f6d6746ec2 --- /dev/null +++ b/trackio/assets/badge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:206b7847247e83279f498510a2760338a03116bb5141a658d71ec14429f9ea9e +size 169669 diff --git a/trackio/assets/trackio_logo_dark.png b/trackio/assets/trackio_logo_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..e6ff7e0a3580bca040d9ec3ea8c91e8cca469e61 Binary files /dev/null and b/trackio/assets/trackio_logo_dark.png differ diff --git a/trackio/assets/trackio_logo_light.png b/trackio/assets/trackio_logo_light.png new file mode 100644 index 0000000000000000000000000000000000000000..b3438262c61989e6c6d16df4801a8935136115b3 Binary files /dev/null and b/trackio/assets/trackio_logo_light.png differ diff --git a/trackio/assets/trackio_logo_old.png b/trackio/assets/trackio_logo_old.png new file mode 100644 index 0000000000000000000000000000000000000000..48a07d40b83e23c9cc9dc0cb6544a3c6ad62b57f --- /dev/null +++ b/trackio/assets/trackio_logo_old.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3922c4d1e465270ad4d8abb12023f3beed5d9f7f338528a4c0ac21dcf358a1c8 +size 487101 diff --git a/trackio/assets/trackio_logo_type_dark.png b/trackio/assets/trackio_logo_type_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6f80a3191e514a8a0beaa6ab2011e5baf8df5eda Binary files /dev/null and b/trackio/assets/trackio_logo_type_dark.png differ diff --git a/trackio/assets/trackio_logo_type_dark_transparent.png b/trackio/assets/trackio_logo_type_dark_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..2495f610c975917290b57706133b38621a58cb8b Binary files /dev/null and b/trackio/assets/trackio_logo_type_dark_transparent.png differ diff --git a/trackio/assets/trackio_logo_type_light.png b/trackio/assets/trackio_logo_type_light.png new file mode 100644 index 0000000000000000000000000000000000000000..f07866d245ea897b9aba417b29403f7f91cc8bbd Binary files /dev/null and b/trackio/assets/trackio_logo_type_light.png differ diff --git a/trackio/assets/trackio_logo_type_light_transparent.png b/trackio/assets/trackio_logo_type_light_transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..a20b4d5e64c61c91546577645310593fe3493508 Binary files /dev/null and b/trackio/assets/trackio_logo_type_light_transparent.png differ diff --git a/trackio/bucket_storage.py b/trackio/bucket_storage.py new file mode 100644 index 0000000000000000000000000000000000000000..59568705e93dc6e71d4cedbd85cfcac959ca224a --- /dev/null +++ b/trackio/bucket_storage.py @@ -0,0 +1,166 @@ +import shutil +import tempfile +from pathlib import Path + +import huggingface_hub + +from trackio.sqlite_storage import SQLiteStorage +from trackio.utils import ( + TRACKIO_DIR, + canonical_project_name, + project_artifacts_dir, + project_media_dir, +) + + +def create_bucket_if_not_exists(bucket_id: str, private: bool | None = None) -> None: + huggingface_hub.create_bucket(bucket_id, private=private, exist_ok=True) + + +def _list_bucket_file_paths(bucket_id: str, prefix: str | None = None) -> list[str]: + items = huggingface_hub.list_bucket_tree(bucket_id, prefix=prefix, recursive=True) + return [ + item.path + for item in items + if getattr(item, "type", None) == "file" and getattr(item, "path", None) + ] + + +def download_bucket_to_trackio_dir(bucket_id: str) -> None: + TRACKIO_DIR.mkdir(parents=True, exist_ok=True) + huggingface_hub.sync_bucket( + source=f"hf://buckets/{bucket_id}/trackio", + dest=str(TRACKIO_DIR), + quiet=True, + ) + + +def upload_project_to_bucket(project: str, bucket_id: str) -> None: + db_path = SQLiteStorage.get_project_db_path(project) + if not db_path.exists(): + raise FileNotFoundError(f"No database found for project '{project}'") + + with SQLiteStorage._get_connection( + db_path, configure_pragmas=False, row_factory=None + ) as conn: + conn.execute("PRAGMA wal_checkpoint(TRUNCATE)") + + files_to_add = [(str(db_path), f"trackio/{db_path.name}")] + + media_dir = project_media_dir(project) + if media_dir.exists(): + for media_file in media_dir.rglob("*"): + if media_file.is_file(): + rel = media_file.relative_to(TRACKIO_DIR) + files_to_add.append((str(media_file), f"trackio/{rel.as_posix()}")) + + artifacts_dir = project_artifacts_dir(project) + if artifacts_dir.exists(): + for blob_file in artifacts_dir.rglob("*"): + if not blob_file.is_file(): + continue + if ".partial." in blob_file.name: + continue + rel = blob_file.relative_to(TRACKIO_DIR) + files_to_add.append((str(blob_file), f"trackio/{rel.as_posix()}")) + + huggingface_hub.batch_bucket_files(bucket_id, add=files_to_add) + + +def _download_db_from_bucket( + project: str, bucket_id: str, dest_path: Path | None = None +) -> bool: + db_filename = SQLiteStorage.get_project_db_filename(project) + remote_path = f"trackio/{db_filename}" + local_path = dest_path or SQLiteStorage.get_project_db_path(project) + local_path.parent.mkdir(parents=True, exist_ok=True) + try: + huggingface_hub.download_bucket_files( + bucket_id, + files=[(remote_path, str(local_path))], + token=huggingface_hub.utils.get_token(), + ) + return local_path.exists() + except Exception: + return False + + +def _local_db_has_data(project: str) -> bool: + db_path = SQLiteStorage.get_project_db_path(project) + if not db_path.exists() or db_path.stat().st_size == 0: + return False + try: + with SQLiteStorage._get_connection( + db_path, configure_pragmas=False, row_factory=None + ) as conn: + count = conn.execute("SELECT COUNT(*) FROM metrics").fetchone()[0] + return count > 0 + except Exception: + return False + + +def _export_and_upload_static( + project: str, + dest_bucket_id: str, + db_path: Path, + media_dir: Path | None = None, +) -> None: + with tempfile.TemporaryDirectory() as tmp_dir: + output_dir = Path(tmp_dir) + SQLiteStorage.export_for_static_space( + project, output_dir, db_path_override=db_path + ) + + if media_dir and media_dir.exists(): + shutil.copytree(media_dir, output_dir / "media") + + files_to_add = [] + for f in output_dir.rglob("*"): + if f.is_file(): + rel = f.relative_to(output_dir) + files_to_add.append((str(f), rel.as_posix())) + + huggingface_hub.batch_bucket_files(dest_bucket_id, add=files_to_add) + + +def _copy_project_media_between_buckets( + source_bucket_id: str, dest_bucket_id: str, project: str +) -> None: + source_media_prefix = f"trackio/media/{canonical_project_name(project)}/" + media_to_copy = _list_bucket_file_paths( + source_bucket_id, prefix=source_media_prefix + ) + if not media_to_copy: + return + + huggingface_hub.copy_files( + f"hf://buckets/{source_bucket_id}/{source_media_prefix}", + f"hf://buckets/{dest_bucket_id}/media/", + ) + + +def upload_project_to_bucket_for_static(project: str, bucket_id: str) -> None: + if not _local_db_has_data(project): + _download_db_from_bucket(project, bucket_id) + + db_path = SQLiteStorage.get_project_db_path(project) + _export_and_upload_static(project, bucket_id, db_path, project_media_dir(project)) + + +def export_from_bucket_for_static( + source_bucket_id: str, + dest_bucket_id: str, + project: str, +) -> None: + with tempfile.TemporaryDirectory() as work_dir: + work_path = Path(work_dir) + db_path = work_path / SQLiteStorage.get_project_db_filename(project) + + if not _download_db_from_bucket(project, source_bucket_id, dest_path=db_path): + raise FileNotFoundError( + f"Could not download database for project '{project}' " + f"from bucket '{source_bucket_id}'." + ) + + _export_and_upload_static(project, dest_bucket_id, db_path) + _copy_project_media_between_buckets(source_bucket_id, dest_bucket_id, project) diff --git a/trackio/cas.py b/trackio/cas.py new file mode 100644 index 0000000000000000000000000000000000000000..727bc48ae5c37ba05c93b3372a53a63d8dd7cdc0 --- /dev/null +++ b/trackio/cas.py @@ -0,0 +1,203 @@ +"""Content-addressed storage (CAS) helpers shared by the artifact client, +server, and storage layers. +""" + +import hashlib +import os +import re +import uuid +from collections.abc import Iterable, Iterator +from pathlib import Path + +from trackio import utils +from trackio.typehints import Sha256Digest + +SHA256_DIGEST_RE = re.compile(r"^[0-9a-f]{64}$") +ARTIFACT_VERSION_SPEC_RE = re.compile(r"^v(\d+)$") +ARTIFACT_NAME_RE = re.compile(r"^[A-Za-z0-9._-]+\Z") +HASH_CHUNK_SIZE = 1024 * 1024 + + +def validate_artifact_name(name: str) -> str: + if not isinstance(name, str) or not ARTIFACT_NAME_RE.match(name): + raise ValueError( + f"Artifact name {name!r} must match ^[A-Za-z0-9._-]+$ " + "(letters, digits, dot, underscore, hyphen)." + ) + return name + + +def validate_aliases(aliases: list[str] | None) -> list[str]: + if aliases is None: + return [] + if isinstance(aliases, str) or not isinstance(aliases, (list, tuple)): + raise ValueError( + f"aliases must be a list of strings, got {type(aliases).__name__}." + ) + validated: list[str] = [] + for alias in aliases: + if not isinstance(alias, str) or not alias: + raise ValueError(f"Alias {alias!r} must be a non-empty string.") + if not ARTIFACT_NAME_RE.match(alias): + raise ValueError( + f"Alias {alias!r} must match ^[A-Za-z0-9._-]+$ " + "(letters, digits, dot, underscore, hyphen)." + ) + if ARTIFACT_VERSION_SPEC_RE.match(alias): + raise ValueError( + f"Alias {alias!r} is reserved for version pointers (vN); " + "choose another." + ) + validated.append(alias) + return validated + + +def _project_blobs_root(project: str) -> Path: + return utils.project_artifacts_dir(project) / "blobs" / "sha256" + + +def blob_path(project: str, digest: Sha256Digest) -> Path: + return _project_blobs_root(project) / digest[:2] / digest + + +def hash_file(path: Path) -> tuple[Sha256Digest, int]: + size = path.stat().st_size + file_digest = getattr(hashlib, "file_digest", None) + if file_digest is not None: + with path.open("rb") as f: + sha = file_digest(f, "sha256") + else: + sha = hashlib.sha256() + with path.open("rb") as f: + while chunk := f.read(HASH_CHUNK_SIZE): + sha.update(chunk) + return Sha256Digest(sha.hexdigest()), size + + +def validate_logical_path(logical: str) -> str: + """Validate a manifest logical path: relative, no `.`/`..` segments, no + backslashes, no drive letters, non-empty. Returns the path unchanged. + """ + if not isinstance(logical, str) or not logical: + raise ValueError(f"Invalid artifact path: {logical!r} (must be non-empty)") + if "\\" in logical or "\x00" in logical: + raise ValueError( + f"Invalid artifact path {logical!r}: backslashes and NUL are not allowed" + ) + if logical.startswith("/") or re.match(r"^[A-Za-z]:", logical): + raise ValueError(f"Invalid artifact path {logical!r}: must be relative") + parts = logical.split("/") + if any(part in ("", ".", "..") for part in parts): + raise ValueError( + f"Invalid artifact path {logical!r}: " + "'.', '..', and empty segments are not allowed" + ) + return logical + + +def assert_manifest_paths_compatible(paths: Iterable[str]) -> None: + """Validate a manifest's logical paths as a set: reject exact duplicates and + file/directory prefix collisions. A path cannot be both a file and a + directory, so `sub` and `sub/x` (or `a/b` and `a/b/c`) cannot coexist; + siblings like `a/b` and `a/c` are fine. + """ + seen: set[str] = set() + for p in paths: + if p in seen: + raise ValueError(f"Duplicate logical path in manifest: {p!r}") + seen.add(p) + for p in seen: + parts = p.split("/") + for i in range(1, len(parts)): + ancestor = "/".join(parts[:i]) + if ancestor in seen: + raise ValueError( + f"Artifact path {p!r} collides with {ancestor!r}: a path " + "cannot be both a file and a directory in the same artifact." + ) + + +def validate_digest(digest: str) -> Sha256Digest: + """Validate that `digest` is a 64-char lowercase sha256 hex string and + return it unchanged. + """ + if not isinstance(digest, str) or not SHA256_DIGEST_RE.match(digest): + raise ValueError(f"Invalid artifact blob digest: {digest!r}") + return Sha256Digest(digest) + + +def stage_blob_from_chunks( + chunks: Iterable[bytes], + claimed_digest: Sha256Digest, + target_path: Path, +) -> None: + """Stream `chunks` to `target_path`, verifying they hash to `claimed_digest`. + No-op if `target_path` already exists (the chunks are not consumed). + """ + if target_path.is_file(): + return + target_path.parent.mkdir(parents=True, exist_ok=True) + partial = target_path.parent / f"{target_path.name}.partial.{uuid.uuid4().hex}" + sha = hashlib.sha256() + try: + with partial.open("wb") as dst: + for chunk in chunks: + if not chunk: + continue + sha.update(chunk) + dst.write(chunk) + actual = sha.hexdigest() + if actual != claimed_digest: + raise ValueError( + f"Digest mismatch: claimed {claimed_digest}, computed {actual}" + ) + os.replace(partial, target_path) + except Exception: + partial.unlink(missing_ok=True) + raise + + +def stage_blob_from_file( + src_path: Path, + claimed_digest: Sha256Digest, + target_path: Path, +) -> None: + """Copy `src_path` to `target_path`, verifying it hashes to `claimed_digest`.""" + if target_path.is_file(): + return + + def _file_chunks() -> Iterator[bytes]: + with src_path.open("rb") as src: + while chunk := src.read(HASH_CHUNK_SIZE): + yield chunk + + stage_blob_from_chunks(_file_chunks(), claimed_digest, target_path) + + +def stage_blob_into_project(src_path: Path, project: str) -> tuple[Sha256Digest, int]: + """Copy `src_path` into the project's CAS in a single pass, computing its + sha256 and size while writing. Returns `(digest, size)`. If the blob is + already present, the copy is discarded. + """ + blobs_root = _project_blobs_root(project) + blobs_root.mkdir(parents=True, exist_ok=True) + partial = blobs_root / f".partial.{uuid.uuid4().hex}" + sha = hashlib.sha256() + size = 0 + try: + with src_path.open("rb") as src, partial.open("wb") as dst: + while chunk := src.read(HASH_CHUNK_SIZE): + sha.update(chunk) + dst.write(chunk) + size += len(chunk) + digest = Sha256Digest(sha.hexdigest()) + target = blob_path(project, digest) + if target.is_file(): + partial.unlink(missing_ok=True) + return digest, size + target.parent.mkdir(parents=True, exist_ok=True) + os.replace(partial, target) + return digest, size + except Exception: + partial.unlink(missing_ok=True) + raise diff --git a/trackio/cli.py b/trackio/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..865c47b292e317cd2d218b445fe3e7c376a48335 --- /dev/null +++ b/trackio/cli.py @@ -0,0 +1,2250 @@ +import argparse +import os +import re +import sys +from pathlib import Path + +import huggingface_hub + +import trackio +from trackio import freeze, show, sync +from trackio.cli_helpers import ( + error_exit, + format_alerts, + format_artifact, + format_artifacts, + format_json, + format_list, + format_metric_values, + format_project_summary, + format_query_result, + format_run_summary, + format_snapshot, + format_spaces, + format_system_metric_names, + format_system_metrics, +) +from trackio.frontend_config import ( + TRACKIO_CONFIG_PATH, + get_persisted_frontend_dir, + set_persisted_frontend_dir, + unset_persisted_frontend_dir, +) +from trackio.markdown import Markdown +from trackio.server import get_project_summary, get_run_summary +from trackio.sqlite_storage import SQLiteStorage + + +def _get_space(args): + return getattr(args, "space", None) + + +def _get_remote(args): + from trackio.remote_client import RemoteClient + + space = _get_space(args) + if not space: + return None + hf_token = getattr(args, "hf_token", None) + return RemoteClient(space, hf_token=hf_token) + + +def _handle_status(): + print("Reading local Trackio projects...\n") + projects = SQLiteStorage.get_projects() + if not projects: + print("No Trackio projects found.") + return + + local_projects = [] + synced_projects = [] + unsynced_projects = [] + + for project in projects: + space_id = SQLiteStorage.get_space_id(project) + if space_id is None: + local_projects.append(project) + elif SQLiteStorage.has_pending_data(project): + unsynced_projects.append(project) + else: + synced_projects.append(project) + + print("Finished reading Trackio projects") + if local_projects: + print(f" * {len(local_projects)} local trackio project(s) [OK]") + if synced_projects: + print(f" * {len(synced_projects)} trackio project(s) synced to Spaces [OK]") + if unsynced_projects: + print( + f" * {len(unsynced_projects)} trackio project(s) with unsynced changes [WARNING]:" + ) + for p in unsynced_projects: + print(f" - {p}") + + if unsynced_projects: + print( + f"\nRun `trackio sync --project {unsynced_projects[0]}` to sync. " + "Or run `trackio sync --all` to sync all unsynced changes." + ) + + +def _handle_sync(args): + from trackio.deploy import sync_incremental + + if args.sync_all and args.project: + error_exit("Cannot use --all and --project together.") + if not args.sync_all and not args.project: + error_exit("Must provide either --project or --all.") + + if args.sync_all: + projects = SQLiteStorage.get_projects() + synced_any = False + for project in projects: + space_id = SQLiteStorage.get_space_id(project) + if space_id and SQLiteStorage.has_pending_data(project): + sync_incremental( + project, + space_id, + private=args.private, + pending_only=True, + frontend_dir=args.frontend, + ) + synced_any = True + if not synced_any: + print("No projects with unsynced data found.") + else: + space_id = args.space_id + if space_id is None: + space_id = SQLiteStorage.get_space_id(args.project) + sync( + project=args.project, + space_id=space_id, + private=args.private, + force=args.force, + sdk=args.sdk, + frontend_dir=args.frontend, + ) + + +def _handle_config(args): + if args.config_command == "get": + frontend_dir = get_persisted_frontend_dir() + if frontend_dir is None: + print("No Trackio frontend config is set.") + print(f"Config file: {TRACKIO_CONFIG_PATH}") + return + print(f"frontend: {frontend_dir}") + print(f"config: {TRACKIO_CONFIG_PATH}") + return + + if args.config_command == "set": + try: + frontend_dir = set_persisted_frontend_dir(args.frontend) + except ValueError as e: + error_exit(str(e)) + print(f"Saved Trackio default frontend: {frontend_dir}") + print("Reset with `trackio config unset frontend`.") + return + + if args.config_command == "unset": + removed = unset_persisted_frontend_dir() + if removed: + print("Removed Trackio default frontend.") + else: + print("No Trackio default frontend was set.") + return + + +def _extract_reports( + run: str, logs: list[dict], report_name: str | None = None +) -> list[dict]: + reports = [] + for log in logs: + timestamp = log.get("timestamp") + step = log.get("step") + for key, value in log.items(): + if report_name is not None and key != report_name: + continue + if isinstance(value, dict) and value.get("_type") == Markdown.TYPE: + content = value.get("_value") + if isinstance(content, str): + reports.append( + { + "run": run, + "report": key, + "step": step, + "timestamp": timestamp, + "content": content, + } + ) + return reports + + +def _handle_query(args): + remote = _get_remote(args) + try: + if remote: + result = remote.predict(args.project, args.sql, api_name="/query_project") + else: + result = SQLiteStorage.query_project(args.project, args.sql) + except FileNotFoundError as e: + error_exit(str(e)) + except ValueError as e: + error_exit(str(e)) + + if args.json: + print(format_json(result)) + else: + print(format_query_result(result)) + + +def _datetime_to_iso(value): + return value.isoformat() if value is not None else None + + +def _space_url(space) -> str | None: + host = getattr(space, "host", None) + if host: + return host if host.startswith("http") else f"https://{host}" + + subdomain = getattr(space, "subdomain", None) + if subdomain: + return f"https://{subdomain}.hf.space" + + space_id = getattr(space, "id", None) + if not space_id: + return None + return f"https://huggingface.co/spaces/{space_id}" + + +def _serialize_space(space) -> dict: + space_id = getattr(space, "id", "") + namespace, _, name = space_id.partition("/") + return { + "id": space_id, + "namespace": namespace, + "name": name or space_id, + "author": getattr(space, "author", None) or namespace, + "private": bool(getattr(space, "private", False)), + "sdk": getattr(space, "sdk", None), + "url": _space_url(space), + "last_modified": _datetime_to_iso( + getattr(space, "last_modified", None) + or getattr(space, "lastModified", None) + ), + "created_at": _datetime_to_iso(getattr(space, "created_at", None)), + "tags": getattr(space, "tags", None) or [], + } + + +def _maybe_handle_logbook_run_argv() -> bool: + argv = sys.argv[1:] + try: + logbook_idx = argv.index("logbook") + except ValueError: + return False + if len(argv) <= logbook_idx + 1 or argv[logbook_idx + 1] != "run": + return False + + run_argv = argv[logbook_idx + 2 :] + + run_parser = argparse.ArgumentParser( + prog=f"{os.path.basename(sys.argv[0])} logbook run", + description=( + "Run a command; log the command, its scripts, and output to a page" + ), + ) + run_parser.add_argument("--page", help="Page title or slug") + run_parser.add_argument("--title", help="Cell title") + run_parser.add_argument( + "--no-artifacts", + action="store_true", + help="Do not record output model/data files as artifact cells", + ) + if "--" in run_argv: + sep = run_argv.index("--") + opts = run_parser.parse_args(run_argv[:sep]) + command = run_argv[sep + 1 :] + else: + opts, command = run_parser.parse_known_args(run_argv) + if not command: + run_parser.error("No command provided. Use: trackio logbook run -- ") + args = argparse.Namespace( + logbook_action="run", + page=opts.page, + title=opts.title, + no_artifacts=opts.no_artifacts, + command=command, + ) + _handle_logbook(args) + return True + + +def _maybe_rewrite_logbook_read_argv() -> None: + argv = sys.argv + for i in range(1, len(argv) - 1): + if argv[i] == "logbook" and argv[i + 1] == "read": + j = i + 2 + if ( + j < len(argv) + and not argv[j].startswith("-") + and argv[j] not in ("pages", "page", "cell") + ): + argv[j : j + 1] = ["--path", argv[j]] + return + + +def _trackio_space_namespaces(api, token: str | None, author: str | None) -> list[str]: + if author: + return [author] + + if not token: + error_exit( + "Log in with `huggingface-cli login`, pass `--hf-token`, or provide `--author`." + ) + + try: + whoami = api.whoami(token=token, cache=True) + except Exception as e: + error_exit(f"Failed to read Hugging Face account information: {e}") + + namespaces = [whoami["name"]] + for org in whoami.get("orgs", []): + org_name = org.get("name") if isinstance(org, dict) else org + if org_name: + namespaces.append(org_name) + + return list(dict.fromkeys(namespaces)) + + +def _handle_list_spaces(args): + if _get_space(args): + error_exit("The 'list spaces' command does not support --space.") + if args.limit is not None and args.limit < 0: + error_exit("--limit must be zero or greater.") + + token = args.hf_token or huggingface_hub.utils.get_token() + api = huggingface_hub.HfApi(token=token) + namespaces = _trackio_space_namespaces(api, token, args.author) + + spaces_by_id = {} + try: + for namespace in namespaces: + spaces = api.list_spaces( + author=namespace, + filter="trackio", + full=True, + token=token, + ) + for space in spaces: + space_id = getattr(space, "id", None) + if space_id: + spaces_by_id[space_id] = _serialize_space(space) + except Exception as e: + error_exit(f"Failed to list Trackio Spaces: {e}") + + spaces = sorted( + spaces_by_id.values(), + key=lambda space: space.get("last_modified") or "", + reverse=True, + ) + if args.limit is not None: + spaces = spaces[: args.limit] + + if args.json: + print(format_json({"spaces": spaces})) + else: + print(format_spaces(spaces)) + + +def main(): + if _maybe_handle_logbook_run_argv(): + return + _maybe_rewrite_logbook_read_argv() + + parser = argparse.ArgumentParser(description="Trackio CLI") + parser.add_argument( + "--version", + action="version", + version=f"trackio {trackio.__version__}", + ) + parser.add_argument( + "--space", + required=False, + help="HF Space ID (e.g. 'user/space') or Space URL to query remotely.", + ) + parser.add_argument( + "--hf-token", + required=False, + help="HF token for accessing private Spaces.", + ) + subparsers = parser.add_subparsers(dest="command") + + ui_parser = subparsers.add_parser( + "show", help="Show the Trackio dashboard UI for a project" + ) + ui_parser.add_argument( + "--project", required=False, help="Project name to show in the dashboard" + ) + ui_parser.add_argument( + "--theme", + required=False, + default="default", + help="A Gradio Theme to use for the dashboard instead of the default, can be a built-in theme (e.g. 'soft', 'citrus'), or a theme from the Hub (e.g. 'gstaff/xkcd').", + ) + ui_parser.add_argument( + "--mcp-server", + action="store_true", + help="Enable MCP server functionality. The Trackio dashboard will be set up as an MCP server and certain functions will be exposed as MCP tools.", + ) + ui_parser.add_argument( + "--footer", + action="store_true", + default=True, + help="Show the Gradio footer. Use --no-footer to hide it.", + ) + ui_parser.add_argument( + "--no-footer", + dest="footer", + action="store_false", + help="Hide the Gradio footer.", + ) + ui_parser.add_argument( + "--color-palette", + required=False, + help="Comma-separated list of hex color codes for plot lines (e.g. '#FF0000,#00FF00,#0000FF'). If not provided, the TRACKIO_COLOR_PALETTE environment variable will be used, or the default palette if not set.", + ) + ui_parser.add_argument( + "--host", + required=False, + help="Host to bind the server to (e.g. '0.0.0.0' for remote access). If not provided, defaults to '127.0.0.1' (localhost only).", + ) + ui_parser.add_argument( + "--frontend", + required=False, + help="Custom frontend directory to serve. Must contain index.html.", + ) + + subparsers.add_parser( + "status", + help="Show the status of all local Trackio projects, including sync status.", + ) + + sync_parser = subparsers.add_parser( + "sync", + help="Sync a local project's database to a Hugging Face Space. If the Space does not exist, it will be created.", + ) + sync_parser.add_argument( + "--project", + required=False, + help="The name of the local project.", + ) + sync_parser.add_argument( + "--space-id", + required=False, + help="The Hugging Face Space ID where the project will be synced (e.g. username/space_id). If not provided, uses the previously-configured Space.", + ) + sync_parser.add_argument( + "--all", + action="store_true", + dest="sync_all", + help="Sync all projects that have unsynced data to their configured Spaces.", + ) + sync_parser.add_argument( + "--private", + action="store_true", + help="Make the Hugging Face Space private if creating a new Space. By default, the repo will be public unless the organization's default is private. This value is ignored if the repo already exists.", + ) + sync_parser.add_argument( + "--force", + action="store_true", + help="Overwrite the existing database without prompting for confirmation.", + ) + sync_parser.add_argument( + "--sdk", + choices=["gradio", "static"], + default="gradio", + help="The type of Space to deploy. 'gradio' (default) deploys a live Gradio server. 'static' deploys a static Space that reads from an HF Bucket.", + ) + sync_parser.add_argument( + "--frontend", + required=False, + help="Custom frontend directory to deploy. Must contain index.html.", + ) + + freeze_parser = subparsers.add_parser( + "freeze", + help="Create a one-time static Space snapshot from a project's data.", + ) + freeze_parser.add_argument( + "--space-id", + required=True, + help="The source Gradio Space ID (e.g. username/space_id).", + ) + freeze_parser.add_argument( + "--project", + required=True, + help="The name of the project to freeze into a static snapshot.", + ) + freeze_parser.add_argument( + "--new-space-id", + required=False, + help="The Space ID for the new static Space. Defaults to {space_id}_static.", + ) + freeze_parser.add_argument( + "--private", + action="store_true", + help="Make the new static Space private.", + ) + freeze_parser.add_argument( + "--frontend", + required=False, + help="Custom frontend directory to deploy to the frozen static Space.", + ) + + config_parser = subparsers.add_parser( + "config", + help="Manage persistent Trackio configuration.", + ) + config_subparsers = config_parser.add_subparsers( + dest="config_command", + required=True, + ) + config_subparsers.add_parser("get", help="Show current Trackio config.") + config_set_parser = config_subparsers.add_parser( + "set", + help="Set a persistent Trackio config value.", + ) + config_set_parser.add_argument( + "key", + choices=["frontend"], + help="Config key to set.", + ) + config_set_parser.add_argument( + "frontend", + help="Frontend directory to persist.", + ) + config_unset_parser = config_subparsers.add_parser( + "unset", + help="Unset a persistent Trackio config value.", + ) + config_unset_parser.add_argument( + "key", + choices=["frontend"], + help="Config key to unset.", + ) + + list_parser = subparsers.add_parser( + "list", + help="List projects, runs, or metrics", + ) + list_subparsers = list_parser.add_subparsers(dest="list_type", required=True) + + list_projects_parser = list_subparsers.add_parser( + "projects", + help="List all projects", + ) + list_projects_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + list_spaces_parser = list_subparsers.add_parser( + "spaces", + help="List Trackio Spaces for your Hugging Face account and organizations", + ) + list_spaces_parser.add_argument( + "--author", + required=False, + help="Only list Trackio Spaces under this user or organization namespace.", + ) + list_spaces_parser.add_argument( + "--limit", + type=int, + required=False, + help="Maximum number of Spaces to return.", + ) + list_spaces_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + list_runs_parser = list_subparsers.add_parser( + "runs", + help="List runs for a project", + ) + list_runs_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + list_runs_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + list_metrics_parser = list_subparsers.add_parser( + "metrics", + help="List metrics for a run", + ) + list_metrics_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + list_metrics_parser.add_argument( + "--run", + required=True, + help="Run name", + ) + list_metrics_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + list_system_metrics_parser = list_subparsers.add_parser( + "system-metrics", + help="List system metrics for a run", + ) + list_system_metrics_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + list_system_metrics_parser.add_argument( + "--run", + required=True, + help="Run name", + ) + list_system_metrics_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + list_alerts_parser = list_subparsers.add_parser( + "alerts", + help="List alerts for a project or run", + ) + list_alerts_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + list_alerts_parser.add_argument( + "--run", + required=False, + help="Run name (optional)", + ) + list_alerts_parser.add_argument( + "--level", + required=False, + help="Filter by alert level (info, warn, error)", + ) + list_alerts_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + list_alerts_parser.add_argument( + "--since", + required=False, + help="Only show alerts after this ISO 8601 timestamp", + ) + + list_reports_parser = list_subparsers.add_parser( + "reports", + help="List markdown reports for a project or run", + ) + list_reports_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + list_reports_parser.add_argument( + "--run", + required=False, + help="Run name (optional)", + ) + list_reports_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + list_artifacts_parser = list_subparsers.add_parser( + "artifacts", + help="List artifacts for a project", + ) + list_artifacts_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + list_artifacts_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + get_parser = subparsers.add_parser( + "get", + help="Get project, run, or metric information", + ) + get_subparsers = get_parser.add_subparsers(dest="get_type", required=True) + + get_project_parser = get_subparsers.add_parser( + "project", + help="Get project summary", + ) + get_project_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_project_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + get_run_parser = get_subparsers.add_parser( + "run", + help="Get run summary", + ) + get_run_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_run_parser.add_argument( + "--run", + required=True, + help="Run name", + ) + get_run_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + get_artifact_parser = get_subparsers.add_parser( + "artifact", + help="Get an artifact version (manifest, aliases, metadata)", + ) + get_artifact_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_artifact_parser.add_argument( + "--name", + required=True, + help="Artifact name", + ) + get_artifact_parser.add_argument( + "--version", + required=False, + help="Version or alias to resolve (e.g. 'v2' or 'best'). Defaults to latest.", + ) + get_artifact_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + get_metric_parser = get_subparsers.add_parser( + "metric", + help="Get metric values for a run", + ) + get_metric_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_metric_parser.add_argument( + "--run", + required=True, + help="Run name", + ) + get_metric_parser.add_argument( + "--metric", + required=True, + help="Metric name", + ) + get_metric_parser.add_argument( + "--step", + type=int, + required=False, + help="Get metric at exactly this step", + ) + get_metric_parser.add_argument( + "--around", + type=int, + required=False, + help="Get metrics around this step (use with --window)", + ) + get_metric_parser.add_argument( + "--at-time", + required=False, + help="Get metrics around this ISO 8601 timestamp (use with --window)", + ) + get_metric_parser.add_argument( + "--window", + type=int, + required=False, + default=10, + help="Window size: ±steps for --around, ±seconds for --at-time (default: 10)", + ) + get_metric_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + get_snapshot_parser = get_subparsers.add_parser( + "snapshot", + help="Get all metrics at/around a step or timestamp", + ) + get_snapshot_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_snapshot_parser.add_argument( + "--run", + required=True, + help="Run name", + ) + get_snapshot_parser.add_argument( + "--step", + type=int, + required=False, + help="Get all metrics at exactly this step", + ) + get_snapshot_parser.add_argument( + "--around", + type=int, + required=False, + help="Get all metrics around this step (use with --window)", + ) + get_snapshot_parser.add_argument( + "--at-time", + required=False, + help="Get all metrics around this ISO 8601 timestamp (use with --window)", + ) + get_snapshot_parser.add_argument( + "--window", + type=int, + required=False, + default=10, + help="Window size: ±steps for --around, ±seconds for --at-time (default: 10)", + ) + get_snapshot_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + get_system_metric_parser = get_subparsers.add_parser( + "system-metric", + help="Get system metric values for a run", + ) + get_system_metric_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_system_metric_parser.add_argument( + "--run", + required=True, + help="Run name", + ) + get_system_metric_parser.add_argument( + "--metric", + required=False, + help="System metric name (optional, if not provided returns all system metrics)", + ) + get_system_metric_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + get_alerts_parser = get_subparsers.add_parser( + "alerts", + help="Get alerts for a project or run", + ) + get_alerts_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_alerts_parser.add_argument( + "--run", + required=False, + help="Run name (optional)", + ) + get_alerts_parser.add_argument( + "--level", + required=False, + help="Filter by alert level (info, warn, error)", + ) + get_alerts_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + get_alerts_parser.add_argument( + "--since", + required=False, + help="Only show alerts after this ISO 8601 timestamp", + ) + + get_report_parser = get_subparsers.add_parser( + "report", + help="Get markdown report entries for a run", + ) + get_report_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + get_report_parser.add_argument( + "--run", + required=True, + help="Run name", + ) + get_report_parser.add_argument( + "--report", + required=True, + help="Report metric name", + ) + get_report_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + query_parser = subparsers.add_parser( + "query", + help="Run a read-only SQL query against a project database", + ) + query_subparsers = query_parser.add_subparsers(dest="query_type", required=True) + query_project_parser = query_subparsers.add_parser( + "project", + help="Run a read-only SQL query against a project's SQLite database", + ) + query_project_parser.add_argument( + "--project", + required=True, + help="Project name", + ) + query_project_parser.add_argument( + "--sql", + required=True, + help="Read-only SQL query to execute", + ) + query_project_parser.add_argument( + "--json", + action="store_true", + help="Output in JSON format", + ) + + skills_parser = subparsers.add_parser( + "skills", + help="Manage Trackio skills for AI coding assistants", + ) + skills_subparsers = skills_parser.add_subparsers( + dest="skills_action", required=True + ) + skills_add_parser = skills_subparsers.add_parser( + "add", + help=( + "Install the Trackio skill to the central .agents/skills location; " + "pass agent flags to also symlink it for specific assistants" + ), + ) + skills_add_parser.add_argument( + "--cursor", + action="store_true", + help="Install for Cursor", + ) + skills_add_parser.add_argument( + "--claude", + action="store_true", + help="Install for Claude Code", + ) + skills_add_parser.add_argument( + "--codex", + action="store_true", + help="Install for Codex", + ) + skills_add_parser.add_argument( + "--opencode", + action="store_true", + help="Install for OpenCode", + ) + skills_add_parser.add_argument( + "--pi", + action="store_true", + help="Install for pi", + ) + skills_add_parser.add_argument( + "--global", + dest="global_", + action="store_true", + help="Install globally (user-level) instead of in the current project directory", + ) + skills_add_parser.add_argument( + "--dest", + type=str, + required=False, + help="Install into a custom destination (path to skills directory)", + ) + skills_add_parser.add_argument( + "--force", + action="store_true", + help="Overwrite existing skill if it already exists", + ) + skills_add_parser.add_argument( + "--no-command", + dest="no_command", + action="store_true", + help="Do not install the /logbook slash command alongside the skill", + ) + skills_add_parser.add_argument( + "--no-hook", + dest="no_hook", + action="store_true", + help="Do not install the Claude Code hook that mirrors todos into the logbook", + ) + + logbook_parser = subparsers.add_parser( + "logbook", + help="Create and publish a shareable experiment logbook", + ) + logbook_sub = logbook_parser.add_subparsers( + dest="logbook_action", + required=True, + metavar="{open,cell,run,page,read,serve,publish,sync}", + ) + + lb_open = logbook_sub.add_parser( + "open", help="Start or attach to the logbook in this directory" + ) + lb_open.add_argument( + "space_id", nargs="?", help="Optional HF Space id to publish to" + ) + lb_open.add_argument("--title", help="Logbook title (only when creating)") + lb_open.add_argument( + "--no-serve", + action="store_true", + help="Open or attach without launching the local logbook preview", + ) + lb_open.add_argument("--port", type=int, default=7861) + lb_open.add_argument("--no-browser", action="store_true") + + lb_cell = logbook_sub.add_parser( + "cell", help="Append a typed notebook-style cell to a logbook page" + ) + lb_cell_sub = lb_cell.add_subparsers(dest="cell_type", required=True) + + lb_cell_md = lb_cell_sub.add_parser("markdown", help="Append a markdown cell") + lb_cell_md.add_argument("body", help="Markdown body") + lb_cell_md.add_argument("--title", help="Cell title") + lb_cell_md.add_argument("--page", help="Page title or slug") + lb_cell_art = lb_cell_sub.add_parser( + "artifact", help="Append an artifact cell referencing a Trackio artifact" + ) + lb_cell_art.add_argument("name", help="Artifact reference project/name:vN") + lb_cell_art.add_argument("--title", help="Cell title") + lb_cell_art.add_argument("--page", help="Page title or slug") + lb_cell_art.add_argument( + "--type", + dest="artifact_type", + help='Artifact type, e.g. "dataset" or "model"', + ) + + lb_cell_code = lb_cell_sub.add_parser("code", help="Append a code cell") + lb_cell_code.add_argument("--title", help="Cell title") + lb_cell_code.add_argument("--page", help="Page title or slug") + lb_cell_code.add_argument( + "--code", action="append", default=[], help="Path to code/config to include" + ) + lb_cell_code.add_argument("--code-text", help="Inline code to include") + lb_cell_code.add_argument("--language", help="Language for --code-text") + lb_cell_code.add_argument("--output", required=True, help="Output text") + + lb_cell_figure = lb_cell_sub.add_parser("figure", help="Append a figure cell") + lb_cell_figure.add_argument("--title", help="Cell title") + lb_cell_figure.add_argument("--page", help="Page title or slug") + lb_cell_figure.add_argument("--html", help="Path to HTML, or inline HTML text") + lb_cell_figure.add_argument("--html-text", help="Inline HTML text") + lb_cell_figure.add_argument("--raw", help="Path/URL/text for raw data") + lb_cell_figure.add_argument("--raw-text", help="Inline raw data") + + lb_cell_dash = lb_cell_sub.add_parser( + "dashboard", help="Embed a Trackio dashboard for a project" + ) + lb_cell_dash.add_argument("project", help="Trackio project name") + lb_cell_dash.add_argument( + "--space", + dest="space_id", + help="HF Space id (owner/name) hosting the dashboard", + ) + lb_cell_dash.add_argument("--title", help="Cell title") + lb_cell_dash.add_argument("--page", help="Page title or slug") + + lb_run = logbook_sub.add_parser( + "run", + help="Run a command; log the command, its scripts, and output to a page", + ) + lb_run.add_argument("--page", help="Page title or slug") + lb_run.add_argument("--title", help="Cell title") + lb_run.add_argument( + "--no-artifacts", + action="store_true", + help="Do not record output model/data files as artifact cells", + ) + lb_run.add_argument("command", nargs="*") + + lb_page = logbook_sub.add_parser( + "page", help="Create or select a page and make it the default target" + ) + lb_page.add_argument("title", help="Page title") + lb_page.add_argument("--parent", default="index", help="Parent page slug") + + lb_read = logbook_sub.add_parser( + "read", help="Read logbook pages/cells in an agent-friendly form" + ) + lb_read.add_argument( + "--path", + help=( + "Logbook to read: local path, HF Space id, or URL " + "(can also be passed positionally: trackio logbook read )" + ), + ) + lb_read.add_argument("--json", action="store_true", help="Output JSON") + lb_read.add_argument( + "--head", + type=int, + default=None, + help="Lines of code shown per code cell (default 3; 0 hides code)", + ) + lb_read.add_argument( + "--tail", + type=int, + default=None, + help="Lines of output shown per code cell (default 3; 0 hides output)", + ) + lb_read.add_argument( + "--raw-limit", + type=int, + default=None, + help="Inline figure raw data up to this many chars (default 500; 0 disables)", + ) + lb_read_sub = lb_read.add_subparsers(dest="read_target") + lb_read_pages = lb_read_sub.add_parser("pages", help="List logbook pages") + lb_read_pages.add_argument("--json", action="store_true", help="Output JSON") + lb_read_page = lb_read_sub.add_parser("page", help="Read a page for agents") + lb_read_page.add_argument("page", nargs="?", help="Page title or slug") + lb_read_page.add_argument("--json", action="store_true", help="Output JSON") + lb_read_page.add_argument( + "--head", type=int, default=argparse.SUPPRESS, help="Code lines per code cell" + ) + lb_read_page.add_argument( + "--tail", type=int, default=argparse.SUPPRESS, help="Output lines per code cell" + ) + lb_read_page.add_argument( + "--raw-limit", + type=int, + default=argparse.SUPPRESS, + help="Inline figure raw data up to this many chars", + ) + lb_read_cell = lb_read_sub.add_parser("cell", help="Read one cell by id") + lb_read_cell.add_argument("cell_id", help="Cell id") + lb_read_cell.add_argument("--json", action="store_true", help="Output JSON") + lb_read_cell.add_argument("--full", action="store_true", help="Include full body") + lb_read_cell.add_argument( + "--raw", action="store_true", help="Include figure raw data" + ) + lb_read_cell.add_argument("--html", action="store_true", help="Include figure HTML") + + lb_serve = logbook_sub.add_parser("serve", help="Preview the logbook locally") + lb_serve.add_argument("path", nargs="?", help="Logbook workspace/path to serve") + lb_serve.add_argument("--port", type=int, default=7861) + lb_serve.add_argument("--no-browser", action="store_true") + + lb_pub = logbook_sub.add_parser( + "publish", help="Publish to a static HF Space (first publish enables auto-sync)" + ) + lb_pub.add_argument("space_id", nargs="?", help="HF Space id (username/space)") + lb_pub.add_argument( + "--private", + action="store_true", + help="Make the logbook and any promoted dashboards/buckets private", + ) + + logbook_sub.add_parser( + "sync", help="Push local edits to the Space now (after the first publish)" + ) + + logbook_sub.add_parser("_sync") + logbook_sub.add_parser("sync-todos") + + args, unknown_args = parser.parse_known_args() + if unknown_args: + trailing_global_parser = argparse.ArgumentParser(add_help=False) + trailing_global_parser.add_argument("--space", required=False) + trailing_global_parser.add_argument("--hf-token", required=False) + trailing_globals, remaining_unknown = trailing_global_parser.parse_known_args( + unknown_args + ) + if remaining_unknown: + parser.error(f"unrecognized arguments: {' '.join(remaining_unknown)}") + if trailing_globals.space is not None: + args.space = trailing_globals.space + if trailing_globals.hf_token is not None: + args.hf_token = trailing_globals.hf_token + + if args.command in ("show", "status", "sync", "freeze", "skills") and _get_space( + args + ): + error_exit( + f"The '{args.command}' command does not support --space (remote mode)." + ) + + if args.command == "show": + color_palette = None + if args.color_palette: + color_palette = [color.strip() for color in args.color_palette.split(",")] + show( + project=args.project, + theme=args.theme, + mcp_server=args.mcp_server, + footer=args.footer, + color_palette=color_palette, + host=args.host, + frontend_dir=args.frontend, + ) + elif args.command == "status": + _handle_status() + elif args.command == "sync": + _handle_sync(args) + elif args.command == "freeze": + freeze( + space_id=args.space_id, + project=args.project, + new_space_id=args.new_space_id, + private=args.private, + frontend_dir=args.frontend, + ) + elif args.command == "config": + _handle_config(args) + elif args.command == "list": + if args.list_type == "spaces": + _handle_list_spaces(args) + return + + remote = _get_remote(args) + if args.list_type == "projects": + if remote: + projects = remote.predict(api_name="/get_all_projects") + else: + projects = SQLiteStorage.get_projects() + if args.json: + print(format_json({"projects": projects})) + else: + print(format_list(projects, "Projects")) + elif args.list_type == "runs": + if remote: + run_records = remote.predict( + args.project, api_name="/get_runs_for_project" + ) + runs = [r["name"] if isinstance(r, dict) else r for r in run_records] + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.json: + print(format_json({"project": args.project, "runs": runs})) + else: + print(format_list(runs, f"Runs in '{args.project}'")) + elif args.list_type == "metrics": + if remote: + metrics = remote.predict( + args.project, args.run, api_name="/get_metrics_for_run" + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run not in runs: + error_exit( + f"Run '{args.run}' not found in project '{args.project}'." + ) + metrics = SQLiteStorage.get_all_metrics_for_run(args.project, args.run) + if args.json: + print( + format_json( + {"project": args.project, "run": args.run, "metrics": metrics} + ) + ) + else: + print( + format_list( + metrics, f"Metrics for '{args.run}' in '{args.project}'" + ) + ) + elif args.list_type == "system-metrics": + if remote: + system_metrics = remote.predict( + args.project, args.run, api_name="/get_system_metrics_for_run" + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run not in runs: + error_exit( + f"Run '{args.run}' not found in project '{args.project}'." + ) + system_metrics = SQLiteStorage.get_all_system_metrics_for_run( + args.project, args.run + ) + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "system_metrics": system_metrics, + } + ) + ) + else: + print(format_system_metric_names(system_metrics)) + elif args.list_type == "alerts": + if remote: + alerts = remote.predict( + args.project, + args.run, + args.level, + args.since, + api_name="/get_alerts", + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + alerts = SQLiteStorage.get_alerts( + args.project, + run_name=args.run, + level=args.level, + since=args.since, + ) + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "level": args.level, + "since": args.since, + "alerts": alerts, + } + ) + ) + else: + print(format_alerts(alerts)) + elif args.list_type == "reports": + if remote: + run_records = remote.predict( + args.project, api_name="/get_runs_for_project" + ) + runs = [r["name"] if isinstance(r, dict) else r for r in run_records] + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run and args.run not in runs: + error_exit(f"Run '{args.run}' not found in project '{args.project}'.") + + target_runs = [args.run] if args.run else runs + all_reports = [] + for run_name in target_runs: + if remote: + logs = remote.predict(args.project, run_name, api_name="/get_logs") + else: + logs = SQLiteStorage.get_logs(args.project, run_name) + all_reports.extend(_extract_reports(run_name, logs)) + + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "reports": all_reports, + } + ) + ) + else: + report_lines = [ + f"{entry['run']} | {entry['report']} | step={entry['step']} | {entry['timestamp']}" + for entry in all_reports + ] + if args.run: + print( + format_list( + report_lines, + f"Reports for '{args.run}' in '{args.project}'", + ) + ) + else: + print(format_list(report_lines, f"Reports in '{args.project}'")) + elif args.list_type == "artifacts": + if remote: + artifacts = remote.predict(args.project, api_name="/get_artifacts") + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + artifacts = SQLiteStorage.get_artifacts(args.project) + if args.json: + print(format_json({"project": args.project, "artifacts": artifacts})) + else: + print(format_artifacts(artifacts, args.project)) + elif args.command == "get": + remote = _get_remote(args) + if args.get_type == "artifact": + if remote: + record = remote.predict( + args.project, + args.name, + args.version, + api_name="/get_artifact_manifest", + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + record = SQLiteStorage.get_artifact_manifest( + args.project, args.name, args.version + ) + if record is None: + spec = f":{args.version}" if args.version else "" + error_exit( + f"Artifact '{args.name}{spec}' not found in project " + f"'{args.project}'." + ) + if args.json: + print(format_json(record)) + else: + print(format_artifact(record)) + elif args.get_type == "project": + if remote: + summary = remote.predict(args.project, api_name="/get_project_summary") + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + summary = get_project_summary(args.project) + if args.json: + print(format_json(summary)) + else: + print(format_project_summary(summary)) + elif args.get_type == "run": + if remote: + summary = remote.predict( + args.project, args.run, api_name="/get_run_summary" + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run not in runs: + error_exit( + f"Run '{args.run}' not found in project '{args.project}'." + ) + summary = get_run_summary(args.project, args.run) + if args.json: + print(format_json(summary)) + else: + print(format_run_summary(summary)) + elif args.get_type == "metric": + at_time = getattr(args, "at_time", None) + if remote: + values = remote.predict( + args.project, + args.run, + args.metric, + args.step, + args.around, + at_time, + args.window, + api_name="/get_metric_values", + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run not in runs: + error_exit( + f"Run '{args.run}' not found in project '{args.project}'." + ) + metrics = SQLiteStorage.get_all_metrics_for_run(args.project, args.run) + if args.metric not in metrics: + error_exit( + f"Metric '{args.metric}' not found in run '{args.run}' of project '{args.project}'." + ) + values = SQLiteStorage.get_metric_values( + args.project, + args.run, + args.metric, + step=args.step, + around_step=args.around, + at_time=at_time, + window=args.window, + ) + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "metric": args.metric, + "values": values, + } + ) + ) + else: + print(format_metric_values(values)) + elif args.get_type == "snapshot": + if not args.step and not args.around and not getattr(args, "at_time", None): + error_exit( + "Provide --step, --around (with --window), or --at-time (with --window)." + ) + at_time = getattr(args, "at_time", None) + if remote: + snapshot = remote.predict( + args.project, + args.run, + args.step, + args.around, + at_time, + args.window, + api_name="/get_snapshot", + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run not in runs: + error_exit( + f"Run '{args.run}' not found in project '{args.project}'." + ) + snapshot = SQLiteStorage.get_snapshot( + args.project, + args.run, + step=args.step, + around_step=args.around, + at_time=at_time, + window=args.window, + ) + if args.json: + result = { + "project": args.project, + "run": args.run, + "metrics": snapshot, + } + if args.step is not None: + result["step"] = args.step + if args.around is not None: + result["around"] = args.around + result["window"] = args.window + if at_time is not None: + result["at_time"] = at_time + result["window"] = args.window + print(format_json(result)) + else: + print(format_snapshot(snapshot)) + elif args.get_type == "system-metric": + if remote: + system_metrics = remote.predict( + args.project, args.run, api_name="/get_system_logs" + ) + if args.metric: + all_system_metric_names = remote.predict( + args.project, + args.run, + api_name="/get_system_metrics_for_run", + ) + if args.metric not in all_system_metric_names: + error_exit( + f"System metric '{args.metric}' not found in run '{args.run}' of project '{args.project}'." + ) + filtered_metrics = [ + { + k: v + for k, v in entry.items() + if k == "timestamp" or k == args.metric + } + for entry in system_metrics + if args.metric in entry + ] + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "metric": args.metric, + "values": filtered_metrics, + } + ) + ) + else: + print(format_system_metrics(filtered_metrics)) + else: + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "system_metrics": system_metrics, + } + ) + ) + else: + print(format_system_metrics(system_metrics)) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run not in runs: + error_exit( + f"Run '{args.run}' not found in project '{args.project}'." + ) + if args.metric: + system_metrics = SQLiteStorage.get_system_logs( + args.project, args.run + ) + all_system_metric_names = ( + SQLiteStorage.get_all_system_metrics_for_run( + args.project, args.run + ) + ) + if args.metric not in all_system_metric_names: + error_exit( + f"System metric '{args.metric}' not found in run '{args.run}' of project '{args.project}'." + ) + filtered_metrics = [ + { + k: v + for k, v in entry.items() + if k == "timestamp" or k == args.metric + } + for entry in system_metrics + if args.metric in entry + ] + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "metric": args.metric, + "values": filtered_metrics, + } + ) + ) + else: + print(format_system_metrics(filtered_metrics)) + else: + system_metrics = SQLiteStorage.get_system_logs( + args.project, args.run + ) + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "system_metrics": system_metrics, + } + ) + ) + else: + print(format_system_metrics(system_metrics)) + elif args.get_type == "alerts": + if remote: + alerts = remote.predict( + args.project, + args.run, + args.level, + args.since, + api_name="/get_alerts", + ) + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + alerts = SQLiteStorage.get_alerts( + args.project, + run_name=args.run, + level=args.level, + since=args.since, + ) + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "level": args.level, + "since": args.since, + "alerts": alerts, + } + ) + ) + else: + print(format_alerts(alerts)) + elif args.get_type == "report": + if remote: + logs = remote.predict(args.project, args.run, api_name="/get_logs") + else: + db_path = SQLiteStorage.get_project_db_path(args.project) + if not db_path.exists(): + error_exit(f"Project '{args.project}' not found.") + runs = SQLiteStorage.get_runs(args.project) + if args.run not in runs: + error_exit( + f"Run '{args.run}' not found in project '{args.project}'." + ) + logs = SQLiteStorage.get_logs(args.project, args.run) + + reports = _extract_reports(args.run, logs, report_name=args.report) + if not reports: + error_exit( + f"Report '{args.report}' not found in run '{args.run}' of project '{args.project}'." + ) + + if args.json: + print( + format_json( + { + "project": args.project, + "run": args.run, + "report": args.report, + "values": reports, + } + ) + ) + else: + output = [] + for idx, entry in enumerate(reports, start=1): + output.append( + f"Entry {idx} | step={entry['step']} | timestamp={entry['timestamp']}" + ) + output.append(entry["content"]) + if idx < len(reports): + output.append("-" * 80) + print("\n".join(output)) + elif args.command == "query": + if args.query_type == "project": + _handle_query(args) + elif args.command == "skills": + if args.skills_action == "add": + _handle_skills_add(args) + elif args.command == "logbook": + _handle_logbook(args) + else: + parser.print_help() + + +def _sync_suffix(lb, proj): + if lb.is_autosync(proj): + space = lb.read_metadata(proj).get("space_id") + return f" · syncing to {space}…" + return "" + + +def _logbook_cell_target(lb, proj, args): + return lb.resolve_page(proj, getattr(args, "page", None)) + + +def _print_logbook_pages(pages): + if not pages: + print("No pages.") + return + print("Pages:") + for page in pages: + count = page["cell_count"] + print( + f"- {page['slug']} · {page['title']} · " + f"{count} cell{'' if count == 1 else 's'}" + ) + + +def _print_logbook_page_outline(page): + print(f"Page: {page['title']} ({page['slug']})") + if not page["cells"]: + print("No cells.") + return + for cell in page["cells"]: + created = ( + f" · {cell['created_at'].replace('T', ' ')[:16]}" + if cell.get("created_at") + else "" + ) + print(f"\n### {cell['title']} · {cell['type']} · {cell['id']}{created}") + if cell.get("preview"): + print(cell["preview"].rstrip()) + print( + "\nFetch full payloads with: trackio logbook read cell " + "[--full|--raw|--html]" + ) + + +def _print_logbook_cell(cell): + print(f"Cell: {cell['title']} ({cell['id']})") + print(f"Page: {cell['page_title']} ({cell['page']})") + print(f"Type: {cell['type']}") + if cell.get("created_at"): + print(f"Created: {cell['created_at']}") + content_keys = [key for key in ("body", "raw", "html") if key in cell] + if not content_keys: + if cell["type"] == "code": + print("\nBody omitted. Use --full to include code/output.") + elif cell["type"] == "figure": + print("\nFigure content omitted. Use --raw, --html, or --full.") + return + for key in content_keys: + label = key.upper() + print(f"\n--- {label} ---\n") + print(cell[key]) + + +def _read_logbook_payload(path_or_text, inline_text): + if inline_text is not None: + return inline_text + if not path_or_text: + return "" + path = Path(path_or_text) + if path.is_file(): + return path.read_text(encoding="utf-8") + return path_or_text + + +def _handle_logbook(args): + from trackio import logbook as lb + + action = args.logbook_action + try: + if action == "open": + print("Warning: Trackio Logbook is an experimental feature.") + proj = lb.find_project_dir() + if proj is not None: + if args.space_id: + metadata = lb.read_metadata(proj) + metadata["space_id"] = args.space_id + lb.write_metadata(proj, metadata) + print(f"Attached to existing logbook at {lb.logbook_root(proj)}") + if args.title: + print( + "Note: --title was ignored because this logbook already " + "exists. To retitle it, edit the '# ...' heading in " + f"{lb.logbook_root(proj) / 'pages' / 'index.md'}." + ) + elif args.space_id: + proj = lb.clone_logbook(args.space_id) + if proj is not None: + print( + f"Cloned logbook from {args.space_id} into " + f"{lb.logbook_root(proj)}" + ) + if proj is None: + proj = lb.create_logbook( + args.title or os.path.basename(os.getcwd()), space_id=args.space_id + ) + print(f"Opened logbook at {lb.logbook_root(proj)}") + if args.space_id: + print(f"Will publish to: {args.space_id}") + if not args.no_serve: + lb.start_preview(proj, port=args.port, open_browser=not args.no_browser) + elif action == "run": + proj = lb.require_project_dir() + command = list(args.command or []) + if command and command[0] == "--": + command = command[1:] + if not command: + error_exit("No command provided. Use: trackio logbook run -- ") + rc = lb.run_and_log( + proj, + command, + page=args.page, + title=args.title, + capture_artifacts=not getattr(args, "no_artifacts", False), + ) + slug = lb.read_metadata(proj).get("last_page", "?") + print(f"Logged run to page '{slug}'.{_sync_suffix(lb, proj)}") + sys.exit(rc) + elif action == "cell": + proj = lb.require_project_dir() + slug = _logbook_cell_target(lb, proj, args) + if args.cell_type == "markdown": + lb.add_markdown_cell(proj, slug, args.body, title=args.title) + elif args.cell_type == "artifact": + lb.add_artifact_cell( + proj, + slug, + args.name, + title=args.title, + artifact_type=args.artifact_type, + ) + elif args.cell_type == "code": + lb.add_code_cell( + proj, + slug, + args.output, + title=args.title, + code_paths=args.code, + code_text=args.code_text, + language=args.language, + ) + elif args.cell_type == "figure": + html = _read_logbook_payload(args.html, args.html_text) + raw = _read_logbook_payload(args.raw, args.raw_text) + lb.add_figure_cell( + proj, + slug, + html=html, + raw=raw, + title=args.title, + ) + elif args.cell_type == "dashboard": + lb.add_dashboard_cell( + proj, + slug, + args.project, + space_id=args.space_id, + title=args.title, + ) + print( + f"Logged {args.cell_type} cell to page " + f"'{slug}'.{_sync_suffix(lb, proj)}" + ) + lb.trigger_autosync(proj) + elif action == "page": + proj = lb.require_project_dir() + page_slug = lb.ensure_page(proj, args.title, parent_slug=args.parent) + print(f"Selected page '{page_slug}' as default.{_sync_suffix(lb, proj)}") + lb.trigger_autosync(proj) + elif action == "read": + proj = lb.resolve_read_source(args.path) + preview_opts = { + "head": lb.DEFAULT_HEAD + if getattr(args, "head", None) is None + else args.head, + "tail": lb.DEFAULT_TAIL + if getattr(args, "tail", None) is None + else args.tail, + "raw_limit": lb.DEFAULT_RAW_LIMIT + if getattr(args, "raw_limit", None) is None + else args.raw_limit, + } + if args.read_target is None: + if args.json: + print(format_json(lb.read_logbook_data(proj, **preview_opts))) + else: + print(lb.read_logbook(proj, **preview_opts)) + elif args.read_target == "pages": + pages = lb.list_pages(proj) + if args.json: + print(format_json({"pages": pages})) + else: + _print_logbook_pages(pages) + elif args.read_target == "page": + page = lb.read_page_outline(proj, args.page, **preview_opts) + if args.json: + print(format_json(page)) + else: + _print_logbook_page_outline(page) + elif args.read_target == "cell": + cell = lb.read_cell( + proj, + args.cell_id, + include_full=args.full, + include_raw=args.raw, + include_html=args.html, + ) + if args.json: + print(format_json(cell)) + else: + _print_logbook_cell(cell) + elif action == "_sync": + lb.sync_worker() + elif action == "sync-todos": + lb.sync_todos_from_stdin() + elif action == "serve": + lb.serve(path=args.path, port=args.port, open_browser=not args.no_browser) + elif action == "publish": + url = lb.publish(space_id=args.space_id, private=args.private) + print(f"Published: {url}") + space_id = lb.read_metadata(lb.require_project_dir()).get("space_id") + if space_id: + subdomain = re.sub(r"[^a-z0-9]+", "-", space_id.lower()).strip("-") + print(f"Rendered at: https://{subdomain}.static.hf.space/") + elif action == "sync": + proj = lb.require_project_dir() + if not lb.is_autosync(proj): + error_exit("Publish first: trackio logbook publish ") + lb.trigger_autosync(proj) + print(f"Syncing to {lb.read_metadata(proj).get('space_id')}…") + except lb.LogbookError as e: + error_exit(str(e)) + + +def _handle_skills_add(args): + import shutil + from pathlib import Path + + CENTRAL_LOCAL = Path(".agents/skills") + CENTRAL_GLOBAL = Path("~/.agents/skills") + CLAUDE_LOCAL = Path(".claude/skills") + CLAUDE_GLOBAL = Path("~/.claude/skills") + + SKILL_ID = "trackio" + GITHUB_RAW = "https://raw.githubusercontent.com/gradio-app/trackio/main" + SKILL_PREFIX = ".agents/skills/trackio" + SKILL_FILES = [ + "SKILL.md", + "alerts.md", + "logging_metrics.md", + "retrieving_metrics.md", + "storage_schema.md", + "logbook.md", + ] + COMMAND_PREFIX = ".agents/commands" + COMMAND_FILE = "logbook.md" + + REPO_ROOT = Path(__file__).resolve().parent.parent + USE_LOCAL = (REPO_ROOT / SKILL_PREFIX / "SKILL.md").is_file() + + if USE_LOCAL: + print(f"Using local Trackio source at {REPO_ROOT}") + + def download(url: str) -> str: + from huggingface_hub.utils import get_session + + try: + response = get_session().get(url) + response.raise_for_status() + except Exception as e: + error_exit( + f"Failed to download {url}\n{e}\n\n" + "Make sure you have internet access. The skill files are fetched from " + "the Trackio GitHub repository." + ) + return response.text + + def get_content(prefix: str, fname: str) -> str: + if USE_LOCAL: + local = REPO_ROOT / prefix / fname + if local.is_file(): + return local.read_text(encoding="utf-8") + return download(f"{GITHUB_RAW}/{prefix}/{fname}") + + def remove_existing(path: Path, force: bool): + if not (path.exists() or path.is_symlink()): + return + if not force: + error_exit( + f"Skill already exists at {path}.\nRe-run with --force to overwrite." + ) + if path.is_dir() and not path.is_symlink(): + shutil.rmtree(path) + else: + path.unlink() + + def install_to(skills_dir: Path, force: bool) -> Path: + skills_dir = skills_dir.expanduser().resolve() + skills_dir.mkdir(parents=True, exist_ok=True) + dest = skills_dir / SKILL_ID + remove_existing(dest, force) + dest.mkdir() + for fname in SKILL_FILES: + (dest / fname).write_text( + get_content(SKILL_PREFIX, fname), encoding="utf-8" + ) + return dest + + def create_symlink( + agent_skills_dir: Path, central_skill_path: Path, force: bool + ) -> Path: + agent_skills_dir = agent_skills_dir.expanduser().resolve() + agent_skills_dir.mkdir(parents=True, exist_ok=True) + link_path = agent_skills_dir / SKILL_ID + remove_existing(link_path, force) + link_path.symlink_to(os.path.relpath(central_skill_path, agent_skills_dir)) + return link_path + + def install_command( + command_dir: Path, force: bool, strip_frontmatter: bool = False + ) -> Path: + import re + + command_dir = command_dir.expanduser().resolve() + command_dir.mkdir(parents=True, exist_ok=True) + dest = command_dir / COMMAND_FILE + if dest.exists() and not force: + error_exit( + f"Command already exists at {dest}.\nRe-run with --force to overwrite." + ) + content = get_content(COMMAND_PREFIX, COMMAND_FILE) + if strip_frontmatter: + content = re.sub(r"\A---\n.*?\n---\n+", "", content, flags=re.S) + dest.write_text(content, encoding="utf-8") + return dest + + global_targets = { + "cursor": Path("~/.cursor/skills"), + "claude": CLAUDE_GLOBAL, + "codex": Path("~/.codex/skills"), + "opencode": Path("~/.opencode/skills"), + "pi": Path("~/.pi/agent/skills"), + } + local_targets = { + "cursor": Path(".cursor/skills"), + "claude": CLAUDE_LOCAL, + "codex": Path(".codex/skills"), + "opencode": Path(".opencode/skills"), + "pi": Path(".pi/skills"), + } + targets_dict = global_targets if args.global_ else local_targets + + command_targets_global = { + "cursor": Path("~/.cursor/commands"), + "claude": Path("~/.claude/commands"), + "codex": Path("~/.codex/prompts"), + "opencode": Path("~/.config/opencode/commands"), + "pi": Path("~/.pi/agent/prompts"), + } + command_targets_local = { + "cursor": Path(".cursor/commands"), + "claude": Path(".claude/commands"), + "codex": Path("~/.codex/prompts"), + "opencode": Path(".opencode/commands"), + "pi": Path(".pi/prompts"), + } + command_dict = command_targets_global if args.global_ else command_targets_local + COMMAND_NOTES = { + "codex": " (Codex only reads ~/.codex/prompts; restart Codex to pick it up)" + } + STRIP_FRONTMATTER = {"pi"} + + if args.dest: + if ( + args.cursor + or args.claude + or args.codex + or args.opencode + or args.pi + or args.global_ + ): + error_exit("--dest cannot be combined with agent flags or --global.") + skill_dest = install_to(Path(args.dest), args.force) + print(f"Installed '{SKILL_ID}' to {skill_dest}") + return + + selected = [ + name + for name, flag in ( + ("cursor", args.cursor), + ("claude", args.claude), + ("codex", args.codex), + ("opencode", args.opencode), + ("pi", args.pi), + ) + if flag + ] + + central_path = CENTRAL_GLOBAL if args.global_ else CENTRAL_LOCAL + central_skill_path = install_to(central_path, args.force) + print(f"Installed '{SKILL_ID}' to central location: {central_skill_path}") + + for name in selected: + link_path = create_symlink(targets_dict[name], central_skill_path, args.force) + print(f"Created symlink: {link_path}") + + if not args.no_command: + for name in selected: + if name in command_dict: + cmd_path = install_command( + command_dict[name], + args.force, + strip_frontmatter=name in STRIP_FRONTMATTER, + ) + note = COMMAND_NOTES.get(name, "") + print(f"Installed '/logbook' command: {cmd_path}{note}") + else: + print( + f"Skipped '/logbook' command for {name} " + "(no slash-command directory convention)." + ) + + if args.claude and not args.no_hook: + hook_path = _install_claude_logbook_hook(args.global_) + if hook_path: + print(f"Installed logbook todo-sync hook: {hook_path}") + + +def _install_claude_logbook_hook(global_: bool): + import json + from pathlib import Path + + settings = ( + Path("~/.claude/settings.json") if global_ else Path(".claude/settings.json") + ).expanduser() + settings.parent.mkdir(parents=True, exist_ok=True) + data = {} + if settings.exists(): + try: + data = json.loads(settings.read_text(encoding="utf-8")) + except Exception: + print(f"Could not parse {settings}; skipping hook install.") + return None + command = "trackio logbook sync-todos" + hooks = data.setdefault("hooks", {}) + post = hooks.setdefault("PostToolUse", []) + for entry in post: + for h in entry.get("hooks", []): + if h.get("command") == command: + return settings + post.append( + { + "matcher": "TodoWrite", + "hooks": [{"type": "command", "command": command}], + } + ) + settings.write_text(json.dumps(data, indent=2), encoding="utf-8") + return settings + + +if __name__ == "__main__": + main() diff --git a/trackio/cli_helpers.py b/trackio/cli_helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..c3bad0f5a7b2797bbbb0d96b34940540b2e758ed --- /dev/null +++ b/trackio/cli_helpers.py @@ -0,0 +1,263 @@ +import json +import sys +from typing import Any + + +def format_json(data: Any) -> str: + """Format data as JSON.""" + return json.dumps(data, indent=2) + + +def format_list(items: list[str], title: str | None = None) -> str: + """Format a list of items in human-readable format.""" + if not items: + return f"No {title.lower() if title else 'items'} found." + + output = [] + if title: + output.append(f"{title}:") + + for item in items: + output.append(f" - {item}") + + return "\n".join(output) + + +def format_artifacts(artifacts: list[dict], project: str | None = None) -> str: + """Format a project's artifacts in human-readable format.""" + if not artifacts: + return "No artifacts found." + + title = f"Artifacts in '{project}'" if project else "Artifacts" + output = [f"{title}:"] + for art in artifacts: + latest = art.get("latest_version") + version = f"v{latest}" if latest is not None else "(no versions)" + aliases = art.get("aliases") or [] + alias_str = f" [{', '.join(aliases)}]" if aliases else "" + output.append( + f" - {art['name']} ({art.get('type', '?')}) " + f"latest={version}{alias_str} " + f"versions={art.get('num_versions', 0)}" + ) + if art.get("description"): + output.append(f" {art['description']}") + return "\n".join(output) + + +def format_artifact(record: dict) -> str: + """Format a single resolved artifact version in human-readable format.""" + lines = [ + f"Artifact: {record['name']} (v{record['version']})", + f" type: {record.get('type')}", + ] + if record.get("description"): + lines.append(f" description: {record['description']}") + aliases = record.get("aliases") or [] + if aliases: + lines.append(f" aliases: {', '.join(aliases)}") + if record.get("metadata"): + lines.append(f" metadata: {record['metadata']}") + lines.append(f" size: {record.get('size_bytes')} bytes") + lines.append(f" digest: {record.get('manifest_digest')}") + manifest = record.get("manifest") or [] + lines.append(f" files ({len(manifest)}):") + for entry in manifest: + lines.append(f" - {entry['path']} ({entry['size']} bytes)") + return "\n".join(lines) + + +def format_spaces(spaces: list[dict]) -> str: + """Format HF Spaces in human-readable format.""" + if not spaces: + return "No Trackio Spaces found." + + output = ["Trackio Spaces:"] + for space in spaces: + visibility = "private" if space.get("private") else "public" + output.append(f" - {space['id']} ({visibility})") + if space.get("url"): + output.append(f" {space['url']}") + + return "\n".join(output) + + +def format_project_summary(summary: dict) -> str: + """Format project summary in human-readable format.""" + output = [f"Project: {summary['project']}"] + output.append(f"Number of runs: {summary['num_runs']}") + + if summary["runs"]: + output.append("\nRuns:") + for run in summary["runs"]: + output.append(f" - {run}") + else: + output.append("\nNo runs found.") + + if summary.get("last_activity"): + output.append(f"\nLast activity (max step): {summary['last_activity']}") + + return "\n".join(output) + + +def format_run_summary(summary: dict) -> str: + """Format run summary in human-readable format.""" + output = [f"Project: {summary['project']}"] + output.append(f"Run: {summary['run']}") + output.append(f"Number of logs: {summary['num_logs']}") + + if summary.get("last_step") is not None: + output.append(f"Last step: {summary['last_step']}") + + if summary.get("metrics"): + output.append("\nMetrics:") + for metric in summary["metrics"]: + output.append(f" - {metric}") + else: + output.append("\nNo metrics found.") + + config = summary.get("config") + if config: + output.append("\nConfig:") + config_display = {k: v for k, v in config.items() if not k.startswith("_")} + if config_display: + for key, value in config_display.items(): + output.append(f" {key}: {value}") + else: + output.append(" (no config)") + else: + output.append("\nConfig: (no config)") + + return "\n".join(output) + + +def format_metric_values(values: list[dict]) -> str: + """Format metric values in human-readable format.""" + if not values: + return "No metric values found." + + output = [f"Found {len(values)} value(s):\n"] + output.append("Step | Timestamp | Value") + output.append("-" * 50) + + for value in values: + step = value.get("step", "N/A") + timestamp = value.get("timestamp", "N/A") + val = value.get("value", "N/A") + output.append(f"{step} | {timestamp} | {val}") + + return "\n".join(output) + + +def format_system_metrics(metrics: list[dict]) -> str: + """Format system metrics in human-readable format.""" + if not metrics: + return "No system metrics found." + + output = [f"Found {len(metrics)} system metric entry/entries:\n"] + + for i, entry in enumerate(metrics): + timestamp = entry.get("timestamp", "N/A") + output.append(f"\nEntry {i + 1} (Timestamp: {timestamp}):") + for key, value in entry.items(): + if key != "timestamp": + output.append(f" {key}: {value}") + + return "\n".join(output) + + +def format_system_metric_names(names: list[str]) -> str: + """Format system metric names in human-readable format.""" + return format_list(names, "System Metrics") + + +def format_snapshot(snapshot: dict[str, list[dict]]) -> str: + """Format a metrics snapshot in human-readable format.""" + if not snapshot: + return "No metrics found in the specified range." + + output = [] + for metric_name, values in sorted(snapshot.items()): + output.append(f"\n{metric_name}:") + output.append(" Step | Timestamp | Value") + output.append(" " + "-" * 48) + for v in values: + step = v.get("step", "N/A") + ts = v.get("timestamp", "N/A") + val = v.get("value", "N/A") + output.append(f" {step} | {ts} | {val}") + + return "\n".join(output) + + +def format_alerts(alerts: list[dict]) -> str: + """Format alerts in human-readable format.""" + if not alerts: + return "No alerts found." + + output = [f"Found {len(alerts)} alert(s):\n"] + output.append("Timestamp | Run | Level | Title | Text | Step") + output.append("-" * 80) + + for a in alerts: + ts = a.get("timestamp", "N/A") + run = a.get("run", "N/A") + level = a.get("level", "N/A").upper() + title = a.get("title", "") + text = a.get("text", "") or "" + step = a.get("step", "N/A") + output.append(f"{ts} | {run} | {level} | {title} | {text} | {step}") + + return "\n".join(output) + + +def format_query_result(result: dict[str, Any]) -> str: + """Format SQL query results in human-readable format.""" + columns = result.get("columns", []) + rows = result.get("rows", []) + row_count = result.get("row_count", 0) + + if not columns: + return f"Query returned {row_count} row(s)." + + rendered_rows = [] + for row in rows: + rendered_rows.append( + [ + "" if row.get(column) is None else str(row.get(column)) + for column in columns + ] + ) + + widths = [] + for idx, column in enumerate(columns): + cell_width = max( + (len(rendered_row[idx]) for rendered_row in rendered_rows), default=0 + ) + widths.append(max(len(column), cell_width)) + + header = " | ".join( + column.ljust(width) for column, width in zip(columns, widths, strict=False) + ) + separator = "-+-".join("-" * width for width in widths) + output = [f"Query returned {row_count} row(s).", header, separator] + + if not rendered_rows: + output.append("(no rows)") + return "\n".join(output) + + for rendered_row in rendered_rows: + output.append( + " | ".join( + value.ljust(width) + for value, width in zip(rendered_row, widths, strict=False) + ) + ) + + return "\n".join(output) + + +def error_exit(message: str, code: int = 1) -> None: + """Print error message and exit.""" + print(f"Error: {message}", file=sys.stderr) + sys.exit(code) diff --git a/trackio/commit_scheduler.py b/trackio/commit_scheduler.py new file mode 100644 index 0000000000000000000000000000000000000000..2e1cbabc2f9e576def2332cd4fbdc5788828ace6 --- /dev/null +++ b/trackio/commit_scheduler.py @@ -0,0 +1,310 @@ +# Originally copied from https://github.com/huggingface/huggingface_hub/blob/d0a948fc2a32ed6e557042a95ef3e4af97ec4a7c/src/huggingface_hub/_commit_scheduler.py + +import atexit +import logging +import time +from concurrent.futures import Future +from dataclasses import dataclass +from pathlib import Path +from threading import Lock, Thread +from typing import Callable, Dict, List, Union + +from huggingface_hub.hf_api import ( + DEFAULT_IGNORE_PATTERNS, + CommitInfo, + CommitOperationAdd, + HfApi, +) +from huggingface_hub.utils import filter_repo_objects + +logger = logging.getLogger(__name__) + + +@dataclass(frozen=True) +class _FileToUpload: + """Temporary dataclass to store info about files to upload. Not meant to be used directly.""" + + local_path: Path + path_in_repo: str + size_limit: int + last_modified: float + + +class CommitScheduler: + """ + Scheduler to upload a local folder to the Hub at regular intervals (e.g. push to hub every 5 minutes). + + The recommended way to use the scheduler is to use it as a context manager. This ensures that the scheduler is + properly stopped and the last commit is triggered when the script ends. The scheduler can also be stopped manually + with the `stop` method. Checkout the [upload guide](https://huggingface.co/docs/huggingface_hub/guides/upload#scheduled-uploads) + to learn more about how to use it. + + Args: + repo_id (`str`): + The id of the repo to commit to. + folder_path (`str` or `Path`): + Path to the local folder to upload regularly. + every (`int` or `float`, *optional*): + The number of minutes between each commit. Defaults to 5 minutes. + path_in_repo (`str`, *optional*): + Relative path of the directory in the repo, for example: `"checkpoints/"`. Defaults to the root folder + of the repository. + repo_type (`str`, *optional*): + The type of the repo to commit to. Defaults to `model`. + revision (`str`, *optional*): + The revision of the repo to commit to. Defaults to `main`. + private (`bool`, *optional*): + Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists. + token (`str`, *optional*): + The token to use to commit to the repo. Defaults to the token saved on the machine. + allow_patterns (`List[str]` or `str`, *optional*): + If provided, only files matching at least one pattern are uploaded. + ignore_patterns (`List[str]` or `str`, *optional*): + If provided, files matching any of the patterns are not uploaded. + squash_history (`bool`, *optional*): + Whether to squash the history of the repo after each commit. Defaults to `False`. Squashing commits is + useful to avoid degraded performances on the repo when it grows too large. + hf_api (`HfApi`, *optional*): + The [`HfApi`] client to use to commit to the Hub. Can be set with custom settings (user agent, token,...). + on_before_commit (`Callable[[], None]`, *optional*): + If specified, a function that will be called before the CommitScheduler lists files to create a commit. + + Example: + ```py + >>> from pathlib import Path + >>> from huggingface_hub import CommitScheduler + + # Scheduler uploads every 10 minutes + >>> csv_path = Path("watched_folder/data.csv") + >>> CommitScheduler(repo_id="test_scheduler", repo_type="dataset", folder_path=csv_path.parent, every=10) + + >>> with csv_path.open("a") as f: + ... f.write("first line") + + # Some time later (...) + >>> with csv_path.open("a") as f: + ... f.write("second line") + ``` + + Example using a context manager: + ```py + >>> from pathlib import Path + >>> from huggingface_hub import CommitScheduler + + >>> with CommitScheduler(repo_id="test_scheduler", repo_type="dataset", folder_path="watched_folder", every=10) as scheduler: + ... csv_path = Path("watched_folder/data.csv") + ... with csv_path.open("a") as f: + ... f.write("first line") + ... (...) + ... with csv_path.open("a") as f: + ... f.write("second line") + + # Scheduler is now stopped and last commit have been triggered + ``` + """ + + def __init__( + self, + *, + repo_id: str, + folder_path: Union[str, Path], + every: Union[int, float] = 5, + path_in_repo: str | None = None, + repo_type: str | None = None, + revision: str | None = None, + private: bool | None = None, + token: str | None = None, + allow_patterns: list[str] | str | None = None, + ignore_patterns: list[str] | str | None = None, + squash_history: bool = False, + hf_api: HfApi | None = None, + on_before_commit: Callable[[], None] | None = None, + ) -> None: + self.api = hf_api or HfApi(token=token) + self.on_before_commit = on_before_commit + + # Folder + self.folder_path = Path(folder_path).expanduser().resolve() + self.path_in_repo = path_in_repo or "" + self.allow_patterns = allow_patterns + + if ignore_patterns is None: + ignore_patterns = [] + elif isinstance(ignore_patterns, str): + ignore_patterns = [ignore_patterns] + self.ignore_patterns = ignore_patterns + DEFAULT_IGNORE_PATTERNS + + if self.folder_path.is_file(): + raise ValueError( + f"'folder_path' must be a directory, not a file: '{self.folder_path}'." + ) + self.folder_path.mkdir(parents=True, exist_ok=True) + + # Repository + repo_url = self.api.create_repo( + repo_id=repo_id, private=private, repo_type=repo_type, exist_ok=True + ) + self.repo_id = repo_url.repo_id + self.repo_type = repo_type + self.revision = revision + self.token = token + + self.last_uploaded: Dict[Path, float] = {} + self.last_push_time: float | None = None + + if not every > 0: + raise ValueError(f"'every' must be a positive integer, not '{every}'.") + self.lock = Lock() + self.every = every + self.squash_history = squash_history + + logger.info( + f"Scheduled job to push '{self.folder_path}' to '{self.repo_id}' every {self.every} minutes." + ) + self._scheduler_thread = Thread(target=self._run_scheduler, daemon=True) + self._scheduler_thread.start() + atexit.register(self._push_to_hub) + + self.__stopped = False + + def stop(self) -> None: + """Stop the scheduler. + + A stopped scheduler cannot be restarted. Mostly for tests purposes. + """ + self.__stopped = True + + def __enter__(self) -> "CommitScheduler": + return self + + def __exit__(self, exc_type, exc_value, traceback) -> None: + # Upload last changes before exiting + self.trigger().result() + self.stop() + return + + def _run_scheduler(self) -> None: + """Dumb thread waiting between each scheduled push to Hub.""" + while True: + self.last_future = self.trigger() + time.sleep(self.every * 60) + if self.__stopped: + break + + def trigger(self) -> Future: + """Trigger a `push_to_hub` and return a future. + + This method is automatically called every `every` minutes. You can also call it manually to trigger a commit + immediately, without waiting for the next scheduled commit. + """ + return self.api.run_as_future(self._push_to_hub) + + def _push_to_hub(self) -> CommitInfo | None: + if self.__stopped: # If stopped, already scheduled commits are ignored + return None + + logger.info("(Background) scheduled commit triggered.") + try: + value = self.push_to_hub() + if self.squash_history: + logger.info("(Background) squashing repo history.") + self.api.super_squash_history( + repo_id=self.repo_id, repo_type=self.repo_type, branch=self.revision + ) + return value + except Exception as e: + logger.error( + f"Error while pushing to Hub: {e}" + ) # Depending on the setup, error might be silenced + raise + + def push_to_hub(self) -> CommitInfo | None: + """ + Push folder to the Hub and return the commit info. + + + + This method is not meant to be called directly. It is run in the background by the scheduler, respecting a + queue mechanism to avoid concurrent commits. Making a direct call to the method might lead to concurrency + issues. + + + + The default behavior of `push_to_hub` is to assume an append-only folder. It lists all files in the folder and + uploads only changed files. If no changes are found, the method returns without committing anything. If you want + to change this behavior, you can inherit from [`CommitScheduler`] and override this method. This can be useful + for example to compress data together in a single file before committing. For more details and examples, check + out our [integration guide](https://huggingface.co/docs/huggingface_hub/main/en/guides/upload#scheduled-uploads). + """ + # Check files to upload (with lock) + with self.lock: + if self.on_before_commit is not None: + self.on_before_commit() + + logger.debug("Listing files to upload for scheduled commit.") + + # List files from folder (taken from `_prepare_upload_folder_additions`) + relpath_to_abspath = { + path.relative_to(self.folder_path).as_posix(): path + for path in sorted( + self.folder_path.glob("**/*") + ) # sorted to be deterministic + if path.is_file() + } + prefix = f"{self.path_in_repo.strip('/')}/" if self.path_in_repo else "" + + # Filter with pattern + filter out unchanged files + retrieve current file size + files_to_upload: List[_FileToUpload] = [] + for relpath in filter_repo_objects( + relpath_to_abspath.keys(), + allow_patterns=self.allow_patterns, + ignore_patterns=self.ignore_patterns, + ): + local_path = relpath_to_abspath[relpath] + stat = local_path.stat() + if ( + self.last_uploaded.get(local_path) is None + or self.last_uploaded[local_path] != stat.st_mtime + ): + files_to_upload.append( + _FileToUpload( + local_path=local_path, + path_in_repo=prefix + relpath, + size_limit=stat.st_size, + last_modified=stat.st_mtime, + ) + ) + + # Return if nothing to upload + if len(files_to_upload) == 0: + logger.debug("Dropping schedule commit: no changed file to upload.") + return None + + # Convert `_FileToUpload` as `CommitOperationAdd` (=> compute file shas + limit to file size) + logger.debug("Removing unchanged files since previous scheduled commit.") + add_operations = [ + CommitOperationAdd( + # TODO: Cap the file to its current size, even if the user append data to it while a scheduled commit is happening + # (requires an upstream fix for XET-535: `hf_xet` should support `BinaryIO` for upload) + path_or_fileobj=file_to_upload.local_path, + path_in_repo=file_to_upload.path_in_repo, + ) + for file_to_upload in files_to_upload + ] + + # Upload files (append mode expected - no need for lock) + logger.debug("Uploading files for scheduled commit.") + commit_info = self.api.create_commit( + repo_id=self.repo_id, + repo_type=self.repo_type, + operations=add_operations, + commit_message="Scheduled Commit", + revision=self.revision, + ) + + for file in files_to_upload: + self.last_uploaded[file.local_path] = file.last_modified + + self.last_push_time = time.time() + + return commit_info diff --git a/trackio/compression.py b/trackio/compression.py new file mode 100644 index 0000000000000000000000000000000000000000..a6b0a59e46d56237c6cc5da742cfb653fd72648a --- /dev/null +++ b/trackio/compression.py @@ -0,0 +1,169 @@ +from __future__ import annotations + +import gzip +import io +from typing import NoReturn + +from starlette.datastructures import Headers, MutableHeaders +from starlette.types import ASGIApp, Message, Receive, Scope, Send + +try: + import brotli + + HAS_BROTLI = True +except ImportError: + brotli = None + HAS_BROTLI = False + +COMPRESSIBLE_CONTENT_TYPES = ( + "application/json", + "application/javascript", + "application/manifest+json", + "application/xml", + "application/xhtml+xml", + "image/svg+xml", + "text/", +) + + +class CompressionMiddleware: + """Negotiates Brotli, then gzip, then identity based on Accept-Encoding. + + Only text-like content types are compressed, so already-compressed media + (images, audio, video) and zero-copy file sends pass through untouched. + """ + + def __init__( + self, + app: ASGIApp, + minimum_size: int = 512, + gzip_level: int = 6, + brotli_quality: int = 5, + ) -> None: + self.app = app + self.minimum_size = minimum_size + self.gzip_level = gzip_level + self.brotli_quality = brotli_quality + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + if scope["type"] != "http": + await self.app(scope, receive, send) + return + + accept_encoding = Headers(scope=scope).get("Accept-Encoding", "") + responder: _CompressionResponder + if HAS_BROTLI and "br" in accept_encoding: + responder = _BrotliResponder( + self.app, self.minimum_size, self.brotli_quality + ) + elif "gzip" in accept_encoding: + responder = _GZipResponder(self.app, self.minimum_size, self.gzip_level) + else: + responder = _CompressionResponder(self.app, self.minimum_size) + + await responder(scope, receive, send) + + +class _CompressionResponder: + content_encoding: str = "" + + def __init__(self, app: ASGIApp, minimum_size: int) -> None: + self.app = app + self.minimum_size = minimum_size + self.send: Send = _unattached_send + self.initial_message: Message = {} + self.started = False + self.passthrough = True + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + self.send = send + await self.app(scope, receive, self.send_with_compression) + + async def send_with_compression(self, message: Message) -> None: + message_type = message["type"] + if message_type == "http.response.start": + self.initial_message = message + headers = Headers(raw=message["headers"]) + content_type = headers.get("content-type", "") + already_encoded = "content-encoding" in headers + self.passthrough = already_encoded or not content_type.startswith( + COMPRESSIBLE_CONTENT_TYPES + ) + elif message_type == "http.response.body" and self.passthrough: + if not self.started: + self.started = True + await self.send(self.initial_message) + await self.send(message) + elif message_type == "http.response.body" and not self.started: + self.started = True + body = message.get("body", b"") + more_body = message.get("more_body", False) + if len(body) < self.minimum_size and not more_body: + await self.send(self.initial_message) + await self.send(message) + else: + compressed = self.apply_compression(body, more_body=more_body) + headers = MutableHeaders(raw=self.initial_message["headers"]) + headers.add_vary_header("Accept-Encoding") + if compressed != body: + headers["Content-Encoding"] = self.content_encoding + if more_body: + del headers["Content-Length"] + else: + headers["Content-Length"] = str(len(compressed)) + message["body"] = compressed + await self.send(self.initial_message) + await self.send(message) + elif message_type == "http.response.body": + body = message.get("body", b"") + more_body = message.get("more_body", False) + message["body"] = self.apply_compression(body, more_body=more_body) + await self.send(message) + elif message_type == "http.response.pathsend": + await self.send(self.initial_message) + await self.send(message) + + def apply_compression(self, body: bytes, *, more_body: bool) -> bytes: + return body + + +class _GZipResponder(_CompressionResponder): + content_encoding = "gzip" + + def __init__(self, app: ASGIApp, minimum_size: int, compresslevel: int) -> None: + super().__init__(app, minimum_size) + self.buffer = io.BytesIO() + self.file = gzip.GzipFile( + mode="wb", fileobj=self.buffer, compresslevel=compresslevel + ) + + async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: + with self.buffer, self.file: + await super().__call__(scope, receive, send) + + def apply_compression(self, body: bytes, *, more_body: bool) -> bytes: + self.file.write(body) + if not more_body: + self.file.close() + data = self.buffer.getvalue() + self.buffer.seek(0) + self.buffer.truncate() + return data + + +class _BrotliResponder(_CompressionResponder): + content_encoding = "br" + + def __init__(self, app: ASGIApp, minimum_size: int, quality: int) -> None: + super().__init__(app, minimum_size) + self.compressor = brotli.Compressor(quality=quality) + + def apply_compression(self, body: bytes, *, more_body: bool) -> bytes: + data = self.compressor.process(body) + if not more_body: + data += self.compressor.finish() + return data + + +async def _unattached_send(message: Message) -> NoReturn: + raise RuntimeError("send awaitable not set") diff --git a/trackio/context_vars.py b/trackio/context_vars.py new file mode 100644 index 0000000000000000000000000000000000000000..ef1404001b8856446ec2940eee81578d634a51fd --- /dev/null +++ b/trackio/context_vars.py @@ -0,0 +1,21 @@ +import contextvars +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from trackio.run import Run + +current_run: contextvars.ContextVar["Run | None"] = contextvars.ContextVar( + "current_run", default=None +) +current_project: contextvars.ContextVar[str | None] = contextvars.ContextVar( + "current_project", default=None +) +current_server: contextvars.ContextVar[str | None] = contextvars.ContextVar( + "current_server", default=None +) +current_space_id: contextvars.ContextVar[str | None] = contextvars.ContextVar( + "current_space_id", default=None +) +current_server_write_token: contextvars.ContextVar[str | None] = contextvars.ContextVar( + "current_server_write_token", default=None +) diff --git a/trackio/cpu.py b/trackio/cpu.py new file mode 100644 index 0000000000000000000000000000000000000000..e11274786d1f17d7d5415286f2fd79a96f7ae2dc --- /dev/null +++ b/trackio/cpu.py @@ -0,0 +1,303 @@ +import importlib +import threading +import time +import warnings +from typing import TYPE_CHECKING, Any + +from trackio import context_vars + +if TYPE_CHECKING: + from trackio.run import Run + +psutil: Any = None +PSUTIL_AVAILABLE = False +_psutil_lock = threading.Lock() + + +def _ensure_psutil(): + global PSUTIL_AVAILABLE, psutil + if PSUTIL_AVAILABLE: + return psutil + with _psutil_lock: + if PSUTIL_AVAILABLE: + return psutil + try: + psutil = importlib.import_module("psutil") + PSUTIL_AVAILABLE = True + return psutil + except ImportError: + raise ImportError( + "psutil is required for CPU and RAM monitoring. " + "Install it with: pip install psutil" + ) + + +def cpu_available() -> bool: + """ + Check if CPU and RAM monitoring is available. + + Returns True if psutil is installed. + """ + try: + _ensure_psutil() + return True + except ImportError: + return False + except Exception: + return False + + +def collect_cpu_metrics( + prev_disk_counters: Any = None, + prev_net_counters: Any = None, + elapsed: float | None = None, + include_static: bool = True, +) -> dict: + """ + Collect CPU, RAM, disk, network, and sensor metrics using psutil. + + Args: + prev_disk_counters: Previous disk I/O counters for computing read/write rates. + If None, only cumulative values are reported. + prev_net_counters: Previous network I/O counters for computing send/recv rates. + If None, only cumulative values are reported. + elapsed: Seconds since prev_disk_counters and prev_net_counters were captured. + If None or non-positive, cumulative values are reported instead of rates. + include_static: Whether to include mostly static metrics such as CPU + frequency and core counts. + + Returns: + Dictionary of system metrics. + """ + if not PSUTIL_AVAILABLE: + try: + _ensure_psutil() + except ImportError: + return {} + + metrics = {} + + try: + per_core = psutil.cpu_percent(interval=0.1, percpu=True) + for i, pct in enumerate(per_core): + metrics[f"cpu/{i}/utilization"] = pct + if per_core: + metrics["cpu/utilization"] = sum(per_core) / len(per_core) + except Exception: + pass + + if include_static: + try: + cpu_freq = psutil.cpu_freq() + if cpu_freq: + metrics["cpu/frequency"] = cpu_freq.current + if cpu_freq.max > 0: + metrics["cpu/frequency_max"] = cpu_freq.max + except Exception: + pass + + try: + cpu_count_logical = psutil.cpu_count(logical=True) + if cpu_count_logical is not None: + metrics["cpu/count_logical"] = cpu_count_logical + cpu_count_physical = psutil.cpu_count(logical=False) + if cpu_count_physical is not None: + metrics["cpu/count_physical"] = cpu_count_physical + except Exception: + pass + + try: + mem = psutil.virtual_memory() + metrics["memory/used"] = mem.used / (1024**3) + metrics["memory/total"] = mem.total / (1024**3) + metrics["memory/available"] = mem.available / (1024**3) + metrics["memory/percent"] = mem.percent + except Exception: + pass + + try: + swap = psutil.swap_memory() + metrics["swap/used"] = swap.used / (1024**3) + metrics["swap/total"] = swap.total / (1024**3) + metrics["swap/percent"] = swap.percent + except Exception: + pass + + try: + disk = psutil.disk_io_counters() + if disk is not None: + if prev_disk_counters is not None and elapsed and elapsed > 0: + metrics["disk/read_mb_per_sec"] = ( + (disk.read_bytes - prev_disk_counters.read_bytes) + / elapsed + / (1024**2) + ) + metrics["disk/write_mb_per_sec"] = ( + (disk.write_bytes - prev_disk_counters.write_bytes) + / elapsed + / (1024**2) + ) + metrics["disk/read_iops"] = ( + disk.read_count - prev_disk_counters.read_count + ) / elapsed + metrics["disk/write_iops"] = ( + disk.write_count - prev_disk_counters.write_count + ) / elapsed + else: + metrics["disk/read_bytes"] = disk.read_bytes + metrics["disk/write_bytes"] = disk.write_bytes + except Exception: + pass + + try: + net = psutil.net_io_counters() + if net is not None: + if prev_net_counters is not None and elapsed and elapsed > 0: + metrics["network/sent_mb_per_sec"] = ( + (net.bytes_sent - prev_net_counters.bytes_sent) + / elapsed + / (1024**2) + ) + metrics["network/recv_mb_per_sec"] = ( + (net.bytes_recv - prev_net_counters.bytes_recv) + / elapsed + / (1024**2) + ) + else: + metrics["network/sent_bytes"] = net.bytes_sent + metrics["network/recv_bytes"] = net.bytes_recv + except Exception: + pass + + try: + sensors = psutil.sensors_temperatures() + if sensors: + for chip_name, entries in sensors.items(): + for i, entry in enumerate(entries): + label = ( + entry.label.strip() + if entry.label and entry.label.strip() + else f"{chip_name}_{i}" + ) + metrics[f"temp/{label}"] = entry.current + except Exception: + pass + + try: + battery = psutil.sensors_battery() + if battery is not None: + metrics["battery/percent"] = battery.percent + metrics["battery/power_plugged"] = int(battery.power_plugged) + except Exception: + pass + + return metrics + + +class CpuMonitor: + def __init__(self, run: "Run", interval: float = 10.0): + self._run = run + self._interval = interval + self._stop_flag = threading.Event() + self._thread: "threading.Thread | None" = None + self._last_disk_counters: Any = None + self._last_net_counters: Any = None + self._last_time: float | None = None + self._include_static_next = True + + def start(self): + if not PSUTIL_AVAILABLE: + try: + _ensure_psutil() + except ImportError: + warnings.warn( + "auto_log_cpu=True but psutil is not installed. " + "CPU and RAM logging disabled. Install with: pip install psutil" + ) + return + + self._thread = threading.Thread(target=self._monitor_loop, daemon=True) + self._thread.start() + + def stop(self): + self._stop_flag.set() + if self._thread is not None: + self._thread.join(timeout=2.0) + + def _monitor_loop(self): + try: + self._last_disk_counters = psutil.disk_io_counters() + except Exception: + pass + try: + self._last_net_counters = psutil.net_io_counters() + except Exception: + pass + self._last_time = time.monotonic() + + while not self._stop_flag.is_set(): + self._stop_flag.wait(timeout=self._interval) + if self._stop_flag.is_set(): + break + try: + now = time.monotonic() + elapsed = now - self._last_time if self._last_time is not None else None + metrics = collect_cpu_metrics( + prev_disk_counters=self._last_disk_counters, + prev_net_counters=self._last_net_counters, + elapsed=elapsed, + include_static=self._include_static_next, + ) + self._include_static_next = False + try: + self._last_disk_counters = psutil.disk_io_counters() + except Exception: + self._last_disk_counters = None + try: + self._last_net_counters = psutil.net_io_counters() + except Exception: + self._last_net_counters = None + self._last_time = now + if metrics: + self._run.log_system(metrics) + except Exception: + pass + + +def log_cpu(run: "Run | None" = None) -> dict: + """ + Log CPU, RAM, disk, network, and sensor metrics to the current or specified run + as system metrics. + + Args: + run: Optional Run instance. If None, uses current run from context. + + Returns: + dict: The system metrics that were logged. + + Example: + ```python + import trackio + + run = trackio.init(project="my-project") + trackio.log({"loss": 0.5}) + trackio.log_cpu() + ``` + """ + if run is None: + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log_cpu().") + + try: + _ensure_psutil() + except ImportError: + warnings.warn( + "trackio.log_cpu() requires psutil. Install it with: pip install trackio[cpu]" + ) + return {} + + metrics = collect_cpu_metrics() + if metrics: + run.log_system(metrics) + return metrics diff --git a/trackio/deploy.py b/trackio/deploy.py new file mode 100644 index 0000000000000000000000000000000000000000..0cc70398cdba5cfac3d76182a12580043015e459 --- /dev/null +++ b/trackio/deploy.py @@ -0,0 +1,1300 @@ +import importlib.metadata +import io +import json as json_mod +import os +import shutil +import tempfile +import threading +import time +import warnings +from collections import Counter +from importlib.resources import files +from pathlib import Path + +import httpx +import huggingface_hub +from gradio_client import handle_file +from httpx import ReadTimeout +from huggingface_hub import Volume +from huggingface_hub.errors import ( + BucketNotFoundError, + HfHubHTTPError, + RepositoryNotFoundError, +) + +import trackio +from trackio.bucket_storage import ( + create_bucket_if_not_exists, + export_from_bucket_for_static, + upload_project_to_bucket, + upload_project_to_bucket_for_static, +) +from trackio.frontend_config import resolve_frontend_dir +from trackio.pending_uploads import replay_pending_uploads +from trackio.remote_client import RemoteClient +from trackio.sqlite_storage import SQLiteStorage +from trackio.utils import ( + get_or_create_project_hash, + on_spaces, + preprocess_space_and_dataset_ids, + project_media_dir, +) + +SPACE_HOST_URL = "https://{user_name}-{space_name}.hf.space/" +SPACE_URL = "https://huggingface.co/spaces/{space_id}" +_BOLD_ORANGE = "\033[1m\033[38;5;208m" +_RESET = "\033[0m" + + +def raise_if_space_is_frozen_for_logging(space_id: str) -> None: + try: + info = huggingface_hub.HfApi().space_info(space_id) + except RepositoryNotFoundError: + return + if getattr(info, "sdk", None) == "static": + raise RuntimeError( + f"Cannot log to Hugging Face Space '{space_id}' because it has been frozen " + f"(it uses the static SDK: a read-only dashboard with no live Trackio server).\n\n" + f"Use a different space_id for training, or create a new Gradio Trackio Space. " + f"Freezing converts a live Gradio Space to static after a run; a frozen Space " + f'cannot accept new logs. See trackio.sync(..., sdk="static") in the Trackio docs.' + ) + + +def _readme_linked_hub_yaml(dataset_id: str | None) -> str: + if dataset_id is not None: + return f"datasets:\n - {dataset_id}\n" + return "" + + +_CUSTOM_SPACE_FRONTEND_DIR = "trackio_custom_frontend" + + +def _space_app_py(frontend_dir: str | None = None) -> str: + if frontend_dir is None: + return "import trackio\ntrackio.show()\n" + return f'import trackio\ntrackio.show(frontend_dir="{frontend_dir}")\n' + + +def _upload_frontend_folder( + hf_api: huggingface_hub.HfApi, + *, + repo_id: str, + repo_type: str, + folder_path: str | Path, + path_in_repo: str | None = None, +) -> None: + kwargs = { + "repo_id": repo_id, + "repo_type": repo_type, + "folder_path": str(folder_path), + } + if path_in_repo is not None: + kwargs["path_in_repo"] = path_in_repo + hf_api.upload_folder(**kwargs) + + +def _retry_hf_write(op_name: str, fn, retries: int = 4, initial_delay: float = 1.5): + delay = initial_delay + for attempt in range(1, retries + 1): + try: + return fn() + except ReadTimeout: + if attempt == retries: + raise + print( + f"* {op_name} timed out (attempt {attempt}/{retries}). Retrying in {delay:.1f}s..." + ) + time.sleep(delay) + delay = min(delay * 2, 12) + except HfHubHTTPError as e: + status = e.response.status_code if e.response is not None else None + if status is None or status < 500 or attempt == retries: + raise + print( + f"* {op_name} failed with HTTP {status} (attempt {attempt}/{retries}). Retrying in {delay:.1f}s..." + ) + time.sleep(delay) + delay = min(delay * 2, 12) + + +def _get_space_volumes( + space_id: str, hf_api: huggingface_hub.HfApi | None = None +) -> list[Volume]: + """ + Return mounted volumes for a Space. + + `HfApi.get_space_runtime()` does not always populate `volumes`, even when the + mount exists. Fall back to `space_info().runtime.volumes`, which currently + carries the volume metadata for running Spaces. + """ + hf_api = hf_api or huggingface_hub.HfApi() + runtime = hf_api.get_space_runtime(space_id) + if runtime.volumes: + return list(runtime.volumes) + + info = hf_api.space_info(space_id) + if info.runtime and info.runtime.volumes: + return list(info.runtime.volumes) + + return [] + + +def _get_space_bucket_at_data_mount( + space_id: str, hf_api: huggingface_hub.HfApi | None = None +) -> str | None: + for volume in _get_space_volumes(space_id, hf_api=hf_api): + if volume.type == "bucket" and volume.mount_path == "/data": + return volume.source + return None + + +def _get_existing_space_bucket( + space_id: str, hf_api: huggingface_hub.HfApi | None = None +) -> str | None: + """Return the Trackio bucket for a Space, preferring the canonical /data mount.""" + bucket_at_data = _get_space_bucket_at_data_mount(space_id, hf_api=hf_api) + if bucket_at_data is not None: + return bucket_at_data + + for volume in _get_space_volumes(space_id, hf_api=hf_api): + if volume.type == "bucket": + return volume.source + return None + + +def _get_existing_static_space_bucket( + space_id: str, hf_api: huggingface_hub.HfApi | None = None +) -> str | None: + hf_api = hf_api or huggingface_hub.HfApi() + try: + config_path = hf_api.hf_hub_download( + repo_id=space_id, + repo_type="space", + filename="config.json", + ) + except (FileNotFoundError, HfHubHTTPError, OSError, ValueError): + return None + + try: + with open(config_path, encoding="utf-8") as config_file: + config = json_mod.load(config_file) + except (OSError, ValueError, TypeError): + return None + + bucket_id = config.get("bucket_id") + if isinstance(bucket_id, str) and bucket_id: + return bucket_id + return None + + +def _ensure_bucket_mounted_at_data( + space_id: str, + bucket_id: str, + hf_api: huggingface_hub.HfApi | None = None, +) -> None: + hf_api = hf_api or huggingface_hub.HfApi() + existing = _get_space_volumes(space_id, hf_api=hf_api) + already_mounted = any( + v.type == "bucket" and v.source == bucket_id and v.mount_path == "/data" + for v in existing + ) + if not already_mounted: + preserved = [ + v + for v in existing + if not ( + v.type == "bucket" + and (v.source == bucket_id or v.mount_path == "/data") + ) + ] + hf_api.set_space_volumes( + space_id, + preserved + [Volume(type="bucket", source=bucket_id, mount_path="/data")], + ) + print(f"* Attached bucket {bucket_id} at '/data'") + + existing_variables = hf_api.get_space_variables(space_id) + current_trackio_dir = getattr(existing_variables.get("TRACKIO_DIR"), "value", None) + if current_trackio_dir != "/data/trackio": + huggingface_hub.add_space_variable(space_id, "TRACKIO_DIR", "/data/trackio") + current_bucket_id = getattr( + existing_variables.get("TRACKIO_BUCKET_ID"), "value", None + ) + if current_bucket_id != bucket_id: + huggingface_hub.add_space_variable(space_id, "TRACKIO_BUCKET_ID", bucket_id) + + +def _bucket_exists(bucket_id: str, hf_api: huggingface_hub.HfApi | None = None) -> bool: + hf_api = hf_api or huggingface_hub.HfApi() + try: + hf_api.bucket_info(bucket_id) + return True + except BucketNotFoundError: + return False + + +def _find_available_bucket_id( + preferred_bucket_id: str, hf_api: huggingface_hub.HfApi | None = None +) -> str: + hf_api = hf_api or huggingface_hub.HfApi() + if not _bucket_exists(preferred_bucket_id, hf_api): + return preferred_bucket_id + + suffix = 2 + while True: + candidate = f"{preferred_bucket_id}-{suffix}" + if not _bucket_exists(candidate, hf_api): + return candidate + suffix += 1 + + +def resolve_auto_bucket_id( + space_id: str, + preferred_bucket_id: str, + hf_api: huggingface_hub.HfApi | None = None, +) -> str: + """ + Resolve the bucket to use for an auto-generated bucket ID. + + Rules: + - Existing Space with a bucket mounted at /data -> reuse that bucket. + - Existing static Space with a bucket_id in config.json -> reuse that bucket. + - Otherwise -> use the preferred auto bucket ID if free, or a suffixed variant. + """ + hf_api = hf_api or huggingface_hub.HfApi() + try: + info = hf_api.space_info(space_id) + except RepositoryNotFoundError: + pass + else: + existing_bucket_id = _get_existing_space_bucket(space_id, hf_api=hf_api) + if existing_bucket_id is None and getattr(info, "sdk", None) == "static": + existing_bucket_id = _get_existing_static_space_bucket( + space_id, hf_api=hf_api + ) + if existing_bucket_id is not None: + return existing_bucket_id + + bucket_id = _find_available_bucket_id(preferred_bucket_id, hf_api) + if bucket_id != preferred_bucket_id: + print( + f"* Auto-generated bucket {preferred_bucket_id} already exists; " + f"using {bucket_id} instead" + ) + return bucket_id + + +def _get_source_install_dependencies() -> str: + """Get trackio dependencies from pyproject.toml for source installs.""" + try: + import tomllib # noqa: PLC0415 + except ModuleNotFoundError: + import tomli as tomllib # noqa: PLC0415 + + trackio_path = files("trackio") + pyproject_path = Path(trackio_path).parent / "pyproject.toml" + with open(pyproject_path, "rb") as f: + pyproject = tomllib.load(f) + deps = pyproject["project"]["dependencies"] + spaces_deps = ( + pyproject["project"].get("optional-dependencies", {}).get("spaces", []) + ) + mcp_deps = pyproject["project"].get("optional-dependencies", {}).get("mcp", []) + return "\n".join(deps + spaces_deps + mcp_deps) + + +def _get_space_install_requirement() -> str: + return f"trackio[spaces,mcp]=={trackio.__version__}" + + +def _is_trackio_installed_from_source() -> bool: + """Check if trackio is installed from source/editable install vs PyPI.""" + try: + trackio_file = trackio.__file__ + if "site-packages" not in trackio_file and "dist-packages" not in trackio_file: + return True + + dist = importlib.metadata.distribution("trackio") + if dist.files: + files = list(dist.files) + has_pth = any(".pth" in str(f) for f in files) + if has_pth: + return True + + return False + except ( + AttributeError, + importlib.metadata.PackageNotFoundError, + importlib.metadata.MetadataError, + ValueError, + TypeError, + ): + return True + + +def deploy_as_space( + space_id: str, + space_storage: huggingface_hub.SpaceStorage | None = None, + dataset_id: str | None = None, + bucket_id: str | None = None, + private: bool | None = None, + frontend_dir: str | Path | None = None, +): + if on_spaces(): # in case a repo with this function is uploaded to spaces + return + + if dataset_id is not None and bucket_id is not None: + raise ValueError( + "Cannot use bucket volume options together with dataset_id; use one persistence mode." + ) + + trackio_path = files("trackio") + + hf_api = huggingface_hub.HfApi() + + try: + huggingface_hub.create_repo( + space_id, + private=private, + space_sdk="gradio", + space_storage=space_storage, + repo_type="space", + exist_ok=True, + ) + except HfHubHTTPError as e: + if e.response.status_code in [401, 403]: # unauthorized or forbidden + print("Need 'write' access token to create a Spaces repo.") + huggingface_hub.login(add_to_git_credential=False) + huggingface_hub.create_repo( + space_id, + private=private, + space_sdk="gradio", + space_storage=space_storage, + repo_type="space", + exist_ok=True, + ) + else: + raise ValueError(f"Failed to create Space: {e}") + + # We can assume huggingface-hub is available; requirements.txt pins trackio. + # Make sure necessary dependencies are installed by creating a requirements.txt. + is_source_install = _is_trackio_installed_from_source() + resolved_frontend = resolve_frontend_dir(frontend_dir, announce=True) + + if bucket_id is not None: + create_bucket_if_not_exists(bucket_id, private=private) + + with open(Path(trackio_path, "README.md"), "r", encoding="utf-8") as f: + readme_content = f.read() + readme_content = readme_content.replace("sdk_version: {GRADIO_VERSION}\n", "") + readme_content = readme_content.replace("{APP_FILE}", "app.py") + readme_content = readme_content.replace( + "{LINKED_HUB_METADATA}", _readme_linked_hub_yaml(dataset_id) + ) + readme_buffer = io.BytesIO(readme_content.encode("utf-8")) + hf_api.upload_file( + path_or_fileobj=readme_buffer, + path_in_repo="README.md", + repo_id=space_id, + repo_type="space", + ) + + if is_source_install: + requirements_content = _get_source_install_dependencies() + else: + requirements_content = _get_space_install_requirement() + + requirements_buffer = io.BytesIO(requirements_content.encode("utf-8")) + hf_api.upload_file( + path_or_fileobj=requirements_buffer, + path_in_repo="requirements.txt", + repo_id=space_id, + repo_type="space", + ) + + huggingface_hub.utils.disable_progress_bars() + + if is_source_install: + dist_index = ( + Path(trackio.__file__).resolve().parent / "frontend" / "dist" / "index.html" + ) + if not dist_index.is_file() and not resolved_frontend.is_custom: + raise ValueError( + "The Trackio frontend build is missing. From the repository root run " + "`cd trackio/frontend && npm ci && npm run build`, then deploy again." + ) + hf_api.upload_folder( + repo_id=space_id, + repo_type="space", + folder_path=trackio_path, + path_in_repo="trackio", + ignore_patterns=[ + "README.md", + "frontend/node_modules/**", + "frontend/src/**", + "frontend/.gitignore", + "frontend/package.json", + "frontend/package-lock.json", + "frontend/vite.config.js", + "frontend/svelte.config.js", + "**/__pycache__/**", + "*.pyc", + ], + ) + + if resolved_frontend.is_custom: + _upload_frontend_folder( + hf_api, + repo_id=space_id, + repo_type="space", + folder_path=resolved_frontend.path, + path_in_repo=_CUSTOM_SPACE_FRONTEND_DIR, + ) + + app_file_content = _space_app_py( + _CUSTOM_SPACE_FRONTEND_DIR if resolved_frontend.is_custom else None + ) + app_file_buffer = io.BytesIO(app_file_content.encode("utf-8")) + hf_api.upload_file( + path_or_fileobj=app_file_buffer, + path_in_repo="app.py", + repo_id=space_id, + repo_type="space", + ) + + if hf_token := huggingface_hub.utils.get_token(): + huggingface_hub.add_space_secret(space_id, "HF_TOKEN", hf_token) + if bucket_id is not None: + _ensure_bucket_mounted_at_data(space_id, bucket_id, hf_api) + elif dataset_id is not None: + huggingface_hub.add_space_variable(space_id, "TRACKIO_DATASET_ID", dataset_id) + if logo_light_url := os.environ.get("TRACKIO_LOGO_LIGHT_URL"): + huggingface_hub.add_space_variable( + space_id, "TRACKIO_LOGO_LIGHT_URL", logo_light_url + ) + if logo_dark_url := os.environ.get("TRACKIO_LOGO_DARK_URL"): + huggingface_hub.add_space_variable( + space_id, "TRACKIO_LOGO_DARK_URL", logo_dark_url + ) + if plot_order := os.environ.get("TRACKIO_PLOT_ORDER"): + huggingface_hub.add_space_variable(space_id, "TRACKIO_PLOT_ORDER", plot_order) + if theme := os.environ.get("TRACKIO_THEME"): + huggingface_hub.add_space_variable(space_id, "TRACKIO_THEME", theme) + huggingface_hub.add_space_variable(space_id, "GRADIO_MCP_SERVER", "True") + + +def create_space_if_not_exists( + space_id: str, + space_storage: huggingface_hub.SpaceStorage | None = None, + dataset_id: str | None = None, + bucket_id: str | None = None, + private: bool | None = None, + frontend_dir: str | Path | None = None, +) -> bool: + """ + Creates a new Hugging Face Space if it does not exist. Returns True if a + new Space was created, False if an existing Space was found. + + Args: + space_id (`str`): + The ID of the Space to create. + space_storage ([`~huggingface_hub.SpaceStorage`], *optional*): + Choice of persistent storage tier for the Space. + dataset_id (`str`, *optional*): + Deprecated. Use `bucket_id` instead. + bucket_id (`str`, *optional*): + Full Hub bucket id (`namespace/name`) to attach via the Hub volumes API (platform mount). + Sets `TRACKIO_DIR` to the mount path. + private (`bool`, *optional*): + Whether to make the Space private. If `None` (default), the repo will be + public unless the organization's default is private. This value is ignored + if the repo already exists. + """ + if "/" not in space_id: + raise ValueError( + f"Invalid space ID: {space_id}. Must be in the format: username/reponame or orgname/reponame." + ) + if dataset_id is not None and "/" not in dataset_id: + raise ValueError( + f"Invalid dataset ID: {dataset_id}. Must be in the format: username/datasetname or orgname/datasetname." + ) + if bucket_id is not None and "/" not in bucket_id: + raise ValueError( + f"Invalid bucket ID: {bucket_id}. Must be in the format: username/bucketname or orgname/bucketname." + ) + try: + huggingface_hub.repo_info(space_id, repo_type="space") + print( + f"* Found existing space: {_BOLD_ORANGE}{SPACE_URL.format(space_id=space_id)}{_RESET}" + ) + if bucket_id is not None: + create_bucket_if_not_exists(bucket_id, private=private) + _ensure_bucket_mounted_at_data(space_id, bucket_id) + elif dataset_id is not None: + huggingface_hub.add_space_variable( + space_id, "TRACKIO_DATASET_ID", dataset_id + ) + resolved_frontend = resolve_frontend_dir(frontend_dir, announce=False) + if resolved_frontend.is_custom: + deploy_as_space( + space_id, + space_storage, + dataset_id, + bucket_id, + private, + frontend_dir=frontend_dir, + ) + return False + except RepositoryNotFoundError: + pass + except HfHubHTTPError as e: + if e.response.status_code in [401, 403]: # unauthorized or forbidden + print("Need 'write' access token to create a Spaces repo.") + huggingface_hub.login(add_to_git_credential=False) + else: + raise ValueError(f"Failed to create Space: {e}") + + print( + f"* Creating new space: {_BOLD_ORANGE}{SPACE_URL.format(space_id=space_id)}{_RESET}" + ) + deploy_as_space( + space_id, + space_storage, + dataset_id, + bucket_id, + private, + frontend_dir=frontend_dir, + ) + threading.Thread( + target=_warn_if_space_build_fails, args=(space_id,), daemon=True + ).start() + return True + + +def space_is_running(space_id: str) -> bool: + try: + info = huggingface_hub.HfApi().space_info(space_id, timeout=30) + return bool(info.runtime) and str(info.runtime.stage) == "RUNNING" + except Exception: + return False + + +def _warn_if_space_build_fails(space_id: str, timeout: int = 600) -> None: + hf_api = huggingface_hub.HfApi() + failure_stages = frozenset( + ("NO_APP_FILE", "CONFIG_ERROR", "BUILD_ERROR", "RUNTIME_ERROR") + ) + start = time.time() + while time.time() - start < timeout: + try: + info = hf_api.space_info(space_id, timeout=30) + if info.runtime: + stage = str(info.runtime.stage) + if stage in failure_stages: + print( + f"\n* WARNING: Space {space_id} failed to build (stage: {stage}). " + f"Logs are being saved to the Bucket and will appear once the Space " + f"is fixed; see the build logs at {SPACE_URL.format(space_id=space_id)}" + ) + return + if stage == "RUNNING": + return + except Exception: + pass + time.sleep(10) + + +def _wait_until_space_running(space_id: str, timeout: int = 300) -> None: + hf_api = huggingface_hub.HfApi() + start = time.time() + delay = 2 + request_timeout = 45.0 + failure_stages = frozenset( + ("NO_APP_FILE", "CONFIG_ERROR", "BUILD_ERROR", "RUNTIME_ERROR") + ) + while time.time() - start < timeout: + try: + info = hf_api.space_info(space_id, timeout=request_timeout) + if info.runtime: + stage = str(info.runtime.stage) + if stage in failure_stages: + raise RuntimeError( + f"Space {space_id} entered terminal stage {stage}. " + "Fix README.md or app files; see build logs on the Hub." + ) + if stage == "RUNNING": + return + except RuntimeError: + raise + except (huggingface_hub.utils.HfHubHTTPError, httpx.RequestError): + pass + time.sleep(delay) + delay = min(delay * 1.5, 15) + raise TimeoutError( + f"Space {space_id} did not reach RUNNING within {timeout}s. " + "Check status and build logs on the Hub." + ) + + +def wait_until_space_exists( + space_id: str, +) -> None: + """ + Blocks the current thread until the Space exists. + + Args: + space_id (`str`): + The ID of the Space to wait for. + + Raises: + `TimeoutError`: If waiting for the Space takes longer than expected. + """ + hf_api = huggingface_hub.HfApi() + delay = 1 + for _ in range(30): + try: + hf_api.space_info(space_id) + return + except (huggingface_hub.utils.HfHubHTTPError, httpx.RequestError): + time.sleep(delay) + delay = min(delay * 2, 60) + raise TimeoutError("Waiting for space to exist took longer than expected") + + +def upload_db_to_space(project: str, space_id: str, force: bool = False) -> None: + """ + Uploads the database of a local Trackio project to a Hugging Face Space. + + This uses the Trackio remote client so newer Trackio Spaces can speak the direct + HTTP API while older Gradio-based Spaces still work through `gradio_client`. + + Args: + project (`str`): + The name of the project to upload. + space_id (`str`): + The ID of the Space to upload to. + force (`bool`, *optional*, defaults to `False`): + If `True`, overwrites the existing database without prompting. If `False`, + prompts for confirmation. + """ + db_path = SQLiteStorage.get_project_db_path(project) + client = RemoteClient( + space_id, + hf_token=huggingface_hub.utils.get_token(), + httpx_kwargs={"timeout": 90}, + ) + + if not force: + try: + existing_projects = client.predict(api_name="/get_all_projects") + if project in existing_projects: + response = input( + f"Database for project '{project}' already exists on Space '{space_id}'. " + f"Overwrite it? (y/N): " + ) + if response.lower() not in ["y", "yes"]: + print("* Upload cancelled.") + return + except Exception as e: + print(f"* Warning: Could not check if project exists on Space: {e}") + print("* Proceeding with upload...") + + client.predict( + api_name="/upload_db_to_space", + project=project, + uploaded_db=handle_file(db_path), + hf_token=huggingface_hub.utils.get_token(), + ) + + +SYNC_BATCH_SIZE = 500 + + +def _replay_pending_uploads( + project: str, + client: "RemoteClient", + hf_token: str | None, +) -> None: + """Replay queued `pending_uploads` rows for `project` via `client` — the + out-of-Run sync path (`trackio sync`); see `replay_pending_uploads` for the + per-kind routing and clearing semantics. + """ + pending_uploads = SQLiteStorage.get_pending_uploads(project) + if not pending_uploads: + return + + def _warn_missing(count: int, sample: str) -> None: + print( + f" Warning: dropping {count} pending upload(s) whose local files " + f"no longer exist (e.g. {sample!r})." + ) + + replay_pending_uploads( + pending_uploads, + project, + predict=client.predict, + hf_token=hf_token, + warn_missing=_warn_missing, + verbose=True, + ) + + +def sync_incremental( + project: str, + space_id: str, + private: bool | None = None, + pending_only: bool = False, + frontend_dir: str | Path | None = None, +) -> None: + """ + Syncs a local Trackio project to a Space via the bulk_log API endpoints + instead of uploading the entire DB file. Supports incremental sync. + + Args: + project: The name of the project to sync. + space_id: The HF Space ID to sync to. + private: Whether to make the Space private if creating. + pending_only: If True, only sync rows tagged with space_id (pending data). + """ + print( + f"* Syncing project '{project}' to: {SPACE_URL.format(space_id=space_id)} (please wait...)" + ) + create_space_if_not_exists(space_id, private=private, frontend_dir=frontend_dir) + wait_until_space_exists(space_id) + hf_token = huggingface_hub.utils.get_token() + expected_run_counts: Counter[str] = Counter() + + client = RemoteClient( + space_id, + hf_token=hf_token, + httpx_kwargs={"timeout": 90}, + ) + + if pending_only: + pending_logs = SQLiteStorage.get_pending_logs(project) + if pending_logs: + logs = pending_logs["logs"] + expected_run_counts.update(log["run"] for log in logs) + for i in range(0, len(logs), SYNC_BATCH_SIZE): + batch = logs[i : i + SYNC_BATCH_SIZE] + print( + f" Syncing metrics: {min(i + SYNC_BATCH_SIZE, len(logs))}/{len(logs)}..." + ) + client.predict(api_name="/bulk_log", logs=batch, hf_token=hf_token) + SQLiteStorage.clear_pending_logs(project, pending_logs["ids"]) + + pending_sys = SQLiteStorage.get_pending_system_logs(project) + if pending_sys: + logs = pending_sys["logs"] + for i in range(0, len(logs), SYNC_BATCH_SIZE): + batch = logs[i : i + SYNC_BATCH_SIZE] + print( + f" Syncing system metrics: {min(i + SYNC_BATCH_SIZE, len(logs))}/{len(logs)}..." + ) + client.predict( + api_name="/bulk_log_system", logs=batch, hf_token=hf_token + ) + SQLiteStorage.clear_pending_system_logs(project, pending_sys["ids"]) + + _replay_pending_uploads(project, client, hf_token) + else: + all_logs = SQLiteStorage.get_all_logs_for_sync(project) + if all_logs: + expected_run_counts.update(log["run"] for log in all_logs) + for i in range(0, len(all_logs), SYNC_BATCH_SIZE): + batch = all_logs[i : i + SYNC_BATCH_SIZE] + print( + f" Syncing metrics: {min(i + SYNC_BATCH_SIZE, len(all_logs))}/{len(all_logs)}..." + ) + client.predict(api_name="/bulk_log", logs=batch, hf_token=hf_token) + + all_sys_logs = SQLiteStorage.get_all_system_logs_for_sync(project) + if all_sys_logs: + for i in range(0, len(all_sys_logs), SYNC_BATCH_SIZE): + batch = all_sys_logs[i : i + SYNC_BATCH_SIZE] + print( + f" Syncing system metrics: {min(i + SYNC_BATCH_SIZE, len(all_sys_logs))}/{len(all_sys_logs)}..." + ) + client.predict( + api_name="/bulk_log_system", logs=batch, hf_token=hf_token + ) + + _wait_for_remote_sync(client, project, expected_run_counts) + SQLiteStorage.set_project_metadata(project, "space_id", space_id) + print( + f"* Synced successfully to space: {_BOLD_ORANGE}{SPACE_URL.format(space_id=space_id)}{_RESET}" + ) + + +def _build_remote_client_with_retry( + space_id: str, + timeout: int = 360, + verbose: bool = False, +) -> RemoteClient: + deadline = time.time() + timeout + delay = 2 + last_error: Exception | None = None + while time.time() < deadline: + try: + return RemoteClient( + space_id, + hf_token=huggingface_hub.utils.get_token(), + verbose=verbose, + httpx_kwargs={"timeout": 90}, + ) + except (ValueError, ConnectionError) as e: + last_error = e + time.sleep(delay) + delay = min(delay * 1.5, 15) + raise ConnectionError( + f"Could not connect to Space '{space_id}' within {timeout}s: {last_error}" + ) + + +def _wait_for_remote_sync( + client: RemoteClient, + project: str, + expected_run_counts: Counter[str], + timeout: int = 180, +) -> None: + if not expected_run_counts: + return + + deadline = time.time() + timeout + delay = 2 + last_error: Exception | None = None + pending = dict(expected_run_counts) + + while time.time() < deadline and pending: + completed = [] + for run_name, expected_num_logs in pending.items(): + try: + summary = client.predict( + project=project, run=run_name, api_name="/get_run_summary" + ) + if summary.get("num_logs") == expected_num_logs: + completed.append(run_name) + except Exception as e: + last_error = e + for run_name in completed: + pending.pop(run_name, None) + if pending: + time.sleep(delay) + delay = min(delay * 1.5, 15) + + if pending: + raise TimeoutError( + f"Remote sync for project '{project}' did not become visible for runs " + f"{sorted(pending.items())} within {timeout}s. " + f"Last error: {last_error!r}" + ) + + +def upload_dataset_for_static( + project: str, + dataset_id: str, + private: bool | None = None, +) -> None: + hf_api = huggingface_hub.HfApi() + + try: + huggingface_hub.create_repo( + dataset_id, + private=private, + repo_type="dataset", + exist_ok=True, + ) + except HfHubHTTPError as e: + if e.response.status_code in [401, 403]: + print("Need 'write' access token to create a Dataset repo.") + huggingface_hub.login(add_to_git_credential=False) + huggingface_hub.create_repo( + dataset_id, + private=private, + repo_type="dataset", + exist_ok=True, + ) + else: + raise ValueError(f"Failed to create Dataset: {e}") + + with tempfile.TemporaryDirectory() as tmp_dir: + output_dir = Path(tmp_dir) + SQLiteStorage.export_for_static_space(project, output_dir) + + media_dir = project_media_dir(project) + if media_dir.exists(): + dest = output_dir / "media" + shutil.copytree(media_dir, dest) + + _retry_hf_write( + "Dataset upload", + lambda: hf_api.upload_folder( + repo_id=dataset_id, + repo_type="dataset", + folder_path=str(output_dir), + ), + ) + + print(f"* Dataset uploaded: https://huggingface.co/datasets/{dataset_id}") + + +def deploy_as_static_space( + space_id: str, + dataset_id: str | None, + project: str, + bucket_id: str | None = None, + private: bool | None = None, + hf_token: str | None = None, + frontend_dir: str | Path | None = None, +) -> None: + if on_spaces(): + return + + if private is True: + raise ValueError( + "private=True is not supported for static Trackio Spaces. Static Spaces " + "run entirely in the browser, so their snapshot data must be public. " + "Use sdk='gradio' for a private dashboard." + ) + hf_api = huggingface_hub.HfApi() + + try: + huggingface_hub.create_repo( + space_id, + private=False, + space_sdk="static", + repo_type="space", + exist_ok=True, + ) + except HfHubHTTPError as e: + if e.response.status_code in [401, 403]: + print("Need 'write' access token to create a Spaces repo.") + huggingface_hub.login(add_to_git_credential=False) + huggingface_hub.create_repo( + space_id, + private=False, + space_sdk="static", + repo_type="space", + exist_ok=True, + ) + else: + raise ValueError(f"Failed to create Space: {e}") + + linked = _readme_linked_hub_yaml(dataset_id) + readme_content = ( + f"---\nemoji: 🎯\nsdk: static\npinned: false\ntags:\n - trackio\n{linked}---\n" + ) + _retry_hf_write( + "Static Space README upload", + lambda: hf_api.upload_file( + path_or_fileobj=io.BytesIO(readme_content.encode("utf-8")), + path_in_repo="README.md", + repo_id=space_id, + repo_type="space", + ), + ) + + resolved_frontend = resolve_frontend_dir(frontend_dir, announce=True) + + _retry_hf_write( + "Static Space frontend upload", + lambda: hf_api.upload_folder( + repo_id=space_id, + repo_type="space", + folder_path=str(resolved_frontend.path), + ), + ) + + config = { + "mode": "static", + "project": project, + "private": bool(private), + } + if bucket_id is not None: + config["bucket_id"] = bucket_id + if dataset_id is not None: + config["dataset_id"] = dataset_id + if hf_token is not None: + warnings.warn( + "`hf_token` is ignored by deploy_as_static_space() for static Space " + "deployment and will be removed in a future release.", + DeprecationWarning, + stacklevel=2, + ) + + _retry_hf_write( + "Static Space config upload", + lambda: hf_api.upload_file( + path_or_fileobj=io.BytesIO(json_mod.dumps(config).encode("utf-8")), + path_in_repo="config.json", + repo_id=space_id, + repo_type="space", + ), + ) + + assets_dir = Path(trackio.__file__).resolve().parent / "assets" + if assets_dir.is_dir(): + _retry_hf_write( + "Static Space assets upload", + lambda: hf_api.upload_folder( + repo_id=space_id, + repo_type="space", + folder_path=str(assets_dir), + path_in_repo="static/trackio", + ), + ) + + print( + f"* Static Space deployed: {_BOLD_ORANGE}{SPACE_URL.format(space_id=space_id)}{_RESET}" + ) + + +def sync( + project: str, + space_id: str | None = None, + private: bool | None = None, + force: bool = False, + run_in_background: bool = False, + sdk: str = "gradio", + dataset_id: str | None = None, + bucket_id: str | None = None, + frontend_dir: str | Path | None = None, +) -> str: + """ + Syncs a local Trackio project's database to a Hugging Face Space. + If the Space does not exist, it will be created. Local data is never deleted. + + **Freezing:** Passing ``sdk="static"`` deploys a static Space backed by an HF Bucket + (read-only dashboard, no Gradio server). You can sync the same project again later to + refresh that static Space. If you want a one-time snapshot of an existing Gradio Space, + use ``freeze()`` instead. + + Args: + project (`str`): The name of the project to upload. + space_id (`str`, *optional*): The ID of the Space to upload to (e.g., `"username/space_id"`). + If not provided, checks project metadata first, then generates a random space_id. + private (`bool`, *optional*): + Whether to make the Space private. If None (default), the repo will be + public unless the organization's default is private. This value is ignored + if the repo already exists. Not supported with ``sdk="static"`` because + static Trackio dashboards read snapshot data directly from the browser. + force (`bool`, *optional*, defaults to `False`): + If `True`, overwrite the existing database without prompting for confirmation. + If `False`, prompt the user before overwriting an existing database. + run_in_background (`bool`, *optional*, defaults to `False`): + If `True`, the Space creation and database upload will be run in a background thread. + If `False`, all the steps will be run synchronously. + sdk (`str`, *optional*, defaults to `"gradio"`): + The type of Space to deploy. `"gradio"` deploys a Gradio Space with a live + server. `"static"` freezes the Space: deploys a static Space that reads from an HF Bucket + (no server needed). + dataset_id (`str`, *optional*): + Deprecated. Use `bucket_id` instead. + bucket_id (`str`, *optional*): + The ID of the HF Bucket to sync to. By default, a bucket is auto-generated + from the space_id. + Returns: + `str`: The Space ID of the synced project. + """ + if sdk not in ("gradio", "static"): + raise ValueError(f"sdk must be 'gradio' or 'static', got '{sdk}'") + if sdk == "static" and private is True: + raise ValueError( + "private=True is not supported for static Trackio Spaces. Static Spaces " + "run entirely in the browser, so their snapshot data must be public. " + "Use sdk='gradio' for a private dashboard." + ) + bucket_id_was_explicit = bucket_id is not None + + if space_id is None: + space_id = SQLiteStorage.get_space_id(project) + if space_id is None: + space_id = f"{project}-{get_or_create_project_hash(project)}" + space_id, dataset_id, bucket_id = preprocess_space_and_dataset_ids( + space_id, dataset_id, bucket_id + ) + if dataset_id is None and bucket_id is not None and not bucket_id_was_explicit: + bucket_id = resolve_auto_bucket_id(space_id, bucket_id) + + def _do_sync(): + try: + info = huggingface_hub.HfApi().space_info(space_id) + existing_sdk = info.sdk + if existing_sdk and existing_sdk != sdk: + raise ValueError( + f"Space '{space_id}' is a '{existing_sdk}' Space but sdk='{sdk}' was requested. " + f"The sdk must match the existing Space type." + ) + except RepositoryNotFoundError: + pass + + if sdk == "static": + if dataset_id is not None: + upload_dataset_for_static(project, dataset_id, private=False) + deploy_as_static_space( + space_id, + dataset_id, + project, + private=False, + frontend_dir=frontend_dir, + ) + elif bucket_id is not None: + create_bucket_if_not_exists(bucket_id, private=False) + upload_project_to_bucket_for_static(project, bucket_id) + print( + f"* Project data uploaded to bucket: https://huggingface.co/buckets/{bucket_id}" + ) + deploy_as_static_space( + space_id, + None, + project, + bucket_id=bucket_id, + private=False, + frontend_dir=frontend_dir, + ) + else: + if bucket_id is not None: + create_bucket_if_not_exists(bucket_id, private=private) + upload_project_to_bucket(project, bucket_id) + print( + f"* Project data uploaded to bucket: https://huggingface.co/buckets/{bucket_id}" + ) + create_space_if_not_exists( + space_id, + bucket_id=bucket_id, + private=private, + frontend_dir=frontend_dir, + ) + _wait_until_space_running(space_id) + _wait_for_remote_sync( + _build_remote_client_with_retry(space_id), + project, + Counter( + log["run"] + for log in SQLiteStorage.get_all_logs_for_sync(project) + ), + ) + else: + sync_incremental( + project, + space_id, + private=private, + pending_only=False, + frontend_dir=frontend_dir, + ) + SQLiteStorage.set_project_metadata(project, "space_id", space_id) + + if run_in_background: + threading.Thread(target=_do_sync).start() + else: + _do_sync() + return space_id + + +def _get_source_bucket(space_id: str) -> str: + bucket_id = _get_existing_space_bucket(space_id) + if bucket_id is not None: + _ensure_bucket_mounted_at_data(space_id, bucket_id) + return bucket_id + raise ValueError( + f"Space '{space_id}' has no bucket mounted at '/data'. " + f"freeze() requires the source Space to use bucket storage." + ) + + +def freeze( + space_id: str, + project: str, + new_space_id: str | None = None, + private: bool | None = None, + bucket_id: str | None = None, + frontend_dir: str | Path | None = None, +) -> str: + """ + Creates a new static Hugging Face Space containing a read-only snapshot of + the data for the specified project from the source Gradio Space. The data is + read from the bucket attached to the source Space at freeze time. The original + Space is not modified, and the new static Space does not automatically reflect + metrics uploaded to the original Gradio Space after the freeze completes. + + Args: + space_id (`str`): + The ID of the source Gradio Space (e.g., `"username/my-space"` or a + short repo name with the logged-in namespace inferred, like `init()`). + Must be a Gradio Space with a bucket mounted at `/data`. + project (`str`): + The name of the project whose data to include in the frozen Space. + new_space_id (`str`, *optional*): + The ID for the new static Space. If not provided, defaults to + `"{space_id}_static"`. + private (`bool`, *optional*): + Not supported. Frozen static dashboards read snapshot data directly + from the browser, so the destination snapshot must be public. + bucket_id (`str`, *optional*): + The ID of the HF Bucket for the new static Space's data storage. + If not provided, one is auto-generated from the new Space ID. + + Returns: + `str`: The Space ID of the newly created static Space. + """ + if private is True: + raise ValueError( + "private=True is not supported for frozen static Trackio Spaces. Static " + "Spaces run entirely in the browser, so their snapshot data must be " + "public. Use a Gradio Space if the frozen dashboard must stay private." + ) + space_id, _, _ = preprocess_space_and_dataset_ids(space_id, None, None) + + try: + info = huggingface_hub.HfApi().space_info(space_id) + if info.sdk != "gradio": + raise ValueError( + f"Space '{space_id}' is not a Gradio Space (sdk='{info.sdk}'). " + f"freeze() requires a Gradio Space as the source." + ) + except RepositoryNotFoundError: + raise ValueError( + f"Space '{space_id}' not found. Provide an existing Gradio Space ID." + ) + + source_bucket_id = _get_source_bucket(space_id) + print(f"* Reading project data from bucket: {source_bucket_id}") + + bucket_id_was_explicit = bucket_id is not None + + if new_space_id is None: + new_space_id = f"{space_id}_static" + new_space_id, _dataset_id, bucket_id = preprocess_space_and_dataset_ids( + new_space_id, None, bucket_id + ) + if bucket_id is not None and not bucket_id_was_explicit: + bucket_id = resolve_auto_bucket_id(new_space_id, bucket_id) + + hf_api = huggingface_hub.HfApi() + try: + dest_info = hf_api.space_info(new_space_id) + tags = dest_info.tags or [] + if dest_info.sdk != "static" or "trackio" not in tags: + raise ValueError( + f"Space '{new_space_id}' already exists and is not a Trackio static Space " + f"(sdk='{dest_info.sdk}', tags={tags}). Choose a different new_space_id " + f"or delete the existing Space first." + ) + except RepositoryNotFoundError: + pass + + create_bucket_if_not_exists(bucket_id, private=False) + export_from_bucket_for_static(source_bucket_id, bucket_id, project) + print( + f"* Project data uploaded to bucket: https://huggingface.co/buckets/{bucket_id}" + ) + deploy_as_static_space( + new_space_id, + None, + project, + bucket_id=bucket_id, + private=False, + frontend_dir=frontend_dir, + ) + return new_space_id diff --git a/trackio/dummy_commit_scheduler.py b/trackio/dummy_commit_scheduler.py new file mode 100644 index 0000000000000000000000000000000000000000..6068fe8a36b8647ade92dd300af0855f4338826f --- /dev/null +++ b/trackio/dummy_commit_scheduler.py @@ -0,0 +1,19 @@ +from concurrent.futures import Future + + +class DummyCommitSchedulerLock: + def __enter__(self): + return None + + def __exit__(self, exception_type, exception_value, exception_traceback): + pass + + +class DummyCommitScheduler: + def __init__(self): + self.lock = DummyCommitSchedulerLock() + + def trigger(self) -> Future: + fut: Future = Future() + fut.set_result(None) + return fut diff --git a/trackio/exceptions.py b/trackio/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..189f56d718245b65790ff43e14005b846aad2402 --- /dev/null +++ b/trackio/exceptions.py @@ -0,0 +1,2 @@ +class TrackioAPIError(Exception): + pass diff --git a/trackio/fragments.py b/trackio/fragments.py new file mode 100644 index 0000000000000000000000000000000000000000..4e70507516ace65cb1e4221482f384853001ffa2 --- /dev/null +++ b/trackio/fragments.py @@ -0,0 +1,368 @@ +"""Append-only JSONL fragments used as a durable fallback for metric logging. + +Fragments are immutable JSONL files, one writer (process) per subdirectory, so +concurrent training processes never contend on a shared file. They are written +either to a Hugging Face Bucket inbox (when a Space is unreachable) or to a +local inbox directory (when SQLite is unsafe, e.g. on network filesystems), and +are later imported into the project SQLite database by the process that owns it +(the Space or the dashboard server). Records carry the same ``log_id``/ +``alert_id`` UUIDs as the HTTP logging endpoints, and imports use +``INSERT OR IGNORE``, so importing a fragment is idempotent: fragments are +deleted only after a successful import, and re-importing after a crash is +harmless. +""" + +import tempfile +import threading +import uuid +from collections.abc import Callable +from pathlib import Path +from typing import Any + +import huggingface_hub +import orjson + +from trackio import utils +from trackio.typehints import AlertEntry, LogEntry, SystemLogEntry + +FRAGMENT_VERSION = 1 +INBOX_DIR_NAME = "inbox" +BUCKET_INBOX_PREFIX = "trackio/inbox" +BUCKET_MEDIA_PREFIX = "trackio/media" + +METRIC_KIND = "metric" +SYSTEM_METRIC_KIND = "system_metric" +ALERT_KIND = "alert" +KINDS = {METRIC_KIND, SYSTEM_METRIC_KIND, ALERT_KIND} + + +def local_inbox_dir() -> Path: + return utils.TRACKIO_DIR / INBOX_DIR_NAME + + +def metric_record(entry: LogEntry | dict) -> dict: + return { + "v": FRAGMENT_VERSION, + "kind": METRIC_KIND, + "project": entry["project"], + "run": entry["run"], + "run_id": entry.get("run_id"), + "metrics": utils.serialize_values(entry.get("metrics") or {}), + "step": entry.get("step"), + "timestamp": entry.get("timestamp"), + "config": utils.serialize_values(entry.get("config")) + if entry.get("config") + else None, + "log_id": entry.get("log_id"), + } + + +def system_metric_record(entry: SystemLogEntry | dict) -> dict: + return { + "v": FRAGMENT_VERSION, + "kind": SYSTEM_METRIC_KIND, + "project": entry["project"], + "run": entry["run"], + "run_id": entry.get("run_id"), + "metrics": utils.serialize_values(entry.get("metrics") or {}), + "timestamp": entry.get("timestamp"), + "log_id": entry.get("log_id"), + } + + +def alert_record(entry: AlertEntry | dict) -> dict: + return { + "v": FRAGMENT_VERSION, + "kind": ALERT_KIND, + "project": entry["project"], + "run": entry["run"], + "run_id": entry.get("run_id"), + "title": entry["title"], + "text": entry.get("text"), + "level": entry.get("level"), + "step": entry.get("step"), + "timestamp": entry.get("timestamp"), + "alert_id": entry.get("alert_id"), + } + + +def bucket_media_path( + project: str, + run: str | None, + step: int | None, + relative_path: str | None, + filename: str, +) -> str: + parts = [BUCKET_MEDIA_PREFIX, utils.canonical_project_name(project)] + if run: + parts.append(run) + if step is not None: + parts.append(str(step)) + else: + parts.append("files") + if relative_path: + parts.append(str(relative_path)) + parts.append(filename) + return "/".join(parts) + + +class FragmentWriter: + """Writes immutable JSONL fragments for a single writer (process).""" + + def __init__(self, writer_id: str | None = None): + self.writer_id = writer_id or uuid.uuid4().hex[:16] + self._seq = 0 + self._lock = threading.Lock() + + def _next_fragment_name(self) -> str: + with self._lock: + name = f"{self._seq:08d}.jsonl" + self._seq += 1 + return name + + @staticmethod + def serialize_records(records: list[dict]) -> bytes: + return b"".join(orjson.dumps(record) + b"\n" for record in records) + + def write_local( + self, records: list[dict], inbox_dir: Path | None = None + ) -> Path | None: + if not records: + return None + inbox = inbox_dir or local_inbox_dir() + writer_dir = inbox / self.writer_id + fragment_path = writer_dir / self._next_fragment_name() + data = self.serialize_records(records) + for attempt in range(3): + writer_dir.mkdir(parents=True, exist_ok=True) + try: + with tempfile.NamedTemporaryFile( + mode="wb", dir=writer_dir, suffix=".tmp", delete=False + ) as tmp: + tmp.write(data) + tmp_path = Path(tmp.name) + tmp_path.replace(fragment_path) + return fragment_path + except FileNotFoundError: + if attempt == 2 or writer_dir.exists(): + raise + + def write_to_bucket(self, records: list[dict], bucket_id: str) -> str | None: + if not records: + return None + remote_path = ( + f"{BUCKET_INBOX_PREFIX}/{self.writer_id}/{self._next_fragment_name()}" + ) + huggingface_hub.batch_bucket_files( + bucket_id, + add=[(self.serialize_records(records), remote_path)], + token=huggingface_hub.utils.get_token(), + ) + return remote_path + + +def parse_fragment_bytes(data: bytes) -> list[dict]: + records = [] + for line in data.splitlines(): + line = line.strip() + if not line: + continue + try: + record = orjson.loads(line) + except orjson.JSONDecodeError: + continue + if isinstance(record, dict) and record.get("kind") in KINDS: + records.append(record) + return records + + +def _group_by_run(records: list[dict]) -> dict[tuple, list[dict]]: + grouped: dict[tuple, list[dict]] = {} + for record in records: + key = (record.get("project"), record.get("run"), record.get("run_id")) + grouped.setdefault(key, []).append(record) + return grouped + + +def import_records(records: list[dict]) -> int: + from trackio.sqlite_storage import SQLiteStorage # noqa: PLC0415 + + metric_records = [r for r in records if r.get("kind") == METRIC_KIND] + system_records = [r for r in records if r.get("kind") == SYSTEM_METRIC_KIND] + alert_records = [r for r in records if r.get("kind") == ALERT_KIND] + imported = 0 + + for (project, run, run_id), group in _group_by_run(metric_records).items(): + if not project or not run: + continue + config = next((r["config"] for r in group if r.get("config")), None) + has_timestamps = all(r.get("timestamp") for r in group) + SQLiteStorage.bulk_log( + project=project, + run=run, + run_id=run_id, + metrics_list=[r.get("metrics") or {} for r in group], + steps=[r.get("step") for r in group], + timestamps=[r["timestamp"] for r in group] if has_timestamps else None, + config=config, + log_ids=[r.get("log_id") for r in group], + ) + imported += len(group) + + for (project, run, run_id), group in _group_by_run(system_records).items(): + if not project or not run: + continue + has_timestamps = all(r.get("timestamp") for r in group) + SQLiteStorage.bulk_log_system( + project=project, + run=run, + run_id=run_id, + metrics_list=[r.get("metrics") or {} for r in group], + timestamps=[r["timestamp"] for r in group] if has_timestamps else None, + log_ids=[r.get("log_id") for r in group], + ) + imported += len(group) + + for (project, run, run_id), group in _group_by_run(alert_records).items(): + if not project or not run: + continue + has_timestamps = all(r.get("timestamp") for r in group) + SQLiteStorage.bulk_alert( + project=project, + run=run, + run_id=run_id, + titles=[r.get("title") or "" for r in group], + texts=[r.get("text") for r in group], + levels=[r.get("level") or "WARN" for r in group], + steps=[r.get("step") for r in group], + timestamps=[r["timestamp"] for r in group] if has_timestamps else None, + alert_ids=[r.get("alert_id") for r in group], + ) + imported += len(group) + + return imported + + +def import_inbox_dir(inbox_dir: Path | None = None) -> int: + inbox = inbox_dir or local_inbox_dir() + if not inbox.exists(): + return 0 + imported = 0 + for fragment_path in sorted(inbox.rglob("*.jsonl")): + try: + data = fragment_path.read_bytes() + except OSError: + continue + records = parse_fragment_bytes(data) + if records: + imported += import_records(records) + try: + fragment_path.unlink() + except OSError: + pass + for writer_dir in inbox.glob("*"): + if writer_dir.is_dir(): + try: + writer_dir.rmdir() + except OSError: + pass + return imported + + +def list_bucket_inbox_paths(bucket_id: str) -> list[str]: + try: + items = huggingface_hub.list_bucket_tree( + bucket_id, + prefix=BUCKET_INBOX_PREFIX, + recursive=True, + token=huggingface_hub.utils.get_token(), + ) + except Exception: + return [] + return sorted( + item.path + for item in items + if getattr(item, "type", None) == "file" + and getattr(item, "path", "").endswith(".jsonl") + ) + + +def import_inbox_from_bucket(bucket_id: str) -> int: + paths = list_bucket_inbox_paths(bucket_id) + if not paths: + return 0 + imported = 0 + consumed: list[str] = [] + with tempfile.TemporaryDirectory() as tmp_dir: + for i, remote_path in enumerate(paths): + local_path = Path(tmp_dir) / f"{i}.jsonl" + try: + huggingface_hub.download_bucket_files( + bucket_id, + files=[(remote_path, str(local_path))], + token=huggingface_hub.utils.get_token(), + ) + records = parse_fragment_bytes(local_path.read_bytes()) + except Exception: + continue + if records: + imported += import_records(records) + consumed.append(remote_path) + if consumed: + try: + huggingface_hub.batch_bucket_files( + bucket_id, + delete=consumed, + token=huggingface_hub.utils.get_token(), + ) + except Exception: + pass + return imported + + +def _add_files_to_bucket(bucket_id: str, additions: list[tuple[str, str]]) -> None: + if additions: + huggingface_hub.batch_bucket_files( + bucket_id, + add=additions, + token=huggingface_hub.utils.get_token(), + ) + + +def _upload_files_to_bucket( + bucket_id: str, + uploads: list[dict[str, Any]], + remote_path: Callable[[dict[str, Any], Path], str], +) -> None: + _add_files_to_bucket( + bucket_id, + [ + (str(p), remote_path(upload, p)) + for upload in uploads + if (p := Path(upload["file_path"])).exists() + ], + ) + + +def upload_media_files_to_bucket(bucket_id: str, uploads: list[dict[str, Any]]) -> None: + _upload_files_to_bucket( + bucket_id, + uploads, + lambda upload, p: bucket_media_path( + project=upload["project"], + run=upload.get("run"), + step=upload.get("step"), + relative_path=upload.get("relative_path"), + filename=p.name, + ), + ) + + +def upload_artifact_blobs_to_bucket( + bucket_id: str, uploads: list[dict[str, Any]] +) -> None: + _upload_files_to_bucket( + bucket_id, + uploads, + lambda upload, p: f"trackio/{p.relative_to(utils.TRACKIO_DIR).as_posix()}", + ) diff --git a/trackio/frontend/dist/assets/index-B3G2cuh_.js b/trackio/frontend/dist/assets/index-B3G2cuh_.js new file mode 100644 index 0000000000000000000000000000000000000000..9fb7af2f85c0dcfd281ae2e468a2d1f0b58973d1 --- /dev/null +++ b/trackio/frontend/dist/assets/index-B3G2cuh_.js @@ -0,0 +1,250 @@ +var bW=Object.defineProperty;var XF=e=>{throw TypeError(e)};var xW=(e,t,n)=>t in e?bW(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Ys=(e,t,n)=>xW(e,typeof t!="symbol"?t+"":t,n),G2=(e,t,n)=>t.has(e)||XF("Cannot "+n);var oe=(e,t,n)=>(G2(e,t,"read from private field"),n?n.call(e):t.get(e)),Pt=(e,t,n)=>t.has(e)?XF("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),Rt=(e,t,n,r)=>(G2(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n),Yn=(e,t,n)=>(G2(e,t,"access private method"),n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function r(i){if(i.ep)return;i.ep=!0;const s=n(i);fetch(i.href,s)}})();const _W="5";var FT;typeof window<"u"&&((FT=window.__svelte??(window.__svelte={})).v??(FT.v=new Set)).add(_W);const wW=1,EW=2,RT=4,AW=8,kW=16,SW=1,CW=2,$W=4,FW=8,DW=16,MW=1,TW=2,kr=Symbol(),NT="http://www.w3.org/1999/xhtml",RW="http://www.w3.org/2000/svg",NW="http://www.w3.org/1998/Math/MathML",OW=!1;var YA=Array.isArray,LW=Array.prototype.indexOf,Ad=Array.prototype.includes,Ay=Array.from,IW=Object.defineProperty,id=Object.getOwnPropertyDescriptor,OT=Object.getOwnPropertyDescriptors,PW=Object.prototype,BW=Array.prototype,VA=Object.getPrototypeOf,KF=Object.isExtensible;const LT=()=>{};function zW(e){return e()}function J_(e){for(var t=0;t{e=r,t=i});return{promise:n,resolve:e,reject:t}}function XA(e,t){if(Array.isArray(e))return e;if(!(Symbol.iterator in e))return Array.from(e);const n=[];for(const r of e)if(n.push(r),n.length===t)break;return n}const vr=2,kd=4,Kg=8,PT=1<<24,xu=16,po=32,Nc=64,Q_=128,Ds=512,ur=1024,Lr=2048,go=4096,ls=8192,Ms=16384,ff=32768,ew=1<<25,Oc=65536,ZF=1<<17,jW=1<<18,fh=1<<19,BT=1<<20,Ko=1<<25,Lc=65536,tw=1<<21,KA=1<<22,Vl=1<<23,Za=Symbol("$state"),UW=Symbol("legacy props"),qW=Symbol(""),Ia=new class extends Error{constructor(){super(...arguments);Ys(this,"name","StaleReactionError");Ys(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};var DT;const WW=!!((DT=globalThis.document)!=null&&DT.contentType)&&globalThis.document.contentType.includes("xml");function HW(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function GW(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function YW(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function VW(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function XW(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function KW(e){throw new Error("https://svelte.dev/e/effect_orphan")}function ZW(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function JW(e){throw new Error("https://svelte.dev/e/props_invalid_value")}function QW(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function eH(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function tH(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function nH(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}function rH(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function iH(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function zT(e){return e===this.v}function jT(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function UT(e){return!jT(e,this.v)}let dh=!1,sH=!1;function oH(){dh=!0}let On=null;function Sd(e){On=e}function En(e,t=!1,n){On={p:On,i:!1,c:null,e:null,s:e,x:null,r:jt,l:dh&&!t?{s:null,u:null,$:[]}:null}}function An(e){var t=On,n=t.e;if(n!==null){t.e=null;for(var r of n)uR(r)}return t.i=!0,On=t.p,{}}function Zg(){return!dh||On!==null&&On.l===null}let cc=[];function qT(){var e=cc;cc=[],J_(e)}function Xl(e){if(cc.length===0&&!Hp){var t=cc;queueMicrotask(()=>{t===cc&&qT()})}cc.push(e)}function aH(){for(;cc.length>0;)qT()}function WT(e){var t=jt;if(t===null)return Ot.f|=Vl,e;if((t.f&ff)===0&&(t.f&kd)===0)throw e;Pl(e,t)}function Pl(e,t){for(;t!==null;){if((t.f&Q_)!==0){if((t.f&ff)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}const lH=-7169;function Un(e,t){e.f=e.f&lH|t}function ZA(e){(e.f&Ds)!==0||e.deps===null?Un(e,ur):Un(e,go)}function HT(e){if(e!==null)for(const t of e)(t.f&vr)===0||(t.f&Lc)===0||(t.f^=Lc,HT(t.deps))}function GT(e,t,n){(e.f&Lr)!==0?t.add(e):(e.f&go)!==0&&n.add(e),HT(e.deps),Un(e,ur)}let tm=!1;function uH(e){var t=tm;try{return tm=!1,[e(),tm]}finally{tm=t}}const Wh=new Set;let Ct=null,Cr=null,nw=null,Hp=!1,Y2=!1,Kf=null,e1=null;var JF=0;let cH=1;var gd,md,vd,yd,Yg,_s,bd,Ll,Uo,xd,ii,rw,iw,sw,ow,YT;const _y=class _y{constructor(){Pt(this,ii);Ys(this,"id",cH++);Ys(this,"current",new Map);Ys(this,"previous",new Map);Pt(this,gd,new Set);Pt(this,md,new Set);Pt(this,vd,0);Pt(this,yd,0);Pt(this,Yg,null);Pt(this,_s,[]);Pt(this,bd,new Set);Pt(this,Ll,new Set);Pt(this,Uo,new Map);Ys(this,"is_fork",!1);Pt(this,xd,!1)}skip_effect(t){oe(this,Uo).has(t)||oe(this,Uo).set(t,{d:[],m:[]})}unskip_effect(t){var n=oe(this,Uo).get(t);if(n){oe(this,Uo).delete(t);for(var r of n.d)Un(r,Lr),this.schedule(r);for(r of n.m)Un(r,go),this.schedule(r)}}capture(t,n){n!==kr&&!this.previous.has(t)&&this.previous.set(t,n),(t.f&Vl)===0&&(this.current.set(t,t.v),Cr==null||Cr.set(t,t.v))}activate(){Ct=this}deactivate(){Ct=null,Cr=null}flush(){try{if(Y2=!0,Ct=this,!Yn(this,ii,rw).call(this)){for(const t of oe(this,bd))oe(this,Ll).delete(t),Un(t,Lr),this.schedule(t);for(const t of oe(this,Ll))Un(t,go),this.schedule(t)}Yn(this,ii,iw).call(this)}finally{JF=0,nw=null,Kf=null,e1=null,Y2=!1,Ct=null,Cr=null,Kl.clear()}}discard(){for(const t of oe(this,md))t(this);oe(this,md).clear()}increment(t){Rt(this,vd,oe(this,vd)+1),t&&Rt(this,yd,oe(this,yd)+1)}decrement(t,n){Rt(this,vd,oe(this,vd)-1),t&&Rt(this,yd,oe(this,yd)-1),!(oe(this,xd)||n)&&(Rt(this,xd,!0),Xl(()=>{Rt(this,xd,!1),this.flush()}))}oncommit(t){oe(this,gd).add(t)}ondiscard(t){oe(this,md).add(t)}settled(){return(oe(this,Yg)??Rt(this,Yg,IT())).promise}static ensure(){if(Ct===null){const t=Ct=new _y;Y2||(Wh.add(Ct),Hp||Xl(()=>{Ct===t&&t.flush()}))}return Ct}apply(){}schedule(t){var i;if(nw=t,(i=t.b)!=null&&i.is_pending&&(t.f&(kd|Kg|PT))!==0&&(t.f&ff)===0){t.b.defer_effect(t);return}for(var n=t;n.parent!==null;){n=n.parent;var r=n.f;if(Kf!==null&&n===jt&&(Ot===null||(Ot.f&vr)===0))return;if((r&(Nc|po))!==0){if((r&ur)===0)return;n.f^=ur}}oe(this,_s).push(n)}};gd=new WeakMap,md=new WeakMap,vd=new WeakMap,yd=new WeakMap,Yg=new WeakMap,_s=new WeakMap,bd=new WeakMap,Ll=new WeakMap,Uo=new WeakMap,xd=new WeakMap,ii=new WeakSet,rw=function(){return this.is_fork||oe(this,yd)>0},iw=function(){var a,l;JF++>1e3&&dH();const t=oe(this,_s);Rt(this,_s,[]),this.apply();var n=Kf=[],r=[],i=e1=[];for(const u of t)Yn(this,ii,sw).call(this,u,n,r);if(Ct=null,i.length>0){var s=_y.ensure();for(const u of i)s.schedule(u)}if(Kf=null,e1=null,Yn(this,ii,rw).call(this)){Yn(this,ii,ow).call(this,r),Yn(this,ii,ow).call(this,n);for(const[u,c]of oe(this,Uo))KT(u,c)}else{oe(this,bd).clear(),oe(this,Ll).clear();for(const u of oe(this,gd))u(this);oe(this,gd).clear(),QF(r),QF(n),oe(this,vd)===0&&Yn(this,ii,YT).call(this),(a=oe(this,Yg))==null||a.resolve()}var o=Ct;if(oe(this,_s).length>0){const u=o??(o=this);oe(u,_s).push(...oe(this,_s).filter(c=>!oe(u,_s).includes(c)))}o!==null&&(Wh.add(o),Yn(l=o,ii,iw).call(l))},sw=function(t,n,r){t.f^=ur;for(var i=t.first;i!==null;){var s=i.f,o=(s&(po|Nc))!==0,a=o&&(s&ur)!==0,l=a||(s&ls)!==0||oe(this,Uo).has(i);if(!l&&i.fn!==null){o?i.f^=ur:(s&kd)!==0?n.push(i):t0(i)&&((s&xu)!==0&&oe(this,Ll).add(i),Fd(i));var u=i.first;if(u!==null){i=u;continue}}for(;i!==null;){var c=i.next;if(c!==null){i=c;break}i=i.parent}}},ow=function(t){for(var n=0;n1){this.previous.clear();var t=Ct,n=Cr,r=!0;for(const s of Wh){if(s===this){r=!1;continue}const o=[];for(const[l,u]of this.current){if(s.current.has(l))if(r&&u!==s.current.get(l))s.current.set(l,u);else continue;o.push(l)}if(o.length===0)continue;const a=[...s.current.keys()].filter(l=>!this.current.has(l));if(a.length>0){s.activate();const l=new Set,u=new Map;for(const c of o)VT(c,a,l,u);if(oe(s,_s).length>0){s.apply();for(const c of oe(s,_s))Yn(i=s,ii,sw).call(i,c,[],[])}s.deactivate()}}Ct=t,Cr=n}oe(this,Uo).clear(),Wh.delete(this)};let Ic=_y;function fH(e){var t=Hp;Hp=!0;try{for(var n;;){if(aH(),Ct===null)return n;Ct.flush()}}finally{Hp=t}}function dH(){try{ZW()}catch(e){Pl(e,nw)}}let Zs=null;function QF(e){var t=e.length;if(t!==0){for(var n=0;n0)){Kl.clear();for(const i of Zs){if((i.f&(Ms|ls))!==0)continue;const s=[i];let o=i.parent;for(;o!==null;)Zs.has(o)&&(Zs.delete(o),s.push(o)),o=o.parent;for(let a=s.length-1;a>=0;a--){const l=s[a];(l.f&(Ms|ls))===0&&Fd(l)}}Zs.clear()}}Zs=null}}function VT(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const i of e.reactions){const s=i.f;(s&vr)!==0?VT(i,t,n,r):(s&(KA|xu))!==0&&(s&Lr)===0&&XT(i,t,r)&&(Un(i,Lr),JA(i))}}function XT(e,t,n){const r=n.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const i of e.deps){if(Ad.call(t,i))return!0;if((i.f&vr)!==0&&XT(i,t,n))return n.set(i,!0),!0}return n.set(e,!1),!1}function JA(e){Ct.schedule(e)}function KT(e,t){if(!((e.f&po)!==0&&(e.f&ur)!==0)){(e.f&Lr)!==0?t.d.push(e):(e.f&go)!==0&&t.m.push(e),Un(e,ur);for(var n=e.first;n!==null;)KT(n,t),n=n.next}}function hH(e){let t=0,n=Pc(0),r;return()=>{nk()&&(v(n),e0(()=>(t===0&&(r=_u(()=>e(()=>Gp(n)))),t+=1,()=>{Xl(()=>{t-=1,t===0&&(r==null||r(),r=void 0,Gp(n))})})))}}var pH=Oc|fh;function gH(e,t,n,r){new mH(e,t,n,r)}var ws,GA,qo,vc,Fi,Wo,Ji,Js,ja,yc,Il,_d,wd,Ed,Ua,wy,rr,vH,yH,bH,aw,t1,n1,lw;class mH{constructor(t,n,r,i){Pt(this,rr);Ys(this,"parent");Ys(this,"is_pending",!1);Ys(this,"transform_error");Pt(this,ws);Pt(this,GA,null);Pt(this,qo);Pt(this,vc);Pt(this,Fi);Pt(this,Wo,null);Pt(this,Ji,null);Pt(this,Js,null);Pt(this,ja,null);Pt(this,yc,0);Pt(this,Il,0);Pt(this,_d,!1);Pt(this,wd,new Set);Pt(this,Ed,new Set);Pt(this,Ua,null);Pt(this,wy,hH(()=>(Rt(this,Ua,Pc(oe(this,yc))),()=>{Rt(this,Ua,null)})));var s;Rt(this,ws,t),Rt(this,qo,n),Rt(this,vc,o=>{var a=jt;a.b=this,a.f|=Q_,r(o)}),this.parent=jt.b,this.transform_error=i??((s=this.parent)==null?void 0:s.transform_error)??(o=>o),Rt(this,Fi,Sy(()=>{Yn(this,rr,aw).call(this)},pH))}defer_effect(t){GT(t,oe(this,wd),oe(this,Ed))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!oe(this,qo).pending}update_pending_count(t,n){Yn(this,rr,lw).call(this,t,n),Rt(this,yc,oe(this,yc)+t),!(!oe(this,Ua)||oe(this,_d))&&(Rt(this,_d,!0),Xl(()=>{Rt(this,_d,!1),oe(this,Ua)&&Cd(oe(this,Ua),oe(this,yc))}))}get_effect_pending(){return oe(this,wy).call(this),v(oe(this,Ua))}error(t){var n=oe(this,qo).onerror;let r=oe(this,qo).failed;if(!n&&!r)throw t;oe(this,Wo)&&(Pi(oe(this,Wo)),Rt(this,Wo,null)),oe(this,Ji)&&(Pi(oe(this,Ji)),Rt(this,Ji,null)),oe(this,Js)&&(Pi(oe(this,Js)),Rt(this,Js,null));var i=!1,s=!1;const o=()=>{if(i){iH();return}i=!0,s&&nH(),oe(this,Js)!==null&&xc(oe(this,Js),()=>{Rt(this,Js,null)}),Yn(this,rr,n1).call(this,()=>{Yn(this,rr,aw).call(this)})},a=l=>{try{s=!0,n==null||n(l,o),s=!1}catch(u){Pl(u,oe(this,Fi)&&oe(this,Fi).parent)}r&&Rt(this,Js,Yn(this,rr,n1).call(this,()=>{try{return Es(()=>{var u=jt;u.b=this,u.f|=Q_,r(oe(this,ws),()=>l,()=>o)})}catch(u){return Pl(u,oe(this,Fi).parent),null}}))};Xl(()=>{var l;try{l=this.transform_error(t)}catch(u){Pl(u,oe(this,Fi)&&oe(this,Fi).parent);return}l!==null&&typeof l=="object"&&typeof l.then=="function"?l.then(a,u=>Pl(u,oe(this,Fi)&&oe(this,Fi).parent)):a(l)})}}ws=new WeakMap,GA=new WeakMap,qo=new WeakMap,vc=new WeakMap,Fi=new WeakMap,Wo=new WeakMap,Ji=new WeakMap,Js=new WeakMap,ja=new WeakMap,yc=new WeakMap,Il=new WeakMap,_d=new WeakMap,wd=new WeakMap,Ed=new WeakMap,Ua=new WeakMap,wy=new WeakMap,rr=new WeakSet,vH=function(){try{Rt(this,Wo,Es(()=>oe(this,vc).call(this,oe(this,ws))))}catch(t){this.error(t)}},yH=function(t){const n=oe(this,qo).failed;n&&Rt(this,Js,Es(()=>{n(oe(this,ws),()=>t,()=>()=>{})}))},bH=function(){const t=oe(this,qo).pending;if(t){this.is_pending=!0,Rt(this,Ji,Es(()=>t(oe(this,ws))));var n=Ct;Xl(()=>{var r=Rt(this,ja,document.createDocumentFragment()),i=Ja();r.append(i),Rt(this,Wo,Yn(this,rr,n1).call(this,()=>Es(()=>oe(this,vc).call(this,i)))),oe(this,Il)===0&&(oe(this,ws).before(r),Rt(this,ja,null),xc(oe(this,Ji),()=>{Rt(this,Ji,null)}),Yn(this,rr,t1).call(this,n))})}},aw=function(){var t=Ct;try{if(this.is_pending=this.has_pending_snippet(),Rt(this,Il,0),Rt(this,yc,0),Rt(this,Wo,Es(()=>{oe(this,vc).call(this,oe(this,ws))})),oe(this,Il)>0){var n=Rt(this,ja,document.createDocumentFragment());ak(oe(this,Wo),n);const r=oe(this,qo).pending;Rt(this,Ji,Es(()=>r(oe(this,ws))))}else Yn(this,rr,t1).call(this,t)}catch(r){this.error(r)}},t1=function(t){this.is_pending=!1;for(const n of oe(this,wd))Un(n,Lr),t.schedule(n);for(const n of oe(this,Ed))Un(n,go),t.schedule(n);oe(this,wd).clear(),oe(this,Ed).clear()},n1=function(t){var n=jt,r=Ot,i=On;oa(oe(this,Fi)),Os(oe(this,Fi)),Sd(oe(this,Fi).ctx);try{return Ic.ensure(),t()}catch(s){return WT(s),null}finally{oa(n),Os(r),Sd(i)}},lw=function(t,n){var r;if(!this.has_pending_snippet()){this.parent&&Yn(r=this.parent,rr,lw).call(r,t,n);return}Rt(this,Il,oe(this,Il)+t),oe(this,Il)===0&&(Yn(this,rr,t1).call(this,n),oe(this,Ji)&&xc(oe(this,Ji),()=>{Rt(this,Ji,null)}),oe(this,ja)&&(oe(this,ws).before(oe(this,ja)),Rt(this,ja,null)))};function xH(e,t,n,r){const i=Zg()?Jg:QA;var s=e.filter(d=>!d.settled);if(n.length===0&&s.length===0){r(t.map(i));return}var o=jt,a=_H(),l=s.length===1?s[0].promise:s.length>1?Promise.all(s.map(d=>d.promise)):null;function u(d){a();try{r(d)}catch(h){(o.f&Ms)===0&&Pl(h,o)}O1()}if(n.length===0){l.then(()=>u(t.map(i)));return}var c=ZT();function f(){Promise.all(n.map(d=>wH(d))).then(d=>u([...t.map(i),...d])).catch(d=>Pl(d,o)).finally(()=>c())}l?l.then(()=>{a(),f(),O1()}):f()}function _H(){var e=jt,t=Ot,n=On,r=Ct;return function(s=!0){oa(e),Os(t),Sd(n),s&&(e.f&Ms)===0&&(r==null||r.activate(),r==null||r.apply())}}function O1(e=!0){oa(null),Os(null),Sd(null),e&&(Ct==null||Ct.deactivate())}function ZT(){var e=jt.b,t=Ct,n=e.is_rendered();return e.update_pending_count(1,t),t.increment(n),(r=!1)=>{e.update_pending_count(-1,t),t.decrement(n,r)}}function Jg(e){var t=vr|Lr,n=Ot!==null&&(Ot.f&vr)!==0?Ot:null;return jt!==null&&(jt.f|=fh),{ctx:On,deps:null,effects:null,equals:zT,f:t,fn:e,reactions:null,rv:0,v:kr,wv:0,parent:n??jt,ac:null}}function wH(e,t,n){let r=jt;r===null&&GW();var i=void 0,s=Pc(kr),o=!Ot,a=new Map;return OH(()=>{var h;var l=jt,u=IT();i=u.promise;try{Promise.resolve(e()).then(u.resolve,u.reject).finally(O1)}catch(p){u.reject(p),O1()}var c=Ct;if(o){if((l.f&ff)!==0)var f=ZT();if(r.b.is_rendered())(h=a.get(c))==null||h.reject(Ia),a.delete(c);else{for(const p of a.values())p.reject(Ia);a.clear()}a.set(c,u)}const d=(p,g=void 0)=>{if(f){var m=g===Ia;f(m)}if(!(g===Ia||(l.f&Ms)!==0)){if(c.activate(),g)s.f|=Vl,Cd(s,g);else{(s.f&Vl)!==0&&(s.f^=Vl),Cd(s,p);for(const[y,b]of a){if(a.delete(y),y===c)break;b.reject(Ia)}}c.deactivate()}};u.promise.then(d,p=>d(null,p||"unknown"))}),rk(()=>{for(const l of a.values())l.reject(Ia)}),new Promise(l=>{function u(c){function f(){c===i?l(s):u(i)}c.then(f,f)}u(i)})}function we(e){const t=Jg(e);return gR(t),t}function QA(e){const t=Jg(e);return t.equals=UT,t}function EH(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n0&&!eR&&CH()}return t}function CH(){eR=!1;for(const e of uw)(e.f&ur)!==0&&Un(e,go),t0(e)&&Fd(e);uw.clear()}function tR(e,t=1){var n=v(e),r=t===1?n++:n--;return D(e,n),r}function Gp(e){D(e,e.v+1)}function nR(e,t,n){var r=e.reactions;if(r!==null)for(var i=Zg(),s=r.length,o=0;o{if(_c===s)return a();var l=Ot,u=_c;Os(null),r5(s);var c=a();return Os(l),r5(u),c};return r&&n.set("length",re(e.length)),new Proxy(e,{defineProperty(a,l,u){(!("value"in u)||u.configurable===!1||u.enumerable===!1||u.writable===!1)&&QW();var c=n.get(l);return c===void 0?o(()=>{var f=re(u.value);return n.set(l,f),f}):D(c,u.value,!0),!0},deleteProperty(a,l){var u=n.get(l);if(u===void 0){if(l in a){const c=o(()=>re(kr));n.set(l,c),Gp(i)}}else D(u,kr),Gp(i);return!0},get(a,l,u){var h;if(l===Za)return e;var c=n.get(l),f=l in a;if(c===void 0&&(!f||(h=id(a,l))!=null&&h.writable)&&(c=o(()=>{var p=xt(f?a[l]:kr),g=re(p);return g}),n.set(l,c)),c!==void 0){var d=v(c);return d===kr?void 0:d}return Reflect.get(a,l,u)},getOwnPropertyDescriptor(a,l){var u=Reflect.getOwnPropertyDescriptor(a,l);if(u&&"value"in u){var c=n.get(l);c&&(u.value=v(c))}else if(u===void 0){var f=n.get(l),d=f==null?void 0:f.v;if(f!==void 0&&d!==kr)return{enumerable:!0,configurable:!0,value:d,writable:!0}}return u},has(a,l){var d;if(l===Za)return!0;var u=n.get(l),c=u!==void 0&&u.v!==kr||Reflect.has(a,l);if(u!==void 0||jt!==null&&(!c||(d=id(a,l))!=null&&d.writable)){u===void 0&&(u=o(()=>{var h=c?xt(a[l]):kr,p=re(h);return p}),n.set(l,u));var f=v(u);if(f===kr)return!1}return c},set(a,l,u,c){var x;var f=n.get(l),d=l in a;if(r&&l==="length")for(var h=u;hre(kr)),n.set(h+"",p))}if(f===void 0)(!d||(x=id(a,l))!=null&&x.writable)&&(f=o(()=>re(void 0)),D(f,xt(u)),n.set(l,f));else{d=f.v!==kr;var g=o(()=>xt(u));D(f,g)}var m=Reflect.getOwnPropertyDescriptor(a,l);if(m!=null&&m.set&&m.set.call(c,u),!d){if(r&&typeof l=="string"){var y=n.get("length"),b=Number(l);Number.isInteger(b)&&b>=y.v&&D(y,b+1)}Gp(i)}return!0},ownKeys(a){v(i);var l=Reflect.ownKeys(a).filter(f=>{var d=n.get(f);return d===void 0||d.v!==kr});for(var[u,c]of n)c.v!==kr&&!(u in a)&&l.push(u);return l},setPrototypeOf(){eH()}})}function e5(e){try{if(e!==null&&typeof e=="object"&&Za in e)return e[Za]}catch{}return e}function $H(e,t){return Object.is(e5(e),e5(t))}var $d,rR,iR,sR;function FH(){if($d===void 0){$d=window,rR=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;iR=id(t,"firstChild").get,sR=id(t,"nextSibling").get,KF(e)&&(e.__click=void 0,e.__className=void 0,e.__attributes=null,e.__style=void 0,e.__e=void 0),KF(n)&&(n.__t=void 0)}}function Ja(e=""){return document.createTextNode(e)}function Zo(e){return iR.call(e)}function Qg(e){return sR.call(e)}function C(e,t){return Zo(e)}function Bt(e,t=!1){{var n=Zo(e);return n instanceof Comment&&n.data===""?Qg(n):n}}function R(e,t=1,n=!1){let r=e;for(;t--;)r=Qg(r);return r}function DH(e){e.textContent=""}function oR(){return!1}function aR(e,t,n){return document.createElementNS(t??NT,e,void 0)}let t5=!1;function MH(){t5||(t5=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{var t;if(!e.defaultPrevented)for(const n of e.target.elements)(t=n.__on_r)==null||t.call(n)})},{capture:!0}))}function ky(e){var t=Ot,n=jt;Os(null),oa(null);try{return e()}finally{Os(t),oa(n)}}function tk(e,t,n,r=n){e.addEventListener(t,()=>ky(n));const i=e.__on_r;i?e.__on_r=()=>{i(),r(!0)}:e.__on_r=()=>r(!0),MH()}function lR(e){jt===null&&(Ot===null&&KW(),XW()),ru&&VW()}function TH(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function ma(e,t){var n=jt;n!==null&&(n.f&ls)!==0&&(e|=ls);var r={ctx:On,deps:null,nodes:null,f:e|Lr|Ds,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null},i=r;if((e&kd)!==0)Kf!==null?Kf.push(r):Ic.ensure().schedule(r);else if(t!==null){try{Fd(r)}catch(o){throw Pi(r),o}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&(i.f&fh)===0&&(i=i.first,(e&xu)!==0&&(e&Oc)!==0&&i!==null&&(i.f|=Oc))}if(i!==null&&(i.parent=n,n!==null&&TH(i,n),Ot!==null&&(Ot.f&vr)!==0&&(e&Nc)===0)){var s=Ot;(s.effects??(s.effects=[])).push(i)}return r}function nk(){return Ot!==null&&!oo}function rk(e){const t=ma(Kg,null);return Un(t,ur),t.teardown=e,t}function zt(e){lR();var t=jt.f,n=!Ot&&(t&po)!==0&&(t&ff)===0;if(n){var r=On;(r.e??(r.e=[])).push(e)}else return uR(e)}function uR(e){return ma(kd|BT,e)}function RH(e){return lR(),ma(Kg|BT,e)}function NH(e){Ic.ensure();const t=ma(Nc|fh,e);return(n={})=>new Promise(r=>{n.outro?xc(t,()=>{Pi(t),r(void 0)}):(Pi(t),r(void 0))})}function ik(e){return ma(kd,e)}function OH(e){return ma(KA|fh,e)}function e0(e,t=0){return ma(Kg|t,e)}function ye(e,t=[],n=[],r=[]){xH(r,t,n,i=>{ma(Kg,()=>e(...i.map(v)))})}function Sy(e,t=0){var n=ma(xu|t,e);return n}function Es(e){return ma(po|fh,e)}function cR(e){var t=e.teardown;if(t!==null){const n=ru,r=Ot;n5(!0),Os(null);try{t.call(null)}finally{n5(n),Os(r)}}}function sk(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const i=n.ac;i!==null&&ky(()=>{i.abort(Ia)});var r=n.next;(n.f&Nc)!==0?n.parent=null:Pi(n,t),n=r}}function LH(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&po)===0&&Pi(t),t=n}}function Pi(e,t=!0){var n=!1;(t||(e.f&jW)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(fR(e.nodes.start,e.nodes.end),n=!0),Un(e,ew),sk(e,t&&!n),fg(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(const s of r)s.stop();cR(e),e.f^=ew,e.f|=Ms;var i=e.parent;i!==null&&i.first!==null&&dR(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=null}function fR(e,t){for(;e!==null;){var n=e===t?null:Qg(e);e.remove(),e=n}}function dR(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function xc(e,t,n=!0){var r=[];hR(e,r,!0);var i=()=>{n&&Pi(e),t&&t()},s=r.length;if(s>0){var o=()=>--s||i();for(var a of r)a.out(o)}else i()}function hR(e,t,n){if((e.f&ls)===0){e.f^=ls;var r=e.nodes&&e.nodes.t;if(r!==null)for(const a of r)(a.is_global||n)&&t.push(a);for(var i=e.first;i!==null;){var s=i.next,o=(i.f&Oc)!==0||(i.f&po)!==0&&(e.f&xu)!==0;hR(i,t,o?n:!1),i=s}}}function ok(e){pR(e,!0)}function pR(e,t){if((e.f&ls)!==0){e.f^=ls,(e.f&ur)===0&&(Un(e,Lr),Ic.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=(n.f&Oc)!==0||(n.f&po)!==0;pR(n,i?t:!1),n=r}var s=e.nodes&&e.nodes.t;if(s!==null)for(const o of s)(o.is_global||t)&&o.in()}}function ak(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:Qg(n);t.append(n),n=i}}let r1=!1,ru=!1;function n5(e){ru=e}let Ot=null,oo=!1;function Os(e){Ot=e}let jt=null;function oa(e){jt=e}let Ts=null;function gR(e){Ot!==null&&(Ts===null?Ts=[e]:Ts.push(e))}let Di=null,Ki=0,xs=null;function IH(e){xs=e}let mR=1,fc=0,_c=fc;function r5(e){_c=e}function vR(){return++mR}function t0(e){var t=e.f;if((t&Lr)!==0)return!0;if(t&vr&&(e.f&=~Lc),(t&go)!==0){for(var n=e.deps,r=n.length,i=0;ie.wv)return!0}(t&Ds)!==0&&Cr===null&&Un(e,ur)}return!1}function yR(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Ts!==null&&Ad.call(Ts,e)))for(var i=0;i{e.ac.abort(Ia)}),e.ac=null);try{e.f|=tw;var c=e.fn,f=c();e.f|=ff;var d=e.deps,h=Ct==null?void 0:Ct.is_fork;if(Di!==null){var p;if(h||fg(e,Ki),d!==null&&Ki>0)for(d.length=Ki+Di.length,p=0;pn==null?void 0:n.call(this,s))}return e.startsWith("pointer")||e.startsWith("touch")||e==="wheel"?Xl(()=>{t.addEventListener(e,i,r)}):t.addEventListener(e,i,r),i}function fn(e,t,n,r,i){var s={capture:r,passive:i},o=BH(e,t,n,s);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&rk(()=>{t.removeEventListener(e,o,s)})}function Oe(e,t,n){(t[dc]??(t[dc]={}))[e]=n}function si(e){for(var t=0;t{throw b});throw d}}finally{e[dc]=t,delete e.currentTarget,Os(c),oa(f)}}}var MT;const V2=((MT=globalThis==null?void 0:globalThis.window)==null?void 0:MT.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function zH(e){return(V2==null?void 0:V2.createHTML(e))??e}function AR(e){var t=aR("template");return t.innerHTML=zH(e.replaceAll("","")),t.content}function Bc(e,t){var n=jt;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function q(e,t){var n=(t&MW)!==0,r=(t&TW)!==0,i,s=!e.startsWith("");return()=>{i===void 0&&(i=AR(s?e:""+e),n||(i=Zo(i)));var o=r||rR?document.importNode(i,!0):i.cloneNode(!0);if(n){var a=Zo(o),l=o.lastChild;Bc(a,l)}else Bc(o,o);return o}}function jH(e,t,n="svg"){var r=!e.startsWith(""),i=`<${n}>${r?e:""+e}`,s;return()=>{if(!s){var o=AR(i),a=Zo(o);s=Zo(a)}var l=s.cloneNode(!0);return Bc(l,l),l}}function Ei(e,t){return jH(e,t,"svg")}function hw(e=""){{var t=Ja(e+"");return Bc(t,t),t}}function Ni(){var e=document.createDocumentFragment(),t=document.createComment(""),n=Ja();return e.append(t,n),Bc(t,n),e}function I(e,t){e!==null&&e.before(t)}const UH=["touchstart","touchmove"];function qH(e){return UH.includes(e)}function me(e,t){var n=t==null?"":typeof t=="object"?`${t}`:t;n!==(e.__t??(e.__t=e.nodeValue))&&(e.__t=n,e.nodeValue=`${n}`)}function WH(e,t){return HH(e,t)}const nm=new Map;function HH(e,{target:t,anchor:n,props:r={},events:i,context:s,intro:o=!0,transformError:a}){FH();var l=void 0,u=NH(()=>{var c=n??t.appendChild(Ja());gH(c,{pending:()=>{}},h=>{En({});var p=On;s&&(p.c=s),i&&(r.$$events=i),l=e(h,r)||{},An()},a);var f=new Set,d=h=>{for(var p=0;p{var m;for(var h of f)for(const y of[t,document]){var p=nm.get(y),g=p.get(h);--g==0?(y.removeEventListener(h,dw),p.delete(h),p.size===0&&nm.delete(y)):p.set(h,g)}fw.delete(d),c!==n&&((m=c.parentNode)==null||m.removeChild(c))}});return GH.set(l,u),l}let GH=new WeakMap;var Qs,Ho,Qi,bc,Vg,Xg,Ey;class kR{constructor(t,n=!0){Ys(this,"anchor");Pt(this,Qs,new Map);Pt(this,Ho,new Map);Pt(this,Qi,new Map);Pt(this,bc,new Set);Pt(this,Vg,!0);Pt(this,Xg,t=>{if(oe(this,Qs).has(t)){var n=oe(this,Qs).get(t),r=oe(this,Ho).get(n);if(r)ok(r),oe(this,bc).delete(n);else{var i=oe(this,Qi).get(n);i&&(oe(this,Ho).set(n,i.effect),oe(this,Qi).delete(n),i.fragment.lastChild.remove(),this.anchor.before(i.fragment),r=i.effect)}for(const[s,o]of oe(this,Qs)){if(oe(this,Qs).delete(s),s===t)break;const a=oe(this,Qi).get(o);a&&(Pi(a.effect),oe(this,Qi).delete(o))}for(const[s,o]of oe(this,Ho)){if(s===n||oe(this,bc).has(s))continue;const a=()=>{if(Array.from(oe(this,Qs).values()).includes(s)){var u=document.createDocumentFragment();ak(o,u),u.append(Ja()),oe(this,Qi).set(s,{effect:o,fragment:u})}else Pi(o);oe(this,bc).delete(s),oe(this,Ho).delete(s)};oe(this,Vg)||!r?(oe(this,bc).add(s),xc(o,a,!1)):a()}}});Pt(this,Ey,t=>{oe(this,Qs).delete(t);const n=Array.from(oe(this,Qs).values());for(const[r,i]of oe(this,Qi))n.includes(r)||(Pi(i.effect),oe(this,Qi).delete(r))});this.anchor=t,Rt(this,Vg,n)}ensure(t,n){var r=Ct,i=oR();if(n&&!oe(this,Ho).has(t)&&!oe(this,Qi).has(t))if(i){var s=document.createDocumentFragment(),o=Ja();s.append(o),oe(this,Qi).set(t,{effect:Es(()=>n(o)),fragment:s})}else oe(this,Ho).set(t,Es(()=>n(this.anchor)));if(oe(this,Qs).set(r,t),i){for(const[a,l]of oe(this,Ho))a===t?r.unskip_effect(l):r.skip_effect(l);for(const[a,l]of oe(this,Qi))a===t?r.unskip_effect(l.effect):r.skip_effect(l.effect);r.oncommit(oe(this,Xg)),r.ondiscard(oe(this,Ey))}else oe(this,Xg).call(this,r)}}Qs=new WeakMap,Ho=new WeakMap,Qi=new WeakMap,bc=new WeakMap,Vg=new WeakMap,Xg=new WeakMap,Ey=new WeakMap;function s5(e,t,...n){var r=new kR(e);Sy(()=>{const i=t()??null;r.ensure(i,i&&(s=>i(s,...n)))},Oc)}function hh(e){On===null&&HW(),dh&&On.l!==null?YH(On).m.push(e):zt(()=>{const t=_u(e);if(typeof t=="function")return t})}function YH(e){var t=e.l;return t.u??(t.u={a:[],b:[],m:[]})}function he(e,t,n=!1){var r=new kR(e),i=n?Oc:0;function s(o,a){r.ensure(o,a)}Sy(()=>{var o=!1;t((a,l=0)=>{o=!0,s(l,a)}),o||s(-1,null)},i)}function Dt(e,t){return t}function VH(e,t,n){for(var r=[],i=t.length,s,o=t.length,a=0;a{if(s){if(s.pending.delete(f),s.done.add(f),s.pending.size===0){var d=e.outrogroups;pw(e,Ay(s.done)),d.delete(s),d.size===0&&(e.outrogroups=null)}}else o-=1},!1)}if(o===0){var l=r.length===0&&n!==null;if(l){var u=n,c=u.parentNode;DH(c),c.append(u),e.items.clear()}pw(e,t,!l)}else s={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(s)}function pw(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(const o of e.pending.values())for(const a of o)r.add(e.items.get(a).e)}for(var i=0;i{var x=n();return YA(x)?x:x==null?[]:Ay(x)}),d,h=new Map,p=!0;function g(x){(b.effect.f&Ms)===0&&(b.pending.delete(x),b.fallback=c,XH(b,d,o,t,r),c!==null&&(d.length===0?(c.f&Ko)===0?ok(c):(c.f^=Ko,vp(c,null,o)):xc(c,()=>{c=null})))}function m(x){b.pending.delete(x)}var y=Sy(()=>{d=v(f);for(var x=d.length,_=new Set,w=Ct,A=oR(),E=0;Es(o)):(c=Es(()=>s(o5??(o5=Ja()))),c.f|=Ko)),x>_.size&&YW(),!p)if(h.set(w,_),A){for(const[M,O]of a)_.has(M)||w.skip_effect(O.e);w.oncommit(g),w.ondiscard(m)}else g(w);v(f)}),b={effect:y,items:a,pending:h,outrogroups:null,fallback:c};p=!1}function Hh(e){for(;e!==null&&(e.f&po)===0;)e=e.next;return e}function XH(e,t,n,r,i){var $,M,O,P,T,F,N,U,j;var s=(r&AW)!==0,o=t.length,a=e.items,l=Hh(e.effect.first),u,c=null,f,d=[],h=[],p,g,m,y;if(s)for(y=0;y0){var S=(r&RT)!==0&&o===0?n:null;if(s){for(y=0;y{var W,Z;if(f!==void 0)for(m of f)(Z=(W=m.nodes)==null?void 0:W.a)==null||Z.apply()})}function KH(e,t,n,r,i,s,o,a){var l=(o&wW)!==0?(o&kW)===0?SH(n,!1,!1):Pc(n):null,u=(o&EW)!==0?Pc(i):null;return{v:l,i:u,e:Es(()=>(s(t,l??n,u??i,a),()=>{e.delete(r)}))}}function vp(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,s=t&&(t.f&Ko)===0?t.nodes.start:n;r!==null;){var o=Qg(r);if(s.before(r),r===i)return;r=o}}function kl(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function ZH(e,t,n=!1,r=!1,i=!1,s=!1){var o=e,a="";if(n)var l=e;ye(()=>{var u=jt;if(a!==(a=t()??"")){if(n){u.nodes=null,l.innerHTML=a,a!==""&&Bc(Zo(l),l.lastChild);return}if(u.nodes!==null&&(fR(u.nodes.start,u.nodes.end),u.nodes=null),a!==""){var c=r?RW:i?NW:void 0,f=aR(r?"svg":i?"math":"template",c);f.innerHTML=a;var d=r||i?f:f.content;if(Bc(Zo(d),d.lastChild),r||i)for(;Zo(d);)o.before(Zo(d));else o.before(d)}}})}function X2(e,t,n){ik(()=>{var r=_u(()=>t(e,n==null?void 0:n())||{});if(n&&(r!=null&&r.update)){var i=!1,s={};e0(()=>{var o=n();wR(o),i&&jT(s,o)&&(s=o,r.update(o))}),i=!0}if(r!=null&&r.destroy)return()=>r.destroy()})}const a5=[...` +\r\f \v\uFEFF`];function JH(e,t,n){var r=e==null?"":""+e;if(n){for(var i of Object.keys(n))if(n[i])r=r?r+" "+i:i;else if(r.length)for(var s=i.length,o=0;(o=r.indexOf(i,o))>=0;){var a=o+s;(o===0||a5.includes(r[o-1]))&&(a===r.length||a5.includes(r[a]))?r=(o===0?"":r.substring(0,o))+r.substring(a+1):o=a}}return r===""?null:r}function l5(e,t=!1){var n=t?" !important;":";",r="";for(var i of Object.keys(e)){var s=e[i];s!=null&&s!==""&&(r+=" "+i+": "+s+n)}return r}function K2(e){return e[0]!=="-"||e[1]!=="-"?e.toLowerCase():e}function QH(e,t){if(t){var n="",r,i;if(Array.isArray(t)?(r=t[0],i=t[1]):r=t,e){e=String(e).replaceAll(/\s*\/\*.*?\*\/\s*/g,"").trim();var s=!1,o=0,a=!1,l=[];r&&l.push(...Object.keys(r).map(K2)),i&&l.push(...Object.keys(i).map(K2));var u=0,c=-1;const g=e.length;for(var f=0;f{SR(e,e.__value)});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),rk(()=>{t.disconnect()})}function L1(e,t,n=t){var r=new WeakSet,i=!0;tk(e,"change",s=>{var o=s?"[selected]":":checked",a;if(e.multiple)a=[].map.call(e.querySelectorAll(o),Yp);else{var l=e.querySelector(o)??e.querySelector("option:not([disabled])");a=l&&Yp(l)}n(a),Ct!==null&&r.add(Ct)}),ik(()=>{var s=t();if(e===document.activeElement){var o=Ct;if(r.has(o))return}if(SR(e,s,i),i&&s===void 0){var a=e.querySelector(":checked");a!==null&&(s=Yp(a),n(s))}e.__value=s,i=!1}),eG(e)}function Yp(e){return"__value"in e?e.__value:e.value}const tG=Symbol("is custom element"),nG=Symbol("is html"),rG=WW?"progress":"PROGRESS";function u5(e,t){var n=lk(e);n.value===(n.value=t??void 0)||e.value===t&&(t!==0||e.nodeName!==rG)||(e.value=t??"")}function Gf(e,t){var n=lk(e);n.checked!==(n.checked=t??void 0)&&(e.checked=t)}function St(e,t,n,r){var i=lk(e);i[t]!==(i[t]=n)&&(t==="loading"&&(e[qW]=n),n==null?e.removeAttribute(t):typeof n!="string"&&iG(e).includes(t)?e[t]=n:e.setAttribute(t,n))}function lk(e){return e.__attributes??(e.__attributes={[tG]:e.nodeName.includes("-"),[nG]:e.namespaceURI===NT})}var c5=new Map;function iG(e){var t=e.getAttribute("is")||e.nodeName,n=c5.get(t);if(n)return n;c5.set(t,n=[]);for(var r,i=e,s=Element.prototype;s!==i;){r=OT(i);for(var o in r)r[o].set&&n.push(o);i=VA(i)}return n}function ph(e,t,n=t){var r=new WeakSet;tk(e,"input",async i=>{var s=i?e.defaultValue:e.value;if(s=J2(e)?Q2(s):s,n(s),Ct!==null&&r.add(Ct),await ns(),s!==(s=t())){var o=e.selectionStart,a=e.selectionEnd,l=e.value.length;if(e.value=s??"",a!==null){var u=e.value.length;o===a&&a===l&&u>l?(e.selectionStart=u,e.selectionEnd=u):(e.selectionStart=o,e.selectionEnd=Math.min(a,u))}}}),_u(t)==null&&e.value&&(n(J2(e)?Q2(e.value):e.value),Ct!==null&&r.add(Ct)),e0(()=>{var i=t();if(e===document.activeElement){var s=Ct;if(r.has(s))return}J2(e)&&i===Q2(e.value)||e.type==="date"&&!i&&!e.value||i!==e.value&&(e.value=i??"")})}function sG(e,t,n=t){tk(e,"change",r=>{var i=r?e.defaultChecked:e.checked;n(i)}),_u(t)==null&&n(e.checked),e0(()=>{var r=t();e.checked=!!r})}function J2(e){var t=e.type;return t==="number"||t==="range"}function Q2(e){return e===""?null:+e}function f5(e,t){return e===t||(e==null?void 0:e[Za])===t}function is(e={},t,n,r){var i=On.r,s=jt;return ik(()=>{var o,a;return e0(()=>{o=a,a=[],_u(()=>{e!==n(...a)&&(t(e,...a),o&&f5(n(...o),e)&&t(null,...o))})}),()=>{let l=s;for(;l!==i&&l.parent!==null&&l.parent.f&ew;)l=l.parent;const u=()=>{a&&f5(n(...a),e)&&t(null,...a)},c=l.teardown;l.teardown=()=>{u(),c==null||c()}}}),e}function oG(e=!1){const t=On,n=t.l.u;if(!n)return;let r=()=>wR(t.s);if(e){let i=0,s={};const o=Jg(()=>{let a=!1;const l=t.s;for(const u in l)l[u]!==s[u]&&(s[u]=l[u],a=!0);return a&&i++,i});r=()=>v(o)}n.b.length&&RH(()=>{d5(t,r),J_(n.b)}),zt(()=>{const i=_u(()=>n.m.map(zW));return()=>{for(const s of i)typeof s=="function"&&s()}}),n.a.length&&zt(()=>{d5(t,r),J_(n.a)})}function d5(e,t){if(e.l.s)for(const n of e.l.s)v(n);t()}function ae(e,t,n,r){var x;var i=!dh||(n&CW)!==0,s=(n&FW)!==0,o=(n&DW)!==0,a=r,l=!0,u=()=>(l&&(l=!1,a=o?_u(r):r),a);let c;if(s){var f=Za in e||UW in e;c=((x=id(e,t))==null?void 0:x.set)??(f&&t in e?_=>e[t]=_:void 0)}var d,h=!1;s?[d,h]=uH(()=>e[t]):d=e[t],d===void 0&&r!==void 0&&(d=u(),c&&(i&&JW(),c(d)));var p;if(i?p=()=>{var _=e[t];return _===void 0?u():(l=!0,_)}:p=()=>{var _=e[t];return _!==void 0&&(a=void 0),_===void 0?a:_},i&&(n&$W)===0)return p;if(c){var g=e.$$legacy;return(function(_,w){return arguments.length>0?((!i||!w||g||h)&&c(w?p():_),_):p()})}var m=!1,y=((n&SW)!==0?Jg:QA)(()=>(m=!1,p()));s&&v(y);var b=jt;return(function(_,w){if(arguments.length>0){const A=w?v(y):i&&s?xt(_):_;return D(y,A),m=!0,a!==void 0&&(a=A),_}return ru&&m||(b.f&Ms)!==0?y.v:v(y)})}var aG=q(""),lG=q('');function uG(e,t){En(t,!0);let n=ae(t,"currentPage",3,"metrics"),r=ae(t,"tabAvailability",19,()=>({})),i=ae(t,"optionalEmptyTabs",19,()=>new Set);const s=[{id:"metrics",label:"Metrics"},{id:"system",label:"System Metrics"},{id:"traces",label:"Traces"},{id:"media",label:"Media & Tables"},{id:"reports",label:"Alerts & Reports"},{id:"runs",label:"Runs"},{id:"files",label:"Files"}];function o(h){var p;(p=t.onNavigate)==null||p.call(t,h)}function a(h){return i().has(h)&&r()[h]===!1}var l=lG(),u=R(C(l),2),c=C(u);$t(c,17,()=>s,Dt,(h,p)=>{var g=aG();let m;var y=C(g);ye((b,x)=>{m=tn(g,1,"nav-link svelte-d8j1hi",null,m,b),St(g,"title",x),me(y,v(p).label)},[()=>({active:n()===v(p).id,empty:a(v(p).id)}),()=>a(v(p).id)?`${v(p).label} is empty for this project`:v(p).label]),Oe("click",g,()=>o(v(p).id)),I(h,g)});var f=R(c,2);let d;ye(()=>d=tn(f,1,"nav-link settings-btn svelte-d8j1hi",null,d,{active:n()==="settings"})),Oe("click",f,()=>o("settings")),I(e,l),An()}si(["click"]);var cG=q(''),fG=q('
');function h5(e,t){En(t,!0);let n=ae(t,"choices",19,()=>[]),r=ae(t,"selected",31,()=>xt([])),i=ae(t,"colors",19,()=>[]),s=ae(t,"ontoggle",3,null),o=ae(t,"getKey",3,c=>c),a=ae(t,"getLabel",3,c=>c);function l(c){var d;const f=o()(c);r().includes(f)?r(r().filter(h=>h!==f)):r([...r(),f]),(d=s())==null||d()}var u=fG();$t(u,21,n,Dt,(c,f,d)=>{var h=cG(),p=C(h),g=R(p,2),m=R(g,2),y=C(m);ye((b,x,_)=>{Gf(p,b),ll(g,`background: ${(i()[d]||"#999")??""}`),St(m,"title",x),me(y,_)},[()=>r().includes(o()(v(f))),()=>a()(v(f)),()=>a()(v(f))]),Oe("change",p,()=>l(v(f))),I(c,h)}),I(e,u),An()}si(["change"]);var dG=q(' '),hG=q(' '),pG=q('
  • '),gG=q('
      '),mG=q('');function ex(e,t){En(t,!0);let n=ae(t,"label",3,"Dropdown"),r=ae(t,"info",3,""),i=ae(t,"value",15,null),s=ae(t,"choices",19,()=>[]),o=ae(t,"filterable",3,!0),a=ae(t,"showLabel",3,!0),l,u=re(!1),c=re(""),f=re(null),d=re(xt([])),h=re(0),p=re(null),g=re(null),m=re(300),y=we(()=>s().map(Y=>typeof Y=="object"&&Y!==null?Y:{label:String(Y),value:Y})),b=we(()=>i()!==null?v(y).findIndex(Y=>Y.value===i()):-1);zt(()=>{if(v(u))return;const Y=v(y).findIndex(J=>J.value===i());i()!==null&&Y>=0?D(c,v(y)[Y].label,!0):D(c,"")}),zt(()=>{D(d,v(u)?x(v(c)):v(y).map((Y,J)=>J),!0)});function x(Y){if(!Y)return v(y).map((ve,Te)=>Te);const J=Y.toLowerCase();return v(y).map((ve,Te)=>ve.label.toLowerCase().includes(J)?Te:-1).filter(ve=>ve>=0)}function _(){var Y;if(D(c,""),D(d,v(y).map((J,ve)=>ve),!0),D(u,!0),l){const J=(Y=l.closest(".wrap"))==null?void 0:Y.getBoundingClientRect();if(J){D(h,J.width,!0);const ve=window.innerHeight-J.bottom,Te=J.top;ve>=200||ve>Te?(D(p,`${J.bottom}px`),D(g,null),D(m,ve-16)):(D(g,`${window.innerHeight-J.top}px`),D(p,null),D(m,Te-16))}}}function w(Y){v(u)&&(Y.preventDefault(),l==null||l.blur())}function A(){const Y=v(y).findIndex(J=>J.label===v(c));if(Y>=0)i(v(y)[Y].value);else if(i()!==null){const J=v(y).findIndex(ve=>ve.value===i());D(c,J>=0?v(y)[J].label:"",!0)}else D(c,"");D(u,!1),D(f,null),D(d,v(y).map((J,ve)=>ve),!0)}function E(Y){const J=parseInt(Y);isNaN(J)||(i(v(y)[J].value),D(c,v(y)[J].label,!0),D(u,!1),D(f,null),l==null||l.blur())}async function k(Y){if(await ns(),D(d,x(v(c)),!0),v(d).length>0&&v(f)===null&&D(f,v(d)[0],!0),Y.key==="ArrowDown")if(Y.preventDefault(),v(f)===null)D(f,v(d)[0]??null,!0);else{const J=v(d).indexOf(v(f));J0&&D(f,v(d)[J-1],!0)}}else Y.key==="Enter"?v(f)!==null&&E(v(f)):Y.key==="Escape"&&(D(u,!1),l==null||l.blur())}var S=mG(),$=C(S);{var M=Y=>{var J=dG(),ve=C(J);ye(()=>me(ve,n())),I(Y,J)};he($,Y=>{a()&&Y(M)})}var O=R($,2);{var P=Y=>{var J=hG(),ve=C(J);ye(()=>me(ve,r())),I(Y,J)};he(O,Y=>{r()&&Y(P)})}var T=R(O,2);let F;var N=C(T),U=C(N),j=C(U);is(j,Y=>l=Y,()=>l);var W=R(T,2);{var Z=Y=>{var J=gG(),ve=C(J);let Te;$t(ve,21,()=>v(d),Dt,(Fe,He)=>{var ut=pG();let wt;var xe=C(ut);let je;var fe=R(xe);ye(()=>{wt=tn(ut,1,"item svelte-kgylqb",null,wt,{selected:v(He)===v(b),active:v(He)===v(f)}),St(ut,"data-index",v(He)),St(ut,"aria-selected",v(He)===v(b)),je=tn(xe,1,"check-mark svelte-kgylqb",null,je,{hide:v(He)!==v(b)}),me(fe,` ${v(y)[v(He)].label??""}`)}),I(Fe,ut)}),ye(()=>Te=ll(ve,"",Te,{top:v(p),bottom:v(g),"max-height":`${v(m)??""}px`,width:`${v(h)??""}px`})),Oe("mousedown",ve,Fe=>{var ut;Fe.preventDefault();const He=(ut=Fe.target.closest("li"))==null?void 0:ut.dataset.index;He!==void 0&&E(He)}),I(Y,J)};he(W,Y=>{v(u)&&Y(Z)})}ye(()=>{F=tn(T,1,"wrap svelte-kgylqb",null,F,{focused:v(u)}),St(j,"aria-label",n()),j.readOnly=!o(),St(j,"placeholder",i()===null?"Select...":"")}),Oe("mousedown",j,w),Oe("keydown",j,k),fn("blur",j,A),fn("focus",j,_),ph(j,()=>v(c),Y=>D(c,Y)),I(e,S),An()}si(["mousedown","keydown"]);var vG=q(' '),yG=q('');function rm(e,t){En(t,!0);let n=ae(t,"label",3,""),r=ae(t,"checked",15,!1),i=ae(t,"showLabel",3,!0);function s(c){r(c.currentTarget.checked)}var o=yG(),a=C(o),l=R(a,2);{var u=c=>{var f=vG(),d=C(f);ye(()=>me(d,n())),I(c,f)};he(l,c=>{i()&&n()&&c(u)})}Oe("input",a,s),sG(a,r),I(e,o),An()}si(["input"]);var bG=q(' '),xG=q(' '),_G=q('
      ');function wG(e,t){En(t,!0);let n=ae(t,"label",3,"Slider"),r=ae(t,"info",3,""),i=ae(t,"value",15,0),s=ae(t,"min",3,0),o=ae(t,"max",3,100),a=ae(t,"step",3,1),l=ae(t,"showLabel",3,!0),u,c=we(()=>i()>o()?100:i(){u&&u.style.setProperty("--range_progress",`${v(c)}%`)});var f=_G(),d=C(f),h=C(d);{var p=E=>{var k=bG(),S=C(k);ye(()=>me(S,n())),I(E,k)};he(h,E=>{l()&&E(p)})}var g=R(d,2);{var m=E=>{var k=xG(),S=C(k);ye(()=>me(S,r())),I(E,k)};he(g,E=>{r()&&E(m)})}var y=R(g,2),b=C(y),x=C(b),_=R(b,2);is(_,E=>u=E,()=>u);var w=R(_,2),A=C(w);ye(()=>{me(x,s()),St(_,"min",s()),St(_,"max",o()),St(_,"step",a()),me(A,o())}),ph(_,i),I(e,f),An()}var EG=q(' '),AG=q(' '),kG=q('
      ');function tx(e,t){En(t,!0);let n=ae(t,"label",3,""),r=ae(t,"info",3,""),i=ae(t,"value",15,""),s=ae(t,"placeholder",3,""),o=ae(t,"showLabel",3,!0);var a=kG(),l=C(a);{var u=p=>{var g=EG(),m=C(g);ye(()=>me(m,n())),I(p,g)};he(l,p=>{o()&&n()&&p(u)})}var c=R(l,2);{var f=p=>{var g=AG(),m=C(g);ye(()=>me(m,r())),I(p,g)};he(c,p=>{r()&&p(f)})}var d=R(c,2),h=C(d);ye(()=>St(h,"placeholder",s())),ph(h,i),I(e,a),An()}const SG=["#A8769B","#E89957","#3B82F6","#10B981","#EF4444","#8B5CF6","#14B8A6","#F59E0B","#EC4899","#06B6D4"];let gw=SG;function CG(e){Array.isArray(e)&&e.length>0&&(gw=e)}function mw(e){return gw[e%gw.length]}function n0(e){const t={};return e.forEach((n,r)=>{const i=typeof n=="string"?n:(n==null?void 0:n.id)??(n==null?void 0:n.name)??String(r);t[i]=mw(r)}),t}function p5(e){return!e||e.length===0?[]:[e[0]]}function $G(e,t,n){const r=e??[],i=t??[],s=n??[],o=new Set(i),a=r.filter(u=>o.has(u));if(r.length===0||a.length===0)return[...i];if(s.length>0&&r.length===s.length){const u=new Set(a),c=i.filter(f=>!u.has(f));return[...a,...c]}return a}const CR=["project","run","timestamp","step","time","metrics"];function FG(e,t,n,r,i,s){if(!e||e.length===0)return null;let o=e.map(d=>({...d}));Object.hasOwn(o[0],"step")||o.forEach((d,h)=>d.step=h);let a="step";if(r==="time"&&Object.hasOwn(o[0],"timestamp")){const d=new Date(o[0].timestamp).getTime();o.forEach(h=>{h.time=(new Date(h.timestamp).getTime()-d)/1e3}),a="time"}else r!=="step"&&o.some(d=>typeof d[r]=="number"&&isFinite(d[r]))&&(a=r);i&&o.forEach(d=>{if(d[a]!=null){const h=d[a];d[a]=h<=0?Math.log10(Math.max(h,0)+1):Math.log10(h)}});const u=$R(o).filter(d=>!CR.includes(d)&&d!==a);s&&o.forEach(d=>{u.forEach(h=>{if(d[h]!=null&&typeof d[h]=="number"){const p=d[h];d[h]=p<=0?Math.log10(Math.max(p,0)+1):Math.log10(p)}})});const c=typeof t=="string"?t:(t==null?void 0:t.id)??(t==null?void 0:t.name),f=typeof t=="string"?t:(t==null?void 0:t.name)??(t==null?void 0:t.id);if(n>0){const d=o.map(p=>({...p,run:f,run_id:c,series_key:c,data_type:"original"})),h=DG(o,u,n).map(p=>({...p,run:f,run_id:c,series_key:c,data_type:"smoothed"}));return{rows:[...d,...h],xColumn:a}}return{rows:o.map(d=>({...d,run:f,run_id:c,series_key:c,data_type:"original"})),xColumn:a}}function DG(e,t,n){const r=Math.max(3,Math.min(n,e.length)),i=Math.floor(r/2);return e.map((s,o)=>{const a={...s};return t.forEach(l=>{if(s[l]==null||typeof s[l]!="number")return;const u=Math.max(0,o-i),c=Math.min(e.length,o+i+1);let f=0,d=0;for(let h=u;h0?f/d:s[l]}),a})}function $R(e){if(!e||e.length===0)return[];const t=new Set;return e.forEach(n=>{Object.keys(n).forEach(r=>{typeof n[r]=="number"&&isFinite(n[r])&&t.add(r)})}),Array.from(t)}function MG(e){return $R(e).filter(t=>!CR.includes(t))}function vw(e,t,n,r){let i=e.filter(a=>a[n]!=null&&a[n]!==void 0);if(r){const a=new Map;for(const u of i){const c=`${u.series_key||u.run||""}\0${u.data_type||"original"}`;a.has(c)||a.set(c,[]),a.get(c).push(u)}const l=[];for(const[,u]of a){u.sort((d,h)=>d[t]-h[t]);let c=0,f=u.length-1;for(;c=0&&u[f][t]>r[1];)f--;c=Math.max(0,c-1),f=Math.min(u.length-1,f+1),l.push(...u.slice(c,f+1))}i=l}const s=i.filter(a=>a.data_type==="original"||!a.data_type);let o;if(s.length>0){let a=1/0,l=-1/0;for(const u of s){const c=u[n];c!=null&&(cl&&(l=c))}a!==1/0&&(o=[a,l])}return{data:FR(i,t,n,"series_key",r,["run","series_key"]).data,yExtent:o}}function g5(e,t,n,r,i,s=[]){const o=[t,n];r&&Object.hasOwn(e[0],r)&&o.push(r),o.push(...s);let a=e.map(p=>{const g={};return[...new Set(o)].forEach(m=>g[m]=p[m]),p.data_type&&(g.data_type=p.data_type),p.run&&(g.run=p.run),g});const l=Math.min(...a.map(p=>p[t]).filter(p=>p!=null)),u=Math.max(...a.map(p=>p[t]).filter(p=>p!=null));let c=i;if(i){const[p,g]=[i[0]??l,i[1]??u];c=[p,g]}const f={};r?a.forEach(p=>{const g=p[r]||"__default";f[g]||(f[g]=[]),f[g].push(p)}):f.__default=a;const d=[],h=100;return Object.values(f).forEach(p=>{if(p.sort((x,_)=>(x[t]||0)-(_[t]||0)),p.length<500){d.push(...p);return}const g=c?c[0]:l,m=c?c[1]:u;if(g===m){d.push(...p);return}const y=(m-g)/h,b=new Map;p.forEach(x=>{const _=x[t];if(_==null)return;const w=Math.min(Math.floor((_-g)/y),h-1);b.has(w)||b.set(w,[]),b.get(w).push(x)}),b.forEach(x=>{if(x.length===0)return;let _=x[0],w=x[0];x.forEach(A=>{A[n]<_[n]&&(_=A),A[n]>w[n]&&(w=A)}),d.push(_),_!==w&&d.push(w)})}),d.sort((p,g)=>(p[t]||0)-(g[t]||0)),{data:d,xLim:c}}function FR(e,t,n,r,i,s=[]){if(!e||e.length===0)return{data:e,xLim:i};if(e.some(a=>a.data_type)&&r&&e[0]&&Object.hasOwn(e[0],r)){const a=new Map;for(const c of e){const f=`${c[r]??"__default"}\0${c.data_type??"original"}`;a.has(f)||a.set(f,[]),a.get(f).push(c)}const l=[];let u=i;for(const c of a.values()){const f=g5(c,t,n,r,i,s);l.push(...f.data),u=f.xLim}return l.sort((c,f)=>(c[t]||0)-(f[t]||0)),{data:l,xLim:u}}return g5(e,t,n,r,i,s)}function DR(e,t=[]){const n=[],r={};e.forEach(u=>{if(u.includes("/")){const c=u.split("/"),f=c[0];if(r[f]||(r[f]={direct:[],subgroups:{}}),c.length===2)r[f].direct.push(u);else{const d=c[1];r[f].subgroups[d]||(r[f].subgroups[d]=[]),r[f].subgroups[d].push(u)}}else n.push(u)});function i(u){if(!t||t.length===0)return u.sort();const c=[],f=[...u];for(const d of t)for(let h=f.length-1;h>=0;h--)s(f[h],d)&&(c.push(f[h]),f.splice(h,1));return f.sort(),[...c,...f]}function s(u,c){return c===u||c.endsWith("/*")&&u.startsWith(c.slice(0,-1))?!0:c.includes("*")?new RegExp("^"+c.replace(/\*/g,".*")+"$").test(u):!1}function o(u){if(!t||t.length===0)return 1/0;for(let c=0;c0&&(a.charts={direct:i(n),subgroups:{}});const l=Object.keys(r);if(l.sort((u,c)=>{const f=o(u),d=o(c);return f!==d?f-d:u.localeCompare(c)}),l.forEach(u=>{const c=r[u];c.direct=i(c.direct),Object.keys(c.subgroups).forEach(f=>{c.subgroups[f]=i(c.subgroups[f])}),a[u]=c}),"charts"in a){const u=o("charts");if(u<1/0){const c=Object.entries(a);c.sort(([d],[h])=>{const p=d==="charts"?u:o(d),g=h==="charts"?u:o(h);return p!==g?p-g:d.localeCompare(h)});const f={};return c.forEach(([d,h])=>{f[d]=h}),f}}return a}function MR(e,t,n){if(!t||!e||e.length===0)return"";const r=new Set,i=[];for(const s of e){const o=s[t];o&&!r.has(o)&&(r.add(o),i.push(`${o}:${n[o]??"#999"}`))}return i.sort(),i.join("|")}function m5(e){if(!e)return null;const t=typeof e.step=="number"?e.step:null,n=e.timestamp??null;return{step:t,ts:n}}function TR(e,t){if(!e||!t)return!!t;if(t.length!==e.length)return!0;if(t.length===0)return!1;const n=m5(e[e.length-1]),r=m5(t[t.length-1]);return!n||!r?!0:n.step!==r.step||n.ts!==r.ts}function Cy(e,t){if(!t||!t.trim())return e;try{const n=new RegExp(t,"i");return e.filter(r=>n.test(r))}catch{return e.filter(n=>n.toLowerCase().includes(t.toLowerCase()))}}const I1=Object.freeze({_Group:"Group",_Username:"Username"});function TG(e){return e.startsWith("_")&&!Object.hasOwn(I1,e)}function RG(e){return I1[e]??e}function NG(e,t){const n=new Set;for(const r of Object.values(e??{})){if(!r||typeof r!="object")continue;const i=r[t],s=i==null?"(unset)":String(i);if(n.add(s),n.size>=2)return!0}return!1}function OG(e){const t=Object.keys(I1).filter(o=>NG(e,o)).map(o=>({label:RG(o),value:o})),n=new Set(t.map(o=>o.label)),r=new Set,i=new Set;for(const o of Object.values(e??{}))if(!(!o||typeof o!="object"))for(const a of Object.keys(o))o[a]===null||o[a]===void 0||TG(a)||Object.hasOwn(I1,a)||n.has(a)||(typeof o[a]=="object"?i.add(a):r.add(a));for(const o of i)r.delete(o);const s=[...r].sort().map(o=>({label:o,value:o}));return[{label:"None",value:null},...t,...s]}function LG(e,t,n){if(!n)return null;const r=new Map;for(const i of e){const o=((t??{})[i.id]??(t??{})[i.name]??{})[n],a=o==null?"(unset)":String(o);r.has(a)||r.set(a,[]),r.get(a).push(i)}return r}var IG=Ei(''),PG=Ei(''),BG=q('
      ',1),zG=q('
      '),jG=Ei(''),UG=q(''),qG=q(''),WG=q(''),HG=Ei(''),GG=q(''),YG=q(''),VG=q(''),XG=q('
      '),KG=q('
      '),ZG=q('
      '),JG=q('
      '),QG=q(''),eY=q('
      '),tY=q('
      ',1),nY=q('
      ',1),rY=q(''),iY=q('

      Signed in, but this account does not have write access to this Space.

      '),sY=q('

      Required to delete or rename runs (Space owner or collaborator with write access).

      ',1),oY=q(''),aY=q(''),lY=q(''),uY=q('
      ');function cY(e,t){En(t,!0);let n=ae(t,"open",15,!0),r=ae(t,"variant",3,"full"),i=ae(t,"currentPage",3,"metrics"),s=ae(t,"projects",19,()=>[]),o=ae(t,"selectedProject",15,null),a=ae(t,"runs",19,()=>[]),l=ae(t,"selectedRuns",31,()=>xt([])),u=ae(t,"availableSystemDevices",19,()=>[]),c=ae(t,"selectedSystemDevices",31,()=>xt([])),f=ae(t,"smoothing",15,10),d=ae(t,"xAxis",15,"step"),h=ae(t,"logScaleX",15,!1),p=ae(t,"logScaleY",15,!1),g=ae(t,"metricFilter",15,""),m=ae(t,"realtimeEnabled",15,!0),y=ae(t,"showHeaders",15,!0),b=ae(t,"filterText",15,""),x=ae(t,"runConfigs",19,()=>({})),_=ae(t,"metricColumns",19,()=>[]),w=ae(t,"spacesMode",3,!1),A=ae(t,"runMutationAllowed",3,!0),E=ae(t,"mutationAuth",3,"local"),k=ae(t,"readOnlySource",3,null),S=ae(t,"projectLocked",3,!1),$=ae(t,"spaceId",3,null),M=ae(t,"logoUrls",19,()=>({light:"/static/trackio/trackio_logo_type_light_transparent.png",dark:"/static/trackio/trackio_logo_type_dark_transparent.png"})),O=ae(t,"darkMode",3,!1),P=re(0),T=null;hh(()=>{const K=()=>{tR(P)};return window.addEventListener("popstate",K),()=>{window.removeEventListener("popstate",K),T&&(clearTimeout(T),T=null)}});let F=we(()=>(v(P),`${window.location.origin}/oauth/hf/start`)),N=we(()=>["step","time",..._()]);function U(){n(!n())}function j(K,ge){return K.indeterminate=ge,{update(_e){K.indeterminate=_e}}}let W=we(()=>{if(!b()||!b().trim())return a();const K=new Set(Cy(a().map(ge=>ge.name),b()));return a().filter(ge=>K.has(ge.name))}),Z=we(()=>n0(a())),Y=we(()=>v(W).map(K=>K.id??K.name)),J=re(null);zt(()=>{o(),D(J,null)}),zt(()=>{v(ve).some(K=>K.value===v(J))||D(J,null)});let ve=we(()=>OG(x())),Te=we(()=>LG(v(W),x(),v(J))),Fe=re(!1),He=re("share"),ut=re(null);function wt(){D(Fe,!v(Fe)),v(Fe)&&v(W).length>0?l(p5(v(Y))):v(Fe)||l([...v(Y)])}zt(()=>{if(!v(Fe)||v(Y).length===0)return;const K=p5(v(Y));(l().length!==K.length||l()[0]!==K[0])&&l(K)});function xe(K){c().includes(K)?c(c().filter(ge=>ge!==K)):c([...c(),K])}function je(K){if(!K||!K.includes("/"))return"";const[ge,_e]=K.split("/",2);return!ge||!_e?"":`${ge}-${_e}.hf.space`}function fe(){const K=je($());if(K)return`https://${K}`;const ge=window.__trackio_base||"/",_e=new URL(ge,window.location.origin);let De=_e.href;return De.endsWith("/")&&(De=De.slice(0,-1)),De||_e.origin}function V(K,ge){const _e=new Set(ge.map(De=>De.id??De.name));return K.filter(De=>_e.has(De))}let B=we(()=>{var ct;if(v(P),i()!=="metrics"||!w()||!o())return"";const K=new URLSearchParams;K.set("project",o()),(ct=g())!=null&&ct.trim()&&K.set("metric_filter",g().trim());const ge=V(l(),a());ge.length&&K.set("run_ids",ge.join(",")),f()!=null&&f()!==10&&K.set("smoothing",f().toString()),y()||K.set("accordion","hidden"),K.set("sidebar","hidden"),K.set("navbar","hidden");const _e=fe(),De=K.toString();return De?`${_e}/?${De}`:`${_e}/`}),L=we(()=>v(B)?``:"");async function X(K,ge){if(K){try{await navigator.clipboard.writeText(K)}catch{const _e=document.createElement("textarea");_e.value=K,_e.style.position="fixed",_e.style.opacity="0",document.body.appendChild(_e),_e.focus(),_e.select(),document.execCommand("copy"),document.body.removeChild(_e)}D(ut,ge,!0),T&&clearTimeout(T),T=setTimeout(()=>{D(ut,null),T=null},2e3)}}var G=uY();let z;var te=C(G),Ne=C(te);{var H=K=>{var ge=IG();I(K,ge)},ee=K=>{var ge=PG();I(K,ge)};he(Ne,K=>{n()?K(H):K(ee,-1)})}var ne=R(te,2);{var be=K=>{var ge=lY(),_e=C(ge),De=C(_e),ct=C(De),ze=R(De,2),Xe=C(ze);{var lt=Ke=>{var Ze=BG(),We=R(Bt(Ze),2),it=C(We);ye(()=>me(it,o()??"—")),I(Ke,Ze)},yt=Ke=>{ex(Ke,{label:"Project",get choices(){return s()},filterable:!0,get value(){return o()},set value(Ze){o(Ze)}})};he(Xe,Ke=>{S()?Ke(lt):Ke(yt,-1)})}var pt=R(ze,2);{var rt=Ke=>{var Ze=zG(),We=C(Ze);tx(We,{label:"Run Filter",info:"Filter runs using regex patterns. Leave empty to show all runs.",placeholder:"e.g., baseline|exp-.*|v2",get value(){return b()},set value(it){b(it)}}),I(Ke,Ze)};he(pt,Ke=>{r()==="compact"&&i()==="runs"&&Ke(rt)})}var Ve=R(pt,2);{var qe=Ke=>{var Ze=nY(),We=Bt(Ze);{var it=Jt=>{var Dn=XG(),Br=C(Dn),hn=C(Br);let pn;var Si=R(hn,2);let oi;var Kn=R(Br,2);{var Zn=ar=>{var Ci=WG(),ai=R(C(Ci),2);{var gn=wr=>{var Er=UG(),bn=C(Er),zr=R(bn,2),Pn=C(zr);{var Sn=Ar=>{var Gs=jG();I(Ar,Gs)},Ma=Ar=>{var Gs=hw("Copy");I(Ar,Gs)};he(Pn,Ar=>{v(ut)==="share"?Ar(Sn):Ar(Ma,-1)})}ye(()=>{u5(bn,v(B)),St(zr,"aria-label",v(ut)==="share"?"Copied":"Copy share link")}),Oe("click",zr,()=>X(v(B),"share")),I(wr,Er)},zu=wr=>{var Er=qG();I(wr,Er)};he(ai,wr=>{v(B)?wr(gn):wr(zu,-1)})}I(ar,Ci)},vs=ar=>{var Ci=VG(),ai=R(C(Ci),2);{var gn=wr=>{var Er=GG(),bn=C(Er),zr=R(bn,2),Pn=C(zr);{var Sn=Ar=>{var Gs=HG();I(Ar,Gs)},Ma=Ar=>{var Gs=hw("Copy");I(Ar,Gs)};he(Pn,Ar=>{v(ut)==="embed"?Ar(Sn):Ar(Ma,-1)})}ye(()=>{u5(bn,v(L)),St(zr,"aria-label",v(ut)==="embed"?"Copied":"Copy embed code")}),Oe("click",zr,()=>X(v(L),"embed")),I(wr,Er)},zu=wr=>{var Er=YG();I(wr,Er)};he(ai,wr=>{v(L)?wr(gn):wr(zu,-1)})}I(ar,Ci)};he(Kn,ar=>{v(He)==="share"?ar(Zn):ar(vs,-1)})}ye(()=>{pn=tn(hn,1,"share-tab-btn svelte-181dlmc",null,pn,{active:v(He)==="share"}),oi=tn(Si,1,"share-tab-btn svelte-181dlmc",null,oi,{active:v(He)==="embed"})}),Oe("click",hn,()=>{D(He,"share")}),Oe("click",Si,()=>{D(He,"embed")}),I(Jt,Dn)};he(We,Jt=>{i()==="metrics"&&w()&&Jt(it)})}var bt=R(We,2),Et=C(bt),Ge=C(Et),dt=C(Ge);X2(dt,(Jt,Dn)=>j==null?void 0:j(Jt,Dn),()=>l().length>0&&l().length{var Dn=ZG();$t(Dn,21,()=>[...v(Te).entries()],Dt,(Br,hn)=>{var pn=we(()=>XA(v(hn),2));let Si=()=>v(pn)[0],oi=()=>v(pn)[1];const Kn=we(()=>oi().map(Pn=>Pn.id??Pn.name)),Zn=we(()=>v(Kn).filter(Pn=>l().includes(Pn)));var vs=KG(),ar=C(vs),Ci=C(ar),ai=C(Ci);X2(ai,(Pn,Sn)=>j==null?void 0:j(Pn,Sn),()=>v(Zn).length>0&&v(Zn).lengthoi().map(Sn=>v(Z)[Sn.id??Sn.name]??mw(Math.max(0,a().indexOf(Sn)))));h5(zr,{get choices(){return oi()},getKey:Sn=>Sn.id??Sn.name,getLabel:Sn=>Sn.name,get colors(){return v(Pn)},ontoggle:()=>{D(Fe,!1)},get selected(){return l()},set selected(Sn){l(Sn)}})}ye(()=>{Gf(ai,v(Zn).length===v(Kn).length&&v(Kn).length>0),St(gn,"title",Si()),me(zu,Si()),me(Er,`(${oi().length??""})`)}),Oe("change",ai,()=>{if(v(Zn).length===v(Kn).length)l(l().filter(Pn=>!v(Kn).includes(Pn)));else{const Pn=v(Kn).filter(Sn=>!l().includes(Sn));l([...l(),...Pn])}D(Fe,!1)}),I(Br,vs)}),I(Jt,Dn)},kn=Jt=>{var Dn=JG(),Br=C(Dn);{let hn=we(()=>v(W).map(pn=>v(Z)[pn.id??pn.name]??mw(Math.max(0,a().indexOf(pn)))));h5(Br,{get choices(){return v(W)},getKey:pn=>pn.id??pn.name,getLabel:pn=>pn.name,get colors(){return v(hn)},ontoggle:()=>{D(Fe,!1)},get selected(){return l()},set selected(pn){l(pn)}})}I(Jt,Dn)};he(Qe,Jt=>{v(Te)?Jt(vt):Jt(kn,-1)})}var In=R(Qe,2);{var Gn=Jt=>{var Dn=eY(),Br=C(Dn),hn=C(Br);X2(hn,(Kn,Zn)=>j==null?void 0:j(Kn,Zn),()=>c().length>0&&c().length{var vs=QG(),ar=C(vs),Ci=R(ar,2),ai=C(Ci);ye(gn=>{Gf(ar,gn),St(Ci,"title",v(Zn)),me(ai,v(Zn))},[()=>c().includes(v(Zn))]),Oe("change",ar,()=>xe(v(Zn))),I(Kn,vs)}),ye(()=>{Gf(hn,c().length===u().length&&u().length>0),me(Si,`Devices (${u().length??""})`)}),Oe("change",hn,()=>{c().length===u().length?c([]):c([...u()])}),I(Jt,Dn)};he(In,Jt=>{i()==="system"&&u().length>0&&Jt(Gn)})}var or=R(bt,2);{var Xi=Jt=>{var Dn=tY(),Br=R(Bt(Dn),2),hn=C(Br);rm(hn,{label:"Refresh metrics realtime",get checked(){return m()},set checked(gn){m(gn)}});var pn=R(hn,2);rm(pn,{label:"Show section headers",get checked(){return y()},set checked(gn){y(gn)}});var Si=R(Br,2),oi=C(Si);wG(oi,{label:"Smoothing Factor (0 = no smoothing)",min:0,max:20,step:1,get value(){return f()},set value(gn){f(gn)}});var Kn=R(Si,2),Zn=C(Kn);ex(Zn,{label:"X-axis",get choices(){return v(N)},filterable:!1,get value(){return d()},set value(gn){d(gn)}});var vs=R(Zn,2);rm(vs,{label:"Log scale X-axis",get checked(){return h()},set checked(gn){h(gn)}});var ar=R(vs,2);rm(ar,{label:"Log scale Y-axis",get checked(){return p()},set checked(gn){p(gn)}});var Ci=R(Kn,2),ai=C(Ci);tx(ai,{label:"Metric Filter",info:"Filter metrics using regex patterns. Leave empty to show all metrics.",placeholder:"e.g., loss|ndcg@10|gpu",get value(){return g()},set value(gn){g(gn)}}),I(Jt,Dn)};he(or,Jt=>{(i()==="metrics"||i()==="system")&&Jt(Xi)})}ye(()=>{Gf(dt,l().length===v(Y).length&&v(Y).length>0),me(se,`Runs (${v(Y).length??""})`),Gf(At,v(Fe))}),Oe("change",dt,()=>{l().length===v(Y).length?l([]):l([...v(Y)]),D(Fe,!1)}),Oe("change",At,wt),I(Ke,Ze)};he(Ve,Ke=>{r()==="full"&&Ke(qe)})}var Q=R(_e,2);{var pe=Ke=>{var Ze=rY(),We=R(C(Ze),2),it=C(We);ye(()=>{St(We,"href",k().url),me(it,k().url)}),I(Ke,Ze)},Ye=Ke=>{var Ze=oY(),We=C(Ze);{var it=Et=>{var Ge=iY();I(Et,Ge)},bt=Et=>{var Ge=sY(),dt=Bt(Ge);ye(()=>St(dt,"href",v(F))),I(Et,Ge)};he(We,Et=>{E()==="oauth_insufficient"?Et(it):Et(bt,-1)})}I(Ke,Ze)},gt=Ke=>{var Ze=aY(),We=R(C(Ze),2);Oe("click",We,()=>{sessionStorage.removeItem("trackio_oauth_session")}),I(Ke,Ze)};he(Q,Ke=>{k()?Ke(pe):w()&&!A()?Ke(Ye,1):w()&&A()&&E()==="oauth"&&Ke(gt,2)})}ye(()=>St(ct,"src",O()?M().dark:M().light)),I(K,ge)};he(ne,K=>{n()&&K(be)})}ye(()=>z=tn(G,1,"sidebar svelte-181dlmc",null,z,{collapsed:!n()})),Oe("click",te,U),I(e,G),An()}si(["click","change"]);var fY=q('
      '),dY=q('
      '),hY=q('
      '),pY=q('
      '),gY=q('
      ');function mY(e,t){En(t,!0);let n=ae(t,"alerts",19,()=>[]);const r={info:"🔵",warn:"🟡",error:"🔴"};let i=re(xt({})),s=re(null),o=re(!1),a=we(()=>v(s)?n().filter(d=>d.level===v(s)):n());function l(d){D(i,{...v(i),[d]:!v(i)[d]},!0)}var u=Ni(),c=Bt(u);{var f=d=>{var h=gY();let p;var g=C(h),m=C(g),y=C(m),b=R(m,2);{var x=k=>{var S=fY(),$=C(S);let M;var O=R($,2);let P;var T=R(O,2);let F;var N=R(T,2);let U;ye(()=>{M=tn($,1,"pill svelte-x5aqew",null,M,{active:v(s)===null}),P=tn(O,1,"pill svelte-x5aqew",null,P,{active:v(s)==="info"}),F=tn(T,1,"pill svelte-x5aqew",null,F,{active:v(s)==="warn"}),U=tn(N,1,"pill svelte-x5aqew",null,U,{active:v(s)==="error"})}),Oe("click",$,j=>{j.stopPropagation(),D(s,null)}),Oe("click",O,j=>{j.stopPropagation(),D(s,"info")}),Oe("click",T,j=>{j.stopPropagation(),D(s,"warn")}),Oe("click",N,j=>{j.stopPropagation(),D(s,"error")}),I(k,S)};he(b,k=>{v(o)||k(x)})}var _=R(b,2);let w;var A=R(g,2);{var E=k=>{var S=pY();$t(S,21,()=>v(a),Dt,($,M,O)=>{var P=hY();let T;var F=C(P),N=C(F),U=C(N),j=R(N,2),W=C(j),Z=R(j,2),Y=C(Z),J=R(F,2);{var ve=Te=>{var Fe=dY(),He=C(Fe);ye(()=>me(He,v(M).text)),I(Te,Fe)};he(J,Te=>{v(i)[O]&&v(M).text&&Te(ve)})}ye(()=>{T=tn(P,1,"alert-item svelte-x5aqew",null,T,{expanded:v(i)[O]}),me(U,r[v(M).level]||""),me(W,v(M).title),me(Y,v(M).meta||"")}),Oe("click",F,()=>l(O)),I($,P)}),I(k,S)};he(A,k=>{v(o)||k(E)})}ye(()=>{p=tn(h,1,"alert-panel svelte-x5aqew",null,p,{collapsed:v(o)}),me(y,`Alerts (${n().length??""})`),w=tn(_,0,"collapse-icon svelte-x5aqew",null,w,{rotated:v(o)})}),Oe("click",g,()=>D(o,!v(o))),Oe("keydown",g,k=>k.key==="Enter"&&D(o,!v(o))),I(d,h)};he(c,d=>{n().length>0&&d(f)})}I(e,u),An()}si(["click","keydown"]);function v5(){const e=window.location.pathname.replace(/\/+$/,"")||"/";switch(e==="/"?"":e.replace(/^\//,"").split("/")[0]){case"":case"metrics":return"metrics";case"system":return"system";case"traces":return"traces";case"media":return"media";case"reports":return"reports";case"runs":return"runs";case"run":return"run-detail";case"files":return"files";case"settings":return"settings";default:return"metrics"}}function yw(e){const t=new URLSearchParams(window.location.search),r={metrics:"/",traces:"/traces",system:"/system",media:"/media",reports:"/reports",runs:"/runs","run-detail":"/run",files:"/files",settings:"/settings"}[e]||"/",i=t.toString(),s=i?`${r}?${i}`:r;window.history.pushState({},"",s),window.dispatchEvent(new PopStateEvent("popstate"))}function Hr(e){return new URLSearchParams(window.location.search).get(e)}function y5(e,t){const n=new URLSearchParams(window.location.search);t!=null&&t!==""?n.set(e,t):n.delete(e);const r=n.toString(),i=r?`${window.location.pathname}?${r}`:window.location.pathname;window.history.replaceState({},"",i)}const vY=/("(?:[^\\"]|\\.)*")|[:,]/g;function nx(e,t={}){const n=JSON.stringify([1],void 0,t.indent===void 0?2:t.indent).slice(2,-3),r=n===""?1/0:t.maxLength===void 0?80:t.maxLength;let{replacer:i}=t;return(function s(o,a,l){o&&typeof o.toJSON=="function"&&(o=o.toJSON());const u=JSON.stringify(o,i);if(u===void 0)return u;const c=r-a.length-l;if(u.length<=c){const f=u.replace(vY,(d,h)=>h||`${d} `);if(f.length<=c)return f}if(i!=null&&(o=JSON.parse(u),i=void 0),typeof o=="object"&&o!==null){const f=a+n,d=[];let h=0,p,g;if(Array.isArray(o)){p="[",g="]";const{length:m}=o;for(;h0)return[p,n+d.join(`, +${f}`),g].join(` +${a}`)}return u})(e,"",0)}function Yi(e,t,n){return e.fields=t||[],e.fname=n,e}function Ln(e){return e==null?null:e.fname}function Kr(e){return e==null?null:e.fields}function RR(e){return e.length===1?yY(e[0]):bY(e)}const yY=e=>function(t){return t[e]},bY=e=>{const t=e.length;return function(n){for(let r=0;ro?u():o=a+1:l==="["?(a>o&&u(),i=o=a+1):l==="]"&&(i||le("Access path missing open bracket: "+e),i>0&&u(),i=0,o=a+1)}return i&&le("Access path missing closing bracket: "+e),r&&le("Access path missing closing quote: "+e),a>o&&(a++,u()),t}function Ls(e,t,n){const r=va(e);return e=r.length===1?r[0]:e,Yi((n&&n.get||RR)(r),[e],t||e)}const r0=Ls("id"),ni=Yi(e=>e,[],"identity"),Ol=Yi(()=>0,[],"zero"),gh=Yi(()=>1,[],"one"),ds=Yi(()=>!0,[],"true"),Cl=Yi(()=>!1,[],"false"),uk=new Set(Object.getOwnPropertyNames(Object.prototype));function xY(e,t,n){const r=[t].concat([].slice.call(n));console[e].apply(console,r)}const NR=0,ck=1,fk=2,OR=3,LR=4;function dk(e,t){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:xY,r=e||NR;return{level(i){return arguments.length?(r=+i,this):r},error(){return r>=ck&&n(t||"error","ERROR",arguments),this},warn(){return r>=fk&&n(t||"warn","WARN",arguments),this},info(){return r>=OR&&n(t||"log","INFO",arguments),this},debug(){return r>=LR&&n(t||"log","DEBUG",arguments),this}}}var de=Array.isArray;function Le(e){return e===Object(e)}const b5=e=>e!=="__proto__";function mh(){for(var e=arguments.length,t=new Array(e),n=0;n{for(const s in i)if(s==="signals")r.signals=_Y(r.signals,i.signals);else{const o=s==="legend"?{layout:1}:s==="style"?!0:null;vh(r,s,i[s],o)}return r},{})}function vh(e,t,n,r){if(!b5(t))return;let i,s;if(Le(n)&&!de(n)){s=Le(e[t])?e[t]:e[t]={};for(i in n)r&&(r===!0||r[i])?vh(s,i,n[i]):b5(i)&&(s[i]=n[i])}else e[t]=n}function _Y(e,t){if(e==null)return t;const n={},r=[];function i(s){n[s.name]||(n[s.name]=1,r.push(s))}return t.forEach(i),e.forEach(i),r}function Wt(e){return e[e.length-1]}function Vr(e){return e==null||e===""?null:+e}const IR=e=>t=>e*Math.exp(t),PR=e=>t=>Math.log(e*t),BR=e=>t=>Math.sign(t)*Math.log1p(Math.abs(t/e)),zR=e=>t=>Math.sign(t)*Math.expm1(Math.abs(t))*e,P1=e=>t=>t<0?-Math.pow(-t,e):Math.pow(t,e);function $y(e,t,n,r){const i=n(e[0]),s=n(Wt(e)),o=(s-i)*t;return[r(i-o),r(s-o)]}function jR(e,t){return $y(e,t,Vr,ni)}function UR(e,t){var n=Math.sign(e[0]);return $y(e,t,PR(n),IR(n))}function qR(e,t,n){return $y(e,t,P1(n),P1(1/n))}function WR(e,t,n){return $y(e,t,BR(n),zR(n))}function Fy(e,t,n,r,i){const s=r(e[0]),o=r(Wt(e)),a=t!=null?r(t):(s+o)/2;return[i(a+(s-a)*n),i(a+(o-a)*n)]}function hk(e,t,n){return Fy(e,t,n,Vr,ni)}function pk(e,t,n){const r=Math.sign(e[0]);return Fy(e,t,n,PR(r),IR(r))}function B1(e,t,n,r){return Fy(e,t,n,P1(r),P1(1/r))}function gk(e,t,n,r){return Fy(e,t,n,BR(r),zR(r))}function HR(e){return 1+~~(new Date(e).getMonth()/3)}function GR(e){return 1+~~(new Date(e).getUTCMonth()/3)}function Be(e){return e!=null?de(e)?e:[e]:[]}function YR(e,t,n){let r=e[0],i=e[1],s;return i=n-t?[t,n]:[r=Math.min(Math.max(r,t),n-s),r+s]}function Tt(e){return typeof e=="function"}const wY="descending";function mk(e,t,n){n=n||{},t=Be(t)||[];const r=[],i=[],s={},o=n.comparator||EY;return Be(e).forEach((a,l)=>{a!=null&&(r.push(t[l]===wY?-1:1),i.push(a=Tt(a)?a:Ls(a,null,n)),(Kr(a)||[]).forEach(u=>s[u]=1))}),i.length===0?null:Yi(o(i,r),Object.keys(s))}const yh=(e,t)=>(et||t==null)&&e!=null?1:(t=t instanceof Date?+t:t,(e=e instanceof Date?+e:e)!==e&&t===t?-1:t!==t&&e===e?1:0),EY=(e,t)=>e.length===1?AY(e[0],t[0]):kY(e,t,e.length),AY=(e,t)=>function(n,r){return yh(e(n),e(r))*t},kY=(e,t,n)=>(t.push(0),function(r,i){let s,o=0,a=-1;for(;o===0&&++ae}function vk(e,t){let n;return r=>{n&&clearTimeout(n),n=setTimeout(()=>(t(r),n=null),e)}}function Mt(e){for(let t,n,r=1,i=arguments.length;ro&&(o=i))}else{for(i=t(e[n]);no&&(o=i))}return[s,o]}function VR(e,t){const n=e.length;let r=-1,i,s,o,a,l;if(t==null){for(;++r=s){i=o=s;break}if(r===n)return[-1,-1];for(a=l=r;++rs&&(i=s,a=r),o=s){i=o=s;break}if(r===n)return[-1,-1];for(a=l=r;++rs&&(i=s,a=r),o{i.set(s,e[s])}),i}function XR(e,t,n,r,i,s){if(!n&&n!==0)return s;const o=+n;let a=e[0],l=Wt(e),u;ls&&(o=i,i=s,s=o),n=n===void 0||n,r=r===void 0||r,(n?i<=e:ia.replace(/\\(.)/g,"$1")):Be(e));const r=e&&e.length,i=n&&n.get||RR,s=a=>i(t?[a]:va(a));let o;if(!r)o=function(){return""};else if(r===1){const a=s(e[0]);o=function(l){return""+a(l)}}else{const a=e.map(s);o=function(l){let u=""+a[0](l),c=0;for(;++c{t={},n={},r=0},s=(o,a)=>(++r>e&&(n=t,t={},r=1),t[o]=a);return i(),{clear:i,has:o=>Ue(t,o)||Ue(n,o),get:o=>Ue(t,o)?t[o]:Ue(n,o)?s(o,n[o]):void 0,set:(o,a)=>Ue(t,o)?t[o]=a:s(o,a)}}function QR(e,t,n,r){const i=t.length,s=n.length;if(!s)return t;if(!i)return n;const o=r||new t.constructor(i+s);let a=0,l=0,u=0;for(;a0?n[l++]:t[a++];for(;a=0;)n+=e;return n}function eN(e,t,n,r){const i=n||" ",s=e+"",o=t-s.length;return o<=0?s:r==="left"?yp(i,o)+s:r==="center"?yp(i,~~(o/2))+s+yp(i,Math.ceil(o/2)):s+yp(i,o)}function i0(e){return e&&Wt(e)-e[0]||0}function $e(e){return de(e)?"["+e.map($e)+"]":Le(e)||Ie(e)?JSON.stringify(e).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):e}function xk(e){return e==null||e===""?null:!e||e==="false"||e==="0"?!1:!!e}const CY=e=>Vt(e)||Zl(e)?e:Date.parse(e);function _k(e,t){return t=t||CY,e==null||e===""?null:t(e)}function wk(e){return e==null||e===""?null:e+""}function mo(e){const t={},n=e.length;for(let r=0;r9999?"+"+$i(e,6):$i(e,4)}function DY(e){var t=e.getUTCHours(),n=e.getUTCMinutes(),r=e.getUTCSeconds(),i=e.getUTCMilliseconds();return isNaN(e)?"Invalid Date":FY(e.getUTCFullYear())+"-"+$i(e.getUTCMonth()+1,2)+"-"+$i(e.getUTCDate(),2)+(i?"T"+$i(t,2)+":"+$i(n,2)+":"+$i(r,2)+"."+$i(i,3)+"Z":r?"T"+$i(t,2)+":"+$i(n,2)+":"+$i(r,2)+"Z":n||t?"T"+$i(t,2)+":"+$i(n,2)+"Z":"")}function MY(e){var t=new RegExp('["'+e+` +\r]`),n=e.charCodeAt(0);function r(f,d){var h,p,g=i(f,function(m,y){if(h)return h(m,y-1);p=m,h=d?$Y(m,d):nN(m)});return g.columns=p||[],g}function i(f,d){var h=[],p=f.length,g=0,m=0,y,b=p<=0,x=!1;f.charCodeAt(p-1)===Gh&&--p,f.charCodeAt(p-1)===sx&&--p;function _(){if(b)return rx;if(x)return x=!1,x5;var A,E=g,k;if(f.charCodeAt(E)===ix){for(;g++=p?b=!0:(k=f.charCodeAt(g++))===Gh?x=!0:k===sx&&(x=!0,f.charCodeAt(g)===Gh&&++g),f.slice(E+1,A-1).replace(/""/g,'"')}for(;g1)r=BY(e,t,n);else for(i=0,r=new Array(s=e.arcs.length);it?1:e>=t?0:NaN}function zY(e,t){return e==null||t==null?NaN:te?1:t>=e?0:NaN}function xh(e){let t,n,r;e.length!==2?(t=Qa,n=(a,l)=>Qa(e(a),l),r=(a,l)=>e(a)-l):(t=e===Qa||e===zY?e:jY,n=e,r=e);function i(a,l,u=0,c=a.length){if(u>>1;n(a[f],l)<0?u=f+1:c=f}while(u>>1;n(a[f],l)<=0?u=f+1:c=f}while(uu&&r(a[f-1],l)>-r(a[f],l)?f-1:f}return{left:i,center:o,right:s}}function jY(){return 0}function iN(e){return e===null?NaN:+e}function*UY(e,t){if(t===void 0)for(let n of e)n!=null&&(n=+n)>=n&&(yield n);else{let n=-1;for(let r of e)(r=t(r,++n,e))!=null&&(r=+r)>=r&&(yield r)}}const sN=xh(Qa),iu=sN.right,qY=sN.left;xh(iN).center;function WY(e,t){let n=0,r,i=0,s=0;if(t===void 0)for(let o of e)o!=null&&(o=+o)>=o&&(r=o-i,i+=r/++n,s+=r*(o-i));else{let o=-1;for(let a of e)(a=t(a,++o,e))!=null&&(a=+a)>=a&&(r=a-i,i+=r/++n,s+=r*(a-i))}if(n>1)return s/(n-1)}function HY(e,t){const n=WY(e,t);return n&&Math.sqrt(n)}class yi{constructor(){this._partials=new Float64Array(32),this._n=0}add(t){const n=this._partials;let r=0;for(let i=0;i0){for(o=t[--n];n>0&&(r=o,i=t[--n],o=r+i,s=i-(o-r),!s););n>0&&(s<0&&t[n-1]<0||s>0&&t[n-1]>0)&&(i=s*2,r=o+i,i==r-o&&(o=r))}return o}}class E5 extends Map{constructor(t,n=lN){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:n}}),t!=null)for(const[r,i]of t)this.set(r,i)}get(t){return super.get(bw(this,t))}has(t){return super.has(bw(this,t))}set(t,n){return super.set(oN(this,t),n)}delete(t){return super.delete(aN(this,t))}}class z1 extends Set{constructor(t,n=lN){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:n}}),t!=null)for(const r of t)this.add(r)}has(t){return super.has(bw(this,t))}add(t){return super.add(oN(this,t))}delete(t){return super.delete(aN(this,t))}}function bw({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):n}function oN({_intern:e,_key:t},n){const r=t(n);return e.has(r)?e.get(r):(e.set(r,n),n)}function aN({_intern:e,_key:t},n){const r=t(n);return e.has(r)&&(n=e.get(r),e.delete(r)),n}function lN(e){return e!==null&&typeof e=="object"?e.valueOf():e}function GY(e,t){return Array.from(t,n=>e[n])}function YY(e=Qa){if(e===Qa)return uN;if(typeof e!="function")throw new TypeError("compare is not a function");return(t,n)=>{const r=e(t,n);return r||r===0?r:(e(n,n)===0)-(e(t,t)===0)}}function uN(e,t){return(e==null||!(e>=e))-(t==null||!(t>=t))||(et?1:0)}const VY=Math.sqrt(50),XY=Math.sqrt(10),KY=Math.sqrt(2);function j1(e,t,n){const r=(t-e)/Math.max(0,n),i=Math.floor(Math.log10(r)),s=r/Math.pow(10,i),o=s>=VY?10:s>=XY?5:s>=KY?2:1;let a,l,u;return i<0?(u=Math.pow(10,-i)/o,a=Math.round(e*u),l=Math.round(t*u),a/ut&&--l,u=-u):(u=Math.pow(10,i)*o,a=Math.round(e/u),l=Math.round(t/u),a*ut&&--l),l0))return[];if(e===t)return[e];const r=t=i))return[];const a=s-i+1,l=new Array(a);if(r)if(o<0)for(let u=0;u=r)&&(n=r);else{let r=-1;for(let i of e)(i=t(i,++r,e))!=null&&(n=i)&&(n=i)}return n}function ww(e,t){let n;if(t===void 0)for(const r of e)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of e)(i=t(i,++r,e))!=null&&(n>i||n===void 0&&i>=i)&&(n=i)}return n}function cN(e,t,n=0,r=1/0,i){if(t=Math.floor(t),n=Math.floor(Math.max(0,n)),r=Math.floor(Math.min(e.length-1,r)),!(n<=t&&t<=r))return e;for(i=i===void 0?uN:YY(i);r>n;){if(r-n>600){const l=r-n+1,u=t-n+1,c=Math.log(l),f=.5*Math.exp(2*c/3),d=.5*Math.sqrt(c*f*(l-f)/l)*(u-l/2<0?-1:1),h=Math.max(n,Math.floor(t-u*f/l+d)),p=Math.min(r,Math.floor(t+(l-u)*f/l+d));cN(e,t,h,p,i)}const s=e[t];let o=n,a=r;for(Yh(e,n,t),i(e[r],s)>0&&Yh(e,n,r);o0;)--a}i(e[n],s)===0?Yh(e,n,a):(++a,Yh(e,a,r)),a<=t&&(n=a+1),t<=a&&(r=a-1)}return e}function Yh(e,t,n){const r=e[t];e[t]=e[n],e[n]=r}function Ew(e,t,n){if(e=Float64Array.from(UY(e,n)),!(!(r=e.length)||isNaN(t=+t))){if(t<=0||r<2)return ww(e);if(t>=1)return wc(e);var r,i=(r-1)*t,s=Math.floor(i),o=wc(cN(e,s).subarray(0,s+1)),a=ww(e.subarray(s+1));return o+(a-o)*(i-s)}}function fN(e,t,n=iN){if(!(!(r=e.length)||isNaN(t=+t))){if(t<=0||r<2)return+n(e[0],0,e);if(t>=1)return+n(e[r-1],r-1,e);var r,i=(r-1)*t,s=Math.floor(i),o=+n(e[s],s,e),a=+n(e[s+1],s+1,e);return o+(a-o)*(i-s)}}function ZY(e,t){let n=0,r=0;if(t===void 0)for(let i of e)i!=null&&(i=+i)>=i&&(++n,r+=i);else{let i=-1;for(let s of e)(s=t(s,++i,e))!=null&&(s=+s)>=s&&(++n,r+=s)}if(n)return r/n}function dN(e,t){return Ew(e,.5,t)}function*JY(e){for(const t of e)yield*t}function hN(e){return Array.from(JY(e))}function ss(e,t,n){e=+e,t=+t,n=(i=arguments.length)<2?(t=e,e=0,1):i<3?1:+n;for(var r=-1,i=Math.max(0,Math.ceil((t-e)/n))|0,s=new Array(i);++r=1e21?e.toLocaleString("en").replace(/,/g,""):e.toString(10)}function U1(e,t){if(!isFinite(e)||e===0)return null;var n=(e=t?e.toExponential(t-1):e.toExponential()).indexOf("e"),r=e.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+e.slice(n+1)]}function Dd(e){return e=U1(Math.abs(e)),e?e[1]:NaN}function rV(e,t){return function(n,r){for(var i=n.length,s=[],o=0,a=e[0],l=0;i>0&&a>0&&(l+a+1>r&&(a=Math.max(1,r-l)),s.push(n.substring(i-=a,i+a)),!((l+=a+1)>r));)a=e[o=(o+1)%e.length];return s.reverse().join(t)}}function iV(e){return function(t){return t.replace(/[0-9]/g,function(n){return e[+n]})}}var sV=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function zc(e){if(!(t=sV.exec(e)))throw new Error("invalid format: "+e);var t;return new Ek({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}zc.prototype=Ek.prototype;function Ek(e){this.fill=e.fill===void 0?" ":e.fill+"",this.align=e.align===void 0?">":e.align+"",this.sign=e.sign===void 0?"-":e.sign+"",this.symbol=e.symbol===void 0?"":e.symbol+"",this.zero=!!e.zero,this.width=e.width===void 0?void 0:+e.width,this.comma=!!e.comma,this.precision=e.precision===void 0?void 0:+e.precision,this.trim=!!e.trim,this.type=e.type===void 0?"":e.type+""}Ek.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function oV(e){e:for(var t=e.length,n=1,r=-1,i;n0&&(r=0);break}return r>0?e.slice(0,r)+e.slice(i+1):e}var q1;function aV(e,t){var n=U1(e,t);if(!n)return q1=void 0,e.toPrecision(t);var r=n[0],i=n[1],s=i-(q1=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,o=r.length;return s===o?r:s>o?r+new Array(s-o+1).join("0"):s>0?r.slice(0,s)+"."+r.slice(s):"0."+new Array(1-s).join("0")+U1(e,Math.max(0,t+s-1))[0]}function A5(e,t){var n=U1(e,t);if(!n)return e+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}const k5={"%":(e,t)=>(e*100).toFixed(t),b:e=>Math.round(e).toString(2),c:e=>e+"",d:nV,e:(e,t)=>e.toExponential(t),f:(e,t)=>e.toFixed(t),g:(e,t)=>e.toPrecision(t),o:e=>Math.round(e).toString(8),p:(e,t)=>A5(e*100,t),r:A5,s:aV,X:e=>Math.round(e).toString(16).toUpperCase(),x:e=>Math.round(e).toString(16)};function S5(e){return e}var C5=Array.prototype.map,$5=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function gN(e){var t=e.grouping===void 0||e.thousands===void 0?S5:rV(C5.call(e.grouping,Number),e.thousands+""),n=e.currency===void 0?"":e.currency[0]+"",r=e.currency===void 0?"":e.currency[1]+"",i=e.decimal===void 0?".":e.decimal+"",s=e.numerals===void 0?S5:iV(C5.call(e.numerals,String)),o=e.percent===void 0?"%":e.percent+"",a=e.minus===void 0?"−":e.minus+"",l=e.nan===void 0?"NaN":e.nan+"";function u(f,d){f=zc(f);var h=f.fill,p=f.align,g=f.sign,m=f.symbol,y=f.zero,b=f.width,x=f.comma,_=f.precision,w=f.trim,A=f.type;A==="n"?(x=!0,A="g"):k5[A]||(_===void 0&&(_=12),w=!0,A="g"),(y||h==="0"&&p==="=")&&(y=!0,h="0",p="=");var E=(d&&d.prefix!==void 0?d.prefix:"")+(m==="$"?n:m==="#"&&/[boxX]/.test(A)?"0"+A.toLowerCase():""),k=(m==="$"?r:/[%p]/.test(A)?o:"")+(d&&d.suffix!==void 0?d.suffix:""),S=k5[A],$=/[defgprs%]/.test(A);_=_===void 0?6:/[gprs]/.test(A)?Math.max(1,Math.min(21,_)):Math.max(0,Math.min(20,_));function M(O){var P=E,T=k,F,N,U;if(A==="c")T=S(O)+T,O="";else{O=+O;var j=O<0||1/O<0;if(O=isNaN(O)?l:S(Math.abs(O),_),w&&(O=oV(O)),j&&+O==0&&g!=="+"&&(j=!1),P=(j?g==="("?g:a:g==="-"||g==="("?"":g)+P,T=(A==="s"&&!isNaN(O)&&q1!==void 0?$5[8+q1/3]:"")+T+(j&&g==="("?")":""),$){for(F=-1,N=O.length;++FU||U>57){T=(U===46?i+O.slice(F+1):O.slice(F))+T,O=O.slice(0,F);break}}}x&&!y&&(O=t(O,1/0));var W=P.length+O.length+T.length,Z=W>1)+P+O+T+Z.slice(W);break;default:O=Z+P+O+T;break}return s(O)}return M.toString=function(){return f+""},M}function c(f,d){var h=Math.max(-8,Math.min(8,Math.floor(Dd(d)/3)))*3,p=Math.pow(10,-h),g=u((f=zc(f),f.type="f",f),{suffix:$5[8+h/3]});return function(m){return g(p*m)}}return{format:u,formatPrefix:c}}var sm,Dy,Ak;lV({thousands:",",grouping:[3],currency:["$",""]});function lV(e){return sm=gN(e),Dy=sm.format,Ak=sm.formatPrefix,sm}function mN(e){return Math.max(0,-Dd(Math.abs(e)))}function vN(e,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(Dd(t)/3)))*3-Dd(Math.abs(e)))}function yN(e,t){return e=Math.abs(e),t=Math.abs(t)-e,Math.max(0,Dd(t)-Dd(e))+1}const ox=new Date,ax=new Date;function ir(e,t,n,r){function i(s){return e(s=arguments.length===0?new Date:new Date(+s)),s}return i.floor=s=>(e(s=new Date(+s)),s),i.ceil=s=>(e(s=new Date(s-1)),t(s,1),e(s),s),i.round=s=>{const o=i(s),a=i.ceil(s);return s-o(t(s=new Date(+s),o==null?1:Math.floor(o)),s),i.range=(s,o,a)=>{const l=[];if(s=i.ceil(s),a=a==null?1:Math.floor(a),!(s0))return l;let u;do l.push(u=new Date(+s)),t(s,a),e(s);while(uir(o=>{if(o>=o)for(;e(o),!s(o);)o.setTime(o-1)},(o,a)=>{if(o>=o)if(a<0)for(;++a<=0;)for(;t(o,-1),!s(o););else for(;--a>=0;)for(;t(o,1),!s(o););}),n&&(i.count=(s,o)=>(ox.setTime(+s),ax.setTime(+o),e(ox),e(ax),Math.floor(n(ox,ax))),i.every=s=>(s=Math.floor(s),!isFinite(s)||!(s>0)?null:s>1?i.filter(r?o=>r(o)%s===0:o=>i.count(0,o)%s===0):i)),i}const Md=ir(()=>{},(e,t)=>{e.setTime(+e+t)},(e,t)=>t-e);Md.every=e=>(e=Math.floor(e),!isFinite(e)||!(e>0)?null:e>1?ir(t=>{t.setTime(Math.floor(t/e)*e)},(t,n)=>{t.setTime(+t+n*e)},(t,n)=>(n-t)/e):Md);Md.range;const Ha=1e3,Ss=Ha*60,Ga=Ss*60,ul=Ga*24,kk=ul*7,F5=ul*30,lx=ul*365,Ya=ir(e=>{e.setTime(e-e.getMilliseconds())},(e,t)=>{e.setTime(+e+t*Ha)},(e,t)=>(t-e)/Ha,e=>e.getUTCSeconds());Ya.range;const My=ir(e=>{e.setTime(e-e.getMilliseconds()-e.getSeconds()*Ha)},(e,t)=>{e.setTime(+e+t*Ss)},(e,t)=>(t-e)/Ss,e=>e.getMinutes());My.range;const Ty=ir(e=>{e.setUTCSeconds(0,0)},(e,t)=>{e.setTime(+e+t*Ss)},(e,t)=>(t-e)/Ss,e=>e.getUTCMinutes());Ty.range;const Ry=ir(e=>{e.setTime(e-e.getMilliseconds()-e.getSeconds()*Ha-e.getMinutes()*Ss)},(e,t)=>{e.setTime(+e+t*Ga)},(e,t)=>(t-e)/Ga,e=>e.getHours());Ry.range;const Ny=ir(e=>{e.setUTCMinutes(0,0,0)},(e,t)=>{e.setTime(+e+t*Ga)},(e,t)=>(t-e)/Ga,e=>e.getUTCHours());Ny.range;const el=ir(e=>e.setHours(0,0,0,0),(e,t)=>e.setDate(e.getDate()+t),(e,t)=>(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*Ss)/ul,e=>e.getDate()-1);el.range;const Jl=ir(e=>{e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCDate(e.getUTCDate()+t)},(e,t)=>(t-e)/ul,e=>e.getUTCDate()-1);Jl.range;const bN=ir(e=>{e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCDate(e.getUTCDate()+t)},(e,t)=>(t-e)/ul,e=>Math.floor(e/ul));bN.range;function df(e){return ir(t=>{t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)},(t,n)=>{t.setDate(t.getDate()+n*7)},(t,n)=>(n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*Ss)/kk)}const _h=df(0),W1=df(1),uV=df(2),cV=df(3),Td=df(4),fV=df(5),dV=df(6);_h.range;W1.range;uV.range;cV.range;Td.range;fV.range;dV.range;function hf(e){return ir(t=>{t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)},(t,n)=>{t.setUTCDate(t.getUTCDate()+n*7)},(t,n)=>(n-t)/kk)}const wh=hf(0),H1=hf(1),hV=hf(2),pV=hf(3),Rd=hf(4),gV=hf(5),mV=hf(6);wh.range;H1.range;hV.range;pV.range;Rd.range;gV.range;mV.range;const dg=ir(e=>{e.setDate(1),e.setHours(0,0,0,0)},(e,t)=>{e.setMonth(e.getMonth()+t)},(e,t)=>t.getMonth()-e.getMonth()+(t.getFullYear()-e.getFullYear())*12,e=>e.getMonth());dg.range;const hg=ir(e=>{e.setUTCDate(1),e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCMonth(e.getUTCMonth()+t)},(e,t)=>t.getUTCMonth()-e.getUTCMonth()+(t.getUTCFullYear()-e.getUTCFullYear())*12,e=>e.getUTCMonth());hg.range;const la=ir(e=>{e.setMonth(0,1),e.setHours(0,0,0,0)},(e,t)=>{e.setFullYear(e.getFullYear()+t)},(e,t)=>t.getFullYear()-e.getFullYear(),e=>e.getFullYear());la.every=e=>!isFinite(e=Math.floor(e))||!(e>0)?null:ir(t=>{t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)},(t,n)=>{t.setFullYear(t.getFullYear()+n*e)});la.range;const ua=ir(e=>{e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,t)=>{e.setUTCFullYear(e.getUTCFullYear()+t)},(e,t)=>t.getUTCFullYear()-e.getUTCFullYear(),e=>e.getUTCFullYear());ua.every=e=>!isFinite(e=Math.floor(e))||!(e>0)?null:ir(t=>{t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,n)=>{t.setUTCFullYear(t.getUTCFullYear()+n*e)});ua.range;function xN(e,t,n,r,i,s){const o=[[Ya,1,Ha],[Ya,5,5*Ha],[Ya,15,15*Ha],[Ya,30,30*Ha],[s,1,Ss],[s,5,5*Ss],[s,15,15*Ss],[s,30,30*Ss],[i,1,Ga],[i,3,3*Ga],[i,6,6*Ga],[i,12,12*Ga],[r,1,ul],[r,2,2*ul],[n,1,kk],[t,1,F5],[t,3,3*F5],[e,1,lx]];function a(u,c,f){const d=cm).right(o,d);if(h===o.length)return e.every(su(u/lx,c/lx,f));if(h===0)return Md.every(Math.max(su(u,c,f),1));const[p,g]=o[d/o[h-1][2](e[t]=1+n,e),{});function Ck(e){const t=Be(e).slice(),n={};return t.length||le("Missing time unit."),t.forEach(i=>{Ue(ux,i)?n[i]=1:le(`Invalid time unit: ${i}.`)}),(n[er]||n[Yr]?1:0)+(n[ji]||n[Zr]||n[Ui]?1:0)+(n[ca]?1:0)>1&&le(`Incompatible time units: ${e}`),t.sort((i,s)=>ux[i]-ux[s]),t}const _V={[Nr]:"%Y ",[ji]:"Q%q ",[Zr]:"%b ",[Ui]:"%d ",[er]:"W%U ",[Yr]:"%a ",[ca]:"%j ",[hs]:"%H:00",[ps]:"00:%M",[Is]:":%S",[vo]:".%L",[`${Nr}-${Zr}`]:"%Y-%m ",[`${Nr}-${Zr}-${Ui}`]:"%Y-%m-%d ",[`${hs}-${ps}`]:"%H:%M"};function _N(e,t){const n=Mt({},_V,t),r=Ck(e),i=r.length;let s="",o=0,a,l;for(o=0;oo;--a)if(l=r.slice(o,a).join("-"),n[l]!=null){s+=n[l],o=a;break}return s.trim()}const ic=new Date;function $k(e){return ic.setFullYear(e),ic.setMonth(0),ic.setDate(1),ic.setHours(0,0,0,0),ic}function wN(e){return AN(new Date(e))}function EN(e){return Aw(new Date(e))}function AN(e){return el.count($k(e.getFullYear())-1,e)}function Aw(e){return _h.count($k(e.getFullYear())-1,e)}function kw(e){return $k(e).getDay()}function wV(e,t,n,r,i,s,o){if(0<=e&&e<100){const a=new Date(-1,t,n,r,i,s,o);return a.setFullYear(e),a}return new Date(e,t,n,r,i,s,o)}function kN(e){return CN(new Date(e))}function SN(e){return Sw(new Date(e))}function CN(e){const t=Date.UTC(e.getUTCFullYear(),0,1);return Jl.count(t-1,e)}function Sw(e){const t=Date.UTC(e.getUTCFullYear(),0,1);return wh.count(t-1,e)}function Cw(e){return ic.setTime(Date.UTC(e,0,1)),ic.getUTCDay()}function EV(e,t,n,r,i,s,o){if(0<=e&&e<100){const a=new Date(Date.UTC(-1,t,n,r,i,s,o));return a.setUTCFullYear(n.y),a}return new Date(Date.UTC(e,t,n,r,i,s,o))}function $N(e,t,n,r,i){const s=t||1,o=Wt(e),a=(y,b,x)=>(x=x||y,AV(n[x],r[x],y===o&&s,b)),l=new Date,u=mo(e),c=u[Nr]?a(Nr):ri(2012),f=u[Zr]?a(Zr):u[ji]?a(ji):Ol,d=u[er]&&u[Yr]?a(Yr,1,er+Yr):u[er]?a(er,1):u[Yr]?a(Yr,1):u[Ui]?a(Ui,1):u[ca]?a(ca,1):gh,h=u[hs]?a(hs):Ol,p=u[ps]?a(ps):Ol,g=u[Is]?a(Is):Ol,m=u[vo]?a(vo):Ol;return function(y){l.setTime(+y);const b=c(l);return i(b,f(l),d(l,b),h(l),p(l),g(l),m(l))}}function AV(e,t,n,r){const i=n<=1?e:r?(s,o)=>r+n*Math.floor((e(s,o)-r)/n):(s,o)=>n*Math.floor(e(s,o)/n);return t?(s,o)=>t(i(s,o),o):i}function Nd(e,t,n){return t+e*7-(n+6)%7}const kV={[Nr]:e=>e.getFullYear(),[ji]:e=>Math.floor(e.getMonth()/3),[Zr]:e=>e.getMonth(),[Ui]:e=>e.getDate(),[hs]:e=>e.getHours(),[ps]:e=>e.getMinutes(),[Is]:e=>e.getSeconds(),[vo]:e=>e.getMilliseconds(),[ca]:e=>AN(e),[er]:e=>Aw(e),[er+Yr]:(e,t)=>Nd(Aw(e),e.getDay(),kw(t)),[Yr]:(e,t)=>Nd(1,e.getDay(),kw(t))},SV={[ji]:e=>3*e,[er]:(e,t)=>Nd(e,0,kw(t))};function FN(e,t){return $N(e,t||1,kV,SV,wV)}const CV={[Nr]:e=>e.getUTCFullYear(),[ji]:e=>Math.floor(e.getUTCMonth()/3),[Zr]:e=>e.getUTCMonth(),[Ui]:e=>e.getUTCDate(),[hs]:e=>e.getUTCHours(),[ps]:e=>e.getUTCMinutes(),[Is]:e=>e.getUTCSeconds(),[vo]:e=>e.getUTCMilliseconds(),[ca]:e=>CN(e),[er]:e=>Sw(e),[Yr]:(e,t)=>Nd(1,e.getUTCDay(),Cw(t)),[er+Yr]:(e,t)=>Nd(Sw(e),e.getUTCDay(),Cw(t))},$V={[ji]:e=>3*e,[er]:(e,t)=>Nd(e,0,Cw(t))};function DN(e,t){return $N(e,t||1,CV,$V,EV)}const FV={[Nr]:la,[ji]:dg.every(3),[Zr]:dg,[er]:_h,[Ui]:el,[Yr]:el,[ca]:el,[hs]:Ry,[ps]:My,[Is]:Ya,[vo]:Md},DV={[Nr]:ua,[ji]:hg.every(3),[Zr]:hg,[er]:wh,[Ui]:Jl,[Yr]:Jl,[ca]:Jl,[hs]:Ny,[ps]:Ty,[Is]:Ya,[vo]:Md};function Eh(e){return FV[e]}function Ah(e){return DV[e]}function MN(e,t,n){return e?e.offset(t,n):void 0}function TN(e,t,n){return MN(Eh(e),t,n)}function RN(e,t,n){return MN(Ah(e),t,n)}function NN(e,t,n,r){return e?e.range(t,n,r):void 0}function ON(e,t,n,r){return NN(Eh(e),t,n,r)}function LN(e,t,n,r){return NN(Ah(e),t,n,r)}const bp=1e3,xp=bp*60,_p=xp*60,Oy=_p*24,MV=Oy*7,D5=Oy*30,$w=Oy*365,IN=[Nr,Zr,Ui,hs,ps,Is,vo],wp=IN.slice(0,-1),Ep=wp.slice(0,-1),Ap=Ep.slice(0,-1),TV=Ap.slice(0,-1),RV=[Nr,er],M5=[Nr,Zr],PN=[Nr],Vh=[[wp,1,bp],[wp,5,5*bp],[wp,15,15*bp],[wp,30,30*bp],[Ep,1,xp],[Ep,5,5*xp],[Ep,15,15*xp],[Ep,30,30*xp],[Ap,1,_p],[Ap,3,3*_p],[Ap,6,6*_p],[Ap,12,12*_p],[TV,1,Oy],[RV,1,MV],[M5,1,D5],[M5,3,3*D5],[PN,1,$w]];function BN(e){const t=e.extent,n=e.maxbins||40,r=Math.abs(i0(t))/n;let i=xh(a=>a[2]).right(Vh,r),s,o;return i===Vh.length?(s=PN,o=su(t[0]/$w,t[1]/$w,n)):i?(i=Vh[r/Vh[i-1][2]53)return null;"w"in V||(V.w=1),"Z"in V?(L=fx(Xh(V.y,0,1)),X=L.getUTCDay(),L=X>4||X===0?H1.ceil(L):H1(L),L=Jl.offset(L,(V.V-1)*7),V.y=L.getUTCFullYear(),V.m=L.getUTCMonth(),V.d=L.getUTCDate()+(V.w+6)%7):(L=cx(Xh(V.y,0,1)),X=L.getDay(),L=X>4||X===0?W1.ceil(L):W1(L),L=el.offset(L,(V.V-1)*7),V.y=L.getFullYear(),V.m=L.getMonth(),V.d=L.getDate()+(V.w+6)%7)}else("W"in V||"U"in V)&&("w"in V||(V.w="u"in V?V.u%7:"W"in V?1:0),X="Z"in V?fx(Xh(V.y,0,1)).getUTCDay():cx(Xh(V.y,0,1)).getDay(),V.m=0,V.d="W"in V?(V.w+6)%7+V.W*7-(X+5)%7:V.w+V.U*7-(X+6)%7);return"Z"in V?(V.H+=V.Z/100|0,V.M+=V.Z%100,fx(V)):cx(V)}}function k(xe,je,fe,V){for(var B=0,L=je.length,X=fe.length,G,z;B=X)return-1;if(G=je.charCodeAt(B++),G===37){if(G=je.charAt(B++),z=w[G in T5?je.charAt(B++):G],!z||(V=z(xe,fe,V))<0)return-1}else if(G!=fe.charCodeAt(V++))return-1}return V}function S(xe,je,fe){var V=u.exec(je.slice(fe));return V?(xe.p=c.get(V[0].toLowerCase()),fe+V[0].length):-1}function $(xe,je,fe){var V=h.exec(je.slice(fe));return V?(xe.w=p.get(V[0].toLowerCase()),fe+V[0].length):-1}function M(xe,je,fe){var V=f.exec(je.slice(fe));return V?(xe.w=d.get(V[0].toLowerCase()),fe+V[0].length):-1}function O(xe,je,fe){var V=y.exec(je.slice(fe));return V?(xe.m=b.get(V[0].toLowerCase()),fe+V[0].length):-1}function P(xe,je,fe){var V=g.exec(je.slice(fe));return V?(xe.m=m.get(V[0].toLowerCase()),fe+V[0].length):-1}function T(xe,je,fe){return k(xe,t,je,fe)}function F(xe,je,fe){return k(xe,n,je,fe)}function N(xe,je,fe){return k(xe,r,je,fe)}function U(xe){return o[xe.getDay()]}function j(xe){return s[xe.getDay()]}function W(xe){return l[xe.getMonth()]}function Z(xe){return a[xe.getMonth()]}function Y(xe){return i[+(xe.getHours()>=12)]}function J(xe){return 1+~~(xe.getMonth()/3)}function ve(xe){return o[xe.getUTCDay()]}function Te(xe){return s[xe.getUTCDay()]}function Fe(xe){return l[xe.getUTCMonth()]}function He(xe){return a[xe.getUTCMonth()]}function ut(xe){return i[+(xe.getUTCHours()>=12)]}function wt(xe){return 1+~~(xe.getUTCMonth()/3)}return{format:function(xe){var je=A(xe+="",x);return je.toString=function(){return xe},je},parse:function(xe){var je=E(xe+="",!1);return je.toString=function(){return xe},je},utcFormat:function(xe){var je=A(xe+="",_);return je.toString=function(){return xe},je},utcParse:function(xe){var je=E(xe+="",!0);return je.toString=function(){return xe},je}}}var T5={"-":"",_:" ",0:"0"},br=/^\s*\d+/,NV=/^%/,OV=/[\\^$*+?|[\]().{}]/g;function Xt(e,t,n){var r=e<0?"-":"",i=(r?-e:e)+"",s=i.length;return r+(s[t.toLowerCase(),n]))}function IV(e,t,n){var r=br.exec(t.slice(n,n+1));return r?(e.w=+r[0],n+r[0].length):-1}function PV(e,t,n){var r=br.exec(t.slice(n,n+1));return r?(e.u=+r[0],n+r[0].length):-1}function BV(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.U=+r[0],n+r[0].length):-1}function zV(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.V=+r[0],n+r[0].length):-1}function jV(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.W=+r[0],n+r[0].length):-1}function R5(e,t,n){var r=br.exec(t.slice(n,n+4));return r?(e.y=+r[0],n+r[0].length):-1}function N5(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function UV(e,t,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(t.slice(n,n+6));return r?(e.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function qV(e,t,n){var r=br.exec(t.slice(n,n+1));return r?(e.q=r[0]*3-3,n+r[0].length):-1}function WV(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.m=r[0]-1,n+r[0].length):-1}function O5(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.d=+r[0],n+r[0].length):-1}function HV(e,t,n){var r=br.exec(t.slice(n,n+3));return r?(e.m=0,e.d=+r[0],n+r[0].length):-1}function L5(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.H=+r[0],n+r[0].length):-1}function GV(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.M=+r[0],n+r[0].length):-1}function YV(e,t,n){var r=br.exec(t.slice(n,n+2));return r?(e.S=+r[0],n+r[0].length):-1}function VV(e,t,n){var r=br.exec(t.slice(n,n+3));return r?(e.L=+r[0],n+r[0].length):-1}function XV(e,t,n){var r=br.exec(t.slice(n,n+6));return r?(e.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function KV(e,t,n){var r=NV.exec(t.slice(n,n+1));return r?n+r[0].length:-1}function ZV(e,t,n){var r=br.exec(t.slice(n));return r?(e.Q=+r[0],n+r[0].length):-1}function JV(e,t,n){var r=br.exec(t.slice(n));return r?(e.s=+r[0],n+r[0].length):-1}function I5(e,t){return Xt(e.getDate(),t,2)}function QV(e,t){return Xt(e.getHours(),t,2)}function eX(e,t){return Xt(e.getHours()%12||12,t,2)}function tX(e,t){return Xt(1+el.count(la(e),e),t,3)}function jN(e,t){return Xt(e.getMilliseconds(),t,3)}function nX(e,t){return jN(e,t)+"000"}function rX(e,t){return Xt(e.getMonth()+1,t,2)}function iX(e,t){return Xt(e.getMinutes(),t,2)}function sX(e,t){return Xt(e.getSeconds(),t,2)}function oX(e){var t=e.getDay();return t===0?7:t}function aX(e,t){return Xt(_h.count(la(e)-1,e),t,2)}function UN(e){var t=e.getDay();return t>=4||t===0?Td(e):Td.ceil(e)}function lX(e,t){return e=UN(e),Xt(Td.count(la(e),e)+(la(e).getDay()===4),t,2)}function uX(e){return e.getDay()}function cX(e,t){return Xt(W1.count(la(e)-1,e),t,2)}function fX(e,t){return Xt(e.getFullYear()%100,t,2)}function dX(e,t){return e=UN(e),Xt(e.getFullYear()%100,t,2)}function hX(e,t){return Xt(e.getFullYear()%1e4,t,4)}function pX(e,t){var n=e.getDay();return e=n>=4||n===0?Td(e):Td.ceil(e),Xt(e.getFullYear()%1e4,t,4)}function gX(e){var t=e.getTimezoneOffset();return(t>0?"-":(t*=-1,"+"))+Xt(t/60|0,"0",2)+Xt(t%60,"0",2)}function P5(e,t){return Xt(e.getUTCDate(),t,2)}function mX(e,t){return Xt(e.getUTCHours(),t,2)}function vX(e,t){return Xt(e.getUTCHours()%12||12,t,2)}function yX(e,t){return Xt(1+Jl.count(ua(e),e),t,3)}function qN(e,t){return Xt(e.getUTCMilliseconds(),t,3)}function bX(e,t){return qN(e,t)+"000"}function xX(e,t){return Xt(e.getUTCMonth()+1,t,2)}function _X(e,t){return Xt(e.getUTCMinutes(),t,2)}function wX(e,t){return Xt(e.getUTCSeconds(),t,2)}function EX(e){var t=e.getUTCDay();return t===0?7:t}function AX(e,t){return Xt(wh.count(ua(e)-1,e),t,2)}function WN(e){var t=e.getUTCDay();return t>=4||t===0?Rd(e):Rd.ceil(e)}function kX(e,t){return e=WN(e),Xt(Rd.count(ua(e),e)+(ua(e).getUTCDay()===4),t,2)}function SX(e){return e.getUTCDay()}function CX(e,t){return Xt(H1.count(ua(e)-1,e),t,2)}function $X(e,t){return Xt(e.getUTCFullYear()%100,t,2)}function FX(e,t){return e=WN(e),Xt(e.getUTCFullYear()%100,t,2)}function DX(e,t){return Xt(e.getUTCFullYear()%1e4,t,4)}function MX(e,t){var n=e.getUTCDay();return e=n>=4||n===0?Rd(e):Rd.ceil(e),Xt(e.getUTCFullYear()%1e4,t,4)}function TX(){return"+0000"}function B5(){return"%"}function z5(e){return+e}function j5(e){return Math.floor(+e/1e3)}var Tf,Fk,HN,Dk,GN;RX({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function RX(e){return Tf=zN(e),Fk=Tf.format,HN=Tf.parse,Dk=Tf.utcFormat,GN=Tf.utcParse,Tf}function kp(e){const t={};return n=>t[n]||(t[n]=e(n))}function NX(e,t){return n=>{const r=e(n),i=r.indexOf(t);if(i<0)return r;let s=OX(r,i);const o=si;)if(r[s]!=="0"){++s;break}return r.slice(0,s)+o}}function OX(e,t){let n=e.lastIndexOf("e"),r;if(n>0)return n;for(n=e.length;--n>t;)if(r=e.charCodeAt(n),r>=48&&r<=57)return n+1}function YN(e){const t=kp(e.format),n=e.formatPrefix;return{format:t,formatPrefix:n,formatFloat(r){const i=zc(r||",");if(i.precision==null){switch(i.precision=12,i.type){case"%":i.precision-=2;break;case"e":i.precision-=1;break}return NX(t(i),t(".1f")(1)[1])}else return t(i)},formatSpan(r,i,s,o){o=zc(o??",f");const a=su(r,i,s),l=Math.max(Math.abs(r),Math.abs(i));let u;if(o.precision==null)switch(o.type){case"s":return isNaN(u=vN(a,l))||(o.precision=u),n(o,l);case"":case"e":case"g":case"p":case"r":{isNaN(u=yN(a,l))||(o.precision=u-(o.type==="e"));break}case"f":case"%":{isNaN(u=mN(a))||(o.precision=u-(o.type==="%")*2);break}}return t(o)}}}let Fw;VN();function VN(){return Fw=YN({format:Dy,formatPrefix:Ak})}function XN(e){return YN(gN(e))}function G1(e){return arguments.length?Fw=XN(e):Fw}function U5(e,t,n){n=n||{},Le(n)||le(`Invalid time multi-format specifier: ${n}`);const r=t(Is),i=t(ps),s=t(hs),o=t(Ui),a=t(er),l=t(Zr),u=t(ji),c=t(Nr),f=e(n[vo]||".%L"),d=e(n[Is]||":%S"),h=e(n[ps]||"%I:%M"),p=e(n[hs]||"%I %p"),g=e(n[Ui]||n[Yr]||"%a %d"),m=e(n[er]||"%b %d"),y=e(n[Zr]||"%B"),b=e(n[ji]||"%B"),x=e(n[Nr]||"%Y");return _=>(r(_)<_?f:i(_)<_?d:s(_)<_?h:o(_)<_?p:l(_)<_?a(_)<_?g:m:c(_)<_?u(_)<_?y:b:x)(_)}function KN(e){const t=kp(e.format),n=kp(e.utcFormat);return{timeFormat:r=>Ie(r)?t(r):U5(t,Eh,r),utcFormat:r=>Ie(r)?n(r):U5(n,Ah,r),timeParse:kp(e.parse),utcParse:kp(e.utcParse)}}let Dw;ZN();function ZN(){return Dw=KN({format:Fk,parse:HN,utcFormat:Dk,utcParse:GN})}function JN(e){return KN(zN(e))}function pg(e){return arguments.length?Dw=JN(e):Dw}const Mw=(e,t)=>Mt({},e,t);function QN(e,t){const n=e?XN(e):G1(),r=t?JN(t):pg();return Mw(n,r)}function Mk(e,t){const n=arguments.length;return n&&n!==2&&le("defaultLocale expects either zero or two arguments."),n?Mw(G1(e),pg(t)):Mw(G1(),pg())}function LX(){return VN(),ZN(),Mk()}const IX=/^(data:|([A-Za-z]+:)?\/\/)/,PX=/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|file|data):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,BX=/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g,q5="file://";function zX(e,t){return n=>({options:n||{},sanitize:UX,load:jX,fileAccess:!1,file:qX(),http:HX(e)})}async function jX(e,t){const n=await this.sanitize(e,t),r=n.href;return n.localFile?this.file(r):this.http(r,t)}async function UX(e,t){t=Mt({},this.options,t);const n=this.fileAccess,r={href:null};let i,s,o;const a=PX.test(e.replace(BX,""));(e==null||typeof e!="string"||!a)&&le("Sanitize failure, invalid URI: "+$e(e));const l=IX.test(e);return(o=t.baseURL)&&!l&&(!e.startsWith("/")&&!o.endsWith("/")&&(e="/"+e),e=o+e),s=(i=e.startsWith(q5))||t.mode==="file"||t.mode!=="http"&&!l&&n,i?e=e.slice(q5.length):e.startsWith("//")&&(t.defaultProtocol==="file"?(e=e.slice(2),s=!0):e=(t.defaultProtocol||"http")+":"+e),Object.defineProperty(r,"localFile",{value:!!s}),r.href=e,t.target&&(r.target=t.target+""),t.rel&&(r.rel=t.rel+""),t.context==="image"&&t.crossOrigin&&(r.crossOrigin=t.crossOrigin+""),r}function qX(e){return WX}async function WX(){le("No file system access.")}function HX(e){return e?async function(t,n){const r=Mt({},this.options.http,n),i=n&&n.response,s=await e(t,r);return s.ok?Tt(s[i])?s[i]():s.text():le(s.status+""+s.statusText)}:GX}async function GX(){le("No HTTP fetch method available.")}const YX=e=>e!=null&&e===e,VX=e=>e==="true"||e==="false"||e===!0||e===!1,XX=e=>!Number.isNaN(Date.parse(e)),eO=e=>!Number.isNaN(+e)&&!(e instanceof Date),KX=e=>eO(e)&&Number.isInteger(+e),Tw={boolean:xk,integer:Vr,number:Vr,date:_k,string:wk,unknown:ni},om=[VX,KX,eO,XX],ZX=["boolean","integer","number","date"];function tO(e,t){if(!e||!e.length)return"unknown";const n=e.length,r=om.length,i=om.map((s,o)=>o+1);for(let s=0,o=0,a,l;ss===0?o:s,0)-1]}function nO(e,t){return t.reduce((n,r)=>(n[r]=tO(e,r),n),{})}function W5(e){const t=function(n,r){const i={delimiter:e};return Tk(n,r?Mt(r,i):i)};return t.responseType="text",t}function Tk(e,t){return t.header&&(e=t.header.map($e).join(t.delimiter)+` +`+e),MY(t.delimiter).parse(e+"")}Tk.responseType="text";function JX(e){return typeof Buffer=="function"&&Tt(Buffer.isBuffer)?Buffer.isBuffer(e):!1}function Rk(e,t){const n=t&&t.property?Ls(t.property):ni;return Le(e)&&!JX(e)?QX(n(e),t):n(JSON.parse(e))}Rk.responseType="json";function QX(e,t){return!de(e)&&KR(e)&&(e=[...e]),t&&t.copy?JSON.parse(JSON.stringify(e)):e}const eK={interior:(e,t)=>e!==t,exterior:(e,t)=>e===t};function rO(e,t){let n,r,i,s;return e=Rk(e,t),t&&t.feature?(n=OY,i=t.feature):t&&t.mesh?(n=IY,i=t.mesh,s=eK[t.filter]):le("Missing TopoJSON feature or mesh parameter."),r=(r=e.objects[i])?n(e,r,s):le("Invalid TopoJSON object: "+i),r&&r.features||[r]}rO.responseType="json";const i1={dsv:Tk,csv:W5(","),tsv:W5(" "),json:Rk,topojson:rO};function Nk(e,t){return arguments.length>1?(i1[e]=t,this):Ue(i1,e)?i1[e]:null}function iO(e){const t=Nk(e);return t&&t.responseType||"text"}function sO(e,t,n,r){t=t||{};const i=Nk(t.type||"json");return i||le("Unknown data format type: "+t.type),e=i(e,t),t.parse&&tK(e,t.parse,n,r),Ue(e,"columns")&&delete e.columns,e}function tK(e,t,n,r){if(!e.length)return;const i=pg();n=n||i.timeParse,r=r||i.utcParse;let s=e.columns||Object.keys(e[0]),o,a,l,u,c,f;t==="auto"&&(t=nO(e,s)),s=Object.keys(t);const d=s.map(h=>{const p=t[h];let g,m;if(p&&(p.startsWith("date:")||p.startsWith("utc:")))return g=p.split(/:(.+)?/,2),m=g[1],(m[0]==="'"&&m[m.length-1]==="'"||m[0]==='"'&&m[m.length-1]==='"')&&(m=m.slice(1,-1)),(g[0]==="utc"?r:n)(m);if(!Tw[p])throw Error("Illegal format pattern: "+h+":"+p);return Tw[p]});for(l=0,c=e.length,f=s.length;l{const s=t(i);return r[s]||(r[s]=1,n.push(i)),n},n.remove=i=>{const s=t(i);if(r[s]){r[s]=0;const o=n.indexOf(i);o>=0&&n.splice(o,1)}return n},n}async function s1(e,t){try{await t(e)}catch(n){e.error(n)}}const oO=Symbol("vega_id");let nK=1;function Py(e){return!!(e&&ot(e))}function ot(e){return e[oO]}function aO(e,t){return e[oO]=t,e}function Zt(e){const t=e===Object(e)?e:{data:e};return ot(t)?t:aO(t,nK++)}function Ok(e){return By(e,Zt({}))}function By(e,t){for(const n in e)t[n]=e[n];return t}function lO(e,t){return aO(t,ot(e))}function pf(e,t){return e?t?(n,r)=>e(n,r)||ot(t(n))-ot(t(r)):(n,r)=>e(n,r)||ot(n)-ot(r):null}function uO(e){return e&&e.constructor===Eu}function Eu(){const e=[],t=[],n=[],r=[],i=[];let s=null,o=!1;return{constructor:Eu,insert(a){const l=Be(a),u=l.length;for(let c=0;c{p(b)&&(u[ot(b)]=-1)});for(f=0,d=e.length;f0&&(y(g,p,h.value),a.modifies(p));for(f=0,d=i.length;f{p(b)&&u[ot(b)]>0&&y(b,h.field,h.value)}),a.modifies(h.field);if(o)a.mod=t.length||r.length?l.filter(b=>u[ot(b)]>0):l.slice();else for(m in c)a.mod.push(c[m]);return(s||s==null&&(t.length||r.length))&&a.clean(!0),a}}}const o1="_:mod:_";function zy(){Object.defineProperty(this,o1,{writable:!0,value:{}})}zy.prototype={set(e,t,n,r){const i=this,s=i[e],o=i[o1];return t!=null&&t>=0?(s[t]!==n||r)&&(s[t]=n,o[t+":"+e]=-1,o[e]=-1):(s!==n||r)&&(i[e]=n,o[e]=de(n)?1+n.length:-1),i},modified(e,t){const n=this[o1];if(arguments.length){if(de(e)){for(let r=0;r=0?t+1{h instanceof cn?(h!==this&&(t&&h.targets().add(this),s.push(h)),i.push({op:h,name:f,index:d})):r.set(f,d,h)};for(o in e)if(a=e[o],o===iK)Be(a).forEach(f=>{f instanceof cn?f!==this&&(f.targets().add(this),s.push(f)):le("Pulse parameters must be operator instances.")}),this.source=a;else if(de(a))for(r.set(o,-1,Array(l=a.length)),u=0;u{const n=Date.now();return n-t>e?(t=n,1):0})},debounce(e){const t=$l();return this.targets().add($l(null,null,vk(e,n=>{const r=n.dataflow;t.receive(n),r&&r.run&&r.run()}))),t},between(e,t){let n=!1;return e.targets().add($l(null,null,()=>n=!0)),t.targets().add($l(null,null,()=>n=!1)),this.filter(()=>n)},detach(){this._filter=ds,this._targets=null}};function fK(e,t,n,r){const i=this,s=$l(n,r),o=function(u){u.dataflow=i;try{s.receive(u)}catch(c){i.error(c)}finally{i.run()}};let a;typeof e=="string"&&typeof document<"u"?a=document.querySelectorAll(e):a=Be(e);const l=a.length;for(let u=0;ut=r);return n.requests=0,n.done=()=>{--n.requests===0&&(e._pending=null,t(e))},e._pending=n}const vK={skip:!0};function yK(e,t,n,r,i){return(e instanceof cn?xK:bK)(this,e,t,n,r,i),this}function bK(e,t,n,r,i,s){const o=Mt({},s,vK);let a,l;Tt(n)||(n=ri(n)),r===void 0?a=u=>e.touch(n(u)):Tt(r)?(l=new cn(null,r,i,!1),a=u=>{l.evaluate(u);const c=n(u),f=l.value;uO(f)?e.pulse(c,f,s):e.update(c,f,o)}):a=u=>e.update(n(u),r,o),t.apply(a)}function xK(e,t,n,r,i,s){if(r===void 0)t.targets().add(n);else{const o=s||{},a=new cn(null,_K(n,r),i,!1);a.modified(o.force),a.rank=t.rank,t.targets().add(a),n&&(a.skip(!0),a.value=n.value,a.targets().add(n),e.connect(n,[a]))}}function _K(e,t){return t=Tt(t)?t:ri(t),e?function(n,r){const i=t(n,r);return e.skip()||(e.skip(i!==this.value).value=i),i}:t}function wK(e){e.rank=++this._rank}function EK(e){const t=[e];let n,r,i;for(;t.length;)if(this.rank(n=t.pop()),r=n._targets)for(i=r.length;--i>=0;)t.push(n=r[i]),n===e&&le("Cycle detected in dataflow graph.")}const Y1={},zo=1,Ml=2,La=4,AK=zo|Ml,G5=zo|La,Rf=zo|Ml|La,Y5=8,Jh=16,V5=32,X5=64;function Ql(e,t,n){this.dataflow=e,this.stamp=t??-1,this.add=[],this.rem=[],this.mod=[],this.fields=null,this.encode=n||null}function dx(e,t){const n=[];return Dl(e,t,r=>n.push(r)),n}function K5(e,t){const n={};return e.visit(t,r=>{n[ot(r)]=1}),r=>n[ot(r)]?null:r}function am(e,t){return e?(n,r)=>e(n,r)&&t(n,r):t}Ql.prototype={StopPropagation:Y1,ADD:zo,REM:Ml,MOD:La,ADD_REM:AK,ADD_MOD:G5,ALL:Rf,REFLOW:Y5,SOURCE:Jh,NO_SOURCE:V5,NO_FIELDS:X5,fork(e){return new Ql(this.dataflow).init(this,e)},clone(){const e=this.fork(Rf);return e.add=e.add.slice(),e.rem=e.rem.slice(),e.mod=e.mod.slice(),e.source&&(e.source=e.source.slice()),e.materialize(Rf|Jh)},addAll(){let e=this;return!e.source||e.add===e.rem||!e.rem.length&&e.source.length===e.add.length||(e=new Ql(this.dataflow).init(this),e.add=e.source,e.rem=[]),e},init(e,t){const n=this;return n.stamp=e.stamp,n.encode=e.encode,e.fields&&!(t&X5)&&(n.fields=e.fields),t&zo?(n.addF=e.addF,n.add=e.add):(n.addF=null,n.add=[]),t&Ml?(n.remF=e.remF,n.rem=e.rem):(n.remF=null,n.rem=[]),t&La?(n.modF=e.modF,n.mod=e.mod):(n.modF=null,n.mod=[]),t&V5?(n.srcF=null,n.source=null):(n.srcF=e.srcF,n.source=e.source,e.cleans&&(n.cleans=e.cleans)),n},runAfter(e){this.dataflow.runAfter(e)},changed(e){const t=e||Rf;return t&zo&&this.add.length||t&Ml&&this.rem.length||t&La&&this.mod.length},reflow(e){if(e)return this.fork(Rf).reflow();const t=this.add.length,n=this.source&&this.source.length;return n&&n!==t&&(this.mod=this.source,t&&this.filter(La,K5(this,zo))),this},clean(e){return arguments.length?(this.cleans=!!e,this):this.cleans},modifies(e){const t=this.fields||(this.fields={});return de(e)?e.forEach(n=>t[n]=!0):t[e]=!0,this},modified(e,t){const n=this.fields;return(t||this.mod.length)&&n?arguments.length?de(e)?e.some(r=>n[r]):n[e]:!!n:!1},filter(e,t){const n=this;return e&zo&&(n.addF=am(n.addF,t)),e&Ml&&(n.remF=am(n.remF,t)),e&La&&(n.modF=am(n.modF,t)),e&Jh&&(n.srcF=am(n.srcF,t)),n},materialize(e){e=e||Rf;const t=this;return e&zo&&t.addF&&(t.add=dx(t.add,t.addF),t.addF=null),e&Ml&&t.remF&&(t.rem=dx(t.rem,t.remF),t.remF=null),e&La&&t.modF&&(t.mod=dx(t.mod,t.modF),t.modF=null),e&Jh&&t.srcF&&(t.source=t.source.filter(t.srcF),t.srcF=null),t},visit(e,t){const n=this,r=t;if(e&Jh)return Dl(n.source,n.srcF,r),n;e&zo&&Dl(n.add,n.addF,r),e&Ml&&Dl(n.rem,n.remF,r),e&La&&Dl(n.mod,n.modF,r);const i=n.source;if(e&Y5&&i){const s=n.add.length+n.mod.length;s===i.length||(s?Dl(i,K5(n,G5),r):Dl(i,n.srcF,r))}return n}};function Lk(e,t,n,r){const i=this;let s=0;this.dataflow=e,this.stamp=t,this.fields=null,this.encode=r||null,this.pulses=n;for(const o of n)if(o.stamp===t){if(o.fields){const a=i.fields||(i.fields={});for(const l in o.fields)a[l]=1}o.changed(i.ADD)&&(s|=i.ADD),o.changed(i.REM)&&(s|=i.REM),o.changed(i.MOD)&&(s|=i.MOD)}this.changes=s}Me(Lk,Ql,{fork(e){const t=new Ql(this.dataflow).init(this,e&this.NO_FIELDS);return e!==void 0&&(e&t.ADD&&this.visit(t.ADD,n=>t.add.push(n)),e&t.REM&&this.visit(t.REM,n=>t.rem.push(n)),e&t.MOD&&this.visit(t.MOD,n=>t.mod.push(n))),t},changed(e){return this.changes&e},modified(e){const t=this,n=t.fields;return n&&t.changes&t.MOD?de(e)?e.some(r=>n[r]):n[e]:0},filter(){le("MultiPulse does not support filtering.")},materialize(){le("MultiPulse does not support materialization.")},visit(e,t){const n=this,r=n.pulses,i=r.length;let s=0;if(e&n.SOURCE)for(;sr._enqueue(c,!0)),r._touched=Iy(r0);let o=0,a,l,u;try{for(;r._heap.size()>0;){if(a=r._heap.pop(),a.rank!==a.qrank){r._enqueue(a,!0);continue}l=a.run(r._getPulse(a,e)),l.then?l=await l:l.async&&(i.push(l.async),l=Y1),l!==Y1&&a._targets&&a._targets.forEach(c=>r._enqueue(c)),++o}}catch(c){r._heap.clear(),u=c}if(r._input={},r._pulse=null,r.debug(`Pulse ${s}: ${o} operators`),u&&(r._postrun=[],r.error(u)),r._postrun.length){const c=r._postrun.sort((f,d)=>d.priority-f.priority);r._postrun=[];for(let f=0;fr.runAsync(null,()=>{c.forEach(f=>{try{f(r)}catch(d){r.error(d)}})})),r}async function SK(e,t,n){for(;this._running;)await this._running;const r=()=>this._running=null;return(this._running=this.evaluate(e,t,n)).then(r,r),this._running}function CK(e,t,n){return this._pulse?cO(this):(this.evaluate(e,t,n),this)}function $K(e,t,n){if(this._pulse||t)this._postrun.push({priority:n||0,callback:e});else try{e(this)}catch(r){this.error(r)}}function cO(e){return e.error("Dataflow already running. Use runAsync() to chain invocations."),e}function FK(e,t){const n=e.stampi.pulse),t):this._input[e.id]||MK(this._pulse,n&&n.pulse)}function MK(e,t){return t&&t.stamp===e.stamp?t:(e=e.fork(),t&&t!==Y1&&(e.source=t.source),e)}const Ik={skip:!1,force:!1};function TK(e,t){const n=t||Ik;return this._pulse?this._enqueue(e):this._touched.add(e),n.skip&&e.skip(!0),this}function RK(e,t,n){const r=n||Ik;return(e.set(t)||r.force)&&this.touch(e,r),this}function NK(e,t,n){this.touch(e,n||Ik);const r=new Ql(this,this._clock+(this._pulse?0:1)),i=e.pulse&&e.pulse.source||[];return r.target=e,this._input[e.id]=t.pulse(r,i),this}function OK(e){let t=[];return{clear:()=>t=[],size:()=>t.length,peek:()=>t[0],push:n=>(t.push(n),fO(t,0,t.length-1,e)),pop:()=>{const n=t.pop();let r;return t.length?(r=t[0],t[0]=n,LK(t,0,e)):r=n,r}}}function fO(e,t,n,r){let i,s;const o=e[n];for(;n>t;){if(s=n-1>>1,i=e[s],r(o,i)<0){e[n]=i,n=s;continue}break}return e[n]=o}function LK(e,t,n){const r=t,i=e.length,s=e[t];let o=(t<<1)+1,a;for(;o=0&&(o=a),e[t]=e[o],t=o,o=(t<<1)+1;return e[t]=s,fO(e,r,t,n)}function sd(){this.logger(dk()),this.logLevel(ck),this._clock=0,this._rank=0,this._locale=Mk();try{this._loader=Ly()}catch{}this._touched=Iy(r0),this._input={},this._pulse=null,this._heap=OK((e,t)=>e.qrank-t.qrank),this._postrun=[]}function Qh(e){return function(){return this._log[e].apply(this,arguments)}}sd.prototype={stamp(){return this._clock},loader(e){return arguments.length?(this._loader=e,this):this._loader},locale(e){return arguments.length?(this._locale=e,this):this._locale},logger(e){return arguments.length?(this._log=e,this):this._log},error:Qh("error"),warn:Qh("warn"),info:Qh("info"),debug:Qh("debug"),logLevel:Qh("level"),cleanThreshold:1e4,add:lK,connect:uK,rank:wK,rerank:EK,pulse:NK,touch:TK,update:RK,changeset:Eu,ingest:hK,parse:dK,preload:gK,request:pK,events:fK,on:yK,evaluate:kK,run:CK,runAsync:SK,runAfter:$K,_enqueue:FK,_getPulse:DK};function ie(e,t){cn.call(this,e,null,t)}Me(ie,cn,{run(e){if(e.stampthis.pulse=n):t!==e.StopPropagation&&(this.pulse=t),t},evaluate(e){const t=this.marshall(e.stamp),n=this.transform(t,e);return t.clear(),n},transform(){}});const Od={};function dO(e){const t=hO(e);return t&&t.Definition||null}function hO(e){return e=e&&e.toLowerCase(),Ue(Od,e)?Od[e]:null}function*pO(e,t){if(t==null)for(let n of e)n!=null&&n!==""&&(n=+n)>=n&&(yield n);else{let n=-1;for(let r of e)r=t(r,++n,e),r!=null&&r!==""&&(r=+r)>=r&&(yield r)}}function Pk(e,t,n){const r=Float64Array.from(pO(e,n));return r.sort(Qa),t.map(i=>fN(r,i))}function Bk(e,t){return Pk(e,[.25,.5,.75],t)}function zk(e,t){const n=e.length,r=HY(e,t),i=Bk(e,t),s=(i[2]-i[0])/1.34;return 1.06*(Math.min(r,s)||r||Math.abs(i[0])||1)*Math.pow(n,-.2)}function gO(e){const t=e.maxbins||20,n=e.base||10,r=Math.log(n),i=e.divide||[5,2];let s=e.extent[0],o=e.extent[1],a,l,u,c,f,d;const h=e.span||o-s||Math.abs(s)||1;if(e.step)a=e.step;else if(e.steps){for(c=h/t,f=0,d=e.steps.length;ft;)a*=n;for(f=0,d=i.length;f=u&&h/c<=t&&(a=c)}c=Math.log(a);const p=c>=0?0:~~(-c/r)+1,g=Math.pow(n,-p-1);return(e.nice||e.nice===void 0)&&(c=Math.floor(s/a+g)*a,s=sd);const i=e.length,s=new Float64Array(i);let o=0,a=1,l=r(e[0]),u=l,c=l+t,f;for(;a=c){for(u=(l+u)/2;o>1);oi;)e[o--]=e[r]}r=i,i=s}return e}function BK(e){return function(){return e=(1103515245*e+12345)%2147483647,e/2147483647}}function zK(e,t){t==null&&(t=e,e=0);let n,r,i;const s={min(o){return arguments.length?(n=o||0,i=r-n,s):n},max(o){return arguments.length?(r=o||0,i=r-n,s):r},sample(){return n+Math.floor(i*Ps())},pdf(o){return o===Math.floor(o)&&o>=n&&o=r?1:(a-n+1)/i},icdf(o){return o>=0&&o<=1?n-1+Math.floor(o*i):NaN}};return s.min(e).max(t)}const yO=Math.sqrt(2*Math.PI),jK=Math.SQRT2;let ep=NaN;function Uy(e,t){e=e||0,t=t??1;let n=0,r=0,i,s;if(ep===ep)n=ep,ep=NaN;else{do n=Ps()*2-1,r=Ps()*2-1,i=n*n+r*r;while(i===0||i>1);s=Math.sqrt(-2*Math.log(i)/i),n*=s,ep=r*s}return e+n*t}function jk(e,t,n){n=n??1;const r=(e-(t||0))/n;return Math.exp(-.5*r*r)/(n*yO)}function qy(e,t,n){t=t||0,n=n??1;const r=(e-t)/n,i=Math.abs(r);let s;if(i>37)s=0;else{const o=Math.exp(-i*i/2);let a;i<7.07106781186547?(a=.0352624965998911*i+.700383064443688,a=a*i+6.37396220353165,a=a*i+33.912866078383,a=a*i+112.079291497871,a=a*i+221.213596169931,a=a*i+220.206867912376,s=o*a,a=.0883883476483184*i+1.75566716318264,a=a*i+16.064177579207,a=a*i+86.7807322029461,a=a*i+296.564248779674,a=a*i+637.333633378831,a=a*i+793.826512519948,a=a*i+440.413735824752,s=s/a):(a=i+.65,a=i+4/a,a=i+3/a,a=i+2/a,a=i+1/a,s=o/a/2.506628274631)}return r>0?1-s:s}function Wy(e,t,n){return e<0||e>1?NaN:(t||0)+(n??1)*jK*UK(2*e-1)}function UK(e){let t=-Math.log((1-e)*(1+e)),n;return t<6.25?(t-=3.125,n=-364441206401782e-35,n=-16850591381820166e-35+n*t,n=128584807152564e-32+n*t,n=11157877678025181e-33+n*t,n=-1333171662854621e-31+n*t,n=20972767875968562e-33+n*t,n=6637638134358324e-30+n*t,n=-4054566272975207e-29+n*t,n=-8151934197605472e-29+n*t,n=26335093153082323e-28+n*t,n=-12975133253453532e-27+n*t,n=-5415412054294628e-26+n*t,n=10512122733215323e-25+n*t,n=-4112633980346984e-24+n*t,n=-29070369957882005e-24+n*t,n=42347877827932404e-23+n*t,n=-13654692000834679e-22+n*t,n=-13882523362786469e-21+n*t,n=.00018673420803405714+n*t,n=-.000740702534166267+n*t,n=-.006033670871430149+n*t,n=.24015818242558962+n*t,n=1.6536545626831027+n*t):t<16?(t=Math.sqrt(t)-3.25,n=22137376921775787e-25,n=9075656193888539e-23+n*t,n=-27517406297064545e-23+n*t,n=18239629214389228e-24+n*t,n=15027403968909828e-22+n*t,n=-4013867526981546e-21+n*t,n=29234449089955446e-22+n*t,n=12475304481671779e-21+n*t,n=-47318229009055734e-21+n*t,n=6828485145957318e-20+n*t,n=24031110387097894e-21+n*t,n=-.0003550375203628475+n*t,n=.0009532893797373805+n*t,n=-.0016882755560235047+n*t,n=.002491442096107851+n*t,n=-.003751208507569241+n*t,n=.005370914553590064+n*t,n=1.0052589676941592+n*t,n=3.0838856104922208+n*t):Number.isFinite(t)?(t=Math.sqrt(t)-5,n=-27109920616438573e-27,n=-2555641816996525e-25+n*t,n=15076572693500548e-25+n*t,n=-3789465440126737e-24+n*t,n=761570120807834e-23+n*t,n=-1496002662714924e-23+n*t,n=2914795345090108e-23+n*t,n=-6771199775845234e-23+n*t,n=22900482228026655e-23+n*t,n=-99298272942317e-20+n*t,n=4526062597223154e-21+n*t,n=-1968177810553167e-20+n*t,n=7599527703001776e-20+n*t,n=-.00021503011930044477+n*t,n=-.00013871931833623122+n*t,n=1.0103004648645344+n*t,n=4.849906401408584+n*t):n=1/0,n*e}function Uk(e,t){let n,r;const i={mean(s){return arguments.length?(n=s||0,i):n},stdev(s){return arguments.length?(r=s??1,i):r},sample:()=>Uy(n,r),pdf:s=>jk(s,n,r),cdf:s=>qy(s,n,r),icdf:s=>Wy(s,n,r)};return i.mean(e).stdev(t)}function qk(e,t){const n=Uk();let r=0;const i={data(s){return arguments.length?(e=s,r=s?s.length:0,i.bandwidth(t)):e},bandwidth(s){return arguments.length?(t=s,!t&&e&&(t=zk(e)),i):t},sample(){return e[~~(Ps()*r)]+t*n.sample()},pdf(s){let o=0,a=0;for(;aWk(n,r),pdf:s=>Hk(s,n,r),cdf:s=>Gk(s,n,r),icdf:s=>Yk(s,n,r)};return i.mean(e).stdev(t)}function xO(e,t){let n=0,r;function i(o){const a=[];let l=0,u;for(u=0;u=t&&e<=n?1/(n-t):0}function Kk(e,t,n){return n==null&&(n=t??1,t=0),en?1:(e-t)/(n-t)}function Zk(e,t,n){return n==null&&(n=t??1,t=0),e>=0&&e<=1?t+e*(n-t):NaN}function _O(e,t){let n,r;const i={min(s){return arguments.length?(n=s||0,i):n},max(s){return arguments.length?(r=s??1,i):r},sample:()=>Vk(n,r),pdf:s=>Xk(s,n,r),cdf:s=>Kk(s,n,r),icdf:s=>Zk(s,n,r)};return t==null&&(t=e??1,e=0),i.min(e).max(t)}function Jk(e,t,n){let r=0,i=0;for(const s of e){const o=n(s);t(s)==null||o==null||isNaN(o)||(r+=(o-r)/++i)}return{coef:[r],predict:()=>r,rSquared:0}}function s0(e,t,n,r){const i=r-e*e,s=Math.abs(i)<1e-24?0:(n-e*t)/i;return[t-s*e,s]}function Hy(e,t,n,r){e=e.filter(h=>{let p=t(h),g=n(h);return p!=null&&(p=+p)>=p&&g!=null&&(g=+g)>=g}),r&&e.sort((h,p)=>t(h)-t(p));const i=e.length,s=new Float64Array(i),o=new Float64Array(i);let a=0,l=0,u=0,c,f,d;for(d of e)s[a]=c=+t(d),o[a]=f=+n(d),++a,l+=(c-l)/a,u+=(f-u)/a;for(a=0;a=s&&o!=null&&(o=+o)>=o&&r(s,o,++i)}function kh(e,t,n,r,i){let s=0,o=0;return o0(e,t,n,(a,l)=>{const u=l-i(a),c=l-r;s+=u*u,o+=c*c}),1-s/o}function Qk(e,t,n){let r=0,i=0,s=0,o=0,a=0;o0(e,t,n,(c,f)=>{++a,r+=(c-r)/a,i+=(f-i)/a,s+=(c*f-s)/a,o+=(c*c-o)/a});const l=s0(r,i,s,o),u=c=>l[0]+l[1]*c;return{coef:l,predict:u,rSquared:kh(e,t,n,i,u)}}function wO(e,t,n){let r=0,i=0,s=0,o=0,a=0;o0(e,t,n,(c,f)=>{++a,c=Math.log(c),r+=(c-r)/a,i+=(f-i)/a,s+=(c*f-s)/a,o+=(c*c-o)/a});const l=s0(r,i,s,o),u=c=>l[0]+l[1]*Math.log(c);return{coef:l,predict:u,rSquared:kh(e,t,n,i,u)}}function EO(e,t,n){const[r,i,s,o]=Hy(e,t,n);let a=0,l=0,u=0,c=0,f=0,d,h,p;o0(e,t,n,(b,x)=>{d=r[f++],h=Math.log(x),p=d*x,a+=(x*h-a)/f,l+=(p-l)/f,u+=(p*h-u)/f,c+=(d*p-c)/f});const[g,m]=s0(l/o,a/o,u/o,c/o),y=b=>Math.exp(g+m*(b-s));return{coef:[Math.exp(g-m*s),m],predict:y,rSquared:kh(e,t,n,o,y)}}function AO(e,t,n){let r=0,i=0,s=0,o=0,a=0,l=0;o0(e,t,n,(f,d)=>{const h=Math.log(f),p=Math.log(d);++l,r+=(h-r)/l,i+=(p-i)/l,s+=(h*p-s)/l,o+=(h*h-o)/l,a+=(d-a)/l});const u=s0(r,i,s,o),c=f=>u[0]*Math.pow(f,u[1]);return u[0]=Math.exp(u[0]),{coef:u,predict:c,rSquared:kh(e,t,n,a,c)}}function eS(e,t,n){const[r,i,s,o]=Hy(e,t,n),a=r.length;let l=0,u=0,c=0,f=0,d=0,h,p,g,m;for(h=0;h(E=E-s,x*E*E+_*E+w+o);return{coef:[w-_*s+x*s*s+o,_-2*x*s,x],predict:A,rSquared:kh(e,t,n,o,A)}}function kO(e,t,n,r){if(r===0)return Jk(e,t,n);if(r===1)return Qk(e,t,n);if(r===2)return eS(e,t,n);const[i,s,o,a]=Hy(e,t,n),l=i.length,u=[],c=[],f=r+1;let d,h,p,g,m;for(d=0;d{x-=o;let _=a+y[0]+y[1]*x+y[2]*x*x;for(d=3;d=0;--s)for(a=t[s],l=1,i[s]+=a,o=1;o<=s;++o)l*=(s+1-o)/o,i[s-o]+=a*Math.pow(n,o)*l;return i[0]+=r,i}function WK(e){const t=e.length-1,n=[];let r,i,s,o,a;for(r=0;rMath.abs(e[r][o])&&(o=i);for(s=r;s=r;s--)e[s][i]-=e[s][r]*e[r][i]/e[r][r]}for(i=t-1;i>=0;--i){for(a=0,s=i+1;si[x]-y?b:x;let w=0,A=0,E=0,k=0,S=0;const $=1/Math.abs(i[_]-y||1);for(let P=b;P<=x;++P){const T=i[P],F=s[P],N=HK(Math.abs(y-T)*$)*d[P],U=T*N;w+=N,A+=U,E+=F*N,k+=F*U,S+=T*U}const[M,O]=s0(A/w,E/w,k/w,S/w);c[m]=M+O*y,f[m]=Math.abs(s[m]-c[m]),GK(i,m+1,p)}if(h===Z5)break;const g=dN(f);if(Math.abs(g)=1?J5:(b=1-y*y)*b}return YK(i,c,o,a)}function HK(e){return(e=1-e*e*e)*e*e}function GK(e,t,n){const r=e[t];let i=n[0],s=n[1]+1;if(!(s>=e.length))for(;t>i&&e[s]-r<=r-e[i];)n[0]=++i,n[1]=s,++s}function YK(e,t,n,r){const i=e.length,s=[];let o=0,a=0,l=[],u;for(;o[g,e(g)],s=t[0],o=t[1],a=o-s,l=a/r,u=[i(s)],c=[];if(n===r){for(let g=1;g0;)c.push(i(s+g/n*a))}let f=u[0],d=c[c.length-1];const h=1/a,p=XK(f[1],c);for(;d;){const g=i((f[0]+d[0])/2);g[0]-f[0]>=l&&KK(f,g,d,h,p)>VK?c.push(g):(f=d,u.push(d),c.pop()),d=c[c.length-1]}return u}function XK(e,t){let n=e,r=e;const i=t.length;for(let s=0;sr&&(r=o)}return 1/(r-n)}function KK(e,t,n,r,i){const s=Math.atan2(i*(n[1]-e[1]),r*(n[0]-e[0])),o=Math.atan2(i*(t[1]-e[1]),r*(t[0]-e[0]));return Math.abs(s-o)}function ZK(e){return t=>{const n=e.length;let r=1,i=String(e[0](t));for(;r{},JK={init:hx,add:hx,rem:hx,idx:0},gg={values:{init:e=>e.cell.store=!0,value:e=>e.cell.data.values(),idx:-1},count:{value:e=>e.cell.num},__count__:{value:e=>e.missing+e.valid},missing:{value:e=>e.missing},valid:{value:e=>e.valid},sum:{init:e=>e.sum=0,value:e=>e.valid?e.sum:void 0,add:(e,t)=>e.sum+=+t,rem:(e,t)=>e.sum-=t},product:{init:e=>e.product=1,value:e=>e.valid?e.product:void 0,add:(e,t)=>e.product*=t,rem:(e,t)=>e.product/=t},mean:{init:e=>e.mean=0,value:e=>e.valid?e.mean:void 0,add:(e,t)=>(e.mean_d=t-e.mean,e.mean+=e.mean_d/e.valid),rem:(e,t)=>(e.mean_d=t-e.mean,e.mean-=e.valid?e.mean_d/e.valid:e.mean)},average:{value:e=>e.valid?e.mean:void 0,req:["mean"],idx:1},variance:{init:e=>e.dev=0,value:e=>e.valid>1?e.dev/(e.valid-1):void 0,add:(e,t)=>e.dev+=e.mean_d*(t-e.mean),rem:(e,t)=>e.dev-=e.mean_d*(t-e.mean),req:["mean"],idx:1},variancep:{value:e=>e.valid>1?e.dev/e.valid:void 0,req:["variance"],idx:2},stdev:{value:e=>e.valid>1?Math.sqrt(e.dev/(e.valid-1)):void 0,req:["variance"],idx:2},stdevp:{value:e=>e.valid>1?Math.sqrt(e.dev/e.valid):void 0,req:["variance"],idx:2},stderr:{value:e=>e.valid>1?Math.sqrt(e.dev/(e.valid*(e.valid-1))):void 0,req:["variance"],idx:2},distinct:{value:e=>e.cell.data.distinct(e.get),req:["values"],idx:3},ci0:{value:e=>e.cell.data.ci0(e.get),req:["values"],idx:3},ci1:{value:e=>e.cell.data.ci1(e.get),req:["values"],idx:3},median:{value:e=>e.cell.data.q2(e.get),req:["values"],idx:3},q1:{value:e=>e.cell.data.q1(e.get),req:["values"],idx:3},q3:{value:e=>e.cell.data.q3(e.get),req:["values"],idx:3},min:{init:e=>e.min=void 0,value:e=>e.min=Number.isNaN(e.min)?e.cell.data.min(e.get):e.min,add:(e,t)=>{(t{t<=e.min&&(e.min=NaN)},req:["values"],idx:4},max:{init:e=>e.max=void 0,value:e=>e.max=Number.isNaN(e.max)?e.cell.data.max(e.get):e.max,add:(e,t)=>{(t>e.max||e.max===void 0)&&(e.max=t)},rem:(e,t)=>{t>=e.max&&(e.max=NaN)},req:["values"],idx:4},argmin:{init:e=>e.argmin=void 0,value:e=>e.argmin||e.cell.data.argmin(e.get),add:(e,t,n)=>{t{t<=e.min&&(e.argmin=void 0)},req:["min","values"],idx:3},argmax:{init:e=>e.argmax=void 0,value:e=>e.argmax||e.cell.data.argmax(e.get),add:(e,t,n)=>{t>e.max&&(e.argmax=n)},rem:(e,t)=>{t>=e.max&&(e.argmax=void 0)},req:["max","values"],idx:3},exponential:{init:(e,t)=>{e.exp=0,e.exp_r=t},value:e=>e.valid?e.exp*(1-e.exp_r)/(1-e.exp_r**e.valid):void 0,add:(e,t)=>e.exp=e.exp_r*e.exp+t,rem:(e,t)=>e.exp=(e.exp-t/e.exp_r**(e.valid-1))/e.exp_r},exponentialb:{value:e=>e.valid?e.exp*(1-e.exp_r):void 0,req:["exponential"],idx:1}},a0=Object.keys(gg).filter(e=>e!=="__count__");function QK(e,t){return(n,r)=>Mt({name:e,aggregate_param:r,out:n||e},JK,t)}[...a0,"__count__"].forEach(e=>{gg[e]=QK(e,gg[e])});function $O(e,t,n){return gg[e](n,t)}function FO(e,t){return e.idx-t.idx}function eZ(e){const t={};e.forEach(r=>t[r.name]=r);const n=r=>{r.req&&r.req.forEach(i=>{t[i]||n(t[i]=gg[i]())})};return e.forEach(n),Object.values(t).sort(FO)}function tZ(){this.valid=0,this.missing=0,this._ops.forEach(e=>e.aggregate_param==null?e.init(this):e.init(this,e.aggregate_param))}function nZ(e,t){if(e==null||e===""){++this.missing;return}e===e&&(++this.valid,this._ops.forEach(n=>n.add(this,e,t)))}function rZ(e,t){if(e==null||e===""){--this.missing;return}e===e&&(--this.valid,this._ops.forEach(n=>n.rem(this,e,t)))}function iZ(e){return this._out.forEach(t=>e[t.out]=t.value(this)),e}function DO(e,t){const n=t||ni,r=eZ(e),i=e.slice().sort(FO);function s(o){this._ops=r,this._out=i,this.cell=o,this.init()}return s.prototype.init=tZ,s.prototype.add=nZ,s.prototype.rem=rZ,s.prototype.set=iZ,s.prototype.get=n,s.fields=e.map(o=>o.out),s}function tS(e){this._key=e?Ls(e):ot,this.reset()}const Pr=tS.prototype;Pr.reset=function(){this._add=[],this._rem=[],this._ext=null,this._get=null,this._q=null};Pr.add=function(e){this._add.push(e)};Pr.rem=function(e){this._rem.push(e)};Pr.values=function(){if(this._get=null,this._rem.length===0)return this._add;const e=this._add,t=this._rem,n=this._key,r=e.length,i=t.length,s=Array(r-i),o={};let a,l,u;for(a=0;a=0;)s=e(t[r])+"",Ue(n,s)||(n[s]=1,++i);return i};Pr.extent=function(e){if(this._get!==e||!this._ext){const t=this.values(),n=VR(t,e);this._ext=[t[n[0]],t[n[1]]],this._get=e}return this._ext};Pr.argmin=function(e){return this.extent(e)[0]||{}};Pr.argmax=function(e){return this.extent(e)[1]||{}};Pr.min=function(e){const t=this.extent(e)[0];return t!=null?e(t):void 0};Pr.max=function(e){const t=this.extent(e)[1];return t!=null?e(t):void 0};Pr.quartile=function(e){return(this._get!==e||!this._q)&&(this._q=Bk(this.values(),e),this._get=e),this._q};Pr.q1=function(e){return this.quartile(e)[0]};Pr.q2=function(e){return this.quartile(e)[1]};Pr.q3=function(e){return this.quartile(e)[2]};Pr.ci=function(e){return(this._get!==e||!this._ci)&&(this._ci=mO(this.values(),1e3,.05,e),this._get=e),this._ci};Pr.ci0=function(e){return this.ci(e)[0]};Pr.ci1=function(e){return this.ci(e)[1]};function ou(e){ie.call(this,null,e),this._adds=[],this._mods=[],this._alen=0,this._mlen=0,this._drop=!0,this._cross=!1,this._dims=[],this._dnames=[],this._measures=[],this._countOnly=!1,this._counts=null,this._prev=null,this._inputs=null,this._outputs=null}ou.Definition={type:"Aggregate",metadata:{generates:!0,changes:!0},params:[{name:"groupby",type:"field",array:!0},{name:"ops",type:"enum",array:!0,values:a0},{name:"aggregate_params",type:"number",null:!0,array:!0},{name:"fields",type:"field",null:!0,array:!0},{name:"as",type:"string",null:!0,array:!0},{name:"drop",type:"boolean",default:!0},{name:"cross",type:"boolean",default:!1},{name:"key",type:"field"}]};Me(ou,ie,{transform(e,t){const n=this,r=t.fork(t.NO_SOURCE|t.NO_FIELDS),i=e.modified();return n.stamp=r.stamp,n.value&&(i||t.modified(n._inputs,!0))?(n._prev=n.value,n.value=i?n.init(e):Object.create(null),t.visit(t.SOURCE,s=>n.add(s))):(n.value=n.value||n.init(e),t.visit(t.REM,s=>n.rem(s)),t.visit(t.ADD,s=>n.add(s))),r.modifies(n._outputs),n._drop=e.drop!==!1,e.cross&&n._dims.length>1&&(n._drop=!1,n.cross()),t.clean()&&n._drop&&r.clean(!0).runAfter(()=>this.clean()),n.changes(r)},cross(){const e=this,t=e.value,n=e._dnames,r=n.map(()=>({})),i=n.length;function s(a){let l,u,c,f;for(l in a)for(c=a[l].tuple,u=0;u{const x=Ln(b);return i(b),n.push(x),x}),this.cellkey=e.key?e.key:Rw(this._dims),this._countOnly=!0,this._counts=[],this._measures=[];const s=e.fields||[null],o=e.ops||["count"],a=e.aggregate_params||[null],l=e.as||[],u=s.length,c={};let f,d,h,p,g,m,y;for(u!==o.length&&le("Unmatched number of fields and aggregate ops."),y=0;yDO(b,b.field)),Object.create(null)},cellkey:Rw(),cell(e,t){let n=this.value[e];return n?n.num===0&&this._drop&&n.stamp{const f=r(c);c[a]=f,c[l]=f==null?null:i+s*(1+(f-i)/s)}:c=>c[a]=r(c)),t.modifies(n?o:a)},_bins(e){if(this.value&&!e.modified())return this.value;const t=e.field,n=gO(e),r=n.step;let i=n.start,s=i+Math.ceil((n.stop-i)/r)*r,o,a;(o=e.anchor)!=null&&(a=o-(i+r*Math.floor((o-i)/r)),i+=a,s+=a);const l=function(u){let c=Vr(t(u));return c==null?null:cs?1/0:(c=Math.max(i,Math.min(c,s-r)),i+r*Math.floor(sZ+(c-i)/r))};return l.start=i,l.stop=n.stop,l.step=r,this.value=Yi(l,Kr(t),e.name||"bin_"+Ln(t))}});function MO(e,t,n){const r=e;let i=t||[],s=n||[],o={},a=0;return{add:l=>s.push(l),remove:l=>o[r(l)]=++a,size:()=>i.length,data:(l,u)=>(a&&(i=i.filter(c=>!o[r(c)]),o={},a=0),u&&l&&i.sort(l),s.length&&(i=l?QR(l,i,s.sort(l)):i.concat(s),s=[]),i)}}function rS(e){ie.call(this,[],e)}rS.Definition={type:"Collect",metadata:{source:!0},params:[{name:"sort",type:"compare"}]};Me(rS,ie,{transform(e,t){const n=t.fork(t.ALL),r=MO(ot,this.value,n.materialize(n.ADD).add),i=e.sort,s=t.changed()||i&&(e.modified("sort")||t.modified(i.fields));return n.visit(n.REM,r.remove),this.modified(s),this.value=n.source=r.data(pf(i),s),t.source&&t.source.root&&(this.value.root=t.source.root),n}});function TO(e){cn.call(this,null,oZ,e)}Me(TO,cn);function oZ(e){return this.value&&!e.modified()?this.value:mk(e.fields,e.orders)}function iS(e){ie.call(this,null,e)}iS.Definition={type:"CountPattern",metadata:{generates:!0,changes:!0},params:[{name:"field",type:"field",required:!0},{name:"case",type:"enum",values:["upper","lower","mixed"],default:"mixed"},{name:"pattern",type:"string",default:'[\\w"]+'},{name:"stopwords",type:"string",default:""},{name:"as",type:"string",array:!0,length:2,default:["text","count"]}]};function aZ(e,t,n){switch(t){case"upper":e=e.toUpperCase();break;case"lower":e=e.toLowerCase();break}return e.match(n)}Me(iS,ie,{transform(e,t){const n=f=>d=>{for(var h=aZ(a(d),e.case,s)||[],p,g=0,m=h.length;gi[f]=1+(i[f]||0)),c=n(f=>i[f]-=1);return r?t.visit(t.SOURCE,u):(t.visit(t.ADD,u),t.visit(t.REM,c)),this._finish(t,l)},_parameterCheck(e,t){let n=!1;return(e.modified("stopwords")||!this._stop)&&(this._stop=new RegExp("^"+(e.stopwords||"")+"$","i"),n=!0),(e.modified("pattern")||!this._match)&&(this._match=new RegExp(e.pattern||"[\\w']+","g"),n=!0),(e.modified("field")||t.modified(e.field.fields))&&(n=!0),n&&(this._counts={}),n},_finish(e,t){const n=this._counts,r=this._tuples||(this._tuples={}),i=t[0],s=t[1],o=e.fork(e.NO_SOURCE|e.NO_FIELDS);let a,l,u;for(a in n)l=r[a],u=n[a]||0,!l&&u?(r[a]=l=Zt({}),l[i]=a,l[s]=u,o.add.push(l)):u===0?(l&&o.rem.push(l),n[a]=null,r[a]=null):l[s]!==u&&(l[s]=u,o.mod.push(l));return o.modifies(t)}});function sS(e){ie.call(this,null,e)}sS.Definition={type:"Cross",metadata:{generates:!0},params:[{name:"filter",type:"expr"},{name:"as",type:"string",array:!0,length:2,default:["a","b"]}]};Me(sS,ie,{transform(e,t){const n=t.fork(t.NO_SOURCE),r=e.as||["a","b"],i=r[0],s=r[1],o=!this.value||t.changed(t.ADD_REM)||e.modified("as")||e.modified("filter");let a=this.value;return o?(a&&(n.rem=a),a=t.materialize(t.SOURCE).source,n.add=this.value=lZ(a,i,s,e.filter||ds)):n.mod=a,n.source=this.value,n.modifies(r)}});function lZ(e,t,n,r){for(var i=[],s={},o=e.length,a=0,l,u;aRO(s,t))):typeof r[i]===eD&&r[i](e[i]);return r}function oS(e){ie.call(this,null,e)}const NO=[{key:{function:"normal"},params:[{name:"mean",type:"number",default:0},{name:"stdev",type:"number",default:1}]},{key:{function:"lognormal"},params:[{name:"mean",type:"number",default:0},{name:"stdev",type:"number",default:1}]},{key:{function:"uniform"},params:[{name:"min",type:"number",default:0},{name:"max",type:"number",default:1}]},{key:{function:"kde"},params:[{name:"field",type:"field",required:!0},{name:"from",type:"data"},{name:"bandwidth",type:"number",default:0}]}],fZ={key:{function:"mixture"},params:[{name:"distributions",type:"param",array:!0,params:NO},{name:"weights",type:"number",array:!0}]};oS.Definition={type:"Density",metadata:{generates:!0},params:[{name:"extent",type:"number",array:!0,length:2},{name:"steps",type:"number"},{name:"minsteps",type:"number",default:25},{name:"maxsteps",type:"number",default:200},{name:"method",type:"string",default:"pdf",values:["pdf","cdf"]},{name:"distribution",type:"param",params:NO.concat(fZ)},{name:"as",type:"string",array:!0,default:["value","density"]}]};Me(oS,ie,{transform(e,t){const n=t.fork(t.NO_SOURCE|t.NO_FIELDS);if(!this.value||t.changed()||e.modified()){const r=RO(e.distribution,dZ(t)),i=e.steps||e.minsteps||25,s=e.steps||e.maxsteps||200;let o=e.method||"pdf";o!=="pdf"&&o!=="cdf"&&le("Invalid density method: "+o),!e.extent&&!r.data&&le("Missing density extent parameter."),o=r[o];const a=e.as||["value","density"],l=e.extent||aa(r.data()),u=Gy(o,l,i,s).map(c=>{const f={};return f[a[0]]=c[0],f[a[1]]=c[1],Zt(f)});this.value&&(n.rem=this.value),this.value=n.add=n.source=u}return n}});function dZ(e){return()=>e.materialize(e.SOURCE).source}function OO(e,t){return e?e.map((n,r)=>t[r]||Ln(n)):null}function aS(e,t,n){const r=[],i=f=>f(l);let s,o,a,l,u,c;if(t==null)r.push(e.map(n));else for(s={},o=0,a=e.length;oi0(aa(e,t))/30;Me(lS,ie,{transform(e,t){if(this.value&&!(e.modified()||t.changed()))return t;const n=t.materialize(t.SOURCE).source,r=aS(t.source,e.groupby,ni),i=e.smooth||!1,s=e.field,o=e.step||hZ(n,s),a=pf((p,g)=>s(p)-s(g)),l=e.as||LO,u=r.length;let c=1/0,f=-1/0,d=0,h;for(;df&&(f=g),p[++h][l]=g}return this.value={start:c,stop:f,step:o},t.reflow(!0).modifies(l)}});function IO(e){cn.call(this,null,pZ,e),this.modified(!0)}Me(IO,cn);function pZ(e){const t=e.expr;return this.value&&!e.modified("expr")?this.value:Yi(n=>t(n,e),Kr(t),Ln(t))}function uS(e){ie.call(this,[void 0,void 0],e)}uS.Definition={type:"Extent",metadata:{},params:[{name:"field",type:"field",required:!0}]};Me(uS,ie,{transform(e,t){const n=this.value,r=e.field,i=t.changed()||t.modified(r.fields)||e.modified("field");let s=n[0],o=n[1];if((i||s==null)&&(s=1/0,o=-1/0),t.visit(i?t.SOURCE:t.ADD,a=>{const l=Vr(r(a));l!=null&&(lo&&(o=l))}),!Number.isFinite(s)||!Number.isFinite(o)){let a=Ln(r);a&&(a=` for field "${a}"`),t.dataflow.warn(`Infinite extent${a}: [${s}, ${o}]`),s=o=void 0}this.value=[s,o]}});function cS(e,t){cn.call(this,e),this.parent=t,this.count=0}Me(cS,cn,{connect(e){return this.detachSubflow=e.detachSubflow,this.targets().add(e),e.source=this},add(e){this.count+=1,this.value.add.push(e)},rem(e){this.count-=1,this.value.rem.push(e)},mod(e){this.value.mod.push(e)},init(e){this.value.init(e,e.NO_SOURCE)},evaluate(){return this.value}});function Yy(e){ie.call(this,{},e),this._keys=bh();const t=this._targets=[];t.active=0,t.forEach=n=>{for(let r=0,i=t.active;rr&&r.count>0);this.initTargets(n)}},initTargets(e){const t=this._targets,n=t.length,r=e?e.length:0;let i=0;for(;ithis.subflow(l,i,t);return this._group=e.group||{},this.initTargets(),t.visit(t.REM,l=>{const u=ot(l),c=s.get(u);c!==void 0&&(s.delete(u),a(c).rem(l))}),t.visit(t.ADD,l=>{const u=r(l);s.set(ot(l),u),a(u).add(l)}),o||t.modified(r.fields)?t.visit(t.MOD,l=>{const u=ot(l),c=s.get(u),f=r(l);c===f?a(f).mod(l):(s.set(u,f),a(c).rem(l),a(f).add(l))}):t.changed(t.MOD)&&t.visit(t.MOD,l=>{a(s.get(ot(l))).mod(l)}),o&&t.visit(t.REFLOW,l=>{const u=ot(l),c=s.get(u),f=r(l);c!==f&&(s.set(u,f),a(c).rem(l),a(f).add(l))}),t.clean()?n.runAfter(()=>{this.clean(),s.clean()}):s.empty>n.cleanThreshold&&n.runAfter(s.clean),t}});function PO(e){cn.call(this,null,gZ,e)}Me(PO,cn);function gZ(e){return this.value&&!e.modified()?this.value:de(e.name)?Be(e.name).map(t=>Ls(t)):Ls(e.name,e.as)}function fS(e){ie.call(this,bh(),e)}fS.Definition={type:"Filter",metadata:{changes:!0},params:[{name:"expr",type:"expr",required:!0}]};Me(fS,ie,{transform(e,t){const n=t.dataflow,r=this.value,i=t.fork(),s=i.add,o=i.rem,a=i.mod,l=e.expr;let u=!0;t.visit(t.REM,f=>{const d=ot(f);r.has(d)?r.delete(d):o.push(f)}),t.visit(t.ADD,f=>{l(f,e)?s.push(f):r.set(ot(f),1)});function c(f){const d=ot(f),h=l(f,e),p=r.get(d);h&&p?(r.delete(d),s.push(f)):!h&&!p?(r.set(d,1),o.push(f)):u&&h&&!p&&a.push(f)}return t.visit(t.MOD,c),e.modified()&&(u=!1,t.visit(t.REFLOW,c)),r.empty>n.cleanThreshold&&n.runAfter(r.clean),i}});function dS(e){ie.call(this,[],e)}dS.Definition={type:"Flatten",metadata:{generates:!0},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"index",type:"string"},{name:"as",type:"string",array:!0}]};Me(dS,ie,{transform(e,t){const n=t.fork(t.NO_SOURCE),r=e.fields,i=OO(r,e.as||[]),s=e.index||null,o=i.length;return n.rem=this.value,t.visit(t.SOURCE,a=>{const l=r.map(p=>p(a)),u=l.reduce((p,g)=>Math.max(p,g.length),0);let c=0,f,d,h;for(;c{for(let c=0,f;co[r]=n(o,e))}});function BO(e){ie.call(this,[],e)}Me(BO,ie,{transform(e,t){const n=t.fork(t.ALL),r=e.generator;let i=this.value,s=e.size-i.length,o,a,l;if(s>0){for(o=[];--s>=0;)o.push(l=Zt(r(e))),i.push(l);n.add=n.add.length?n.materialize(n.ADD).add.concat(o):o}else a=i.slice(0,-s),n.rem=n.rem.length?n.materialize(n.REM).rem.concat(a):a,i=i.slice(-s);return n.source=this.value=i,n}});const lm={value:"value",median:dN,mean:ZY,min:ww,max:wc},mZ=[];function gS(e){ie.call(this,[],e)}gS.Definition={type:"Impute",metadata:{changes:!0},params:[{name:"field",type:"field",required:!0},{name:"key",type:"field",required:!0},{name:"keyvals",array:!0},{name:"groupby",type:"field",array:!0},{name:"method",type:"enum",default:"value",values:["value","mean","median","max","min"]},{name:"value",default:0}]};function vZ(e){var t=e.method||lm.value,n;if(lm[t]==null)le("Unrecognized imputation method: "+t);else return t===lm.value?(n=e.value!==void 0?e.value:0,()=>n):lm[t]}function yZ(e){const t=e.field;return n=>n?t(n):NaN}Me(gS,ie,{transform(e,t){var n=t.fork(t.ALL),r=vZ(e),i=yZ(e),s=Ln(e.field),o=Ln(e.key),a=(e.groupby||[]).map(Ln),l=bZ(t.source,e.groupby,e.key,e.keyvals),u=[],c=this.value,f=l.domain.length,d,h,p,g,m,y,b,x,_,w;for(m=0,x=l.length;my(m),s=[],o=r?r.slice():[],a={},l={},u,c,f,d,h,p,g,m;for(o.forEach((y,b)=>a[y]=b+1),d=0,g=e.length;dn.add(s))):(i=n.value=n.value||this.init(e),t.visit(t.REM,s=>n.rem(s)),t.visit(t.ADD,s=>n.add(s))),n.changes(),t.visit(t.SOURCE,s=>{Mt(s,i[n.cellkey(s)].tuple)}),t.reflow(r).modifies(this._outputs)},changes(){const e=this._adds,t=this._mods;let n,r;for(n=0,r=this._alen;n{const p=qk(h,o)[a],g=e.counts?h.length:1,m=c||aa(h);Gy(p,m,f,d).forEach(y=>{const b={};for(let x=0;x(this._pending=Be(i.data),s=>s.touch(this)))}:n.request(e.url,e.format).then(r=>px(this,t,Be(r.data)))}});function _Z(e){return e.modified("async")&&!(e.modified("values")||e.modified("url")||e.modified("format"))}function px(e,t,n){n.forEach(Zt);const r=t.fork(t.NO_FIELDS&t.NO_SOURCE);return r.rem=e.value,e.value=r.source=r.add=n,e._pending=null,r.rem.length&&r.clean(!0),r}function yS(e){ie.call(this,{},e)}yS.Definition={type:"Lookup",metadata:{modifies:!0},params:[{name:"index",type:"index",params:[{name:"from",type:"data",required:!0},{name:"key",type:"field",required:!0}]},{name:"values",type:"field",array:!0},{name:"fields",type:"field",array:!0,required:!0},{name:"as",type:"string",array:!0},{name:"default",default:null}]};Me(yS,ie,{transform(e,t){const n=e.fields,r=e.index,i=e.values,s=e.default==null?null:e.default,o=e.modified(),a=n.length;let l=o?t.SOURCE:t.ADD,u=t,c=e.as,f,d,h;return i?(d=i.length,a>1&&!c&&le('Multi-field lookup requires explicit "as" parameter.'),c&&c.length!==a*d&&le('The "as" parameter has too few output field names.'),c=c||i.map(Ln),f=function(p){for(var g=0,m=0,y,b;gt.modified(p.fields)),l|=h?t.MOD:0),t.visit(l,f),u.modifies(c)}});function UO(e){cn.call(this,null,wZ,e)}Me(UO,cn);function wZ(e){if(this.value&&!e.modified())return this.value;const t=e.extents,n=t.length;let r=1/0,i=-1/0,s,o;for(s=0;si&&(i=o[1]);return[r,i]}function qO(e){cn.call(this,null,EZ,e)}Me(qO,cn);function EZ(e){return this.value&&!e.modified()?this.value:e.values.reduce((t,n)=>t.concat(n),[])}function WO(e){ie.call(this,null,e)}Me(WO,ie,{transform(e,t){return this.modified(e.modified()),this.value=e,t.fork(t.NO_SOURCE|t.NO_FIELDS)}});function bS(e){ou.call(this,e)}bS.Definition={type:"Pivot",metadata:{generates:!0,changes:!0},params:[{name:"groupby",type:"field",array:!0},{name:"field",type:"field",required:!0},{name:"value",type:"field",required:!0},{name:"op",type:"enum",values:a0,default:"sum"},{name:"limit",type:"number",default:0},{name:"key",type:"field"}]};Me(bS,ou,{_transform:ou.prototype.transform,transform(e,t){return this._transform(AZ(e,t),t)}});function AZ(e,t){const n=e.field,r=e.value,i=(e.op==="count"?"__count__":e.op)||"sum",s=Kr(n).concat(Kr(r)),o=SZ(n,e.limit||0,t);return t.changed()&&e.set("__pivot__",null,null,!0),{key:e.key,groupby:e.groupby,ops:o.map(()=>i),fields:o.map(a=>kZ(a,n,r,s)),as:o.map(a=>a+""),modified:e.modified.bind(e)}}function kZ(e,t,n,r){return Yi(i=>t(i)===e?n(i):NaN,r,e+"")}function SZ(e,t,n){const r={},i=[];return n.visit(n.SOURCE,s=>{const o=e(s);r[o]||(r[o]=1,i.push(o))}),i.sort(yh),t?i.slice(0,t):i}function HO(e){Yy.call(this,e)}Me(HO,Yy,{transform(e,t){const n=e.subflow,r=e.field,i=s=>this.subflow(ot(s),n,t,s);return(e.modified("field")||r&&t.modified(Kr(r)))&&le("PreFacet does not support field modification."),this.initTargets(),r?(t.visit(t.MOD,s=>{const o=i(s);r(s).forEach(a=>o.mod(a))}),t.visit(t.ADD,s=>{const o=i(s);r(s).forEach(a=>o.add(Zt(a)))}),t.visit(t.REM,s=>{const o=i(s);r(s).forEach(a=>o.rem(a))})):(t.visit(t.MOD,s=>i(s).mod(s)),t.visit(t.ADD,s=>i(s).add(s)),t.visit(t.REM,s=>i(s).rem(s))),t.clean()&&t.runAfter(()=>this.clean()),t}});function xS(e){ie.call(this,null,e)}xS.Definition={type:"Project",metadata:{generates:!0,changes:!0},params:[{name:"fields",type:"field",array:!0},{name:"as",type:"string",null:!0,array:!0}]};Me(xS,ie,{transform(e,t){const n=t.fork(t.NO_SOURCE),r=e.fields,i=OO(e.fields,e.as||[]),s=r?(a,l)=>CZ(a,l,r,i):By;let o;return this.value?o=this.value:(t=t.addAll(),o=this.value={}),t.visit(t.REM,a=>{const l=ot(a);n.rem.push(o[l]),o[l]=null}),t.visit(t.ADD,a=>{const l=s(a,Zt({}));o[ot(a)]=l,n.add.push(l)}),t.visit(t.MOD,a=>{n.mod.push(s(a,o[ot(a)]))}),n}});function CZ(e,t,n,r){for(let i=0,s=n.length;i{const d=Pk(f,u);for(let h=0;h{const s=ot(i);n.rem.push(r[s]),r[s]=null}),t.visit(t.ADD,i=>{const s=Ok(i);r[ot(i)]=s,n.add.push(s)}),t.visit(t.MOD,i=>{const s=r[ot(i)];for(const o in i)s[o]=i[o],n.modifies(o);n.mod.push(s)})),n}});function wS(e){ie.call(this,[],e),this.count=0}wS.Definition={type:"Sample",metadata:{},params:[{name:"size",type:"number",default:1e3}]};Me(wS,ie,{transform(e,t){const n=t.fork(t.NO_SOURCE),r=e.modified("size"),i=e.size,s=this.value.reduce((c,f)=>(c[ot(f)]=1,c),{});let o=this.value,a=this.count,l=0;function u(c){let f,d;o.length=l&&(f=o[d],s[ot(f)]&&n.rem.push(f),o[d]=c)),++a}if(t.rem.length&&(t.visit(t.REM,c=>{const f=ot(c);s[f]&&(s[f]=-1,n.rem.push(c)),--a}),o=o.filter(c=>s[ot(c)]!==-1)),(t.rem.length||r)&&o.length{s[ot(c)]||u(c)}),l=-1),r&&o.length>i){const c=o.length-i;for(let f=0;f{s[ot(c)]&&n.mod.push(c)}),t.add.length&&t.visit(t.ADD,u),(t.add.length||l<0)&&(n.add=o.filter(c=>!s[ot(c)])),this.count=a,this.value=n.source=o,n}});function ES(e){ie.call(this,null,e)}ES.Definition={type:"Sequence",metadata:{generates:!0,changes:!0},params:[{name:"start",type:"number",required:!0},{name:"stop",type:"number",required:!0},{name:"step",type:"number",default:1},{name:"as",type:"string",default:"data"}]};Me(ES,ie,{transform(e,t){if(this.value&&!e.modified())return;const n=t.materialize().fork(t.MOD),r=e.as||"data";return n.rem=this.value?t.rem.concat(this.value):t.rem,this.value=ss(e.start,e.stop,e.step||1).map(i=>{const s={};return s[r]=i,Zt(s)}),n.add=t.add.concat(this.value),n}});function VO(e){ie.call(this,null,e),this.modified(!0)}Me(VO,ie,{transform(e,t){return this.value=t.source,t.changed()?t.fork(t.NO_SOURCE|t.NO_FIELDS):t.StopPropagation}});function AS(e){ie.call(this,null,e)}const XO=["unit0","unit1"];AS.Definition={type:"TimeUnit",metadata:{modifies:!0},params:[{name:"field",type:"field",required:!0},{name:"interval",type:"boolean",default:!0},{name:"units",type:"enum",values:Sk,array:!0},{name:"step",type:"number",default:1},{name:"maxbins",type:"number",default:40},{name:"extent",type:"date",array:!0},{name:"timezone",type:"enum",default:"local",values:["local","utc"]},{name:"as",type:"string",array:!0,length:2,default:XO}]};Me(AS,ie,{transform(e,t){const n=e.field,r=e.interval!==!1,i=e.timezone==="utc",s=this._floor(e,t),o=(i?Ah:Eh)(s.unit).offset,a=e.as||XO,l=a[0],u=a[1],c=s.step;let f=s.start||1/0,d=s.stop||-1/0,h=t.ADD;return(e.modified()||t.changed(t.REM)||t.modified(Kr(n)))&&(t=t.reflow(!0),h=t.SOURCE,f=1/0,d=-1/0),t.visit(h,p=>{const g=n(p);let m,y;g==null?(p[l]=null,r&&(p[u]=null)):(p[l]=m=y=s(g),r&&(p[u]=y=o(m,c)),md&&(d=y))}),s.start=f,s.stop=d,t.modifies(r?a:l)},_floor(e,t){const n=e.timezone==="utc",{units:r,step:i}=e.units?{units:e.units,step:e.step||1}:BN({extent:e.extent||aa(t.materialize(t.SOURCE).source,e.field),maxbins:e.maxbins}),s=Ck(r),o=this.value||{},a=(n?DN:FN)(s,i);return a.unit=Wt(s),a.units=s,a.step=i,a.start=o.start,a.stop=o.stop,this.value=a}});function KO(e){ie.call(this,bh(),e)}Me(KO,ie,{transform(e,t){const n=t.dataflow,r=e.field,i=this.value,s=a=>i.set(r(a),a);let o=!0;return e.modified("field")||t.modified(r.fields)?(i.clear(),t.visit(t.SOURCE,s)):t.changed()?(t.visit(t.REM,a=>i.delete(r(a))),t.visit(t.ADD,s)):o=!1,this.modified(o),i.empty>n.cleanThreshold&&n.runAfter(i.clean),t.fork()}});function ZO(e){ie.call(this,null,e)}Me(ZO,ie,{transform(e,t){(!this.value||e.modified("field")||e.modified("sort")||t.changed()||e.sort&&t.modified(e.sort.fields))&&(this.value=(e.sort?t.source.slice().sort(pf(e.sort)):t.source).map(e.field))}});function FZ(e,t,n,r){const i=mg[e](t,n);return{init:i.init||Ol,update:function(s,o){o[r]=i.next(s)}}}const mg={row_number:function(){return{next:e=>e.index+1}},rank:function(){let e;return{init:()=>e=1,next:t=>{const n=t.index,r=t.data;return n&&t.compare(r[n-1],r[n])?e=n+1:e}}},dense_rank:function(){let e;return{init:()=>e=1,next:t=>{const n=t.index,r=t.data;return n&&t.compare(r[n-1],r[n])?++e:e}}},percent_rank:function(){const e=mg.rank(),t=e.next;return{init:e.init,next:n=>(t(n)-1)/(n.data.length-1)}},cume_dist:function(){let e;return{init:()=>e=0,next:t=>{const n=t.data,r=t.compare;let i=t.index;if(e0||le("ntile num must be greater than zero.");const n=mg.cume_dist(),r=n.next;return{init:n.init,next:i=>Math.ceil(t*r(i))}},lag:function(e,t){return t=+t||1,{next:n=>{const r=n.index-t;return r>=0?e(n.data[r]):null}}},lead:function(e,t){return t=+t||1,{next:n=>{const r=n.index+t,i=n.data;return re(t.data[t.i0])}},last_value:function(e){return{next:t=>e(t.data[t.i1-1])}},nth_value:function(e,t){return t=+t,t>0||le("nth_value nth must be greater than zero."),{next:n=>{const r=n.i0+(t-1);return rt=null,next:n=>{const r=e(n.data[n.index]);return r!=null?t=r:t}}},next_value:function(e){let t,n;return{init:()=>(t=null,n=-1),next:r=>{const i=r.data;return r.index<=n?t:(n=DZ(e,i,r.index))<0?(n=i.length,t=null):t=e(i[n])}}}};function DZ(e,t,n){for(let r=t.length;nl[g]=1)}h(e.sort),t.forEach((p,g)=>{const m=n[g],y=r[g],b=i[g]||null,x=Ln(m),_=CO(p,x,s[g]);if(h(m),o.push(_),Ue(mg,p))a.push(FZ(p,m,y,_));else{if(m==null&&p!=="count"&&le("Null aggregate field specified."),p==="count"){c.push(_);return}d=!1;let w=u[x];w||(w=u[x]=[],w.field=m,f.push(w)),w.push($O(p,b,_))}}),(c.length||f.length)&&(this.cell=TZ(f,c,d)),this.inputs=Object.keys(l)}const QO=JO.prototype;QO.init=function(){this.windows.forEach(e=>e.init()),this.cell&&this.cell.init()};QO.update=function(e,t){const n=this.cell,r=this.windows,i=e.data,s=r&&r.length;let o;if(n){for(o=e.p0;oDO(l,l.field));const r={num:0,agg:null,store:!1,count:t};if(!n)for(var i=e.length,s=r.agg=Array(i),o=0;othis.group(i(a));let o=this.state;(!o||n)&&(o=this.state=new JO(e)),n||t.modified(o.inputs)?(this.value={},t.visit(t.SOURCE,a=>s(a).add(a))):(t.visit(t.REM,a=>s(a).remove(a)),t.visit(t.ADD,a=>s(a).add(a)));for(let a=0,l=this._mlen;a0&&!i(s[n],s[n-1])&&(e.i0=t.left(s,s[n])),r1?0:e<-1?Ld:Math.acos(e)}function nD(e){return e>=1?V1:e<=-1?-V1:Math.asin(e)}const Nw=Math.PI,Ow=2*Nw,tc=1e-6,BZ=Ow-tc;function t7(e){this._+=e[0];for(let t=1,n=e.length;t=0))throw new Error(`invalid digits: ${e}`);if(t>15)return t7;const n=10**t;return function(r){this._+=r[0];for(let i=1,s=r.length;itc)if(!(Math.abs(f*l-u*c)>tc)||!s)this._append`L${this._x1=t},${this._y1=n}`;else{let h=r-o,p=i-a,g=l*l+u*u,m=h*h+p*p,y=Math.sqrt(g),b=Math.sqrt(d),x=s*Math.tan((Nw-Math.acos((g+d-m)/(2*y*b)))/2),_=x/b,w=x/y;Math.abs(_-1)>tc&&this._append`L${t+_*c},${n+_*f}`,this._append`A${s},${s},0,0,${+(f*h>c*p)},${this._x1=t+w*l},${this._y1=n+w*u}`}}arc(t,n,r,i,s,o){if(t=+t,n=+n,r=+r,o=!!o,r<0)throw new Error(`negative radius: ${r}`);let a=r*Math.cos(i),l=r*Math.sin(i),u=t+a,c=n+l,f=1^o,d=o?i-s:s-i;this._x1===null?this._append`M${u},${c}`:(Math.abs(this._x1-u)>tc||Math.abs(this._y1-c)>tc)&&this._append`L${u},${c}`,r&&(d<0&&(d=d%Ow+Ow),d>BZ?this._append`A${r},${r},0,1,${f},${t-a},${n-l}A${r},${r},0,1,${f},${this._x1=u},${this._y1=c}`:d>tc&&this._append`A${r},${r},0,${+(d>=Nw)},${f},${this._x1=t+r*Math.cos(s)},${this._y1=n+r*Math.sin(s)}`)}rect(t,n,r,i){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+n}h${r=+r}v${+i}h${-r}Z`}toString(){return this._}};function Vy(){return new SS}Vy.prototype=SS.prototype;function Xy(e){let t=3;return e.digits=function(n){if(!arguments.length)return t;if(n==null)t=null;else{const r=Math.floor(n);if(!(r>=0))throw new RangeError(`invalid digits: ${n}`);t=r}return e},()=>new SS(t)}function jZ(e){return e.innerRadius}function UZ(e){return e.outerRadius}function qZ(e){return e.startAngle}function WZ(e){return e.endAngle}function HZ(e){return e&&e.padAngle}function GZ(e,t,n,r,i,s,o,a){var l=n-e,u=r-t,c=o-i,f=a-s,d=f*l-c*u;if(!(d*dT*T+F*F&&(k=$,S=M),{cx:k,cy:S,x01:-c,y01:-f,x11:k*(i/w-1),y11:S*(i/w-1)}}function YZ(){var e=jZ,t=UZ,n=Qt(0),r=null,i=qZ,s=WZ,o=HZ,a=null,l=Xy(u);function u(){var c,f,d=+e.apply(this,arguments),h=+t.apply(this,arguments),p=i.apply(this,arguments)-V1,g=s.apply(this,arguments)-V1,m=tD(g-p),y=g>p;if(a||(a=c=l()),hqr))a.moveTo(0,0);else if(m>e7-qr)a.moveTo(h*Wu(p),h*No(p)),a.arc(0,0,h,p,g,!y),d>qr&&(a.moveTo(d*Wu(g),d*No(g)),a.arc(0,0,d,g,p,y));else{var b=p,x=g,_=p,w=g,A=m,E=m,k=o.apply(this,arguments)/2,S=k>qr&&(r?+r.apply(this,arguments):hc(d*d+h*h)),$=gx(tD(h-d)/2,+n.apply(this,arguments)),M=$,O=$,P,T;if(S>qr){var F=nD(S/d*No(k)),N=nD(S/h*No(k));(A-=F*2)>qr?(F*=y?1:-1,_+=F,w-=F):(A=0,_=w=(p+g)/2),(E-=N*2)>qr?(N*=y?1:-1,b+=N,x-=N):(E=0,b=x=(p+g)/2)}var U=h*Wu(b),j=h*No(b),W=d*Wu(w),Z=d*No(w);if($>qr){var Y=h*Wu(x),J=h*No(x),ve=d*Wu(_),Te=d*No(_),Fe;if(mqr?O>qr?(P=um(ve,Te,U,j,h,O,y),T=um(Y,J,W,Z,h,O,y),a.moveTo(P.cx+P.x01,P.cy+P.y01),O<$?a.arc(P.cx,P.cy,O,jr(P.y01,P.x01),jr(T.y01,T.x01),!y):(a.arc(P.cx,P.cy,O,jr(P.y01,P.x01),jr(P.y11,P.x11),!y),a.arc(0,0,h,jr(P.cy+P.y11,P.cx+P.x11),jr(T.cy+T.y11,T.cx+T.x11),!y),a.arc(T.cx,T.cy,O,jr(T.y11,T.x11),jr(T.y01,T.x01),!y))):(a.moveTo(U,j),a.arc(0,0,h,b,x,!y)):a.moveTo(U,j),!(d>qr)||!(A>qr)?a.lineTo(W,Z):M>qr?(P=um(W,Z,Y,J,d,-M,y),T=um(U,j,ve,Te,d,-M,y),a.lineTo(P.cx+P.x01,P.cy+P.y01),M<$?a.arc(P.cx,P.cy,M,jr(P.y01,P.x01),jr(T.y01,T.x01),!y):(a.arc(P.cx,P.cy,M,jr(P.y01,P.x01),jr(P.y11,P.x11),!y),a.arc(0,0,d,jr(P.cy+P.y11,P.cx+P.x11),jr(T.cy+T.y11,T.cx+T.x11),y),a.arc(T.cx,T.cy,M,jr(T.y11,T.x11),jr(T.y01,T.x01),!y))):a.arc(0,0,d,w,_,y)}if(a.closePath(),c)return a=null,c+""||null}return u.centroid=function(){var c=(+e.apply(this,arguments)+ +t.apply(this,arguments))/2,f=(+i.apply(this,arguments)+ +s.apply(this,arguments))/2-Ld/2;return[Wu(f)*c,No(f)*c]},u.innerRadius=function(c){return arguments.length?(e=typeof c=="function"?c:Qt(+c),u):e},u.outerRadius=function(c){return arguments.length?(t=typeof c=="function"?c:Qt(+c),u):t},u.cornerRadius=function(c){return arguments.length?(n=typeof c=="function"?c:Qt(+c),u):n},u.padRadius=function(c){return arguments.length?(r=c==null?null:typeof c=="function"?c:Qt(+c),u):r},u.startAngle=function(c){return arguments.length?(i=typeof c=="function"?c:Qt(+c),u):i},u.endAngle=function(c){return arguments.length?(s=typeof c=="function"?c:Qt(+c),u):s},u.padAngle=function(c){return arguments.length?(o=typeof c=="function"?c:Qt(+c),u):o},u.context=function(c){return arguments.length?(a=c??null,u):a},u}function n7(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function r7(e){this._context=e}r7.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:this._context.lineTo(e,t);break}}};function CS(e){return new r7(e)}function i7(e){return e[0]}function s7(e){return e[1]}function o7(e,t){var n=Qt(!0),r=null,i=CS,s=null,o=Xy(a);e=typeof e=="function"?e:e===void 0?i7:Qt(e),t=typeof t=="function"?t:t===void 0?s7:Qt(t);function a(l){var u,c=(l=n7(l)).length,f,d=!1,h;for(r==null&&(s=i(h=o())),u=0;u<=c;++u)!(u=h;--p)a.point(x[p],_[p]);a.lineEnd(),a.areaEnd()}y&&(x[d]=+e(m,d,f),_[d]=+t(m,d,f),a.point(r?+r(m,d,f):x[d],n?+n(m,d,f):_[d]))}if(b)return a=null,b+""||null}function c(){return o7().defined(i).curve(o).context(s)}return u.x=function(f){return arguments.length?(e=typeof f=="function"?f:Qt(+f),r=null,u):e},u.x0=function(f){return arguments.length?(e=typeof f=="function"?f:Qt(+f),u):e},u.x1=function(f){return arguments.length?(r=f==null?null:typeof f=="function"?f:Qt(+f),u):r},u.y=function(f){return arguments.length?(t=typeof f=="function"?f:Qt(+f),n=null,u):t},u.y0=function(f){return arguments.length?(t=typeof f=="function"?f:Qt(+f),u):t},u.y1=function(f){return arguments.length?(n=f==null?null:typeof f=="function"?f:Qt(+f),u):n},u.lineX0=u.lineY0=function(){return c().x(e).y(t)},u.lineY1=function(){return c().x(e).y(n)},u.lineX1=function(){return c().x(r).y(t)},u.defined=function(f){return arguments.length?(i=typeof f=="function"?f:Qt(!!f),u):i},u.curve=function(f){return arguments.length?(o=f,s!=null&&(a=o(s)),u):o},u.context=function(f){return arguments.length?(f==null?s=a=null:a=o(s=f),u):s},u}const VZ={draw(e,t){const n=hc(t/Ld);e.moveTo(n,0),e.arc(0,0,n,0,e7)}};function XZ(e,t){let n=null,r=Xy(i);e=typeof e=="function"?e:Qt(e||VZ),t=typeof t=="function"?t:Qt(t===void 0?64:+t);function i(){let s;if(n||(n=s=r()),e.apply(this,arguments).draw(n,+t.apply(this,arguments)),s)return n=null,s+""||null}return i.type=function(s){return arguments.length?(e=typeof s=="function"?s:Qt(s),i):e},i.size=function(s){return arguments.length?(t=typeof s=="function"?s:Qt(+s),i):t},i.context=function(s){return arguments.length?(n=s??null,i):n},i}function au(){}function X1(e,t,n){e._context.bezierCurveTo((2*e._x0+e._x1)/3,(2*e._y0+e._y1)/3,(e._x0+2*e._x1)/3,(e._y0+2*e._y1)/3,(e._x0+4*e._x1+t)/6,(e._y0+4*e._y1+n)/6)}function Ky(e){this._context=e}Ky.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:X1(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:X1(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function KZ(e){return new Ky(e)}function l7(e){this._context=e}l7.prototype={areaStart:au,areaEnd:au,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x2=e,this._y2=t;break;case 1:this._point=2,this._x3=e,this._y3=t;break;case 2:this._point=3,this._x4=e,this._y4=t,this._context.moveTo((this._x0+4*this._x1+e)/6,(this._y0+4*this._y1+t)/6);break;default:X1(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function ZZ(e){return new l7(e)}function u7(e){this._context=e}u7.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+e)/6,r=(this._y0+4*this._y1+t)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:X1(this,e,t);break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t}};function JZ(e){return new u7(e)}function c7(e,t){this._basis=new Ky(e),this._beta=t}c7.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var e=this._x,t=this._y,n=e.length-1;if(n>0)for(var r=e[0],i=t[0],s=e[n]-r,o=t[n]-i,a=-1,l;++a<=n;)l=a/n,this._basis.point(this._beta*e[a]+(1-this._beta)*(r+l*s),this._beta*t[a]+(1-this._beta)*(i+l*o));this._x=this._y=null,this._basis.lineEnd()},point:function(e,t){this._x.push(+e),this._y.push(+t)}};const QZ=(function e(t){function n(r){return t===1?new Ky(r):new c7(r,t)}return n.beta=function(r){return e(+r)},n})(.85);function K1(e,t,n){e._context.bezierCurveTo(e._x1+e._k*(e._x2-e._x0),e._y1+e._k*(e._y2-e._y0),e._x2+e._k*(e._x1-t),e._y2+e._k*(e._y1-n),e._x2,e._y2)}function $S(e,t){this._context=e,this._k=(1-t)/6}$S.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:K1(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2,this._x1=e,this._y1=t;break;case 2:this._point=3;default:K1(this,e,t);break}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};const eJ=(function e(t){function n(r){return new $S(r,t)}return n.tension=function(r){return e(+r)},n})(0);function FS(e,t){this._context=e,this._k=(1-t)/6}FS.prototype={areaStart:au,areaEnd:au,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:K1(this,e,t);break}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};const tJ=(function e(t){function n(r){return new FS(r,t)}return n.tension=function(r){return e(+r)},n})(0);function DS(e,t){this._context=e,this._k=(1-t)/6}DS.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:K1(this,e,t);break}this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};const nJ=(function e(t){function n(r){return new DS(r,t)}return n.tension=function(r){return e(+r)},n})(0);function MS(e,t,n){var r=e._x1,i=e._y1,s=e._x2,o=e._y2;if(e._l01_a>qr){var a=2*e._l01_2a+3*e._l01_a*e._l12_a+e._l12_2a,l=3*e._l01_a*(e._l01_a+e._l12_a);r=(r*a-e._x0*e._l12_2a+e._x2*e._l01_2a)/l,i=(i*a-e._y0*e._l12_2a+e._y2*e._l01_2a)/l}if(e._l23_a>qr){var u=2*e._l23_2a+3*e._l23_a*e._l12_a+e._l12_2a,c=3*e._l23_a*(e._l23_a+e._l12_a);s=(s*u+e._x1*e._l23_2a-t*e._l12_2a)/c,o=(o*u+e._y1*e._l23_2a-n*e._l12_2a)/c}e._context.bezierCurveTo(r,i,s,o,e._x2,e._y2)}function f7(e,t){this._context=e,this._alpha=t}f7.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3;default:MS(this,e,t);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};const rJ=(function e(t){function n(r){return t?new f7(r,t):new $S(r,0)}return n.alpha=function(r){return e(+r)},n})(.5);function d7(e,t){this._context=e,this._alpha=t}d7.prototype={areaStart:au,areaEnd:au,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=e,this._y3=t;break;case 1:this._point=2,this._context.moveTo(this._x4=e,this._y4=t);break;case 2:this._point=3,this._x5=e,this._y5=t;break;default:MS(this,e,t);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};const iJ=(function e(t){function n(r){return t?new d7(r,t):new FS(r,0)}return n.alpha=function(r){return e(+r)},n})(.5);function h7(e,t){this._context=e,this._alpha=t}h7.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){if(e=+e,t=+t,this._point){var n=this._x2-e,r=this._y2-t;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:MS(this,e,t);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=e,this._y0=this._y1,this._y1=this._y2,this._y2=t}};const sJ=(function e(t){function n(r){return t?new h7(r,t):new DS(r,0)}return n.alpha=function(r){return e(+r)},n})(.5);function p7(e){this._context=e}p7.prototype={areaStart:au,areaEnd:au,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(e,t){e=+e,t=+t,this._point?this._context.lineTo(e,t):(this._point=1,this._context.moveTo(e,t))}};function oJ(e){return new p7(e)}function rD(e){return e<0?-1:1}function iD(e,t,n){var r=e._x1-e._x0,i=t-e._x1,s=(e._y1-e._y0)/(r||i<0&&-0),o=(n-e._y1)/(i||r<0&&-0),a=(s*i+o*r)/(r+i);return(rD(s)+rD(o))*Math.min(Math.abs(s),Math.abs(o),.5*Math.abs(a))||0}function sD(e,t){var n=e._x1-e._x0;return n?(3*(e._y1-e._y0)/n-t)/2:t}function mx(e,t,n){var r=e._x0,i=e._y0,s=e._x1,o=e._y1,a=(s-r)/3;e._context.bezierCurveTo(r+a,i+a*t,s-a,o-a*n,s,o)}function Z1(e){this._context=e}Z1.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:mx(this,this._t0,sD(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},point:function(e,t){var n=NaN;if(e=+e,t=+t,!(e===this._x1&&t===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;break;case 2:this._point=3,mx(this,sD(this,n=iD(this,e,t)),n);break;default:mx(this,this._t0,n=iD(this,e,t));break}this._x0=this._x1,this._x1=e,this._y0=this._y1,this._y1=t,this._t0=n}}};function g7(e){this._context=new m7(e)}(g7.prototype=Object.create(Z1.prototype)).point=function(e,t){Z1.prototype.point.call(this,t,e)};function m7(e){this._context=e}m7.prototype={moveTo:function(e,t){this._context.moveTo(t,e)},closePath:function(){this._context.closePath()},lineTo:function(e,t){this._context.lineTo(t,e)},bezierCurveTo:function(e,t,n,r,i,s){this._context.bezierCurveTo(t,e,r,n,s,i)}};function aJ(e){return new Z1(e)}function lJ(e){return new g7(e)}function v7(e){this._context=e}v7.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var e=this._x,t=this._y,n=e.length;if(n)if(this._line?this._context.lineTo(e[0],t[0]):this._context.moveTo(e[0],t[0]),n===2)this._context.lineTo(e[1],t[1]);else for(var r=oD(e),i=oD(t),s=0,o=1;o=0;--t)i[t]=(o[t]-i[t+1])/s[t];for(s[n-1]=(e[n]+i[n-1])/2,t=0;t=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(e,t){switch(e=+e,t=+t,this._point){case 0:this._point=1,this._line?this._context.lineTo(e,t):this._context.moveTo(e,t);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,t),this._context.lineTo(e,t);else{var n=this._x*(1-this._t)+e*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,t)}break}}this._x=e,this._y=t}};function cJ(e){return new Zy(e,.5)}function fJ(e){return new Zy(e,0)}function dJ(e){return new Zy(e,1)}function eu(e,t){if(typeof document<"u"&&document.createElement){const n=document.createElement("canvas");if(n&&n.getContext)return n.width=e,n.height=t,n}return null}const hJ=()=>typeof Image<"u"?Image:null;function ya(e,t){switch(arguments.length){case 0:break;case 1:this.range(e);break;default:this.range(t).domain(e);break}return this}function Au(e,t){switch(arguments.length){case 0:break;case 1:{typeof e=="function"?this.interpolator(e):this.range(e);break}default:{this.domain(e),typeof t=="function"?this.interpolator(t):this.range(t);break}}return this}const Lw=Symbol("implicit");function TS(){var e=new E5,t=[],n=[],r=Lw;function i(s){let o=e.get(s);if(o===void 0){if(r!==Lw)return r;e.set(s,o=t.push(s)-1)}return n[o%n.length]}return i.domain=function(s){if(!arguments.length)return t.slice();t=[],e=new E5;for(const o of s)e.has(o)||e.set(o,t.push(o)-1);return i},i.range=function(s){return arguments.length?(n=Array.from(s),i):n.slice()},i.unknown=function(s){return arguments.length?(r=s,i):r},i.copy=function(){return TS(t,n).unknown(r)},ya.apply(i,arguments),i}function Sh(e,t,n){e.prototype=t.prototype=n,n.constructor=e}function l0(e,t){var n=Object.create(e.prototype);for(var r in t)n[r]=t[r];return n}function ku(){}var jc=.7,Id=1/jc,od="\\s*([+-]?\\d+)\\s*",vg="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",ea="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",pJ=/^#([0-9a-f]{3,8})$/,gJ=new RegExp(`^rgb\\(${od},${od},${od}\\)$`),mJ=new RegExp(`^rgb\\(${ea},${ea},${ea}\\)$`),vJ=new RegExp(`^rgba\\(${od},${od},${od},${vg}\\)$`),yJ=new RegExp(`^rgba\\(${ea},${ea},${ea},${vg}\\)$`),bJ=new RegExp(`^hsl\\(${vg},${ea},${ea}\\)$`),xJ=new RegExp(`^hsla\\(${vg},${ea},${ea},${vg}\\)$`),aD={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Sh(ku,yg,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:lD,formatHex:lD,formatHex8:_J,formatHsl:wJ,formatRgb:uD,toString:uD});function lD(){return this.rgb().formatHex()}function _J(){return this.rgb().formatHex8()}function wJ(){return y7(this).formatHsl()}function uD(){return this.rgb().formatRgb()}function yg(e){var t,n;return e=(e+"").trim().toLowerCase(),(t=pJ.exec(e))?(n=t[1].length,t=parseInt(t[1],16),n===6?cD(t):n===3?new cr(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?cm(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?cm(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=gJ.exec(e))?new cr(t[1],t[2],t[3],1):(t=mJ.exec(e))?new cr(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=vJ.exec(e))?cm(t[1],t[2],t[3],t[4]):(t=yJ.exec(e))?cm(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=bJ.exec(e))?hD(t[1],t[2]/100,t[3]/100,1):(t=xJ.exec(e))?hD(t[1],t[2]/100,t[3]/100,t[4]):aD.hasOwnProperty(e)?cD(aD[e]):e==="transparent"?new cr(NaN,NaN,NaN,0):null}function cD(e){return new cr(e>>16&255,e>>8&255,e&255,1)}function cm(e,t,n,r){return r<=0&&(e=t=n=NaN),new cr(e,t,n,r)}function RS(e){return e instanceof ku||(e=yg(e)),e?(e=e.rgb(),new cr(e.r,e.g,e.b,e.opacity)):new cr}function lu(e,t,n,r){return arguments.length===1?RS(e):new cr(e,t,n,r??1)}function cr(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}Sh(cr,lu,l0(ku,{brighter(e){return e=e==null?Id:Math.pow(Id,e),new cr(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?jc:Math.pow(jc,e),new cr(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new cr(Ec(this.r),Ec(this.g),Ec(this.b),J1(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:fD,formatHex:fD,formatHex8:EJ,formatRgb:dD,toString:dD}));function fD(){return`#${pc(this.r)}${pc(this.g)}${pc(this.b)}`}function EJ(){return`#${pc(this.r)}${pc(this.g)}${pc(this.b)}${pc((isNaN(this.opacity)?1:this.opacity)*255)}`}function dD(){const e=J1(this.opacity);return`${e===1?"rgb(":"rgba("}${Ec(this.r)}, ${Ec(this.g)}, ${Ec(this.b)}${e===1?")":`, ${e})`}`}function J1(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function Ec(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function pc(e){return e=Ec(e),(e<16?"0":"")+e.toString(16)}function hD(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new io(e,t,n,r)}function y7(e){if(e instanceof io)return new io(e.h,e.s,e.l,e.opacity);if(e instanceof ku||(e=yg(e)),!e)return new io;if(e instanceof io)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),s=Math.max(t,n,r),o=NaN,a=s-i,l=(s+i)/2;return a?(t===s?o=(n-r)/a+(n0&&l<1?0:o,new io(o,a,l,e.opacity)}function Q1(e,t,n,r){return arguments.length===1?y7(e):new io(e,t,n,r??1)}function io(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}Sh(io,Q1,l0(ku,{brighter(e){return e=e==null?Id:Math.pow(Id,e),new io(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?jc:Math.pow(jc,e),new io(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new cr(vx(e>=240?e-240:e+120,i,r),vx(e,i,r),vx(e<120?e+240:e-120,i,r),this.opacity)},clamp(){return new io(pD(this.h),fm(this.s),fm(this.l),J1(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const e=J1(this.opacity);return`${e===1?"hsl(":"hsla("}${pD(this.h)}, ${fm(this.s)*100}%, ${fm(this.l)*100}%${e===1?")":`, ${e})`}`}}));function pD(e){return e=(e||0)%360,e<0?e+360:e}function fm(e){return Math.max(0,Math.min(1,e||0))}function vx(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}const b7=Math.PI/180,x7=180/Math.PI,ev=18,_7=.96422,w7=1,E7=.82521,A7=4/29,ad=6/29,k7=3*ad*ad,AJ=ad*ad*ad;function S7(e){if(e instanceof ta)return new ta(e.l,e.a,e.b,e.opacity);if(e instanceof Va)return C7(e);e instanceof cr||(e=RS(e));var t=_x(e.r),n=_x(e.g),r=_x(e.b),i=yx((.2225045*t+.7168786*n+.0606169*r)/w7),s,o;return t===n&&n===r?s=o=i:(s=yx((.4360747*t+.3850649*n+.1430804*r)/_7),o=yx((.0139322*t+.0971045*n+.7141733*r)/E7)),new ta(116*i-16,500*(s-i),200*(i-o),e.opacity)}function tv(e,t,n,r){return arguments.length===1?S7(e):new ta(e,t,n,r??1)}function ta(e,t,n,r){this.l=+e,this.a=+t,this.b=+n,this.opacity=+r}Sh(ta,tv,l0(ku,{brighter(e){return new ta(this.l+ev*(e??1),this.a,this.b,this.opacity)},darker(e){return new ta(this.l-ev*(e??1),this.a,this.b,this.opacity)},rgb(){var e=(this.l+16)/116,t=isNaN(this.a)?e:e+this.a/500,n=isNaN(this.b)?e:e-this.b/200;return t=_7*bx(t),e=w7*bx(e),n=E7*bx(n),new cr(xx(3.1338561*t-1.6168667*e-.4906146*n),xx(-.9787684*t+1.9161415*e+.033454*n),xx(.0719453*t-.2289914*e+1.4052427*n),this.opacity)}}));function yx(e){return e>AJ?Math.pow(e,1/3):e/k7+A7}function bx(e){return e>ad?e*e*e:k7*(e-A7)}function xx(e){return 255*(e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055)}function _x(e){return(e/=255)<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function kJ(e){if(e instanceof Va)return new Va(e.h,e.c,e.l,e.opacity);if(e instanceof ta||(e=S7(e)),e.a===0&&e.b===0)return new Va(NaN,0=1?(n=1,t-1):Math.floor(n*t),i=e[r],s=e[r+1],o=r>0?e[r-1]:2*i-s,a=r()=>e;function T7(e,t){return function(n){return e+n*t}}function CJ(e,t,n){return e=Math.pow(e,n),t=Math.pow(t,n)-e,n=1/n,function(r){return Math.pow(e+r*t,n)}}function eb(e,t){var n=t-e;return n?T7(e,n>180||n<-180?n-360*Math.round(n/360):n):Qy(isNaN(e)?t:e)}function $J(e){return(e=+e)==1?fr:function(t,n){return n-t?CJ(t,n,e):Qy(isNaN(t)?n:t)}}function fr(e,t){var n=t-e;return n?T7(e,n):Qy(isNaN(e)?t:e)}const Pw=(function e(t){var n=$J(t);function r(i,s){var o=n((i=lu(i)).r,(s=lu(s)).r),a=n(i.g,s.g),l=n(i.b,s.b),u=fr(i.opacity,s.opacity);return function(c){return i.r=o(c),i.g=a(c),i.b=l(c),i.opacity=u(c),i+""}}return r.gamma=e,r})(1);function R7(e){return function(t){var n=t.length,r=new Array(n),i=new Array(n),s=new Array(n),o,a;for(o=0;on&&(s=t.slice(n,s),a[o]?a[o]+=s:a[++o]=s),(r=r[0])===(i=i[0])?a[o]?a[o]+=i:a[++o]=i:(a[++o]=null,l.push({i:o,x:no(r,i)})),n=wx.lastIndex;return n180?c+=360:c-u>180&&(u+=360),d.push({i:f.push(i(f)+"rotate(",null,r)-2,x:no(u,c)})):c&&f.push(i(f)+"rotate("+c+r)}function a(u,c,f,d){u!==c?d.push({i:f.push(i(f)+"skewX(",null,r)-2,x:no(u,c)}):c&&f.push(i(f)+"skewX("+c+r)}function l(u,c,f,d,h,p){if(u!==f||c!==d){var g=h.push(i(h)+"scale(",null,",",null,")");p.push({i:g-4,x:no(u,f)},{i:g-2,x:no(c,d)})}else(f!==1||d!==1)&&h.push(i(h)+"scale("+f+","+d+")")}return function(u,c){var f=[],d=[];return u=e(u),c=e(c),s(u.translateX,u.translateY,c.translateX,c.translateY,f,d),o(u.rotate,c.rotate,f,d),a(u.skewX,c.skewX,f,d),l(u.scaleX,u.scaleY,c.scaleX,c.scaleY,f,d),u=c=null,function(h){for(var p=-1,g=d.length,m;++pt&&(n=e,e=t,t=n),function(r){return Math.max(e,Math.min(t,r))}}function tQ(e,t,n){var r=e[0],i=e[1],s=t[0],o=t[1];return i2?nQ:tQ,l=u=null,f}function f(d){return d==null||isNaN(d=+d)?s:(l||(l=a(e.map(r),t,n)))(r(o(d)))}return f.invert=function(d){return o(i((u||(u=a(t,e.map(r),no)))(d)))},f.domain=function(d){return arguments.length?(e=Array.from(d,jw),c()):e.slice()},f.range=function(d){return arguments.length?(t=Array.from(d),c()):t.slice()},f.rangeRound=function(d){return t=Array.from(d),n=u0,c()},f.clamp=function(d){return arguments.length?(o=d?!0:Ii,c()):o!==Ii},f.interpolate=function(d){return arguments.length?(n=d,c()):n},f.unknown=function(d){return arguments.length?(s=d,f):s},function(d,h){return r=d,i=h,c()}}function W7(){return tb()(Ii,Ii)}function H7(e,t,n,r){var i=su(e,t,n),s;switch(r=zc(r??",f"),r.type){case"s":{var o=Math.max(Math.abs(e),Math.abs(t));return r.precision==null&&!isNaN(s=vN(i,o))&&(r.precision=s),Ak(r,o)}case"":case"e":case"g":case"p":case"r":{r.precision==null&&!isNaN(s=yN(i,Math.max(Math.abs(e),Math.abs(t))))&&(r.precision=s-(r.type==="e"));break}case"f":case"%":{r.precision==null&&!isNaN(s=mN(i))&&(r.precision=s-(r.type==="%")*2);break}}return Dy(r)}function gf(e){var t=e.domain;return e.ticks=function(n){var r=t();return xw(r[0],r[r.length-1],n??10)},e.tickFormat=function(n,r){var i=t();return H7(i[0],i[i.length-1],n??10,r)},e.nice=function(n){n==null&&(n=10);var r=t(),i=0,s=r.length-1,o=r[i],a=r[s],l,u,c=10;for(a0;){if(u=_w(o,a,n),u===l)return r[i]=o,r[s]=a,t(r);if(u>0)o=Math.floor(o/u)*u,a=Math.ceil(a/u)*u;else if(u<0)o=Math.ceil(o*u)/u,a=Math.floor(a*u)/u;else break;l=u}return e},e}function G7(){var e=W7();return e.copy=function(){return c0(e,G7())},ya.apply(e,arguments),gf(e)}function Y7(e){var t;function n(r){return r==null||isNaN(r=+r)?t:r}return n.invert=n,n.domain=n.range=function(r){return arguments.length?(e=Array.from(r,jw),n):e.slice()},n.unknown=function(r){return arguments.length?(t=r,n):t},n.copy=function(){return Y7(e).unknown(t)},e=arguments.length?Array.from(e,jw):[0,1],gf(n)}function V7(e,t){e=e.slice();var n=0,r=e.length-1,i=e[n],s=e[r],o;return sMath.pow(e,t)}function aQ(e){return e===Math.E?Math.log:e===10&&Math.log10||e===2&&Math.log2||(e=Math.log(e),t=>Math.log(t)/e)}function ED(e){return(t,n)=>-e(-t,n)}function PS(e){const t=e(_D,wD),n=t.domain;let r=10,i,s;function o(){return i=aQ(r),s=oQ(r),n()[0]<0?(i=ED(i),s=ED(s),e(rQ,iQ)):e(_D,wD),t}return t.base=function(a){return arguments.length?(r=+a,o()):r},t.domain=function(a){return arguments.length?(n(a),o()):n()},t.ticks=a=>{const l=n();let u=l[0],c=l[l.length-1];const f=c0){for(;d<=h;++d)for(p=1;pc)break;y.push(g)}}else for(;d<=h;++d)for(p=r-1;p>=1;--p)if(g=d>0?p/s(-d):p*s(d),!(gc)break;y.push(g)}y.length*2{if(a==null&&(a=10),l==null&&(l=r===10?"s":","),typeof l!="function"&&(!(r%1)&&(l=zc(l)).precision==null&&(l.trim=!0),l=Dy(l)),a===1/0)return l;const u=Math.max(1,r*a/t.ticks().length);return c=>{let f=c/s(Math.round(i(c)));return f*rn(V7(n(),{floor:a=>s(Math.floor(i(a))),ceil:a=>s(Math.ceil(i(a)))})),t}function X7(){const e=PS(tb()).domain([1,10]);return e.copy=()=>c0(e,X7()).base(e.base()),ya.apply(e,arguments),e}function AD(e){return function(t){return Math.sign(t)*Math.log1p(Math.abs(t/e))}}function kD(e){return function(t){return Math.sign(t)*Math.expm1(Math.abs(t))*e}}function BS(e){var t=1,n=e(AD(t),kD(t));return n.constant=function(r){return arguments.length?e(AD(t=+r),kD(t)):t},gf(n)}function K7(){var e=BS(tb());return e.copy=function(){return c0(e,K7()).constant(e.constant())},ya.apply(e,arguments)}function SD(e){return function(t){return t<0?-Math.pow(-t,e):Math.pow(t,e)}}function lQ(e){return e<0?-Math.sqrt(-e):Math.sqrt(e)}function uQ(e){return e<0?-e*e:e*e}function zS(e){var t=e(Ii,Ii),n=1;function r(){return n===1?e(Ii,Ii):n===.5?e(lQ,uQ):e(SD(n),SD(1/n))}return t.exponent=function(i){return arguments.length?(n=+i,r()):n},gf(t)}function jS(){var e=zS(tb());return e.copy=function(){return c0(e,jS()).exponent(e.exponent())},ya.apply(e,arguments),e}function cQ(){return jS.apply(null,arguments).exponent(.5)}function Z7(){var e=[],t=[],n=[],r;function i(){var o=0,a=Math.max(1,t.length);for(n=new Array(a-1);++o0?n[a-1]:e[0],a=n?[r[n-1],t]:[r[u-1],r[u]]},o.unknown=function(l){return arguments.length&&(s=l),o},o.thresholds=function(){return r.slice()},o.copy=function(){return J7().domain([e,t]).range(i).unknown(s)},ya.apply(gf(o),arguments)}function Q7(){var e=[.5],t=[0,1],n,r=1;function i(s){return s!=null&&s<=s?t[iu(e,s,0,r)]:n}return i.domain=function(s){return arguments.length?(e=Array.from(s),r=Math.min(e.length,t.length-1),i):e.slice()},i.range=function(s){return arguments.length?(t=Array.from(s),r=Math.min(e.length,t.length-1),i):t.slice()},i.invertExtent=function(s){var o=t.indexOf(s);return[e[o-1],e[o]]},i.unknown=function(s){return arguments.length?(n=s,i):n},i.copy=function(){return Q7().domain(e).range(t).unknown(n)},ya.apply(i,arguments)}function fQ(e){return new Date(e)}function dQ(e){return e instanceof Date?+e:+new Date(+e)}function US(e,t,n,r,i,s,o,a,l,u){var c=W7(),f=c.invert,d=c.domain,h=u(".%L"),p=u(":%S"),g=u("%I:%M"),m=u("%I %p"),y=u("%a %d"),b=u("%b %d"),x=u("%B"),_=u("%Y");function w(A){return(l(A)0?r:1:0}const CQ="identity",Pd="linear",cl="log",f0="pow",d0="sqrt",ib="symlog",Uc="time",qc="utc",na="sequential",Ch="diverging",Bd="quantile",sb="quantize",ob="threshold",YS="ordinal",qw="point",s9="band",VS="bin-ordinal",sr="continuous",h0="discrete",p0="discretizing",qs="interpolating",XS="temporal";function $Q(e){return function(t){let n=t[0],r=t[1],i;return r=r&&n[l]<=i&&(s<0&&(s=l),o=l);if(!(s<0))return r=e.invertExtent(n[s]),i=e.invertExtent(n[o]),[r[0]===void 0?r[1]:r[0],i[1]===void 0?i[0]:i[1]]}}function KS(){const e=TS().unknown(void 0),t=e.domain,n=e.range;let r=[0,1],i,s,o=!1,a=0,l=0,u=.5;delete e.unknown;function c(){const f=t().length,d=r[1]g+i*y);return n(d?m.reverse():m)}return e.domain=function(f){return arguments.length?(t(f),c()):t()},e.range=function(f){return arguments.length?(r=[+f[0],+f[1]],c()):r.slice()},e.rangeRound=function(f){return r=[+f[0],+f[1]],o=!0,c()},e.bandwidth=function(){return s},e.step=function(){return i},e.round=function(f){return arguments.length?(o=!!f,c()):o},e.padding=function(f){return arguments.length?(l=Math.max(0,Math.min(1,f)),a=l,c()):a},e.paddingInner=function(f){return arguments.length?(a=Math.max(0,Math.min(1,f)),c()):a},e.paddingOuter=function(f){return arguments.length?(l=Math.max(0,Math.min(1,f)),c()):l},e.align=function(f){return arguments.length?(u=Math.max(0,Math.min(1,f)),c()):u},e.invertRange=function(f){if(f[0]==null||f[1]==null)return;const d=r[1]r[1-d])))return y=Math.max(0,iu(h,g)-1),b=g===m?y:iu(h,m)-1,g-h[y]>s+1e-10&&++y,d&&(x=y,y=p-b,b=p-x),y>b?void 0:t().slice(y,b+1)},e.invert=function(f){const d=e.invertRange([f,f]);return d&&d[0]},e.copy=function(){return KS().domain(t()).range(r).round(o).paddingInner(a).paddingOuter(l).align(u)},c()}function o9(e){const t=e.copy;return e.padding=e.paddingOuter,delete e.paddingInner,e.copy=function(){return o9(t())},e}function DQ(){return o9(KS().paddingInner(1))}var MQ=Array.prototype.map;function TQ(e){return MQ.call(e,Vr)}const RQ=Array.prototype.slice;function a9(){let e=[],t=[];function n(r){return r==null||r!==r?void 0:t[(iu(e,r)-1)%t.length]}return n.domain=function(r){return arguments.length?(e=TQ(r),n):e.slice()},n.range=function(r){return arguments.length?(t=RQ.call(r),n):t.slice()},n.tickFormat=function(r,i){return H7(e[0],Wt(e),r??10,i)},n.copy=function(){return a9().domain(n.domain()).range(n.range())},n}const rv=new Map,l9=Symbol("vega_scale");function u9(e){return e[l9]=!0,e}function CD(e){return e&&e[l9]===!0}function NQ(e,t,n){const r=function(){const s=t();return s.invertRange||(s.invertRange=s.invert?$Q(s):s.invertExtent?FQ(s):void 0),s.type=e,u9(s)};return r.metadata=mo(Be(n)),r}function Kt(e,t,n){return arguments.length>1?(rv.set(e,NQ(e,t,n)),this):c9(e)?rv.get(e):void 0}Kt(CQ,Y7);Kt(Pd,G7,sr);Kt(cl,X7,[sr,cl]);Kt(f0,jS,sr);Kt(d0,cQ,sr);Kt(ib,K7,sr);Kt(Uc,hQ,[sr,XS]);Kt(qc,pQ,[sr,XS]);Kt(na,qS,[sr,qs]);Kt(`${na}-${Pd}`,qS,[sr,qs]);Kt(`${na}-${cl}`,e9,[sr,qs,cl]);Kt(`${na}-${f0}`,WS,[sr,qs]);Kt(`${na}-${d0}`,gQ,[sr,qs]);Kt(`${na}-${ib}`,t9,[sr,qs]);Kt(`${Ch}-${Pd}`,n9,[sr,qs]);Kt(`${Ch}-${cl}`,r9,[sr,qs,cl]);Kt(`${Ch}-${f0}`,HS,[sr,qs]);Kt(`${Ch}-${d0}`,mQ,[sr,qs]);Kt(`${Ch}-${ib}`,i9,[sr,qs]);Kt(Bd,Z7,[p0,Bd]);Kt(sb,J7,p0);Kt(ob,Q7,p0);Kt(VS,a9,[h0,p0]);Kt(YS,TS,h0);Kt(s9,KS,h0);Kt(qw,DQ,h0);function c9(e){return rv.has(e)}function mf(e,t){const n=rv.get(e);return n&&n.metadata[t]}function ZS(e){return mf(e,sr)}function zd(e){return mf(e,h0)}function Ww(e){return mf(e,p0)}function f9(e){return mf(e,cl)}function OQ(e){return mf(e,XS)}function d9(e){return mf(e,qs)}function h9(e){return mf(e,Bd)}const LQ=["clamp","base","constant","exponent"];function p9(e,t){const n=t[0],r=Wt(t)-n;return function(i){return e(n+i*r)}}function ab(e,t,n){return IS(JS(t||"rgb",n),e)}function g9(e,t){const n=new Array(t),r=t+1;for(let i=0;ie[a]?o[a](e[a]()):0),o)}function JS(e,t){const n=JJ[IQ(e)];return t!=null&&n&&n.gamma?n.gamma(t):n}function IQ(e){return"interpolate"+e.toLowerCase().split("-").map(t=>t[0].toUpperCase()+t.slice(1)).join("")}const PQ={blues:"cfe1f2bed8eca8cee58fc1de74b2d75ba3cf4592c63181bd206fb2125ca40a4a90",greens:"d3eecdc0e6baabdda594d3917bc77d60ba6c46ab5e329a512089430e7735036429",greys:"e2e2e2d4d4d4c4c4c4b1b1b19d9d9d8888887575756262624d4d4d3535351e1e1e",oranges:"fdd8b3fdc998fdb87bfda55efc9244f87f2cf06b18e4580bd14904b93d029f3303",purples:"e2e1efd4d4e8c4c5e0b4b3d6a3a0cc928ec3827cb97566ae684ea25c3696501f8c",reds:"fdc9b4fcb49afc9e80fc8767fa7051f6573fec3f2fdc2a25c81b1db21218970b13",blueGreen:"d5efedc1e8e0a7ddd18bd2be70c6a958ba9144ad77319c5d2089460e7736036429",bluePurple:"ccddecbad0e4a8c2dd9ab0d4919cc98d85be8b6db28a55a6873c99822287730f71",greenBlue:"d3eecec5e8c3b1e1bb9bd8bb82cec269c2ca51b2cd3c9fc7288abd1675b10b60a1",orangeRed:"fddcaffdcf9bfdc18afdad77fb9562f67d53ee6545e24932d32d1ebf130da70403",purpleBlue:"dbdaebc8cee4b1c3de97b7d87bacd15b9fc93a90c01e7fb70b70ab056199045281",purpleBlueGreen:"dbd8eac8cee4b0c3de93b7d872acd1549fc83892bb1c88a3097f8702736b016353",purpleRed:"dcc9e2d3b3d7ce9eccd186c0da6bb2e14da0e23189d91e6fc61159ab07498f023a",redPurple:"fccfccfcbec0faa9b8f98faff571a5ec539ddb3695c41b8aa908808d0179700174",yellowGreen:"e4f4acd1eca0b9e2949ed68880c97c62bb6e47aa5e3297502083440e723b036034",yellowOrangeBrown:"feeaa1fedd84fecc63feb746fca031f68921eb7215db5e0bc54c05ab3d038f3204",yellowOrangeRed:"fee087fed16ffebd59fea849fd903efc7335f9522bee3423de1b20ca0b22af0225",blueOrange:"134b852f78b35da2cb9dcae1d2e5eff2f0ebfce0bafbbf74e8932fc5690d994a07",brownBlueGreen:"704108a0651ac79548e3c78af3e6c6eef1eac9e9e48ed1c74da79e187a72025147",purpleGreen:"5b1667834792a67fb6c9aed3e6d6e8eff0efd9efd5aedda971bb75368e490e5e29",purpleOrange:"4114696647968f83b7b9b4d6dadbebf3eeeafce0bafbbf74e8932fc5690d994a07",redBlue:"8c0d25bf363adf745ef4ae91fbdbc9f2efeed2e5ef9dcae15da2cb2f78b3134b85",redGrey:"8c0d25bf363adf745ef4ae91fcdccbfaf4f1e2e2e2c0c0c0969696646464343434",yellowGreenBlue:"eff9bddbf1b4bde5b594d5b969c5be45b4c22c9ec02182b82163aa23479c1c3185",redYellowBlue:"a50026d4322cf16e43fcac64fedd90faf8c1dcf1ecabd6e875abd04a74b4313695",redYellowGreen:"a50026d4322cf16e43fcac63fedd8df9f7aed7ee8ea4d86e64bc6122964f006837",pinkYellowGreen:"8e0152c0267edd72adf0b3d6faddedf5f3efe1f2cab6de8780bb474f9125276419",spectral:"9e0142d13c4bf0704afcac63fedd8dfbf8b0e0f3a1a9dda269bda94288b55e4fa2",viridis:"440154470e61481a6c482575472f7d443a834144873d4e8a39568c35608d31688e2d708e2a788e27818e23888e21918d1f988b1fa08822a8842ab07f35b77943bf7154c56866cc5d7ad1518fd744a5db36bcdf27d2e21be9e51afde725",magma:"0000040404130b0924150e3720114b2c11603b0f704a107957157e651a80721f817f24828c29819a2e80a8327db6377ac43c75d1426fde4968e95462f1605df76f5cfa7f5efc8f65fe9f6dfeaf78febf84fece91fddea0fcedaffcfdbf",inferno:"0000040403130c0826170c3b240c4f330a5f420a68500d6c5d126e6b176e781c6d86216b932667a12b62ae305cbb3755c73e4cd24644dd513ae65c30ed6925f3771af8850ffb9506fca50afcb519fac62df6d645f2e661f3f484fcffa4",plasma:"0d088723069033059742039d5002a25d01a66a00a87801a88405a7900da49c179ea72198b12a90ba3488c33d80cb4779d35171da5a69e16462e76e5bed7953f2834cf68f44fa9a3dfca636fdb32ffec029fcce25f9dc24f5ea27f0f921",cividis:"00205100235800265d002961012b65042e670831690d346b11366c16396d1c3c6e213f6e26426e2c456e31476e374a6e3c4d6e42506e47536d4c566d51586e555b6e5a5e6e5e616e62646f66676f6a6a706e6d717270717573727976737c79747f7c75827f758682768985778c8877908b78938e789691789a94789e9778a19b78a59e77a9a177aea575b2a874b6ab73bbaf71c0b26fc5b66dc9b96acebd68d3c065d8c462ddc85fe2cb5ce7cf58ebd355f0d652f3da4ff7de4cfae249fce647",rainbow:"6e40aa883eb1a43db3bf3cafd83fa4ee4395fe4b83ff576eff6659ff7847ff8c38f3a130e2b72fcfcc36bee044aff05b8ff4576ff65b52f6673af27828ea8d1ddfa319d0b81cbecb23abd82f96e03d82e14c6edb5a5dd0664dbf6e40aa",sinebow:"ff4040fc582af47218e78d0bd5a703bfbf00a7d5038de70b72f41858fc2a40ff402afc5818f4720be78d03d5a700bfbf03a7d50b8de71872f42a58fc4040ff582afc7218f48d0be7a703d5bf00bfd503a7e70b8df41872fc2a58ff4040",turbo:"23171b32204a3e2a71453493493eae4b49c54a53d7485ee44569ee4074f53c7ff8378af93295f72e9ff42ba9ef28b3e926bce125c5d925cdcf27d5c629dcbc2de3b232e9a738ee9d3ff39347f68950f9805afc7765fd6e70fe667cfd5e88fc5795fb51a1f84badf545b9f140c5ec3cd0e637dae034e4d931ecd12ef4c92bfac029ffb626ffad24ffa223ff9821ff8d1fff821dff771cfd6c1af76118f05616e84b14df4111d5380fcb2f0dc0260ab61f07ac1805a313029b0f00950c00910b00",browns:"eedbbdecca96e9b97ae4a865dc9856d18954c7784cc0673fb85536ad44339f3632",tealBlues:"bce4d89dd3d181c3cb65b3c245a2b9368fae347da0306a932c5985",teals:"bbdfdfa2d4d58ac9c975bcbb61b0af4da5a43799982b8b8c1e7f7f127273006667",warmGreys:"dcd4d0cec5c1c0b8b4b3aaa7a59c9998908c8b827f7e7673726866665c5a59504e",goldGreen:"f4d166d5ca60b6c35c98bb597cb25760a6564b9c533f8f4f33834a257740146c36",goldOrange:"f4d166f8be5cf8aa4cf5983bf3852aef701be2621fd65322c54923b142239e3a26",goldRed:"f4d166f6be59f9aa51fc964ef6834bee734ae56249db5247cf4244c43141b71d3e",lightGreyRed:"efe9e6e1dad7d5cbc8c8bdb9bbaea9cd967ddc7b43e15f19df4011dc000b",lightGreyTeal:"e4eaead6dcddc8ced2b7c2c7a6b4bc64b0bf22a6c32295c11f85be1876bc",lightMulti:"e0f1f2c4e9d0b0de9fd0e181f6e072f6c053f3993ef77440ef4a3c",lightOrange:"f2e7daf7d5baf9c499fab184fa9c73f68967ef7860e8645bde515bd43d5b",lightTealBlue:"e3e9e0c0dccf9aceca7abfc859afc0389fb9328dad2f7ca0276b95255988",darkBlue:"3232322d46681a5c930074af008cbf05a7ce25c0dd38daed50f3faffffff",darkGold:"3c3c3c584b37725e348c7631ae8b2bcfa424ecc31ef9de30fff184ffffff",darkGreen:"3a3a3a215748006f4d048942489e4276b340a6c63dd2d836ffeb2cffffaa",darkMulti:"3737371f5287197d8c29a86995ce3fffe800ffffff",darkRed:"3434347036339e3c38cc4037e75d1eec8620eeab29f0ce32ffeb2c"},BQ={accent:yQ,category10:vQ,category20:"1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5",category20b:"393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6",category20c:"3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9",dark2:bQ,observable10:xQ,paired:_Q,pastel1:wQ,pastel2:EQ,set1:AQ,set2:kQ,set3:SQ,tableau10:"4c78a8f58518e4575672b7b254a24beeca3bb279a2ff9da69d755dbab0ac",tableau20:"4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5"};function v9(e){if(de(e))return e;const t=e.length/6|0,n=new Array(t);for(let r=0;rab(v9(e)));function QS(e,t){return e=e&&e.toLowerCase(),arguments.length>1?($D[e]=t,this):$D[e]}const a1="symbol",zQ="discrete",jQ="gradient",UQ=e=>de(e)?e.map(t=>String(t)):String(e),qQ=(e,t)=>e[1]-t[1],WQ=(e,t)=>t[1]-e[1];function e3(e,t,n){let r;return Vt(t)&&(e.bins&&(t=Math.max(t,e.bins.length)),n!=null&&(t=Math.min(t,Math.floor(i0(e.domain())/n||1)+1))),Le(t)&&(r=t.step,t=t.interval),Ie(t)&&(t=e.type===Uc?Eh(t):e.type==qc?Ah(t):le("Only time and utc scales accept interval strings."),r&&(t=t.every(r))),t}function b9(e,t,n){let r=e.range(),i=r[0],s=Wt(r),o=qQ;if(i>s&&(r=s,s=i,i=r,o=WQ),i=Math.floor(i),s=Math.ceil(s),t=t.map(a=>[a,e(a)]).filter(a=>i<=a[1]&&a[1]<=s).sort(o).map(a=>a[0]),n>0&&t.length>1){const a=[t[0],Wt(t)];for(;t.length>n&&t.length>=3;)t=t.filter((l,u)=>!(u%2));t.length<3&&(t=a)}return t}function t3(e,t){return e.bins?b9(e,e.bins,t):e.ticks?e.ticks(t):e.domain()}function x9(e,t,n,r,i,s){const o=t.type;let a=UQ;if(o===Uc||i===Uc)a=e.timeFormat(r);else if(o===qc||i===qc)a=e.utcFormat(r);else if(f9(o)){const l=e.formatFloat(r);if(s||t.bins)a=l;else{const u=_9(t,n,!1);a=c=>u(c)?l(c):""}}else if(t.tickFormat){const l=t.domain();a=e.formatSpan(l[0],l[l.length-1],n,r)}else r&&(a=e.format(r));return a}function _9(e,t,n){const r=t3(e,t),i=e.base(),s=Math.log(i),o=Math.max(1,i*t/r.length),a=l=>{let u=l/Math.pow(i,Math.round(Math.log(l)/s));return u*i1?r[1]-r[0]:r[0],o;for(o=1;oHw[e.type]||e.bins;function A9(e,t,n,r,i,s,o){const a=w9[t.type]&&s!==Uc&&s!==qc?HQ(e,t,i):x9(e,t,n,i,s,o);return r===a1&&VQ(t)?XQ(a):r===zQ?KQ(a):ZQ(a)}const XQ=e=>(t,n,r)=>{const i=FD(r[n+1],FD(r.max,1/0)),s=DD(t,e),o=DD(i,e);return s&&o?s+" – "+o:o?"< "+o:"≥ "+s},FD=(e,t)=>e??t,KQ=e=>(t,n)=>n?e(t):null,ZQ=e=>t=>e(t),DD=(e,t)=>Number.isFinite(e)?t(e):null;function JQ(e){const t=e.domain(),n=t.length-1;let r=+t[0],i=+Wt(t),s=i-r;if(e.type===ob){const o=n?s/n:.1;r-=o,i+=o,s=i-r}return o=>(o-r)/s}function QQ(e,t,n,r){const i=r||t.type;return Ie(n)&&OQ(i)&&(n=n.replace(/%a/g,"%A").replace(/%b/g,"%B")),!n&&i===Uc?e.timeFormat("%A, %d %B %Y, %X"):!n&&i===qc?e.utcFormat("%A, %d %B %Y, %X UTC"):A9(e,t,5,null,n,r,!0)}function k9(e,t,n){n=n||{};const r=Math.max(3,n.maxlen||7),i=QQ(e,t,n.format,n.formatType);if(Ww(t.type)){const s=E9(t).slice(1).map(i),o=s.length;return`${o} boundar${o===1?"y":"ies"}: ${s.join(", ")}`}else if(zd(t.type)){const s=t.domain(),o=s.length,a=o>r?s.slice(0,r-2).map(i).join(", ")+", ending with "+s.slice(-1).map(i):s.map(i).join(", ");return`${o} value${o===1?"":"s"}: ${a}`}else{const s=t.domain();return`values from ${i(s[0])} to ${i(Wt(s))}`}}let S9=0;function eee(){S9=0}const iv="p_";function n3(e){return e&&e.gradient}function C9(e,t,n){const r=e.gradient;let i=e.id,s=r==="radial"?iv:"";return i||(i=e.id="gradient_"+S9++,r==="radial"?(e.x1=Oo(e.x1,.5),e.y1=Oo(e.y1,.5),e.r1=Oo(e.r1,0),e.x2=Oo(e.x2,.5),e.y2=Oo(e.y2,.5),e.r2=Oo(e.r2,.5),s=iv):(e.x1=Oo(e.x1,0),e.y1=Oo(e.y1,0),e.x2=Oo(e.x2,1),e.y2=Oo(e.y2,0))),t[i]=e,"url("+(n||"")+"#"+s+i+")"}function Oo(e,t){return e??t}function $9(e,t){var n=[],r;return r={gradient:"linear",x1:e?e[0]:0,y1:e?e[1]:0,x2:t?t[0]:1,y2:t?t[1]:0,stops:n,stop:function(i,s){return n.push({offset:i,color:s}),r}}}const MD={basis:{curve:KZ},"basis-closed":{curve:ZZ},"basis-open":{curve:JZ},bundle:{curve:QZ,tension:"beta",value:.85},cardinal:{curve:eJ,tension:"tension",value:0},"cardinal-open":{curve:nJ,tension:"tension",value:0},"cardinal-closed":{curve:tJ,tension:"tension",value:0},"catmull-rom":{curve:rJ,tension:"alpha",value:.5},"catmull-rom-closed":{curve:iJ,tension:"alpha",value:.5},"catmull-rom-open":{curve:sJ,tension:"alpha",value:.5},linear:{curve:CS},"linear-closed":{curve:oJ},monotone:{horizontal:lJ,vertical:aJ},natural:{curve:uJ},step:{curve:cJ},"step-after":{curve:dJ},"step-before":{curve:fJ}};function r3(e,t,n){var r=Ue(MD,e)&&MD[e],i=null;return r&&(i=r.curve||r[t||"vertical"],r.tension&&n!=null&&(i=i[r.tension](n))),i}const tee={m:2,l:2,h:1,v:1,z:0,c:6,s:4,q:4,t:2,a:7},nee=/[mlhvzcsqta]([^mlhvzcsqta]+|$)/gi,ree=/^[+-]?(([0-9]*\.[0-9]+)|([0-9]+\.)|([0-9]+))([eE][+-]?[0-9]+)?/,iee=/^((\s+,?\s*)|(,\s*))/,see=/^[01]/;function jd(e){const t=[];return(e.match(nee)||[]).forEach(r=>{let i=r[0];const s=i.toLowerCase(),o=tee[s],a=oee(s,o,r.slice(1).trim()),l=a.length;if(l1&&(g=Math.sqrt(g),n*=g,r*=g);const m=d/n,y=f/n,b=-f/r,x=d/r,_=m*a+y*l,w=b*a+x*l,A=m*e+y*t,E=b*e+x*t;let S=1/((A-_)*(A-_)+(E-w)*(E-w))-.25;S<0&&(S=0);let $=Math.sqrt(S);s==i&&($=-$);const M=.5*(_+A)-$*(E-w),O=.5*(w+E)+$*(A-_),P=Math.atan2(w-O,_-M);let F=Math.atan2(E-O,A-M)-P;F<0&&s===1?F+=Yo:F>0&&s===0&&(F-=Yo);const N=Math.ceil(Math.abs(F/(sc+.001))),U=[];for(let j=0;j+e}function hm(e,t,n){return Math.max(t,Math.min(e,n))}function M9(){var e=dee,t=hee,n=pee,r=gee,i=Ta(0),s=i,o=i,a=i,l=null;function u(c,f,d){var h,p=f??+e.call(this,c),g=d??+t.call(this,c),m=+n.call(this,c),y=+r.call(this,c),b=Math.min(m,y)/2,x=hm(+i.call(this,c),0,b),_=hm(+s.call(this,c),0,b),w=hm(+o.call(this,c),0,b),A=hm(+a.call(this,c),0,b);if(l||(l=h=Vy()),x<=0&&_<=0&&w<=0&&A<=0)l.rect(p,g,m,y);else{var E=p+m,k=g+y;l.moveTo(p+x,g),l.lineTo(E-_,g),l.bezierCurveTo(E-Sl*_,g,E,g+Sl*_,E,g+_),l.lineTo(E,k-A),l.bezierCurveTo(E,k-Sl*A,E-Sl*A,k,E-A,k),l.lineTo(p+w,k),l.bezierCurveTo(p+Sl*w,k,p,k-Sl*w,p,k-w),l.lineTo(p,g+x),l.bezierCurveTo(p,g+Sl*x,p+Sl*x,g,p+x,g),l.closePath()}if(h)return l=null,h+""||null}return u.x=function(c){return arguments.length?(e=Ta(c),u):e},u.y=function(c){return arguments.length?(t=Ta(c),u):t},u.width=function(c){return arguments.length?(n=Ta(c),u):n},u.height=function(c){return arguments.length?(r=Ta(c),u):r},u.cornerRadius=function(c,f,d,h){return arguments.length?(i=Ta(c),s=f!=null?Ta(f):i,a=d!=null?Ta(d):i,o=h!=null?Ta(h):s,u):i},u.context=function(c){return arguments.length?(l=c??null,u):l},u}function T9(){var e,t,n,r,i=null,s,o,a,l;function u(f,d,h){const p=h/2;if(s){var g=a-d,m=f-o;if(g||m){var y=Math.hypot(g,m),b=(g/=y)*l,x=(m/=y)*l,_=Math.atan2(m,g);i.moveTo(o-b,a-x),i.lineTo(f-g*p,d-m*p),i.arc(f,d,p,_-Math.PI,_),i.lineTo(o+b,a+x),i.arc(o,a,l,_,_+Math.PI)}else i.arc(f,d,p,0,Yo);i.closePath()}else s=1;o=f,a=d,l=p}function c(f){var d,h=f.length,p,g=!1,m;for(i==null&&(i=m=Vy()),d=0;d<=h;++d)!(de.x||0,v0=e=>e.y||0,mee=e=>e.width||0,vee=e=>e.height||0,yee=e=>(e.x||0)+(e.width||0),bee=e=>(e.y||0)+(e.height||0),xee=e=>e.startAngle||0,_ee=e=>e.endAngle||0,wee=e=>e.padAngle||0,Eee=e=>e.innerRadius||0,Aee=e=>e.outerRadius||0,kee=e=>e.cornerRadius||0,See=e=>g0(e.cornerRadiusTopLeft,e.cornerRadius)||0,Cee=e=>g0(e.cornerRadiusTopRight,e.cornerRadius)||0,$ee=e=>g0(e.cornerRadiusBottomRight,e.cornerRadius)||0,Fee=e=>g0(e.cornerRadiusBottomLeft,e.cornerRadius)||0,Dee=e=>g0(e.size,64),Mee=e=>e.size||1,lb=e=>e.defined!==!1,Tee=e=>D9(e.shape||"circle"),Ree=YZ().startAngle(xee).endAngle(_ee).padAngle(wee).innerRadius(Eee).outerRadius(Aee).cornerRadius(kee),Nee=a7().x(m0).y1(v0).y0(bee).defined(lb),Oee=a7().y(v0).x1(m0).x0(yee).defined(lb),Lee=o7().x(m0).y(v0).defined(lb),Iee=M9().x(m0).y(v0).width(mee).height(vee).cornerRadius(See,Cee,$ee,Fee),Pee=XZ().type(Tee).size(Dee),Bee=T9().x(m0).y(v0).defined(lb).size(Mee);function i3(e){return e.cornerRadius||e.cornerRadiusTopLeft||e.cornerRadiusTopRight||e.cornerRadiusBottomRight||e.cornerRadiusBottomLeft}function zee(e,t){return Ree.context(e)(t)}function jee(e,t){const n=t[0],r=n.interpolate||"linear";return(n.orient==="horizontal"?Oee:Nee).curve(r3(r,n.orient,n.tension)).context(e)(t)}function Uee(e,t){const n=t[0],r=n.interpolate||"linear";return Lee.curve(r3(r,n.orient,n.tension)).context(e)(t)}function $h(e,t,n,r){return Iee.context(e)(t,n,r)}function qee(e,t){return(t.mark.shape||t.shape).context(e)(t)}function Wee(e,t){return Pee.context(e)(t)}function Hee(e,t){return Bee.context(e)(t)}var R9=1;function N9(){R9=1}function s3(e,t,n){var r=t.clip,i=e._defs,s=t.clip_id||(t.clip_id="clip"+R9++),o=i.clipping[s]||(i.clipping[s]={id:s});return Tt(r)?o.path=r(null):i3(n)?o.path=$h(null,n,0,0):(o.width=n.width||0,o.height=n.height||0),"url(#"+s+")"}function Vn(e){this.clear(),e&&this.union(e)}Vn.prototype={clone(){return new Vn(this)},clear(){return this.x1=+Number.MAX_VALUE,this.y1=+Number.MAX_VALUE,this.x2=-Number.MAX_VALUE,this.y2=-Number.MAX_VALUE,this},empty(){return this.x1===+Number.MAX_VALUE&&this.y1===+Number.MAX_VALUE&&this.x2===-Number.MAX_VALUE&&this.y2===-Number.MAX_VALUE},equals(e){return this.x1===e.x1&&this.y1===e.y1&&this.x2===e.x2&&this.y2===e.y2},set(e,t,n,r){return nthis.x2&&(this.x2=e),t>this.y2&&(this.y2=t),this},expand(e){return this.x1-=e,this.y1-=e,this.x2+=e,this.y2+=e,this},round(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},scale(e){return this.x1*=e,this.y1*=e,this.x2*=e,this.y2*=e,this},translate(e,t){return this.x1+=e,this.x2+=e,this.y1+=t,this.y2+=t,this},rotate(e,t,n){const r=this.rotatedPoints(e,t,n);return this.clear().add(r[0],r[1]).add(r[2],r[3]).add(r[4],r[5]).add(r[6],r[7])},rotatedPoints(e,t,n){var{x1:r,y1:i,x2:s,y2:o}=this,a=Math.cos(e),l=Math.sin(e),u=t-t*a+n*l,c=n-t*l-n*a;return[a*r-l*i+u,l*r+a*i+c,a*r-l*o+u,l*r+a*o+c,a*s-l*i+u,l*s+a*i+c,a*s-l*o+u,l*s+a*o+c]},union(e){return e.x1this.x2&&(this.x2=e.x2),e.y2>this.y2&&(this.y2=e.y2),this},intersect(e){return e.x1>this.x1&&(this.x1=e.x1),e.y1>this.y1&&(this.y1=e.y1),e.x2=e.x2&&this.y1<=e.y1&&this.y2>=e.y2},alignsWith(e){return e&&(this.x1==e.x1||this.x2==e.x2||this.y1==e.y1||this.y2==e.y2)},intersects(e){return e&&!(this.x2e.x2||this.y2e.y2)},contains(e,t){return!(ethis.x2||tthis.y2)},width(){return this.x2-this.x1},height(){return this.y2-this.y1}};function ub(e){this.mark=e,this.bounds=this.bounds||new Vn}function cb(e){ub.call(this,e),this.items=this.items||[]}Me(cb,ub);class O9{constructor(t){this._pending=0,this._loader=t||Ly()}pending(){return this._pending}sanitizeURL(t){const n=this;return OD(n),n._loader.sanitize(t,{context:"href"}).then(r=>(tp(n),r)).catch(()=>(tp(n),null))}loadImage(t){const n=this,r=hJ();return OD(n),n._loader.sanitize(t,{context:"image"}).then(i=>{const s=i.href;if(!s||!r)throw{url:s};const o=new r,a=Ue(i,"crossOrigin")?i.crossOrigin:"anonymous";return a!=null&&(o.crossOrigin=a),o.onload=()=>tp(n),o.onerror=()=>tp(n),o.src=s,o}).catch(i=>(tp(n),{complete:!1,width:0,height:0,src:i&&i.url||""}))}ready(){const t=this;return new Promise(n=>{function r(i){t.pending()?setTimeout(()=>{r(!0)},10):n(i)}r(!1)})}}function OD(e){e._pending+=1}function tp(e){e._pending-=1}function gl(e,t,n){if(t.stroke&&t.opacity!==0&&t.strokeOpacity!==0){const r=t.strokeWidth!=null?+t.strokeWidth:1;e.expand(r+(n?Gee(t,r):0))}return e}function Gee(e,t){return e.strokeJoin&&e.strokeJoin!=="miter"?0:t}const Yee=Yo-1e-8;let fb,l1,u1,gc,Gw,c1,Yw,Vw;const Bl=(e,t)=>fb.add(e,t),f1=(e,t)=>Bl(l1=e,u1=t),LD=e=>Bl(e,fb.y1),ID=e=>Bl(fb.x1,e),oc=(e,t)=>Gw*e+Yw*t,ac=(e,t)=>c1*e+Vw*t,Sx=(e,t)=>Bl(oc(e,t),ac(e,t)),Cx=(e,t)=>f1(oc(e,t),ac(e,t));function y0(e,t){return fb=e,t?(gc=t*uu,Gw=Vw=Math.cos(gc),c1=Math.sin(gc),Yw=-c1):(Gw=Vw=1,gc=c1=Yw=0),Vee}const Vee={beginPath(){},closePath(){},moveTo:Cx,lineTo:Cx,rect(e,t,n,r){gc?(Sx(e+n,t),Sx(e+n,t+r),Sx(e,t+r),Cx(e,t)):(Bl(e+n,t+r),f1(e,t))},quadraticCurveTo(e,t,n,r){const i=oc(e,t),s=ac(e,t),o=oc(n,r),a=ac(n,r);PD(l1,i,o,LD),PD(u1,s,a,ID),f1(o,a)},bezierCurveTo(e,t,n,r,i,s){const o=oc(e,t),a=ac(e,t),l=oc(n,r),u=ac(n,r),c=oc(i,s),f=ac(i,s);BD(l1,o,l,c,LD),BD(u1,a,u,f,ID),f1(c,f)},arc(e,t,n,r,i,s){if(r+=gc,i+=gc,l1=n*Math.cos(i)+e,u1=n*Math.sin(i)+t,Math.abs(i-r)>Yee)Bl(e-n,t-n),Bl(e+n,t+n);else{const o=u=>Bl(n*Math.cos(u)+e,n*Math.sin(u)+t);let a,l;if(o(r),o(i),i!==r)if(r=r%Yo,r<0&&(r+=Yo),i=i%Yo,i<0&&(i+=Yo),ii;++l,a-=sc)o(a);else for(a=r-r%sc+sc,l=0;l<4&&aaee?(c=o*o+a*s,c>=0&&(c=Math.sqrt(c),l=(-o+c)/s,u=(-o-c)/s)):l=.5*a/o,0d)return!1;g>f&&(f=g)}else if(h>0){if(g0?(e.globalAlpha=n,e.fillStyle=P9(e,t,t.fill),!0):!1}var Kee=[];function qd(e,t,n){var r=(r=t.strokeWidth)!=null?r:1;return r<=0?!1:(n*=t.strokeOpacity==null?1:t.strokeOpacity,n>0?(e.globalAlpha=n,e.strokeStyle=P9(e,t,t.stroke),e.lineWidth=r,e.lineCap=t.strokeCap||"butt",e.lineJoin=t.strokeJoin||"miter",e.miterLimit=t.strokeMiterLimit||10,e.setLineDash&&(e.setLineDash(t.strokeDash||Kee),e.lineDashOffset=t.strokeDashOffset||0),!0):!1)}function Zee(e,t){return e.zindex-t.zindex||e.index-t.index}function l3(e){if(!e.zdirty)return e.zitems;var t=e.items,n=[],r,i,s;for(i=0,s=t.length;i=0;)if(r=t(n[i]))return r;if(n===s){for(n=e.items,i=n.length;--i>=0;)if(!n[i].zindex&&(r=t(n[i])))return r}return null}function u3(e){return function(t,n,r){yo(n,i=>{(!r||r.intersects(i.bounds))&&B9(e,t,i,i)})}}function Jee(e){return function(t,n,r){n.items.length&&(!r||r.intersects(n.bounds))&&B9(e,t,n.items[0],n.items)}}function B9(e,t,n,r){var i=n.opacity==null?1:n.opacity;i!==0&&(e(t,r)||(Ud(t,n),n.fill&&sv(t,n,i)&&t.fill(),n.stroke&&qd(t,n,i)&&t.stroke()))}function db(e){return e=e||ds,function(t,n,r,i,s,o){return r*=t.pixelRatio,i*=t.pixelRatio,ov(n,a=>{const l=a.bounds;if(!(l&&!l.contains(s,o)||!l)&&e(t,a,r,i,s,o))return a})}}function b0(e,t){return function(n,r,i,s){var o=Array.isArray(r)?r[0]:r,a=t??o.fill,l=o.stroke&&n.isPointInStroke,u,c;return l&&(u=o.strokeWidth,c=o.strokeCap,n.lineWidth=u??1,n.lineCap=c??"butt"),e(n,r)?!1:a&&n.isPointInPath(i,s)||l&&n.isPointInStroke(i,s)}}function c3(e){return db(b0(e))}function kc(e,t){return"translate("+e+","+t+")"}function f3(e){return"rotate("+e+")"}function Qee(e,t){return"scale("+e+","+t+")"}function z9(e){return kc(e.x||0,e.y||0)}function ete(e){return kc(e.x||0,e.y||0)+(e.angle?" "+f3(e.angle):"")}function tte(e){return kc(e.x||0,e.y||0)+(e.angle?" "+f3(e.angle):"")+(e.scaleX||e.scaleY?" "+Qee(e.scaleX||1,e.scaleY||1):"")}function d3(e,t,n){function r(o,a){o("transform",ete(a)),o("d",t(null,a))}function i(o,a){return t(y0(o,a.angle),a),gl(o,a).translate(a.x||0,a.y||0)}function s(o,a){var l=a.x||0,u=a.y||0,c=a.angle||0;o.translate(l,u),c&&o.rotate(c*=uu),o.beginPath(),t(o,a),c&&o.rotate(-c),o.translate(-l,-u)}return{type:e,tag:"path",nested:!1,attr:r,bound:i,draw:u3(s),pick:c3(s),isect:n||o3(s)}}var nte=d3("arc",zee);function rte(e,t){for(var n=e[0].orient==="horizontal"?t[1]:t[0],r=e[0].orient==="horizontal"?"y":"x",i=e.length,s=1/0,o,a;--i>=0;)e[i].defined!==!1&&(a=Math.abs(e[i][r]-n),a=0;)if(e[r].defined!==!1&&(i=e[r].x-t[0],s=e[r].y-t[1],o=i*i+s*s,o=0;)if(e[n].defined!==!1&&(r=e[n].x-t[0],i=e[n].y-t[1],s=r*r+i*i,r=e[n].size||1,s.5&&t<1.5?.5-Math.abs(t-1):0}function lte(e,t){e("transform",z9(t))}function q9(e,t){const n=U9(t);e("d",$h(null,t,n,n))}function ute(e,t){e("class","background"),e("aria-hidden",!0),q9(e,t)}function cte(e,t){e("class","foreground"),e("aria-hidden",!0),t.strokeForeground?q9(e,t):e("d","")}function fte(e,t,n){const r=t.clip?s3(n,t,t):null;e("clip-path",r)}function dte(e,t){if(!t.clip&&t.items){const n=t.items,r=n.length;for(let i=0;i{const s=i.x||0,o=i.y||0,a=i.strokeForeground,l=i.opacity==null?1:i.opacity;(i.stroke||i.fill)&&l&&(_g(e,i,s,o),Ud(e,i),i.fill&&sv(e,i,l)&&e.fill(),i.stroke&&!a&&qd(e,i,l)&&e.stroke()),e.save(),e.translate(s,o),i.clip&&j9(e,i),n&&n.translate(-s,-o),yo(i,u=>{(u.marktype==="group"||r==null||r.includes(u.marktype))&&this.draw(e,u,n,r)}),n&&n.translate(s,o),e.restore(),a&&i.stroke&&l&&(_g(e,i,s,o),Ud(e,i),qd(e,i,l)&&e.stroke())})}function vte(e,t,n,r,i,s){if(t.bounds&&!t.bounds.contains(i,s)||!t.items)return null;const o=n*e.pixelRatio,a=r*e.pixelRatio;return ov(t,l=>{let u,c,f;const d=l.bounds;if(d&&!d.contains(i,s))return;c=l.x||0,f=l.y||0;const h=c+(l.width||0),p=f+(l.height||0),g=l.clip;if(g&&(ih||sp))return;if(e.save(),e.translate(c,f),c=i-c,f=s-f,g&&i3(l)&&!gte(e,l,o,a))return e.restore(),null;const m=l.strokeForeground,y=t.interactive!==!1;return y&&m&&l.stroke&&pte(e,l,o,a)?(e.restore(),l):(u=ov(l,b=>yte(b,c,f)?this.pick(b,n,r,c,f):null),!u&&y&&(l.fill||!m&&l.stroke)&&hte(e,l,o,a)&&(u=l),e.restore(),u||null)})}function yte(e,t,n){return(e.interactive!==!1||e.marktype==="group")&&e.bounds&&e.bounds.contains(t,n)}var bte={type:"group",tag:"g",nested:!1,attr:lte,bound:dte,draw:mte,pick:vte,isect:L9,content:fte,background:ute,foreground:cte},wg={xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",version:"1.1"};function p3(e,t){var n=e.image;return(!n||e.url&&e.url!==n.url)&&(n={complete:!1,width:0,height:0},t.loadImage(e.url).then(r=>{e.image=r,e.image.url=e.url})),n}function g3(e,t){return e.width!=null?e.width:!t||!t.width?0:e.aspect!==!1&&e.height?e.height*t.width/t.height:t.width}function m3(e,t){return e.height!=null?e.height:!t||!t.height?0:e.aspect!==!1&&e.width?e.width*t.height/t.width:t.height}function hb(e,t){return e==="center"?t/2:e==="right"?t:0}function pb(e,t){return e==="middle"?t/2:e==="bottom"?t:0}function xte(e,t,n){const r=p3(t,n),i=g3(t,r),s=m3(t,r),o=(t.x||0)-hb(t.align,i),a=(t.y||0)-pb(t.baseline,s),l=!r.src&&r.toDataURL?r.toDataURL():r.src||"";e("href",l,wg["xmlns:xlink"],"xlink:href"),e("transform",kc(o,a)),e("width",i),e("height",s),e("preserveAspectRatio",t.aspect===!1?"none":"xMidYMid")}function _te(e,t){const n=t.image,r=g3(t,n),i=m3(t,n),s=(t.x||0)-hb(t.align,r),o=(t.y||0)-pb(t.baseline,i);return e.set(s,o,s+r,o+i)}function wte(e,t,n){yo(t,r=>{if(n&&!n.intersects(r.bounds))return;const i=p3(r,this);let s=g3(r,i),o=m3(r,i);if(s===0||o===0)return;let a=(r.x||0)-hb(r.align,s),l=(r.y||0)-pb(r.baseline,o),u,c,f,d;r.aspect!==!1&&(c=i.width/i.height,f=r.width/r.height,c===c&&f===f&&c!==f&&(f{if(!(n&&!n.intersects(r.bounds))){var i=r.opacity==null?1:r.opacity;i&&W9(e,r,i)&&(Ud(e,r),e.stroke())}})}function Nte(e,t,n,r){return e.isPointInStroke?W9(e,t,1)&&e.isPointInStroke(n,r):!1}var Ote={type:"rule",tag:"line",nested:!1,attr:Mte,bound:Tte,draw:Rte,pick:db(Nte),isect:I9},Lte=d3("shape",qee),Ite=d3("symbol",Wee,a3);const qD=JR();var us={height:xa,measureWidth:v3,estimateWidth:av,width:av,canvas:H9};H9(!0);function H9(e){us.width=e&&tu?v3:av}function av(e,t){return G9(fu(e,t),xa(e))}function G9(e,t){return~~(.8*e.length*t)}function v3(e,t){return xa(e)<=0||!(t=fu(e,t))?0:Y9(t,gb(e))}function Y9(e,t){const n=`(${t}) ${e}`;let r=qD.get(n);return r===void 0&&(tu.font=t,r=tu.measureText(e).width,qD.set(n,r)),r}function xa(e){return e.fontSize!=null?+e.fontSize||0:11}function cu(e){return e.lineHeight!=null?e.lineHeight:xa(e)+2}function Pte(e){return de(e)?e.length>1?e:e[0]:e}function x0(e){return Pte(e.lineBreak&&e.text&&!de(e.text)?e.text.split(e.lineBreak):e.text)}function y3(e){const t=x0(e);return(de(t)?t.length-1:0)*cu(e)}function fu(e,t){const n=t==null?"":(t+"").trim();return e.limit>0&&n.length?zte(e,n):n}function Bte(e){if(us.width===v3){const t=gb(e);return n=>Y9(n,t)}else if(us.width===av){const t=xa(e);return n=>G9(n,t)}else return t=>us.width(e,t)}function zte(e,t){var n=+e.limit,r=Bte(e);if(r(t)>>1,r(t.slice(l))>n?o=l+1:a=l;return i+t.slice(o)}else{for(;o>>1),r(t.slice(0,l))Math.max(d,us.width(t,h)),0)):f=us.width(t,c),i==="center"?l-=f/2:i==="right"&&(l-=f),e.set(l+=o,u+=a,l+f,u+r),t.angle&&!n)e.rotate(t.angle*uu,o,a);else if(n===2)return e.rotatedPoints(t.angle*uu,o,a);return e}function qte(e,t,n){yo(t,r=>{var i=r.opacity==null?1:r.opacity,s,o,a,l,u,c,f;if(!(n&&!n.intersects(r.bounds)||i===0||r.fontSize<=0||r.text==null||r.text.length===0)){if(e.font=gb(r),e.textAlign=r.align||"left",s=mb(r),o=s.x1,a=s.y1,r.angle&&(e.save(),e.translate(o,a),e.rotate(r.angle*uu),o=a=0),o+=r.dx||0,a+=(r.dy||0)+b3(r),c=x0(r),Ud(e,r),de(c))for(u=cu(r),l=0;lt;)e.removeChild(n[--r]);return e}function Q9(e){return"mark-"+e.marktype+(e.role?" role-"+e.role:"")+(e.name?" "+e.name:"")}function vb(e,t){const n=t.getBoundingClientRect();return[e.clientX-n.left-(t.clientLeft||0),e.clientY-n.top-(t.clientTop||0)]}function Xte(e,t,n,r){var i=e&&e.mark,s,o;if(i&&(s=gs[i.marktype]).tip){for(o=vb(t,n),o[0]-=r[0],o[1]-=r[1];e=e.mark.group;)o[0]-=e.x||0,o[1]-=e.y||0;e=s.tip(i.items,o)}return e}let w3=class{constructor(t,n){this._active=null,this._handlers={},this._loader=t||Ly(),this._tooltip=n||Kte}initialize(t,n,r){return this._el=t,this._obj=r||null,this.origin(n)}element(){return this._el}canvas(){return this._el&&this._el.firstChild}origin(t){return arguments.length?(this._origin=t||[0,0],this):this._origin.slice()}scene(t){return arguments.length?(this._scene=t,this):this._scene}on(){}off(){}_handlerIndex(t,n,r){for(let i=t?t.length:0;--i>=0;)if(t[i].type===n&&(!r||t[i].handler===r))return i;return-1}handlers(t){const n=this._handlers,r=[];if(t)r.push(...n[this.eventName(t)]);else for(const i in n)r.push(...n[i]);return r}eventName(t){const n=t.indexOf(".");return n<0?t:t.slice(0,n)}handleHref(t,n,r){this._loader.sanitize(r,{context:"href"}).then(i=>{const s=new MouseEvent(t.type,t),o=zl(null,"a");for(const a in i)o.setAttribute(a,i[a]);o.dispatchEvent(s)}).catch(()=>{})}handleTooltip(t,n,r){if(n&&n.tooltip!=null){n=Xte(n,t,this.canvas(),this._origin);const i=r&&n&&n.tooltip||null;this._tooltip.call(this._obj,this,t,n,i)}}getItemBoundingClientRect(t){const n=this.canvas();if(!n)return;const r=n.getBoundingClientRect(),i=this._origin,s=t.bounds,o=s.width(),a=s.height();let l=s.x1+i[0]+r.left,u=s.y1+i[1]+r.top;for(;t.mark&&(t=t.mark.group);)l+=t.x||0,u+=t.y||0;return{x:l,y:u,width:o,height:a,left:l,top:u,right:l+o,bottom:u+a}}};function Kte(e,t,n,r){e.element().setAttribute("title",r||"")}class w0{constructor(t){this._el=null,this._bgcolor=null,this._loader=new O9(t)}initialize(t,n,r,i,s){return this._el=t,this.resize(n,r,i,s)}element(){return this._el}canvas(){return this._el&&this._el.firstChild}background(t){return arguments.length===0?this._bgcolor:(this._bgcolor=t,this)}resize(t,n,r,i){return this._width=t,this._height=n,this._origin=r||[0,0],this._scale=i||1,this}dirty(){}render(t,n){const r=this;return r._call=function(){r._render(t,n)},r._call(),r._call=null,r}_render(){}renderAsync(t,n){const r=this.render(t,n);return this._ready?this._ready.then(()=>r):Promise.resolve(r)}_load(t,n){var r=this,i=r._loader[t](n);if(!r._ready){const s=r._call;r._ready=r._loader.ready().then(o=>{o&&s(),r._ready=null})}return i}sanitizeURL(t){return this._load("sanitizeURL",t)}loadImage(t){return this._load("loadImage",t)}}const Zte="keydown",Jte="keypress",Qte="keyup",eL="dragenter",h1="dragleave",tL="dragover",Zw="pointerdown",ene="pointerup",lv="pointermove",p1="pointerout",nL="pointerover",Jw="mousedown",tne="mouseup",rL="mousemove",uv="mouseout",iL="mouseover",cv="click",nne="dblclick",rne="wheel",sL="mousewheel",fv="touchstart",dv="touchmove",hv="touchend",ine=[Zte,Jte,Qte,eL,h1,tL,Zw,ene,lv,p1,nL,Jw,tne,rL,uv,iL,cv,nne,rne,sL,fv,dv,hv],Qw=lv,Xp=uv,eE=cv;class E0 extends w3{constructor(t,n){super(t,n),this._down=null,this._touch=null,this._first=!0,this._events={},this.events=ine,this.pointermove=YD([lv,rL],[nL,iL],[p1,uv]),this.dragover=YD([tL],[eL],[h1]),this.pointerout=VD([p1,uv]),this.dragleave=VD([h1])}initialize(t,n,r){return this._canvas=t&&_3(t,"canvas"),[cv,Jw,Zw,lv,p1,h1].forEach(i=>GD(this,i)),super.initialize(t,n,r)}canvas(){return this._canvas}context(){return this._canvas.getContext("2d")}DOMMouseScroll(t){this.fire(sL,t)}pointerdown(t){this._down=this._active,this.fire(Zw,t)}mousedown(t){this._down=this._active,this.fire(Jw,t)}click(t){this._down===this._active&&(this.fire(cv,t),this._down=null)}touchstart(t){this._touch=this.pickEvent(t.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire(fv,t,!0)}touchmove(t){this.fire(dv,t,!0)}touchend(t){this.fire(hv,t,!0),this._touch=null}fire(t,n,r){const i=r?this._touch:this._active,s=this._handlers[t];if(n.vegaType=t,t===eE&&i&&i.href?this.handleHref(n,i,i.href):(t===Qw||t===Xp)&&this.handleTooltip(n,i,t!==Xp),s)for(let o=0,a=s.length;o=0&&i.splice(s,1),this}pickEvent(t){const n=vb(t,this._canvas),r=this._origin;return this.pick(this._scene,n[0],n[1],n[0]-r[0],n[1]-r[1])}pick(t,n,r,i,s){const o=this.context();return gs[t.marktype].pick.call(this,o,t,n,r,i,s)}}const sne=e=>e===fv||e===dv||e===hv?[fv,dv,hv]:[e];function GD(e,t){sne(t).forEach(n=>one(e,n))}function one(e,t){const n=e.canvas();n&&!e._events[t]&&(e._events[t]=1,n.addEventListener(t,e[t]?r=>e[t](r):r=>e.fire(t,r)))}function Sp(e,t,n){t.forEach(r=>e.fire(r,n))}function YD(e,t,n){return function(r){const i=this._active,s=this.pickEvent(r);s===i?Sp(this,e,r):((!i||!i.exit)&&Sp(this,n,r),this._active=s,Sp(this,t,r),Sp(this,e,r))}}function VD(e){return function(t){Sp(this,e,t),this._active=null}}function ane(){return typeof window<"u"&&window.devicePixelRatio||1}function lne(e,t,n,r,i,s){const o=typeof HTMLElement<"u"&&e instanceof HTMLElement&&e.parentNode!=null,a=e.getContext("2d"),l=o?ane():i;e.width=t*l,e.height=n*l;for(const u in s)a[u]=s[u];return o&&l!==1&&(e.style.width=t+"px",e.style.height=n+"px"),a.pixelRatio=l,a.setTransform(l,0,0,l,l*r[0],l*r[1]),e}class pv extends w0{constructor(t){super(t),this._options={},this._redraw=!1,this._dirty=new Vn,this._tempb=new Vn}initialize(t,n,r,i,s,o){return this._options=o||{},this._canvas=this._options.externalContext?null:eu(1,1,this._options.type),t&&this._canvas&&(As(t,0).appendChild(this._canvas),this._canvas.setAttribute("class","marks")),super.initialize(t,n,r,i,s)}resize(t,n,r,i){if(super.resize(t,n,r,i),this._canvas)lne(this._canvas,this._width,this._height,this._origin,this._scale,this._options.context);else{const s=this._options.externalContext;s||le("CanvasRenderer is missing a valid canvas or context"),s.scale(this._scale,this._scale),s.translate(this._origin[0],this._origin[1])}return this._redraw=!0,this}canvas(){return this._canvas}context(){return this._options.externalContext||(this._canvas?this._canvas.getContext("2d"):null)}dirty(t){const n=this._tempb.clear().union(t.bounds);let r=t.mark.group;for(;r;)n.translate(r.x||0,r.y||0),r=r.mark.group;this._dirty.union(n)}_render(t,n){const r=this.context(),i=this._origin,s=this._width,o=this._height,a=this._dirty,l=une(i,s,o);r.save();const u=this._redraw||a.empty()?(this._redraw=!1,l.expand(1)):cne(r,l.intersect(a),i);return this.clear(-i[0],-i[1],s,o),this.draw(r,t,u,n),r.restore(),a.clear(),this}draw(t,n,r,i){if(n.marktype!=="group"&&i!=null&&!i.includes(n.marktype))return;const s=gs[n.marktype];n.clip&&ate(t,n),s.draw.call(this,t,n,r,i),n.clip&&t.restore()}clear(t,n,r,i){const s=this._options,o=this.context();s.type!=="pdf"&&!s.externalContext&&o.clearRect(t,n,r,i),this._bgcolor!=null&&(o.fillStyle=this._bgcolor,o.fillRect(t,n,r,i))}}const une=(e,t,n)=>new Vn().set(0,0,t,n).translate(-e[0],-e[1]);function cne(e,t,n){return t.expand(1).round(),e.pixelRatio%1&&t.scale(e.pixelRatio).round().scale(1/e.pixelRatio),t.translate(-(n[0]%1),-(n[1]%1)),e.beginPath(),e.rect(t.x1,t.y1,t.width(),t.height()),e.clip(),t}class oL extends w3{constructor(t,n){super(t,n);const r=this;r._hrefHandler=$x(r,(i,s)=>{s&&s.href&&r.handleHref(i,s,s.href)}),r._tooltipHandler=$x(r,(i,s)=>{r.handleTooltip(i,s,i.type!==Xp)})}initialize(t,n,r){let i=this._svg;return i&&(i.removeEventListener(eE,this._hrefHandler),i.removeEventListener(Qw,this._tooltipHandler),i.removeEventListener(Xp,this._tooltipHandler)),this._svg=i=t&&_3(t,"svg"),i&&(i.addEventListener(eE,this._hrefHandler),i.addEventListener(Qw,this._tooltipHandler),i.addEventListener(Xp,this._tooltipHandler)),super.initialize(t,n,r)}canvas(){return this._svg}on(t,n){const r=this.eventName(t),i=this._handlers;if(this._handlerIndex(i[r],t,n)<0){const o={type:t,handler:n,listener:$x(this,n)};(i[r]||(i[r]=[])).push(o),this._svg&&this._svg.addEventListener(r,o.listener)}return this}off(t,n){const r=this.eventName(t),i=this._handlers[r],s=this._handlerIndex(i,t,n);return s>=0&&(this._svg&&this._svg.removeEventListener(r,i[s].listener),i.splice(s,1)),this}}const $x=(e,t)=>n=>{let r=n.target.__data__;r=Array.isArray(r)?r[0]:r,n.vegaType=n.type,t.call(e._obj,n,r)},aL="aria-hidden",E3="aria-label",A3="role",k3="aria-roledescription",lL="graphics-object",S3="graphics-symbol",uL=(e,t,n)=>({[A3]:e,[k3]:t,[E3]:n||void 0}),fne=mo(["axis-domain","axis-grid","axis-label","axis-tick","axis-title","legend-band","legend-entry","legend-gradient","legend-label","legend-title","legend-symbol","title"]),XD={axis:{desc:"axis",caption:pne},legend:{desc:"legend",caption:gne},"title-text":{desc:"title",caption:e=>`Title text '${ZD(e)}'`},"title-subtitle":{desc:"subtitle",caption:e=>`Subtitle text '${ZD(e)}'`}},KD={ariaRole:A3,ariaRoleDescription:k3,description:E3};function cL(e,t){const n=t.aria===!1;if(e(aL,n||void 0),n||t.description==null)for(const r in KD)e(KD[r],void 0);else{const r=t.mark.marktype;e(E3,t.description),e(A3,t.ariaRole||(r==="group"?lL:S3)),e(k3,t.ariaRoleDescription||`${r} mark`)}}function fL(e){return e.aria===!1?{[aL]:!0}:fne[e.role]?null:XD[e.role]?hne(e,XD[e.role]):dne(e)}function dne(e){const t=e.marktype,n=t==="group"||t==="text"||e.items.some(r=>r.description!=null&&r.aria!==!1);return uL(n?lL:S3,`${t} mark container`,e.description)}function hne(e,t){try{const n=e.items[0],r=t.caption||(()=>"");return uL(t.role||S3,t.desc,n.description||r(n))}catch{return null}}function ZD(e){return Be(e.text).join(" ")}function pne(e){const t=e.datum,n=e.orient,r=t.title?dL(e):null,i=e.context,s=i.scales[t.scale].value,o=i.dataflow.locale(),a=s.type;return`${n==="left"||n==="right"?"Y":"X"}-axis`+(r?` titled '${r}'`:"")+` for a ${zd(a)?"discrete":a} scale with ${k9(o,s,e)}`}function gne(e){const t=e.datum,n=t.title?dL(e):null,r=`${t.type||""} legend`.trim(),i=t.scales,s=Object.keys(i),o=e.context,a=o.scales[i[s[0]]].value,l=o.dataflow.locale();return vne(r)+(n?` titled '${n}'`:"")+` for ${mne(s)} with ${k9(l,a,e)}`}function dL(e){try{return Be(Wt(e.items).items[0].text).join(" ")}catch{return null}}function mne(e){return e=e.map(t=>t+(t==="fill"||t==="stroke"?" color":"")),e.length<2?e[0]:e.slice(0,-1).join(", ")+" and "+Wt(e)}function vne(e){return e.length?e[0].toUpperCase()+e.slice(1):e}const hL=e=>(e+"").replace(/&/g,"&").replace(//g,">"),yne=e=>hL(e).replace(/"/g,""").replace(/\t/g," ").replace(/\n/g," ").replace(/\r/g," ");function C3(){let e="",t="",n="";const r=[],i=()=>t=n="",s=l=>{t&&(e+=`${t}>${n}`,i()),r.push(l)},o=(l,u)=>(u!=null&&(t+=` ${l}="${yne(u)}"`),a),a={open(l){s(l),t="<"+l;for(var u=arguments.length,c=new Array(u>1?u-1:0),f=1;f${n}`:"/>"):e+=``,i(),a},attr:o,text:l=>(n+=hL(l),a),toString:()=>e};return a}const pL=e=>gL(C3(),e)+"";function gL(e,t){if(e.open(t.tagName),t.hasAttributes()){const n=t.attributes,r=n.length;for(let i=0;i{c.dirty=n})),!i.zdirty){if(r.exit){o.nested&&i.items.length?(u=i.items[0],u._svg&&this._update(o,u._svg,u)):r._svg&&(u=r._svg.parentNode,u&&u.removeChild(r._svg)),r._svg=null;continue}r=o.nested?i.items[0]:r,r._update!==n&&(!r._svg||!r._svg.ownerSVGElement?(this._dirtyAll=!1,QD(r,n)):this._update(o,r._svg,r),r._update=n)}return!this._dirtyAll}mark(t,n,r,i){if(!this.isDirty(n))return n._svg;const s=this._svg,o=n.marktype,a=gs[o],l=n.interactive===!1?"none":null,u=a.tag==="g",c=e4(n,t,r,"g",s);if(o!=="group"&&i!=null&&!i.includes(o))return As(c,0),n._svg;c.setAttribute("class",Q9(n));const f=fL(n);for(const g in f)ci(c,g,f[g]);u||ci(c,"pointer-events",l),ci(c,"clip-path",n.clip?s3(this,n,n.group):null);let d=null,h=0;const p=g=>{const m=this.isDirty(g),y=e4(g,c,d,a.tag,s);m&&(this._update(a,y,g),u&&_ne(this,y,g,i)),d=y,++h};return a.nested?n.items.length&&p(n.items[0]):yo(n,p),As(c,h),c}_update(t,n,r){Xa=n,Gr=n.__values__,cL(Kp,r),t.attr(Kp,r,this);const i=Ene[t.type];i&&i.call(this,t,n,r),Xa&&this.style(Xa,r)}style(t,n){if(n!=null){for(const r in gv){let i=r==="font"?_0(n):n[r];if(i===Gr[r])continue;const s=gv[r];i==null?t.removeAttribute(s):(n3(i)&&(i=C9(i,this._defs.gradient,vL())),t.setAttribute(s,i+"")),Gr[r]=i}for(const r in mv)g1(t,mv[r],n[r])}}defs(){const t=this._svg,n=this._defs;let r=n.el,i=0;for(const s in n.gradient)r||(n.el=r=Qn(t,np+1,"defs",Jn)),i=bne(r,n.gradient[s],i);for(const s in n.clipping)r||(n.el=r=Qn(t,np+1,"defs",Jn)),i=xne(r,n.clipping[s],i);r&&(i===0?(t.removeChild(r),n.el=null):As(r,i))}_clearDefs(){const t=this._defs;t.gradient={},t.clipping={}}}function QD(e,t){for(;e&&e.dirty!==t;e=e.mark.group)if(e.dirty=t,e.mark&&e.mark.dirty!==t)e.mark.dirty=t;else return}function bne(e,t,n){let r,i,s;if(t.gradient==="radial"){let o=Qn(e,n++,"pattern",Jn);jl(o,{id:iv+t.id,viewBox:"0,0,1,1",width:"100%",height:"100%",preserveAspectRatio:"xMidYMid slice"}),o=Qn(o,0,"rect",Jn),jl(o,{width:1,height:1,fill:`url(${vL()}#${t.id})`}),e=Qn(e,n++,"radialGradient",Jn),jl(e,{id:t.id,fx:t.x1,fy:t.y1,fr:t.r1,cx:t.x2,cy:t.y2,r:t.r2})}else e=Qn(e,n++,"linearGradient",Jn),jl(e,{id:t.id,x1:t.x1,x2:t.x2,y1:t.y1,y2:t.y2});for(r=0,i=t.stops.length;r{i=e.mark(t,o,i,r),++s}),As(t,1+s)}function e4(e,t,n,r,i){let s=e._svg,o;if(!s&&(o=t.ownerDocument,s=zl(o,r,Jn),e._svg=s,e.mark&&(s.__data__=e,s.__values__={fill:"default"},r==="g"))){const a=zl(o,"path",Jn);s.appendChild(a),a.__data__=e;const l=zl(o,"g",Jn);s.appendChild(l),l.__data__=e;const u=zl(o,"path",Jn);s.appendChild(u),u.__data__=e,u.__values__={fill:"default"}}return(s.ownerSVGElement!==i||wne(s,n))&&t.insertBefore(s,n?n.nextSibling:t.firstChild),s}function wne(e,t){return e.parentNode&&e.parentNode.childNodes.length>1&&e.previousSibling!=t}let Xa=null,Gr=null;const Ene={group(e,t,n){const r=Xa=t.childNodes[2];Gr=r.__values__,e.foreground(Kp,n,this),Gr=t.__values__,Xa=t.childNodes[1],e.content(Kp,n,this);const i=Xa=t.childNodes[0];e.background(Kp,n,this);const s=n.mark.interactive===!1?"none":null;if(s!==Gr.events&&(ci(r,"pointer-events",s),ci(i,"pointer-events",s),Gr.events=s),n.strokeForeground&&n.stroke){const o=n.fill;ci(r,"display",null),this.style(i,n),ci(i,"stroke",null),o&&(n.fill=null),Gr=r.__values__,this.style(r,n),o&&(n.fill=o),Xa=null}else ci(r,"display","none")},image(e,t,n){n.smooth===!1?(g1(t,"image-rendering","optimizeSpeed"),g1(t,"image-rendering","pixelated")):g1(t,"image-rendering",null)},text(e,t,n){const r=x0(n);let i,s,o,a;de(r)?(s=r.map(l=>fu(n,l)),i=s.join(` +`),i!==Gr.text&&(As(t,0),o=t.ownerDocument,a=cu(n),s.forEach((l,u)=>{const c=zl(o,"tspan",Jn);c.__data__=n,c.textContent=l,u&&(c.setAttribute("x",0),c.setAttribute("dy",a)),t.appendChild(c)}),Gr.text=i)):(s=fu(n,r),s!==Gr.text&&(t.textContent=s,Gr.text=s)),ci(t,"font-family",_0(n)),ci(t,"font-size",xa(n)+"px"),ci(t,"font-style",n.fontStyle),ci(t,"font-variant",n.fontVariant),ci(t,"font-weight",n.fontWeight)}};function Kp(e,t,n){t!==Gr[e]&&(n?Ane(Xa,e,t,n):ci(Xa,e,t),Gr[e]=t)}function g1(e,t,n){n!==Gr[t]&&(n==null?e.style.removeProperty(t):e.style.setProperty(t,n+""),Gr[t]=n)}function jl(e,t){for(const n in t)ci(e,n,t[n])}function ci(e,t,n){n!=null?e.setAttribute(t,n):e.removeAttribute(t)}function Ane(e,t,n,r){n!=null?e.setAttributeNS(r,t,n):e.removeAttributeNS(r,t)}function vL(){let e;return typeof window>"u"?"":(e=window.location).hash?e.href.slice(0,-e.hash.length):e.href}class yL extends w0{constructor(t){super(t),this._text=null,this._defs={gradient:{},clipping:{}}}svg(){return this._text}_render(t){const n=C3();n.open("svg",Mt({},wg,{class:"marks",width:this._width*this._scale,height:this._height*this._scale,viewBox:`0 0 ${this._width} ${this._height}`}));const r=this._bgcolor;return r&&r!=="transparent"&&r!=="none"&&n.open("rect",{width:this._width,height:this._height,fill:r}).close(),n.open("g",mL,{transform:"translate("+this._origin+")"}),this.mark(n,t),n.close(),this.defs(n),this._text=n.close()+"",this}mark(t,n){const r=gs[n.marktype],i=r.tag,s=[cL,r.attr];t.open("g",{class:Q9(n),"clip-path":n.clip?s3(this,n,n.group):null},fL(n),{"pointer-events":i!=="g"&&n.interactive===!1?"none":null});const o=a=>{const l=this.href(a);if(l&&t.open("a",l),t.open(i,this.attr(n,a,s,i!=="g"?i:null)),i==="text"){const u=x0(a);if(de(u)){const c={x:0,dy:cu(a)};for(let f=0;fthis.mark(t,d)),t.close(),u&&f?(c&&(a.fill=null),a.stroke=f,t.open("path",this.attr(n,a,r.foreground,"bgrect")).close(),c&&(a.fill=c)):t.open("path",this.attr(n,a,r.foreground,"bgfore")).close()}t.close(),l&&t.close()};return r.nested?n.items&&n.items.length&&o(n.items[0]):yo(n,o),t.close()}href(t){const n=t.href;let r;if(n){if(r=this._hrefs&&this._hrefs[n])return r;this.sanitizeURL(n).then(i=>{i["xlink:href"]=i.href,i.href=null,(this._hrefs||(this._hrefs={}))[n]=i})}return null}attr(t,n,r,i){const s={},o=(a,l,u,c)=>{s[c||a]=l};return Array.isArray(r)?r.forEach(a=>a(o,n,this)):r(o,n,this),i&&kne(s,n,t,i,this._defs),s}defs(t){const n=this._defs.gradient,r=this._defs.clipping;if(Object.keys(n).length+Object.keys(r).length!==0){t.open("defs");for(const s in n){const o=n[s],a=o.stops;o.gradient==="radial"?(t.open("pattern",{id:iv+s,viewBox:"0,0,1,1",width:"100%",height:"100%",preserveAspectRatio:"xMidYMid slice"}),t.open("rect",{width:"1",height:"1",fill:"url(#"+s+")"}).close(),t.close(),t.open("radialGradient",{id:s,fx:o.x1,fy:o.y1,fr:o.r1,cx:o.x2,cy:o.y2,r:o.r2})):t.open("linearGradient",{id:s,x1:o.x1,x2:o.x2,y1:o.y1,y2:o.y2});for(let l=0;l!eo.svgMarkTypes.includes(s));this._svgRenderer.render(t,eo.svgMarkTypes),this._canvasRenderer.render(t,i)}resize(t,n,r,i){return super.resize(t,n,r,i),this._svgRenderer.resize(t,n,r,i),this._canvasRenderer.resize(t,n,r,i),this}background(t){return eo.svgOnTop?this._canvasRenderer.background(t):this._svgRenderer.background(t),this}}class bL extends E0{constructor(t,n){super(t,n)}initialize(t,n,r){const i=Qn(Qn(t,0,"div"),eo.svgOnTop?0:1,"div");return super.initialize(i,n,r)}}const xL="canvas",_L="hybrid",wL="png",EL="svg",AL="none",Ul={Canvas:xL,PNG:wL,SVG:EL,Hybrid:_L,None:AL},Wc={};Wc[xL]=Wc[wL]={renderer:pv,headless:pv,handler:E0};Wc[EL]={renderer:$3,headless:yL,handler:oL};Wc[_L]={renderer:tE,headless:tE,handler:bL};Wc[AL]={};function yb(e,t){return e=String(e||"").toLowerCase(),arguments.length>1?(Wc[e]=t,this):Wc[e]}function kL(e,t,n){const r=[],i=new Vn().union(t),s=e.marktype;return s?SL(e,i,n,r):s==="group"?CL(e,i,n,r):le("Intersect scene must be mark node or group item.")}function SL(e,t,n,r){if(Cne(e,t,n)){const i=e.items,s=e.marktype,o=i.length;let a=0;if(s==="group")for(;a=0;s--)if(n[s]!=r[s])return!1;for(s=n.length-1;s>=0;s--)if(i=n[s],!F3(e[i],t[i],i))return!1;return typeof e==typeof t}function Dne(){N9(),eee()}const Wd="top",so="left",ao="right",du="bottom",Mne="top-left",Tne="top-right",Rne="bottom-left",Nne="bottom-right",D3="start",nE="middle",fi="end",One="x",Lne="y",bb="group",M3="axis",T3="title",Ine="frame",Pne="scope",R3="legend",ML="row-header",TL="row-footer",RL="row-title",NL="column-header",OL="column-footer",LL="column-title",Bne="padding",zne="symbol",IL="fit",PL="fit-x",BL="fit-y",jne="pad",N3="none",pm="all",rE="each",O3="flush",ql="column",Wl="row";function zL(e){ie.call(this,null,e)}Me(zL,ie,{transform(e,t){const n=t.dataflow,r=e.mark,i=r.marktype,s=gs[i],o=s.bound;let a=r.bounds,l;if(s.nested)r.items.length&&n.dirty(r.items[0]),a=gm(r,o),r.items.forEach(u=>{u.bounds.clear().union(a)});else if(i===bb||e.modified())switch(t.visit(t.MOD,u=>n.dirty(u)),a.clear(),r.items.forEach(u=>a.union(gm(u,o))),r.role){case M3:case R3:case T3:t.reflow()}else l=t.changed(t.REM),t.visit(t.ADD,u=>{a.union(gm(u,o))}),t.visit(t.MOD,u=>{l=l||a.alignsWith(u.bounds),n.dirty(u),a.union(gm(u,o))}),l&&(a.clear(),r.items.forEach(u=>a.union(u.bounds)));return FL(r),t.modifies("bounds")}});function gm(e,t,n){return t(e.bounds.clear(),e,n)}const t4=":vega_identifier:";function L3(e){ie.call(this,0,e)}L3.Definition={type:"Identifier",metadata:{modifies:!0},params:[{name:"as",type:"string",required:!0}]};Me(L3,ie,{transform(e,t){const n=Une(t.dataflow),r=e.as;let i=n.value;return t.visit(t.ADD,s=>s[r]=s[r]||++i),n.set(this.value=i),t}});function Une(e){return e._signals[t4]||(e._signals[t4]=e.add(0))}function jL(e){ie.call(this,null,e)}Me(jL,ie,{transform(e,t){let n=this.value;n||(n=t.dataflow.scenegraph().mark(e.markdef,qne(e),e.index),n.group.context=e.context,e.context.group||(e.context.group=n.group),n.source=this.source,n.clip=e.clip,n.interactive=e.interactive,this.value=n);const r=n.marktype===bb?cb:ub;return t.visit(t.ADD,i=>r.call(i,n)),(e.modified("clip")||e.modified("interactive"))&&(n.clip=e.clip,n.interactive=!!e.interactive,n.zdirty=!0,t.reflow()),n.items=t.source,t}});function qne(e){const t=e.groups,n=e.parent;return t&&t.size===1?t.get(Object.keys(t.object)[0]):t&&n?t.lookup(n):null}function UL(e){ie.call(this,null,e)}const n4={parity:e=>e.filter((t,n)=>n%2?t.opacity=0:1),greedy:(e,t)=>{let n;return e.filter((r,i)=>!i||!qL(n.bounds,r.bounds,t)?(n=r,1):r.opacity=0)}},qL=(e,t,n)=>n>Math.max(t.x1-e.x2,e.x1-t.x2,t.y1-e.y2,e.y1-t.y2),r4=(e,t)=>{for(var n=1,r=e.length,i=e[0].bounds,s;n{const t=e.bounds;return t.width()>1&&t.height()>1},Hne=(e,t,n)=>{var r=e.range(),i=new Vn;return t===Wd||t===du?i.set(r[0],-1/0,r[1],1/0):i.set(-1/0,r[0],1/0,r[1]),i.expand(n||1),s=>i.encloses(s.bounds)},i4=e=>(e.forEach(t=>t.opacity=1),e),s4=(e,t)=>e.reflow(t.modified()).modifies("opacity");Me(UL,ie,{transform(e,t){const n=n4[e.method]||n4.parity,r=e.separation||0;let i=t.materialize(t.SOURCE).source,s,o;if(!i||!i.length)return;if(!e.method)return e.modified("method")&&(i4(i),t=s4(t,e)),t;if(i=i.filter(Wne),!i.length)return;if(e.sort&&(i=i.slice().sort(e.sort)),s=i4(i),t=s4(t,e),s.length>=3&&r4(s,r)){do s=n(s,r);while(s.length>=3&&r4(s,r));s.length<3&&!Wt(i).opacity&&(s.length>1&&(Wt(s).opacity=0),Wt(i).opacity=1)}e.boundScale&&e.boundTolerance>=0&&(o=Hne(e.boundScale,e.boundOrient,+e.boundTolerance),i.forEach(l=>{o(l)||(l.opacity=0)}));const a=s[0].mark.bounds.clear();return i.forEach(l=>{l.opacity&&a.union(l.bounds)}),t}});function WL(e){ie.call(this,null,e)}Me(WL,ie,{transform(e,t){const n=t.dataflow;if(t.visit(t.ALL,r=>n.dirty(r)),t.fields&&t.fields.zindex){const r=t.source&&t.source[0];r&&(r.mark.zdirty=!0)}}});const Wr=new Vn;function Qf(e,t,n){return e[t]===n?0:(e[t]=n,1)}function Gne(e){var t=e.items[0].orient;return t===so||t===ao}function Yne(e){let t=+e.grid;return[e.ticks?t++:-1,e.labels?t++:-1,t+ +e.domain]}function Vne(e,t,n,r){var i=t.items[0],s=i.datum,o=i.translate!=null?i.translate:.5,a=i.orient,l=Yne(s),u=i.range,c=i.offset,f=i.position,d=i.minExtent,h=i.maxExtent,p=s.title&&i.items[l[2]].items[0],g=i.titlePadding,m=i.bounds,y=p&&y3(p),b=0,x=0,_,w;switch(Wr.clear().union(m),m.clear(),(_=l[0])>-1&&m.union(i.items[_].bounds),(_=l[1])>-1&&m.union(i.items[_].bounds),a){case Wd:b=f||0,x=-c,w=Math.max(d,Math.min(h,-m.y1)),m.add(0,-w).add(u,0),p&&mm(e,p,w,g,y,0,-1,m);break;case so:b=-c,x=f||0,w=Math.max(d,Math.min(h,-m.x1)),m.add(-w,0).add(0,u),p&&mm(e,p,w,g,y,1,-1,m);break;case ao:b=n+c,x=f||0,w=Math.max(d,Math.min(h,m.x2)),m.add(0,0).add(w,u),p&&mm(e,p,w,g,y,1,1,m);break;case du:b=f||0,x=r+c,w=Math.max(d,Math.min(h,m.y2)),m.add(0,0).add(u,w),p&&mm(e,p,w,g,0,0,1,m);break;default:b=i.x,x=i.y}return gl(m.translate(b,x),i),Qf(i,"x",b+o)|Qf(i,"y",x+o)&&(i.bounds=Wr,e.dirty(i),i.bounds=m,e.dirty(i)),i.mark.bounds.clear().union(m)}function mm(e,t,n,r,i,s,o,a){const l=t.bounds;if(t.auto){const u=o*(n+i+r);let c=0,f=0;e.dirty(t),s?c=(t.x||0)-(t.x=u):f=(t.y||0)-(t.y=u),t.mark.bounds.clear().union(l.translate(-c,-f)),e.dirty(t)}a.union(l)}const o4=(e,t)=>Math.floor(Math.min(e,t)),a4=(e,t)=>Math.ceil(Math.max(e,t));function Xne(e){var t=e.items,n=t.length,r=0,i,s;const o={marks:[],rowheaders:[],rowfooters:[],colheaders:[],colfooters:[],rowtitle:null,coltitle:null};for(;r1)for(E=0;E0&&(x[E]+=T/2);if(a&&xn(n.center,Wl)&&c!==1)for(E=0;E0&&(_[E]+=F/2);for(E=0;Ei&&(e.warn("Grid headers exceed limit: "+i),t=t.slice(0,i)),g+=s,b=0,_=t.length;b<_;++b)e.dirty(t[b]),t[b].mark.bounds.clear();for(y=c,b=0,_=t.length;b<_;++b,y+=f){for(A=t[b],w=A.mark.bounds,x=y;x>=0&&(E=n[x])==null;x-=d);a?(k=h==null?E.x:Math.round(E.bounds.x1+h*E.bounds.width()),S=g):(k=g,S=h==null?E.y:Math.round(E.bounds.y1+h*E.bounds.height())),w.union(A.bounds.translate(k-(A.x||0),S-(A.y||0))),A.x=k,A.y=S,e.dirty(A),m=o(m,w[u])}return m}function u4(e,t,n,r,i,s){if(t){e.dirty(t);var o=n,a=n;r?o=Math.round(i.x1+s*i.width()):a=Math.round(i.y1+s*i.height()),t.bounds.translate(o-(t.x||0),a-(t.y||0)),t.mark.bounds.clear().union(t.bounds),t.x=o,t.y=a,e.dirty(t)}}function tre(e,t){const n=e[t]||{};return(r,i)=>n[r]!=null?n[r]:e[r]!=null?e[r]:i}function nre(e,t){let n=-1/0;return e.forEach(r=>{r.offset!=null&&(n=Math.max(n,r.offset))}),n>-1/0?n:t}function rre(e,t,n,r,i,s,o){const a=tre(n,t),l=nre(e,a("offset",0)),u=a("anchor",D3),c=u===fi?1:u===nE?.5:0,f={align:rE,bounds:a("bounds",O3),columns:a("direction")==="vertical"?1:e.length,padding:a("margin",8),center:a("center"),nodirty:!0};switch(t){case so:f.anchor={x:Math.floor(r.x1)-l,column:fi,y:c*(o||r.height()+2*r.y1),row:u};break;case ao:f.anchor={x:Math.ceil(r.x2)+l,y:c*(o||r.height()+2*r.y1),row:u};break;case Wd:f.anchor={y:Math.floor(i.y1)-l,row:fi,x:c*(s||i.width()+2*i.x1),column:u};break;case du:f.anchor={y:Math.ceil(i.y2)+l,x:c*(s||i.width()+2*i.x1),column:u};break;case Mne:f.anchor={x:l,y:l};break;case Tne:f.anchor={x:s-l,y:l,column:fi};break;case Rne:f.anchor={x:l,y:o-l,row:fi};break;case Nne:f.anchor={x:s-l,y:o-l,column:fi,row:fi};break}return f}function ire(e,t){var n=t.items[0],r=n.datum,i=n.orient,s=n.bounds,o=n.x,a=n.y,l,u;return n._bounds?n._bounds.clear().union(s):n._bounds=s.clone(),s.clear(),ore(e,n,n.items[0].items[0]),s=sre(n,s),l=2*n.padding,u=2*n.padding,s.empty()||(l=Math.ceil(s.width()+l),u=Math.ceil(s.height()+u)),r.type===zne&&are(n.items[0].items[0].items[0].items),i!==N3&&(n.x=o=0,n.y=a=0),n.width=l,n.height=u,gl(s.set(o,a,o+l,a+u),n),n.mark.bounds.clear().union(s),n}function sre(e,t){return e.items.forEach(n=>t.union(n.bounds)),t.x1=e.padding,t.y1=e.padding,t}function ore(e,t,n){var r=t.padding,i=r-n.x,s=r-n.y;if(!t.datum.title)(i||s)&&rp(e,n,i,s);else{var o=t.items[1].items[0],a=o.anchor,l=t.titlePadding||0,u=r-o.x,c=r-o.y;switch(o.orient){case so:i+=Math.ceil(o.bounds.width())+l;break;case ao:case du:break;default:s+=o.bounds.height()+l}switch((i||s)&&rp(e,n,i,s),o.orient){case so:c+=Of(t,n,o,a,1,1);break;case ao:u+=Of(t,n,o,fi,0,0)+l,c+=Of(t,n,o,a,1,1);break;case du:u+=Of(t,n,o,a,0,0),c+=Of(t,n,o,fi,-1,0,1)+l;break;default:u+=Of(t,n,o,a,0,0)}(u||c)&&rp(e,o,u,c),(u=Math.round(o.bounds.x1-r))<0&&(rp(e,n,-u,0),rp(e,o,-u,0))}}function Of(e,t,n,r,i,s,o){const a=e.datum.type!=="symbol",l=n.datum.vgrad,u=a&&(s||!l)&&!o?t.items[0]:t,c=u.bounds[i?"y2":"x2"]-e.padding,f=l&&s?c:0,d=l&&s?0:c,h=i<=0?0:y3(n);return Math.round(r===D3?f:r===fi?d-h:.5*(c-h))}function rp(e,t,n,r){t.x+=n,t.y+=r,t.bounds.translate(n,r),t.mark.bounds.translate(n,r),e.dirty(t)}function are(e){const t=e.reduce((n,r)=>(n[r.column]=Math.max(r.bounds.x2-r.x,n[r.column]||0),n),{});e.forEach(n=>{n.width=t[n.column],n.height=n.bounds.y2-n.y})}function lre(e,t,n,r,i){var s=t.items[0],o=s.frame,a=s.orient,l=s.anchor,u=s.offset,c=s.padding,f=s.items[0].items[0],d=s.items[1]&&s.items[1].items[0],h=a===so||a===ao?r:n,p=0,g=0,m=0,y=0,b=0,x;if(o!==bb?a===so?(p=i.y2,h=i.y1):a===ao?(p=i.y1,h=i.y2):(p=i.x1,h=i.x2):a===so&&(p=r,h=0),x=l===D3?p:l===fi?h:(p+h)/2,d&&d.text){switch(a){case Wd:case du:b=f.bounds.height()+c;break;case so:y=f.bounds.width()+c;break;case ao:y=-f.bounds.width()-c;break}Wr.clear().union(d.bounds),Wr.translate(y-(d.x||0),b-(d.y||0)),Qf(d,"x",y)|Qf(d,"y",b)&&(e.dirty(d),d.bounds.clear().union(Wr),d.mark.bounds.clear().union(Wr),e.dirty(d)),Wr.clear().union(d.bounds)}else Wr.clear();switch(Wr.union(f.bounds),a){case Wd:g=x,m=i.y1-Wr.height()-u;break;case so:g=i.x1-Wr.width()-u,m=x;break;case ao:g=i.x2+Wr.width()+u,m=x;break;case du:g=x,m=i.y2+u;break;default:g=s.x,m=s.y}return Qf(s,"x",g)|Qf(s,"y",m)&&(Wr.translate(g,m),e.dirty(s),s.bounds.clear().union(Wr),t.bounds.clear().union(Wr),e.dirty(s)),s.bounds}function GL(e){ie.call(this,null,e)}Me(GL,ie,{transform(e,t){const n=t.dataflow;return e.mark.items.forEach(r=>{e.layout&&Jne(n,r,e.layout),cre(n,r,e)}),ure(e.mark.group)?t.reflow():t}});function ure(e){return e&&e.mark.role!=="legend-entry"}function cre(e,t,n){var r=t.items,i=Math.max(0,t.width||0),s=Math.max(0,t.height||0),o=new Vn().set(0,0,i,s),a=o.clone(),l=o.clone(),u=[],c,f,d,h,p,g;for(p=0,g=r.length;p{d=y.orient||ao,d!==N3&&(m[d]||(m[d]=[])).push(y)});for(const y in m){const b=m[y];HL(e,b,rre(b,y,n.legends,a,l,i,s))}u.forEach(y=>{const b=y.bounds;if(b.equals(y._bounds)||(y.bounds=y._bounds,e.dirty(y),y.bounds=b,e.dirty(y)),n.autosize&&(n.autosize.type===IL||n.autosize.type===PL||n.autosize.type===BL))switch(y.orient){case so:case ao:o.add(b.x1,0).add(b.x2,0);break;case Wd:case du:o.add(0,b.y1).add(0,b.y2)}else o.union(b)})}o.union(a).union(l),c&&o.union(lre(e,c,i,s,o)),t.clip&&o.set(0,0,t.width||0,t.height||0),fre(e,t,o,n)}function fre(e,t,n,r){const i=r.autosize||{},s=i.type;if(e._autosize<1||!s)return;let o=e._width,a=e._height,l=Math.max(0,t.width||0),u=Math.max(0,Math.ceil(-n.x1)),c=Math.max(0,t.height||0),f=Math.max(0,Math.ceil(-n.y1));const d=Math.max(0,Math.ceil(n.x2-l)),h=Math.max(0,Math.ceil(n.y2-c));if(i.contains===Bne){const p=e.padding();o-=p.left+p.right,a-=p.top+p.bottom}s===N3?(u=0,f=0,l=o,c=a):s===IL?(l=Math.max(0,o-u-d),c=Math.max(0,a-f-h)):s===PL?(l=Math.max(0,o-u-d),a=c+f+h):s===BL?(o=l+u+d,c=Math.max(0,a-f-h)):s===jne&&(o=l+u+d,a=c+f+h),e._resizeView(o,a,l,c,[u,f],i.resize)}const dre=Object.freeze(Object.defineProperty({__proto__:null,bound:zL,identifier:L3,mark:jL,overlap:UL,render:WL,viewlayout:GL},Symbol.toStringTag,{value:"Module"}));function YL(e){ie.call(this,null,e)}Me(YL,ie,{transform(e,t){if(this.value&&!e.modified())return t.StopPropagation;var n=t.dataflow.locale(),r=t.fork(t.NO_SOURCE|t.NO_FIELDS),i=this.value,s=e.scale,o=e.count==null?e.values?e.values.length:10:e.count,a=e3(s,o,e.minstep),l=e.format||x9(n,s,a,e.formatSpecifier,e.formatType,!!e.values),u=e.values?b9(s,e.values,a):t3(s,a);return i&&(r.rem=i),i=u.map((c,f)=>Zt({index:f/(u.length-1||1),value:c,label:l(c)})),e.extra&&i.length&&i.push(Zt({index:-1,extra:{value:i[0].value},label:""})),r.source=i,r.add=i,this.value=i,r}});function VL(e){ie.call(this,null,e)}function hre(){return Zt({})}function pre(e){const t=bh().test(n=>n.exit);return t.lookup=n=>t.get(e(n)),t}Me(VL,ie,{transform(e,t){var n=t.dataflow,r=t.fork(t.NO_SOURCE|t.NO_FIELDS),i=e.item||hre,s=e.key||ot,o=this.value;return de(r.encode)&&(r.encode=null),o&&(e.modified("key")||t.modified(s))&&le("DataJoin does not support modified key function or fields."),o||(t=t.addAll(),this.value=o=pre(s)),t.visit(t.ADD,a=>{const l=s(a);let u=o.get(l);u?u.exit?(o.empty--,r.add.push(u)):r.mod.push(u):(u=i(a),o.set(l,u),r.add.push(u)),u.datum=a,u.exit=!1}),t.visit(t.MOD,a=>{const l=s(a),u=o.get(l);u&&(u.datum=a,r.mod.push(u))}),t.visit(t.REM,a=>{const l=s(a),u=o.get(l);a===u.datum&&!u.exit&&(r.rem.push(u),u.exit=!0,++o.empty)}),t.changed(t.ADD_MOD)&&r.modifies("datum"),(t.clean()||e.clean&&o.empty>n.cleanThreshold)&&n.runAfter(o.clean),r}});function XL(e){ie.call(this,null,e)}Me(XL,ie,{transform(e,t){var n=t.fork(t.ADD_REM),r=e.mod||!1,i=e.encoders,s=t.encode;if(de(s))if(n.changed()||s.every(f=>i[f]))s=s[0],n.encode=null;else return t.StopPropagation;var o=s==="enter",a=i.update||Cl,l=i.enter||Cl,u=i.exit||Cl,c=(s&&!o?i[s]:a)||Cl;if(t.changed(t.ADD)&&(t.visit(t.ADD,f=>{l(f,e),a(f,e)}),n.modifies(l.output),n.modifies(a.output),c!==Cl&&c!==a&&(t.visit(t.ADD,f=>{c(f,e)}),n.modifies(c.output))),t.changed(t.REM)&&u!==Cl&&(t.visit(t.REM,f=>{u(f,e)}),n.modifies(u.output)),o||c!==Cl){const f=t.MOD|(e.modified()?t.REFLOW:0);o?(t.visit(f,d=>{const h=l(d,e)||r;(c(d,e)||h)&&n.mod.push(d)}),n.mod.length&&n.modifies(l.output)):t.visit(f,d=>{(c(d,e)||r)&&n.mod.push(d)}),n.mod.length&&n.modifies(c.output)}return n.changed()?n:t.StopPropagation}});function KL(e){ie.call(this,[],e)}Me(KL,ie,{transform(e,t){if(this.value!=null&&!e.modified())return t.StopPropagation;var n=t.dataflow.locale(),r=t.fork(t.NO_SOURCE|t.NO_FIELDS),i=this.value,s=e.type||a1,o=e.scale,a=+e.limit,l=e3(o,e.count==null?5:e.count,e.minstep),u=!!e.values||s===a1,c=e.format||A9(n,o,l,s,e.formatSpecifier,e.formatType,u),f=e.values||E9(o,l),d,h,p,g,m;return i&&(r.rem=i),s===a1?(a&&f.length>a?(t.dataflow.warn("Symbol legend count exceeds limit, filtering items."),i=f.slice(0,a-1),m=!0):i=f,Tt(p=e.size)?(!e.values&&o(i[0])===0&&(i=i.slice(1)),g=i.reduce((y,b)=>Math.max(y,p(b,e)),0)):p=ri(g=p||8),i=i.map((y,b)=>Zt({index:b,label:c(y,b,i),value:y,offset:g,size:p(y,e)})),m&&(m=f[i.length],i.push(Zt({index:i.length,label:`…${f.length-i.length} entries`,value:m,offset:g,size:p(m,e)})))):s===jQ?(d=o.domain(),h=m9(o,d[0],Wt(d)),f.length<3&&!e.values&&d[0]!==Wt(d)&&(f=[d[0],Wt(d)]),i=f.map((y,b)=>Zt({index:b,label:c(y,b,f),value:y,perc:h(y)}))):(p=f.length-1,h=JQ(o),i=f.map((y,b)=>Zt({index:b,label:c(y,b,f),value:y,perc:b?h(y):0,perc2:b===p?1:h(f[b+1])}))),r.source=i,r.add=i,this.value=i,r}});const gre=e=>e.source.x,mre=e=>e.source.y,vre=e=>e.target.x,yre=e=>e.target.y;function I3(e){ie.call(this,{},e)}I3.Definition={type:"LinkPath",metadata:{modifies:!0},params:[{name:"sourceX",type:"field",default:"source.x"},{name:"sourceY",type:"field",default:"source.y"},{name:"targetX",type:"field",default:"target.x"},{name:"targetY",type:"field",default:"target.y"},{name:"orient",type:"enum",default:"vertical",values:["horizontal","vertical","radial"]},{name:"shape",type:"enum",default:"line",values:["line","arc","curve","diagonal","orthogonal"]},{name:"require",type:"signal"},{name:"as",type:"string",default:"path"}]};Me(I3,ie,{transform(e,t){var n=e.sourceX||gre,r=e.sourceY||mre,i=e.targetX||vre,s=e.targetY||yre,o=e.as||"path",a=e.orient||"vertical",l=e.shape||"line",u=c4.get(l+"-"+a)||c4.get(l);return u||le("LinkPath unsupported type: "+e.shape+(e.orient?"-"+e.orient:"")),t.visit(t.SOURCE,c=>{c[o]=u(n(c),r(c),i(c),s(c))}),t.reflow(e.modified()).modifies(o)}});const ZL=(e,t,n,r)=>"M"+e+","+t+"L"+n+","+r,bre=(e,t,n,r)=>ZL(t*Math.cos(e),t*Math.sin(e),r*Math.cos(n),r*Math.sin(n)),JL=(e,t,n,r)=>{var i=n-e,s=r-t,o=Math.hypot(i,s)/2,a=180*Math.atan2(s,i)/Math.PI;return"M"+e+","+t+"A"+o+","+o+" "+a+" 0 1 "+n+","+r},xre=(e,t,n,r)=>JL(t*Math.cos(e),t*Math.sin(e),r*Math.cos(n),r*Math.sin(n)),QL=(e,t,n,r)=>{const i=n-e,s=r-t,o=.2*(i+s),a=.2*(s-i);return"M"+e+","+t+"C"+(e+o)+","+(t+a)+" "+(n+a)+","+(r-o)+" "+n+","+r},_re=(e,t,n,r)=>QL(t*Math.cos(e),t*Math.sin(e),r*Math.cos(n),r*Math.sin(n)),wre=(e,t,n,r)=>"M"+e+","+t+"V"+r+"H"+n,Ere=(e,t,n,r)=>"M"+e+","+t+"H"+n+"V"+r,Are=(e,t,n,r)=>{const i=Math.cos(e),s=Math.sin(e),o=Math.cos(n),a=Math.sin(n),l=Math.abs(n-e)>Math.PI?n<=e:n>e;return"M"+t*i+","+t*s+"A"+t+","+t+" 0 0,"+(l?1:0)+" "+t*o+","+t*a+"L"+r*o+","+r*a},kre=(e,t,n,r)=>{const i=(e+n)/2;return"M"+e+","+t+"C"+i+","+t+" "+i+","+r+" "+n+","+r},Sre=(e,t,n,r)=>{const i=(t+r)/2;return"M"+e+","+t+"C"+e+","+i+" "+n+","+i+" "+n+","+r},Cre=(e,t,n,r)=>{const i=Math.cos(e),s=Math.sin(e),o=Math.cos(n),a=Math.sin(n),l=(t+r)/2;return"M"+t*i+","+t*s+"C"+l*i+","+l*s+" "+l*o+","+l*a+" "+r*o+","+r*a},c4=bh({line:ZL,"line-radial":bre,arc:JL,"arc-radial":xre,curve:QL,"curve-radial":_re,"orthogonal-horizontal":wre,"orthogonal-vertical":Ere,"orthogonal-radial":Are,"diagonal-horizontal":kre,"diagonal-vertical":Sre,"diagonal-radial":Cre});function P3(e){ie.call(this,null,e)}P3.Definition={type:"Pie",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"startAngle",type:"number",default:0},{name:"endAngle",type:"number",default:6.283185307179586},{name:"sort",type:"boolean",default:!1},{name:"as",type:"string",array:!0,length:2,default:["startAngle","endAngle"]}]};Me(P3,ie,{transform(e,t){var n=e.as||["startAngle","endAngle"],r=n[0],i=n[1],s=e.field||gh,o=e.startAngle||0,a=e.endAngle!=null?e.endAngle:2*Math.PI,l=t.source,u=l.map(s),c=u.length,f=o,d=(a-o)/pN(u),h=ss(c),p,g,m;for(e.sort&&h.sort((y,b)=>u[y]-u[b]),p=0;p-1)return r;var i=t.domain,s=e.type,o=t.zero||t.zero===void 0&&Fre(e),a,l;if(!i)return 0;if((o||t.domainMin!=null||t.domainMax!=null||t.domainMid!=null)&&(a=(i=i.slice()).length-1||1,o&&(i[0]>0&&(i[0]=0),i[a]<0&&(i[a]=0)),t.domainMin!=null&&(i[0]=t.domainMin),t.domainMax!=null&&(i[a]=t.domainMax),t.domainMid!=null)){l=t.domainMid;const u=l>i[a]?a+1:li+(s<0?-1:s>0?1:0),0));r!==t.length&&n.warn("Log scale domain includes zero: "+$e(t))}return t}function Lre(e,t,n){let r=t.bins;if(r&&!de(r)){const i=e.domain(),s=i[0],o=Wt(i),a=r.step;let l=r.start==null?s:r.start,u=r.stop==null?o:r.stop;a||le("Scale bins parameter missing step property."),lo&&(u=a*Math.floor(o/a)),r=ss(l,u+a/2,a)}return r?e.bins=r:e.bins&&delete e.bins,e.type===VS&&(r?!t.domain&&!t.domainRaw&&(e.domain(r),n=r.length):e.bins=e.domain()),n}function Ire(e,t,n){var r=e.type,i=t.round||!1,s=t.range;if(t.rangeStep!=null)s=Pre(r,t,n);else if(t.scheme&&(s=Bre(r,t,n),Tt(s))){if(e.interpolator)return e.interpolator(s);le(`Scale type ${r} does not support interpolating color schemes.`)}if(s&&d9(r))return e.interpolator(ab(iE(s,t.reverse),t.interpolate,t.interpolateGamma));s&&t.interpolate&&e.interpolate?e.interpolate(JS(t.interpolate,t.interpolateGamma)):Tt(e.round)?e.round(i):Tt(e.rangeRound)&&e.interpolate(i?u0:Su),s&&e.range(iE(s,t.reverse))}function Pre(e,t,n){e!==s9&&e!==qw&&le("Only band and point scales support rangeStep.");var r=(t.paddingOuter!=null?t.paddingOuter:t.padding)||0,i=e===qw?1:(t.paddingInner!=null?t.paddingInner:t.padding)||0;return[0,t.rangeStep*GS(n,i,r)]}function Bre(e,t,n){var r=t.schemeExtent,i,s;return de(t.scheme)?s=ab(t.scheme,t.interpolate,t.interpolateGamma):(i=t.scheme.toLowerCase(),s=QS(i),s||le(`Unrecognized scheme name: ${t.scheme}`)),n=e===ob?n+1:e===VS?n-1:e===Bd||e===sb?+t.schemeCount||$re:n,d9(e)?f4(s,r,t.reverse):Tt(s)?g9(f4(s,r),n):e===YS?s:s.slice(0,n)}function f4(e,t,n){return Tt(e)&&(t||n)?p9(e,iE(t||[0,1],n)):e}function iE(e,t){return t?e.slice().reverse():e}function rI(e){ie.call(this,null,e)}Me(rI,ie,{transform(e,t){const n=e.modified("sort")||t.changed(t.ADD)||t.modified(e.sort.fields)||t.modified("datum");return n&&t.source.sort(pf(e.sort)),this.modified(n),t}});const d4="zero",iI="center",sI="normalize",oI=["y0","y1"];function B3(e){ie.call(this,null,e)}B3.Definition={type:"Stack",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"groupby",type:"field",array:!0},{name:"sort",type:"compare"},{name:"offset",type:"enum",default:d4,values:[d4,iI,sI]},{name:"as",type:"string",array:!0,length:2,default:oI}]};Me(B3,ie,{transform(e,t){var n=e.as||oI,r=n[0],i=n[1],s=pf(e.sort),o=e.field||gh,a=e.offset===iI?zre:e.offset===sI?jre:Ure,l,u,c,f;for(l=qre(t.source,e.groupby,s,o),u=0,c=l.length,f=l.max;ug(c),o,a,l,u,c,f,d,h,p;if(t==null)i.push(e.slice());else for(o={},a=0,l=e.length;ap&&(p=h),n&&d.sort(n)}return i.max=p,i}const Wre=Object.freeze(Object.defineProperty({__proto__:null,axisticks:YL,datajoin:VL,encode:XL,legendentries:KL,linkpath:I3,pie:P3,scale:tI,sortitems:rI,stack:B3},Symbol.toStringTag,{value:"Module"}));var ft=1e-6,vv=1e-12,Lt=Math.PI,Nn=Lt/2,yv=Lt/4,xi=Lt*2,zn=180/Lt,Nt=Lt/180,qt=Math.abs,Fh=Math.atan,Bs=Math.atan2,ht=Math.cos,ym=Math.ceil,aI=Math.exp,sE=Math.hypot,bv=Math.log,Dx=Math.pow,at=Math.sin,Cs=Math.sign||function(e){return e>0?1:e<0?-1:0},_i=Math.sqrt,z3=Math.tan;function lI(e){return e>1?0:e<-1?Lt:Math.acos(e)}function qi(e){return e>1?Nn:e<-1?-Nn:Math.asin(e)}function Mr(){}function xv(e,t){e&&p4.hasOwnProperty(e.type)&&p4[e.type](e,t)}var h4={Feature:function(e,t){xv(e.geometry,t)},FeatureCollection:function(e,t){for(var n=e.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,s=ht(t),o=at(t),a=uE*o,l=lE*s+a*ht(i),u=a*r*at(i);_v.add(Bs(u,l)),aE=e,lE=s,uE=o}function Vre(e){return wv=new yi,qa(e,fa),wv*2}function Ev(e){return[Bs(e[1],e[0]),qi(e[2])]}function Hc(e){var t=e[0],n=e[1],r=ht(n);return[r*ht(t),r*at(t),at(n)]}function bm(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function Hd(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function Mx(e,t){e[0]+=t[0],e[1]+=t[1],e[2]+=t[2]}function xm(e,t){return[e[0]*t,e[1]*t,e[2]*t]}function Av(e){var t=_i(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]);e[0]/=t,e[1]/=t,e[2]/=t}var Cn,Ri,Tn,ts,nc,dI,hI,ld,Zp,Tl,fl,Pa={point:cE,lineStart:m4,lineEnd:v4,polygonStart:function(){Pa.point=gI,Pa.lineStart=Xre,Pa.lineEnd=Kre,Zp=new yi,fa.polygonStart()},polygonEnd:function(){fa.polygonEnd(),Pa.point=cE,Pa.lineStart=m4,Pa.lineEnd=v4,_v<0?(Cn=-(Tn=180),Ri=-(ts=90)):Zp>ft?ts=90:Zp<-ft&&(Ri=-90),fl[0]=Cn,fl[1]=Tn},sphere:function(){Cn=-(Tn=180),Ri=-(ts=90)}};function cE(e,t){Tl.push(fl=[Cn=e,Tn=e]),tts&&(ts=t)}function pI(e,t){var n=Hc([e*Nt,t*Nt]);if(ld){var r=Hd(ld,n),i=[r[1],-r[0],0],s=Hd(i,r);Av(s),s=Ev(s);var o=e-nc,a=o>0?1:-1,l=s[0]*zn*a,u,c=qt(o)>180;c^(a*ncts&&(ts=u)):(l=(l+360)%360-180,c^(a*ncts&&(ts=t))),c?ees(Cn,Tn)&&(Tn=e):es(e,Tn)>es(Cn,Tn)&&(Cn=e):Tn>=Cn?(eTn&&(Tn=e)):e>nc?es(Cn,e)>es(Cn,Tn)&&(Tn=e):es(e,Tn)>es(Cn,Tn)&&(Cn=e)}else Tl.push(fl=[Cn=e,Tn=e]);tts&&(ts=t),ld=n,nc=e}function m4(){Pa.point=pI}function v4(){fl[0]=Cn,fl[1]=Tn,Pa.point=cE,ld=null}function gI(e,t){if(ld){var n=e-nc;Zp.add(qt(n)>180?n+(n>0?360:-360):n)}else dI=e,hI=t;fa.point(e,t),pI(e,t)}function Xre(){fa.lineStart()}function Kre(){gI(dI,hI),fa.lineEnd(),qt(Zp)>ft&&(Cn=-(Tn=180)),fl[0]=Cn,fl[1]=Tn,ld=null}function es(e,t){return(t-=e)<0?t+360:t}function Zre(e,t){return e[0]-t[0]}function y4(e,t){return e[0]<=e[1]?e[0]<=t&&t<=e[1]:tes(r[0],r[1])&&(r[1]=i[1]),es(i[0],r[1])>es(r[0],r[1])&&(r[0]=i[0])):s.push(r=i);for(o=-1/0,n=s.length-1,t=0,r=s[n];t<=n;r=i,++t)i=s[t],(a=es(r[1],i[0]))>o&&(o=a,Cn=i[0],Tn=r[1])}return Tl=fl=null,Cn===1/0||Ri===1/0?[[NaN,NaN],[NaN,NaN]]:[[Cn,Ri],[Tn,ts]]}var Cp,kv,Sv,Cv,$v,Fv,Dv,Mv,fE,dE,hE,mI,vI,di,hi,pi,lo={sphere:Mr,point:j3,lineStart:b4,lineEnd:x4,polygonStart:function(){lo.lineStart=tie,lo.lineEnd=nie},polygonEnd:function(){lo.lineStart=b4,lo.lineEnd=x4}};function j3(e,t){e*=Nt,t*=Nt;var n=ht(t);A0(n*ht(e),n*at(e),at(t))}function A0(e,t,n){++Cp,Sv+=(e-Sv)/Cp,Cv+=(t-Cv)/Cp,$v+=(n-$v)/Cp}function b4(){lo.point=Qre}function Qre(e,t){e*=Nt,t*=Nt;var n=ht(t);di=n*ht(e),hi=n*at(e),pi=at(t),lo.point=eie,A0(di,hi,pi)}function eie(e,t){e*=Nt,t*=Nt;var n=ht(t),r=n*ht(e),i=n*at(e),s=at(t),o=Bs(_i((o=hi*s-pi*i)*o+(o=pi*r-di*s)*o+(o=di*i-hi*r)*o),di*r+hi*i+pi*s);kv+=o,Fv+=o*(di+(di=r)),Dv+=o*(hi+(hi=i)),Mv+=o*(pi+(pi=s)),A0(di,hi,pi)}function x4(){lo.point=j3}function tie(){lo.point=rie}function nie(){yI(mI,vI),lo.point=j3}function rie(e,t){mI=e,vI=t,e*=Nt,t*=Nt,lo.point=yI;var n=ht(t);di=n*ht(e),hi=n*at(e),pi=at(t),A0(di,hi,pi)}function yI(e,t){e*=Nt,t*=Nt;var n=ht(t),r=n*ht(e),i=n*at(e),s=at(t),o=hi*s-pi*i,a=pi*r-di*s,l=di*i-hi*r,u=sE(o,a,l),c=qi(u),f=u&&-c/u;fE.add(f*o),dE.add(f*a),hE.add(f*l),kv+=c,Fv+=c*(di+(di=r)),Dv+=c*(hi+(hi=i)),Mv+=c*(pi+(pi=s)),A0(di,hi,pi)}function iie(e){Cp=kv=Sv=Cv=$v=Fv=Dv=Mv=0,fE=new yi,dE=new yi,hE=new yi,qa(e,lo);var t=+fE,n=+dE,r=+hE,i=sE(t,n,r);return iLt&&(e-=Math.round(e/xi)*xi),[e,t]}gE.invert=gE;function bI(e,t,n){return(e%=xi)?t||n?pE(w4(e),E4(t,n)):w4(e):t||n?E4(t,n):gE}function _4(e){return function(t,n){return t+=e,qt(t)>Lt&&(t-=Math.round(t/xi)*xi),[t,n]}}function w4(e){var t=_4(e);return t.invert=_4(-e),t}function E4(e,t){var n=ht(e),r=at(e),i=ht(t),s=at(t);function o(a,l){var u=ht(l),c=ht(a)*u,f=at(a)*u,d=at(l),h=d*n+c*r;return[Bs(f*i-h*s,c*n-d*r),qi(h*i+f*s)]}return o.invert=function(a,l){var u=ht(l),c=ht(a)*u,f=at(a)*u,d=at(l),h=d*i-f*s;return[Bs(f*i+d*s,c*n+h*r),qi(h*n-c*r)]},o}function sie(e){e=bI(e[0]*Nt,e[1]*Nt,e.length>2?e[2]*Nt:0);function t(n){return n=e(n[0]*Nt,n[1]*Nt),n[0]*=zn,n[1]*=zn,n}return t.invert=function(n){return n=e.invert(n[0]*Nt,n[1]*Nt),n[0]*=zn,n[1]*=zn,n},t}function oie(e,t,n,r,i,s){if(n){var o=ht(t),a=at(t),l=r*n;i==null?(i=t+r*xi,s=t-l/2):(i=A4(o,i),s=A4(o,s),(r>0?is)&&(i+=r*xi));for(var u,c=i;r>0?c>s:c1&&e.push(e.pop().concat(e.shift()))},result:function(){var n=e;return e=[],t=null,n}}}function m1(e,t){return qt(e[0]-t[0])=0;--a)i.point((f=c[a])[0],f[1]);else r(d.x,d.p.x,-1,i);d=d.p}d=d.o,c=d.z,h=!h}while(!d.v);i.lineEnd()}}}function k4(e){if(t=e.length){for(var t,n=0,r=e[0],i;++n=0?1:-1,$=S*k,M=$>Lt,O=m*A;if(l.add(Bs(O*S*at($),y*E+O*ht($))),o+=M?k+S*xi:k,M^p>=n^_>=n){var P=Hd(Hc(h),Hc(x));Av(P);var T=Hd(s,P);Av(T);var F=(M^k>=0?-1:1)*qi(T[2]);(r>F||r===F&&(P[0]||P[1]))&&(a+=M^k>=0?1:-1)}}return(o<-ft||o0){for(l||(i.polygonStart(),l=!0),i.lineStart(),A=0;A1&&_&2&&w.push(w.pop().concat(w.shift())),c.push(w.filter(lie))}}return d}}function lie(e){return e.length>1}function uie(e,t){return((e=e.x)[0]<0?e[1]-Nn-ft:Nn-e[1])-((t=t.x)[0]<0?t[1]-Nn-ft:Nn-t[1])}const S4=wI(function(){return!0},cie,die,[-Lt,-Nn]);function cie(e){var t=NaN,n=NaN,r=NaN,i;return{lineStart:function(){e.lineStart(),i=1},point:function(s,o){var a=s>0?Lt:-Lt,l=qt(s-t);qt(l-Lt)0?Nn:-Nn),e.point(r,n),e.lineEnd(),e.lineStart(),e.point(a,n),e.point(s,n),i=0):r!==a&&l>=Lt&&(qt(t-r)ft?Fh((at(t)*(s=ht(r))*at(n)-at(r)*(i=ht(t))*at(e))/(i*s*o)):(t+r)/2}function die(e,t,n,r){var i;if(e==null)i=n*Nn,r.point(-Lt,i),r.point(0,i),r.point(Lt,i),r.point(Lt,0),r.point(Lt,-i),r.point(0,-i),r.point(-Lt,-i),r.point(-Lt,0),r.point(-Lt,i);else if(qt(e[0]-t[0])>ft){var s=e[0]0,i=qt(t)>ft;function s(c,f,d,h){oie(h,e,n,d,c,f)}function o(c,f){return ht(c)*ht(f)>t}function a(c){var f,d,h,p,g;return{lineStart:function(){p=h=!1,g=1},point:function(m,y){var b=[m,y],x,_=o(m,y),w=r?_?0:u(m,y):_?u(m+(m<0?Lt:-Lt),y):0;if(!f&&(p=h=_)&&c.lineStart(),_!==h&&(x=l(f,b),(!x||m1(f,x)||m1(b,x))&&(b[2]=1)),_!==h)g=0,_?(c.lineStart(),x=l(b,f),c.point(x[0],x[1])):(x=l(f,b),c.point(x[0],x[1],2),c.lineEnd()),f=x;else if(i&&f&&r^_){var A;!(w&d)&&(A=l(b,f,!0))&&(g=0,r?(c.lineStart(),c.point(A[0][0],A[0][1]),c.point(A[1][0],A[1][1]),c.lineEnd()):(c.point(A[1][0],A[1][1]),c.lineEnd(),c.lineStart(),c.point(A[0][0],A[0][1],3)))}_&&(!f||!m1(f,b))&&c.point(b[0],b[1]),f=b,h=_,d=w},lineEnd:function(){h&&c.lineEnd(),f=null},clean:function(){return g|(p&&h)<<1}}}function l(c,f,d){var h=Hc(c),p=Hc(f),g=[1,0,0],m=Hd(h,p),y=bm(m,m),b=m[0],x=y-b*b;if(!x)return!d&&c;var _=t*y/x,w=-t*b/x,A=Hd(g,m),E=xm(g,_),k=xm(m,w);Mx(E,k);var S=A,$=bm(E,S),M=bm(S,S),O=$*$-M*(bm(E,E)-1);if(!(O<0)){var P=_i(O),T=xm(S,(-$-P)/M);if(Mx(T,E),T=Ev(T),!d)return T;var F=c[0],N=f[0],U=c[1],j=f[1],W;N0^T[1]<(qt(T[0]-F)Lt^(F<=T[0]&&T[0]<=N)){var ve=xm(S,(-$+P)/M);return Mx(ve,E),[T,Ev(ve)]}}}function u(c,f){var d=r?e:Lt-e,h=0;return c<-d?h|=1:c>d&&(h|=2),f<-d?h|=4:f>d&&(h|=8),h}return wI(o,a,s,r?[0,-e]:[-Lt,e-Lt])}function pie(e,t,n,r,i,s){var o=e[0],a=e[1],l=t[0],u=t[1],c=0,f=1,d=l-o,h=u-a,p;if(p=n-o,!(!d&&p>0)){if(p/=d,d<0){if(p0){if(p>f)return;p>c&&(c=p)}if(p=i-o,!(!d&&p<0)){if(p/=d,d<0){if(p>f)return;p>c&&(c=p)}else if(d>0){if(p0)){if(p/=h,h<0){if(p0){if(p>f)return;p>c&&(c=p)}if(p=s-a,!(!h&&p<0)){if(p/=h,h<0){if(p>f)return;p>c&&(c=p)}else if(h>0){if(p0&&(e[0]=o+c*d,e[1]=a+c*h),f<1&&(t[0]=o+f*d,t[1]=a+f*h),!0}}}}}var $p=1e9,wm=-$p;function EI(e,t,n,r){function i(u,c){return e<=u&&u<=n&&t<=c&&c<=r}function s(u,c,f,d){var h=0,p=0;if(u==null||(h=o(u,f))!==(p=o(c,f))||l(u,c)<0^f>0)do d.point(h===0||h===3?e:n,h>1?r:t);while((h=(h+f+4)%4)!==p);else d.point(c[0],c[1])}function o(u,c){return qt(u[0]-e)0?0:3:qt(u[0]-n)0?2:1:qt(u[1]-t)0?1:0:c>0?3:2}function a(u,c){return l(u.x,c.x)}function l(u,c){var f=o(u,1),d=o(c,1);return f!==d?f-d:f===0?c[1]-u[1]:f===1?u[0]-c[0]:f===2?u[1]-c[1]:c[0]-u[0]}return function(u){var c=u,f=xI(),d,h,p,g,m,y,b,x,_,w,A,E={point:k,lineStart:O,lineEnd:P,polygonStart:$,polygonEnd:M};function k(F,N){i(F,N)&&c.point(F,N)}function S(){for(var F=0,N=0,U=h.length;Nr&&(Te-J)*(r-ve)>(Fe-ve)*(e-J)&&++F:Fe<=r&&(Te-J)*(r-ve)<(Fe-ve)*(e-J)&&--F;return F}function $(){c=f,d=[],h=[],A=!0}function M(){var F=S(),N=A&&F,U=(d=hN(d)).length;(N||U)&&(u.polygonStart(),N&&(u.lineStart(),s(null,null,1,u),u.lineEnd()),U&&_I(d,a,F,s,u),u.polygonEnd()),c=u,d=h=p=null}function O(){E.point=T,h&&h.push(p=[]),w=!0,_=!1,b=x=NaN}function P(){d&&(T(g,m),y&&_&&f.rejoin(),d.push(f.result())),E.point=k,_&&c.lineEnd()}function T(F,N){var U=i(F,N);if(h&&p.push([F,N]),w)g=F,m=N,y=U,w=!1,U&&(c.lineStart(),c.point(F,N));else if(U&&_)c.point(F,N);else{var j=[b=Math.max(wm,Math.min($p,b)),x=Math.max(wm,Math.min($p,x))],W=[F=Math.max(wm,Math.min($p,F)),N=Math.max(wm,Math.min($p,N))];pie(j,W,e,t,n,r)?(_||(c.lineStart(),c.point(j[0],j[1])),c.point(W[0],W[1]),U||c.lineEnd(),A=!1):U&&(c.lineStart(),c.point(F,N),A=!1)}b=F,x=N,_=U}return E}}function C4(e,t,n){var r=ss(e,t-ft,n).concat(t);return function(i){return r.map(function(s){return[i,s]})}}function $4(e,t,n){var r=ss(e,t-ft,n).concat(t);return function(i){return r.map(function(s){return[s,i]})}}function gie(){var e,t,n,r,i,s,o,a,l=10,u=l,c=90,f=360,d,h,p,g,m=2.5;function y(){return{type:"MultiLineString",coordinates:b()}}function b(){return ss(ym(r/c)*c,n,c).map(p).concat(ss(ym(a/f)*f,o,f).map(g)).concat(ss(ym(t/l)*l,e,l).filter(function(x){return qt(x%c)>ft}).map(d)).concat(ss(ym(s/u)*u,i,u).filter(function(x){return qt(x%f)>ft}).map(h))}return y.lines=function(){return b().map(function(x){return{type:"LineString",coordinates:x}})},y.outline=function(){return{type:"Polygon",coordinates:[p(r).concat(g(o).slice(1),p(n).reverse().slice(1),g(a).reverse().slice(1))]}},y.extent=function(x){return arguments.length?y.extentMajor(x).extentMinor(x):y.extentMinor()},y.extentMajor=function(x){return arguments.length?(r=+x[0][0],n=+x[1][0],a=+x[0][1],o=+x[1][1],r>n&&(x=r,r=n,n=x),a>o&&(x=a,a=o,o=x),y.precision(m)):[[r,a],[n,o]]},y.extentMinor=function(x){return arguments.length?(t=+x[0][0],e=+x[1][0],s=+x[0][1],i=+x[1][1],t>e&&(x=t,t=e,e=x),s>i&&(x=s,s=i,i=x),y.precision(m)):[[t,s],[e,i]]},y.step=function(x){return arguments.length?y.stepMajor(x).stepMinor(x):y.stepMinor()},y.stepMajor=function(x){return arguments.length?(c=+x[0],f=+x[1],y):[c,f]},y.stepMinor=function(x){return arguments.length?(l=+x[0],u=+x[1],y):[l,u]},y.precision=function(x){return arguments.length?(m=+x,d=C4(s,i,90),h=$4(t,e,m),p=C4(a,o,90),g=$4(r,n,m),y):m},y.extentMajor([[-180,-90+ft],[180,90-ft]]).extentMinor([[-180,-80-ft],[180,80+ft]])}const Eg=e=>e;var Rx=new yi,mE=new yi,AI,kI,vE,yE,Wa={point:Mr,lineStart:Mr,lineEnd:Mr,polygonStart:function(){Wa.lineStart=mie,Wa.lineEnd=yie},polygonEnd:function(){Wa.lineStart=Wa.lineEnd=Wa.point=Mr,Rx.add(qt(mE)),mE=new yi},result:function(){var e=Rx/2;return Rx=new yi,e}};function mie(){Wa.point=vie}function vie(e,t){Wa.point=SI,AI=vE=e,kI=yE=t}function SI(e,t){mE.add(yE*e-vE*t),vE=e,yE=t}function yie(){SI(AI,kI)}var Gd=1/0,Tv=Gd,Ag=-Gd,Rv=Ag,Nv={point:bie,lineStart:Mr,lineEnd:Mr,polygonStart:Mr,polygonEnd:Mr,result:function(){var e=[[Gd,Tv],[Ag,Rv]];return Ag=Rv=-(Tv=Gd=1/0),e}};function bie(e,t){eAg&&(Ag=e),tRv&&(Rv=t)}var bE=0,xE=0,Fp=0,Ov=0,Lv=0,ed=0,_E=0,wE=0,Dp=0,CI,$I,Vo,Xo,ks={point:Gc,lineStart:F4,lineEnd:D4,polygonStart:function(){ks.lineStart=wie,ks.lineEnd=Eie},polygonEnd:function(){ks.point=Gc,ks.lineStart=F4,ks.lineEnd=D4},result:function(){var e=Dp?[_E/Dp,wE/Dp]:ed?[Ov/ed,Lv/ed]:Fp?[bE/Fp,xE/Fp]:[NaN,NaN];return bE=xE=Fp=Ov=Lv=ed=_E=wE=Dp=0,e}};function Gc(e,t){bE+=e,xE+=t,++Fp}function F4(){ks.point=xie}function xie(e,t){ks.point=_ie,Gc(Vo=e,Xo=t)}function _ie(e,t){var n=e-Vo,r=t-Xo,i=_i(n*n+r*r);Ov+=i*(Vo+e)/2,Lv+=i*(Xo+t)/2,ed+=i,Gc(Vo=e,Xo=t)}function D4(){ks.point=Gc}function wie(){ks.point=Aie}function Eie(){FI(CI,$I)}function Aie(e,t){ks.point=FI,Gc(CI=Vo=e,$I=Xo=t)}function FI(e,t){var n=e-Vo,r=t-Xo,i=_i(n*n+r*r);Ov+=i*(Vo+e)/2,Lv+=i*(Xo+t)/2,ed+=i,i=Xo*e-Vo*t,_E+=i*(Vo+e),wE+=i*(Xo+t),Dp+=i*3,Gc(Vo=e,Xo=t)}function DI(e){this._context=e}DI.prototype={_radius:4.5,pointRadius:function(e){return this._radius=e,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){this._line===0&&this._context.closePath(),this._point=NaN},point:function(e,t){switch(this._point){case 0:{this._context.moveTo(e,t),this._point=1;break}case 1:{this._context.lineTo(e,t);break}default:{this._context.moveTo(e+this._radius,t),this._context.arc(e,t,this._radius,0,xi);break}}},result:Mr};var EE=new yi,Nx,MI,TI,Mp,Tp,kg={point:Mr,lineStart:function(){kg.point=kie},lineEnd:function(){Nx&&RI(MI,TI),kg.point=Mr},polygonStart:function(){Nx=!0},polygonEnd:function(){Nx=null},result:function(){var e=+EE;return EE=new yi,e}};function kie(e,t){kg.point=RI,MI=Mp=e,TI=Tp=t}function RI(e,t){Mp-=e,Tp-=t,EE.add(_i(Mp*Mp+Tp*Tp)),Mp=e,Tp=t}let M4,Iv,T4,R4;class N4{constructor(t){this._append=t==null?NI:Sie(t),this._radius=4.5,this._=""}pointRadius(t){return this._radius=+t,this}polygonStart(){this._line=0}polygonEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){this._line===0&&(this._+="Z"),this._point=NaN}point(t,n){switch(this._point){case 0:{this._append`M${t},${n}`,this._point=1;break}case 1:{this._append`L${t},${n}`;break}default:{if(this._append`M${t},${n}`,this._radius!==T4||this._append!==Iv){const r=this._radius,i=this._;this._="",this._append`m0,${r}a${r},${r} 0 1,1 0,${-2*r}a${r},${r} 0 1,1 0,${2*r}z`,T4=r,Iv=this._append,R4=this._,this._=i}this._+=R4;break}}}result(){const t=this._;return this._="",t.length?t:null}}function NI(e){let t=1;this._+=e[0];for(const n=e.length;t=0))throw new RangeError(`invalid digits: ${e}`);if(t>15)return NI;if(t!==M4){const n=10**t;M4=t,Iv=function(i){let s=1;this._+=i[0];for(const o=i.length;s=0))throw new RangeError(`invalid digits: ${a}`);n=l}return t===null&&(s=new N4(n)),o},o.projection(e).digits(n).context(t)}function xb(e){return function(t){var n=new AE;for(var r in e)n[r]=e[r];return n.stream=t,n}}function AE(){}AE.prototype={constructor:AE,point:function(e,t){this.stream.point(e,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};function U3(e,t,n){var r=e.clipExtent&&e.clipExtent();return e.scale(150).translate([0,0]),r!=null&&e.clipExtent(null),qa(n,e.stream(Nv)),t(Nv.result()),r!=null&&e.clipExtent(r),e}function _b(e,t,n){return U3(e,function(r){var i=t[1][0]-t[0][0],s=t[1][1]-t[0][1],o=Math.min(i/(r[1][0]-r[0][0]),s/(r[1][1]-r[0][1])),a=+t[0][0]+(i-o*(r[1][0]+r[0][0]))/2,l=+t[0][1]+(s-o*(r[1][1]+r[0][1]))/2;e.scale(150*o).translate([a,l])},n)}function q3(e,t,n){return _b(e,[[0,0],t],n)}function W3(e,t,n){return U3(e,function(r){var i=+t,s=i/(r[1][0]-r[0][0]),o=(i-s*(r[1][0]+r[0][0]))/2,a=-s*r[0][1];e.scale(150*s).translate([o,a])},n)}function H3(e,t,n){return U3(e,function(r){var i=+t,s=i/(r[1][1]-r[0][1]),o=-s*r[0][0],a=(i-s*(r[1][1]+r[0][1]))/2;e.scale(150*s).translate([o,a])},n)}var O4=16,Cie=ht(30*Nt);function L4(e,t){return+t?Fie(e,t):$ie(e)}function $ie(e){return xb({point:function(t,n){t=e(t,n),this.stream.point(t[0],t[1])}})}function Fie(e,t){function n(r,i,s,o,a,l,u,c,f,d,h,p,g,m){var y=u-r,b=c-i,x=y*y+b*b;if(x>4*t&&g--){var _=o+d,w=a+h,A=l+p,E=_i(_*_+w*w+A*A),k=qi(A/=E),S=qt(qt(A)-1)t||qt((y*P+b*T)/x-.5)>.3||o*d+a*h+l*p2?F[2]%360*Nt:0,P()):[a*zn,l*zn,u*zn]},M.angle=function(F){return arguments.length?(f=F%360*Nt,P()):f*zn},M.reflectX=function(F){return arguments.length?(d=F?-1:1,P()):d<0},M.reflectY=function(F){return arguments.length?(h=F?-1:1,P()):h<0},M.precision=function(F){return arguments.length?(A=L4(E,w=F*F),T()):_i(w)},M.fitExtent=function(F,N){return _b(M,F,N)},M.fitSize=function(F,N){return q3(M,F,N)},M.fitWidth=function(F,N){return W3(M,F,N)},M.fitHeight=function(F,N){return H3(M,F,N)};function P(){var F=I4(n,0,0,d,h,f).apply(null,t(s,o)),N=I4(n,r-F[0],i-F[1],d,h,f);return c=bI(a,l,u),E=pE(t,N),k=pE(c,E),A=L4(E,w),T()}function T(){return S=$=null,M}return function(){return t=e.apply(this,arguments),M.invert=t.invert&&O,P()}}function G3(e){var t=0,n=Lt/3,r=LI(e),i=r(t,n);return i.parallels=function(s){return arguments.length?r(t=s[0]*Nt,n=s[1]*Nt):[t*zn,n*zn]},i}function Rie(e){var t=ht(e);function n(r,i){return[r*t,at(i)/t]}return n.invert=function(r,i){return[r/t,qi(i*t)]},n}function Nie(e,t){var n=at(e),r=(n+at(t))/2;if(qt(r)=.12&&m<.234&&g>=-.425&&g<-.214?i:m>=.166&&m<.234&&g>=-.214&&g<-.115?o:n).invert(d)},c.stream=function(d){return e&&t===d?e:e=Oie([n.stream(t=d),i.stream(d),o.stream(d)])},c.precision=function(d){return arguments.length?(n.precision(d),i.precision(d),o.precision(d),f()):n.precision()},c.scale=function(d){return arguments.length?(n.scale(d),i.scale(d*.35),o.scale(d),c.translate(n.translate())):n.scale()},c.translate=function(d){if(!arguments.length)return n.translate();var h=n.scale(),p=+d[0],g=+d[1];return r=n.translate(d).clipExtent([[p-.455*h,g-.238*h],[p+.455*h,g+.238*h]]).stream(u),s=i.translate([p-.307*h,g+.201*h]).clipExtent([[p-.425*h+ft,g+.12*h+ft],[p-.214*h-ft,g+.234*h-ft]]).stream(u),a=o.translate([p-.205*h,g+.212*h]).clipExtent([[p-.214*h+ft,g+.166*h+ft],[p-.115*h-ft,g+.234*h-ft]]).stream(u),f()},c.fitExtent=function(d,h){return _b(c,d,h)},c.fitSize=function(d,h){return q3(c,d,h)},c.fitWidth=function(d,h){return W3(c,d,h)},c.fitHeight=function(d,h){return H3(c,d,h)};function f(){return e=t=null,c}return c.scale(1070)}function PI(e){return function(t,n){var r=ht(t),i=ht(n),s=e(r*i);return s===1/0?[2,0]:[s*i*at(t),s*at(n)]}}function k0(e){return function(t,n){var r=_i(t*t+n*n),i=e(r),s=at(i),o=ht(i);return[Bs(t*s,r*o),qi(r&&n*s/r)]}}var BI=PI(function(e){return _i(2/(1+e))});BI.invert=k0(function(e){return 2*qi(e/2)});function Iie(){return _a(BI).scale(124.75).clipAngle(180-.001)}var zI=PI(function(e){return(e=lI(e))&&e/at(e)});zI.invert=k0(function(e){return e});function Pie(){return _a(zI).scale(79.4188).clipAngle(180-.001)}function wb(e,t){return[e,bv(z3((Nn+t)/2))]}wb.invert=function(e,t){return[e,2*Fh(aI(t))-Nn]};function Bie(){return jI(wb).scale(961/xi)}function jI(e){var t=_a(e),n=t.center,r=t.scale,i=t.translate,s=t.clipExtent,o=null,a,l,u;t.scale=function(f){return arguments.length?(r(f),c()):r()},t.translate=function(f){return arguments.length?(i(f),c()):i()},t.center=function(f){return arguments.length?(n(f),c()):n()},t.clipExtent=function(f){return arguments.length?(f==null?o=a=l=u=null:(o=+f[0][0],a=+f[0][1],l=+f[1][0],u=+f[1][1]),c()):o==null?null:[[o,a],[l,u]]};function c(){var f=Lt*r(),d=t(sie(t.rotate()).invert([0,0]));return s(o==null?[[d[0]-f,d[1]-f],[d[0]+f,d[1]+f]]:e===wb?[[Math.max(d[0]-f,o),a],[Math.min(d[0]+f,l),u]]:[[o,Math.max(d[1]-f,a)],[l,Math.min(d[1]+f,u)]])}return c()}function Em(e){return z3((Nn+e)/2)}function zie(e,t){var n=ht(e),r=e===t?at(e):bv(n/ht(t))/bv(Em(t)/Em(e)),i=n*Dx(Em(e),r)/r;if(!r)return wb;function s(o,a){i>0?a<-Nn+ft&&(a=-Nn+ft):a>Nn-ft&&(a=Nn-ft);var l=i/Dx(Em(a),r);return[l*at(r*o),i-l*ht(r*o)]}return s.invert=function(o,a){var l=i-a,u=Cs(r)*_i(o*o+l*l),c=Bs(o,qt(l))*Cs(l);return l*r<0&&(c-=Lt*Cs(o)*Cs(l)),[c/r,2*Fh(Dx(i/u,1/r))-Nn]},s}function jie(){return G3(zie).scale(109.5).parallels([30,30])}function Bv(e,t){return[e,t]}Bv.invert=Bv;function Uie(){return _a(Bv).scale(152.63)}function qie(e,t){var n=ht(e),r=e===t?at(e):(n-ht(t))/(t-e),i=n/r+e;if(qt(r)ft&&--r>0);return[e/(.8707+(s=n*n)*(-.131979+s*(-.013791+s*s*s*(.003971-.001529*s)))),n]};function Xie(){return _a(WI).scale(175.295)}function HI(e,t){return[ht(t)*at(e),at(t)]}HI.invert=k0(qi);function Kie(){return _a(HI).scale(249.5).clipAngle(90+ft)}function GI(e,t){var n=ht(t),r=1+ht(e)*n;return[n*at(e)/r,at(t)/r]}GI.invert=k0(function(e){return 2*Fh(e)});function Zie(){return _a(GI).scale(250).clipAngle(142)}function YI(e,t){return[bv(z3((Nn+t)/2)),-e]}YI.invert=function(e,t){return[-t,2*Fh(aI(e))-Nn]};function Jie(){var e=jI(YI),t=e.center,n=e.rotate;return e.center=function(r){return arguments.length?t([-r[1],r[0]]):(r=t(),[r[1],-r[0]])},e.rotate=function(r){return arguments.length?n([r[0],r[1],r.length>2?r[2]+90:90]):(r=n(),[r[0],r[1],r[2]-90])},n([0,0,90]).scale(159.155)}var Qie=Math.abs,kE=Math.cos,jv=Math.sin,ese=1e-6,VI=Math.PI,SE=VI/2,P4=tse(2);function B4(e){return e>1?SE:e<-1?-SE:Math.asin(e)}function tse(e){return e>0?Math.sqrt(e):0}function nse(e,t){var n=e*jv(t),r=30,i;do t-=i=(t+jv(t)-n)/(1+kE(t));while(Qie(i)>ese&&--r>0);return t/2}function rse(e,t,n){function r(i,s){return[e*i*kE(s=nse(n,s)),t*jv(s)]}return r.invert=function(i,s){return s=B4(s/t),[i/(e*kE(s)),B4((2*s+jv(2*s))/n)]},r}var ise=rse(P4/SE,P4,VI);function sse(){return _a(ise).scale(169.529)}const ose=OI(),CE=["clipAngle","clipExtent","scale","translate","center","rotate","parallels","precision","reflectX","reflectY","coefficient","distance","fraction","lobes","parallel","radius","ratio","spacing","tilt"];function ase(e,t){return function n(){const r=t();return r.type=e,r.path=OI().projection(r),r.copy=r.copy||function(){const i=n();return CE.forEach(s=>{r[s]&&i[s](r[s]())}),i.path.pointRadius(r.path.pointRadius()),i},u9(r)}}function Y3(e,t){if(!e||typeof e!="string")throw new Error("Projection type must be a name string.");return e=e.toLowerCase(),arguments.length>1?(Uv[e]=ase(e,t),this):Uv[e]||null}function XI(e){return e&&e.path||ose}const Uv={albers:II,albersusa:Lie,azimuthalequalarea:Iie,azimuthalequidistant:Pie,conicconformal:jie,conicequalarea:Pv,conicequidistant:Wie,equalEarth:Gie,equirectangular:Uie,gnomonic:Yie,identity:Vie,mercator:Bie,mollweide:sse,naturalEarth1:Xie,orthographic:Kie,stereographic:Zie,transversemercator:Jie};for(const e in Uv)Y3(e,Uv[e]);function lse(){}const Ra=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]];function KI(){var e=1,t=1,n=a;function r(l,u){return u.map(c=>i(l,c))}function i(l,u){var c=[],f=[];return s(l,u,d=>{n(d,l,u),use(d)>0?c.push([d]):f.push(d)}),f.forEach(d=>{for(var h=0,p=c.length,g;h=u,Ra[m<<1].forEach(x);++h=u,Ra[g|m<<1].forEach(x);for(Ra[m<<0].forEach(x);++p=u,y=l[p*e]>=u,Ra[m<<1|y<<2].forEach(x);++h=u,b=y,y=l[p*e+h+1]>=u,Ra[g|m<<1|y<<2|b<<3].forEach(x);Ra[m|y<<3].forEach(x)}for(h=-1,y=l[p*e]>=u,Ra[y<<2].forEach(x);++h=u,Ra[y<<2|b<<3].forEach(x);Ra[y<<3].forEach(x);function x(_){var w=[_[0][0]+h,_[0][1]+p],A=[_[1][0]+h,_[1][1]+p],E=o(w),k=o(A),S,$;(S=d[E])?($=f[k])?(delete d[S.end],delete f[$.start],S===$?(S.ring.push(A),c(S.ring)):f[S.start]=d[$.end]={start:S.start,end:$.end,ring:S.ring.concat($.ring)}):(delete d[S.end],S.ring.push(A),d[S.end=k]=S):(S=f[k])?($=d[E])?(delete f[S.start],delete d[$.end],S===$?(S.ring.push(A),c(S.ring)):f[$.start]=d[S.end]={start:$.start,end:S.end,ring:$.ring.concat(S.ring)}):(delete f[S.start],S.ring.unshift(w),f[S.start=E]=S):f[E]=d[k]={start:E,end:k,ring:[w,A]}}}function o(l){return l[0]*2+l[1]*(e+1)*4}function a(l,u,c){l.forEach(f=>{var d=f[0],h=f[1],p=d|0,g=h|0,m,y=u[g*e+p];d>0&&d0&&h=0&&c>=0||le("invalid size"),e=u,t=c,r},r.smooth=function(l){return arguments.length?(n=l?a:lse,r):n===a},r}function use(e){for(var t=0,n=e.length,r=e[n-1][1]*e[0][0]-e[n-1][0]*e[0][1];++tr!=h>r&&n<(d-u)*(r-c)/(h-c)+u&&(i=-i)}return i}function dse(e,t,n){var r;return hse(e,t,n)&&pse(e[r=+(e[0]===t[0])],n[r],t[r])}function hse(e,t,n){return(t[0]-e[0])*(n[1]-e[1])===(n[0]-e[0])*(t[1]-e[1])}function pse(e,t,n){return e<=t&&t<=n||n<=t&&t<=e}function ZI(e,t,n){return function(r){var i=aa(r),s=n?Math.min(i[0],0):i[0],o=i[1],a=o-s,l=t?su(s,o,e):a/(e+1);return ss(s+l,o,l)}}function V3(e){ie.call(this,null,e)}V3.Definition={type:"Isocontour",metadata:{generates:!0},params:[{name:"field",type:"field"},{name:"thresholds",type:"number",array:!0},{name:"levels",type:"number"},{name:"nice",type:"boolean",default:!1},{name:"resolve",type:"enum",values:["shared","independent"],default:"independent"},{name:"zero",type:"boolean",default:!0},{name:"smooth",type:"boolean",default:!0},{name:"scale",type:"number",expr:!0},{name:"translate",type:"number",array:!0,expr:!0},{name:"as",type:"string",null:!0,default:"contour"}]};Me(V3,ie,{transform(e,t){if(this.value&&!t.changed()&&!e.modified())return t.StopPropagation;var n=t.fork(t.NO_SOURCE|t.NO_FIELDS),r=t.materialize(t.SOURCE).source,i=e.field||ni,s=KI().smooth(e.smooth!==!1),o=e.thresholds||gse(r,i,e),a=e.as===null?null:e.as||"contour",l=[];return r.forEach(u=>{const c=i(u),f=s.size([c.width,c.height])(c.values,de(o)?o:o(c.values));mse(f,c,u,e),f.forEach(d=>{l.push(By(u,Zt(a!=null?{[a]:d}:d)))})}),this.value&&(n.rem=this.value),this.value=n.source=n.add=l,n}});function gse(e,t,n){const r=ZI(n.levels||10,n.nice,n.zero!==!1);return n.resolve!=="shared"?r:r(e.map(i=>wc(t(i).values)))}function mse(e,t,n,r){let i=r.scale||t.scale,s=r.translate||t.translate;if(Tt(i)&&(i=i(n,r)),Tt(s)&&(s=s(n,r)),(i===1||i==null)&&!s)return;const o=(Vt(i)?i:i[0])||1,a=(Vt(i)?i:i[1])||1,l=s&&s[0]||0,u=s&&s[1]||0;e.forEach(JI(t,o,a,l,u))}function JI(e,t,n,r,i){const s=e.x1||0,o=e.y1||0,a=t*n<0;function l(f){f.forEach(u)}function u(f){a&&f.reverse(),f.forEach(c)}function c(f){f[0]=(f[0]-s)*t+r,f[1]=(f[1]-o)*n+i}return function(f){return f.coordinates.forEach(l),f}}function z4(e,t,n){const r=e>=0?e:zk(t,n);return Math.round((Math.sqrt(4*r*r+1)-1)/2)}function Ox(e){return Tt(e)?e:ri(+e)}function QI(){var e=l=>l[0],t=l=>l[1],n=gh,r=[-1,-1],i=960,s=500,o=2;function a(l,u){const c=z4(r[0],l,e)>>o,f=z4(r[1],l,t)>>o,d=c?c+2:0,h=f?f+2:0,p=2*d+(i>>o),g=2*h+(s>>o),m=new Float32Array(p*g),y=new Float32Array(p*g);let b=m;l.forEach(_=>{const w=d+(+e(_)>>o),A=h+(+t(_)>>o);w>=0&&w=0&&A0&&f>0?(Lf(p,g,m,y,c),If(p,g,y,m,f),Lf(p,g,m,y,c),If(p,g,y,m,f),Lf(p,g,m,y,c),If(p,g,y,m,f)):c>0?(Lf(p,g,m,y,c),Lf(p,g,y,m,c),Lf(p,g,m,y,c),b=y):f>0&&(If(p,g,m,y,f),If(p,g,y,m,f),If(p,g,m,y,f),b=y);const x=u?Math.pow(2,-2*o):1/pN(b);for(let _=0,w=p*g;_>o),y2:h+(s>>o)}}return a.x=function(l){return arguments.length?(e=Ox(l),a):e},a.y=function(l){return arguments.length?(t=Ox(l),a):t},a.weight=function(l){return arguments.length?(n=Ox(l),a):n},a.size=function(l){if(!arguments.length)return[i,s];var u=+l[0],c=+l[1];return u>=0&&c>=0||le("invalid size"),i=u,s=c,a},a.cellSize=function(l){return arguments.length?((l=+l)>=1||le("invalid cell size"),o=Math.floor(Math.log(l)/Math.LN2),a):1<=i&&(a>=s&&(l-=n[a-s+o*e]),r[a-i+o*e]=l/Math.min(a+1,e-1+s-a,s))}function If(e,t,n,r,i){const s=(i<<1)+1;for(let o=0;o=i&&(a>=s&&(l-=n[o+(a-s)*e]),r[o+(a-i)*e]=l/Math.min(a+1,t-1+s-a,s))}function X3(e){ie.call(this,null,e)}X3.Definition={type:"KDE2D",metadata:{generates:!0},params:[{name:"size",type:"number",array:!0,length:2,required:!0},{name:"x",type:"field",required:!0},{name:"y",type:"field",required:!0},{name:"weight",type:"field"},{name:"groupby",type:"field",array:!0},{name:"cellSize",type:"number"},{name:"bandwidth",type:"number",array:!0,length:2},{name:"counts",type:"boolean",default:!1},{name:"as",type:"string",default:"grid"}]};const vse=["x","y","weight","size","cellSize","bandwidth"];function eP(e,t){return vse.forEach(n=>t[n]!=null?e[n](t[n]):0),e}Me(X3,ie,{transform(e,t){if(this.value&&!t.changed()&&!e.modified())return t.StopPropagation;var n=t.fork(t.NO_SOURCE|t.NO_FIELDS),r=t.materialize(t.SOURCE).source,i=yse(r,e.groupby),s=(e.groupby||[]).map(Ln),o=eP(QI(),e),a=e.as||"grid",l=[];function u(c,f){for(let d=0;dZt(u({[a]:o(c,e.counts)},c.dims))),this.value&&(n.rem=this.value),this.value=n.source=n.add=l,n}});function yse(e,t){var n=[],r=c=>c(a),i,s,o,a,l,u;if(t==null)n.push(e);else for(i={},s=0,o=e.length;sn.push(a(c))),s&&o&&(t.visit(l,c=>{var f=s(c),d=o(c);f!=null&&d!=null&&(f=+f)===f&&(d=+d)===d&&r.push([f,d])}),n=n.concat({type:$E,geometry:{type:bse,coordinates:r}})),this.value={type:Z3,features:n}}});function Q3(e){ie.call(this,null,e)}Q3.Definition={type:"GeoPath",metadata:{modifies:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"path"}]};Me(Q3,ie,{transform(e,t){var n=t.fork(t.ALL),r=this.value,i=e.field||ni,s=e.as||"path",o=n.SOURCE;!r||e.modified()?(this.value=r=XI(e.projection),n.materialize().reflow()):o=i===ni||t.modified(i.fields)?n.ADD_MOD:n.ADD;const a=xse(r,e.pointRadius);return n.visit(o,l=>l[s]=r(i(l))),r.pointRadius(a),n.modifies(s)}});function xse(e,t){const n=e.pointRadius();return e.context(null),t!=null&&e.pointRadius(t),n}function eC(e){ie.call(this,null,e)}eC.Definition={type:"GeoPoint",metadata:{modifies:!0},params:[{name:"projection",type:"projection",required:!0},{name:"fields",type:"field",array:!0,required:!0,length:2},{name:"as",type:"string",array:!0,length:2,default:["x","y"]}]};Me(eC,ie,{transform(e,t){var n=e.projection,r=e.fields[0],i=e.fields[1],s=e.as||["x","y"],o=s[0],a=s[1],l;function u(c){const f=n([r(c),i(c)]);f?(c[o]=f[0],c[a]=f[1]):(c[o]=void 0,c[a]=void 0)}return e.modified()?t=t.materialize().reflow(!0).visit(t.SOURCE,u):(l=t.modified(r.fields)||t.modified(i.fields),t.visit(l?t.ADD_MOD:t.ADD,u)),t.modifies(s)}});function tC(e){ie.call(this,null,e)}tC.Definition={type:"GeoShape",metadata:{modifies:!0,nomod:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field",default:"datum"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"shape"}]};Me(tC,ie,{transform(e,t){var n=t.fork(t.ALL),r=this.value,i=e.as||"shape",s=n.ADD;return(!r||e.modified())&&(this.value=r=_se(XI(e.projection),e.field||Ls("datum"),e.pointRadius),n.materialize().reflow(),s=n.SOURCE),n.visit(s,o=>o[i]=r),n.modifies(i)}});function _se(e,t,n){const r=n==null?i=>e(t(i)):i=>{var s=e.pointRadius(),o=e.pointRadius(n)(t(i));return e.pointRadius(s),o};return r.context=i=>(e.context(i),r),r}function nC(e){ie.call(this,[],e),this.generator=gie()}nC.Definition={type:"Graticule",metadata:{changes:!0,generates:!0},params:[{name:"extent",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMajor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMinor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"step",type:"number",array:!0,length:2},{name:"stepMajor",type:"number",array:!0,length:2,default:[90,360]},{name:"stepMinor",type:"number",array:!0,length:2,default:[10,10]},{name:"precision",type:"number",default:2.5}]};Me(nC,ie,{transform(e,t){var n=this.value,r=this.generator,i;if(!n.length||e.modified())for(const s in e)Tt(r[s])&&r[s](e[s]);return i=r(),n.length?t.mod.push(lO(n[0],i)):t.add.push(Zt(i)),n[0]=i,t}});function rC(e){ie.call(this,null,e)}rC.Definition={type:"heatmap",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"color",type:"string",expr:!0},{name:"opacity",type:"number",expr:!0},{name:"resolve",type:"enum",values:["shared","independent"],default:"independent"},{name:"as",type:"string",default:"image"}]};Me(rC,ie,{transform(e,t){if(!t.changed()&&!e.modified())return t.StopPropagation;var n=t.materialize(t.SOURCE).source,r=e.resolve==="shared",i=e.field||ni,s=Ese(e.opacity,e),o=wse(e.color,e),a=e.as||"image",l={$x:0,$y:0,$value:0,$max:r?wc(n.map(u=>wc(i(u).values))):0};return n.forEach(u=>{const c=i(u),f=Mt({},u,l);r||(f.$max=wc(c.values||[])),u[a]=Ase(c,f,o.dep?o:ri(o(f)),s.dep?s:ri(s(f)))}),t.reflow(!0).modifies(a)}});function wse(e,t){let n;return Tt(e)?(n=r=>lu(e(r,t)),n.dep=tP(e)):n=ri(lu(e||"#888")),n}function Ese(e,t){let n;return Tt(e)?(n=r=>e(r,t),n.dep=tP(e)):e?n=ri(e):(n=r=>r.$value/r.$max||0,n.dep=!0),n}function tP(e){if(!Tt(e))return!1;const t=mo(Kr(e));return t.$x||t.$y||t.$value||t.$max}function Ase(e,t,n,r){const i=e.width,s=e.height,o=e.x1||0,a=e.y1||0,l=e.x2||i,u=e.y2||s,c=e.values,f=c?m=>c[m]:Ol,d=eu(l-o,u-a),h=d.getContext("2d"),p=h.getImageData(0,0,l-o,u-a),g=p.data;for(let m=a,y=0;m{e[r]!=null&&j4(n,r,e[r])})):CE.forEach(r=>{e.modified(r)&&j4(n,r,e[r])}),e.pointRadius!=null&&n.path.pointRadius(e.pointRadius),e.fit&&kse(n,e),t.fork(t.NO_SOURCE|t.NO_FIELDS)}});function kse(e,t){const n=Cse(t.fit);t.extent?e.fitExtent(t.extent,n):t.size&&e.fitSize(t.size,n)}function Sse(e){const t=Y3((e||"mercator").toLowerCase());return t||le("Unrecognized projection type: "+e),t()}function j4(e,t,n){Tt(e[t])&&e[t](n)}function Cse(e){return e=Be(e),e.length===1?e[0]:{type:Z3,features:e.reduce((t,n)=>t.concat($se(n)),[])}}function $se(e){return e.type===Z3?e.features:Be(e).filter(t=>t!=null).map(t=>t.type===$E?t:{type:$E,geometry:t})}const Fse=Object.freeze(Object.defineProperty({__proto__:null,contour:K3,geojson:J3,geopath:Q3,geopoint:eC,geoshape:tC,graticule:nC,heatmap:rC,isocontour:V3,kde2d:X3,projection:nP},Symbol.toStringTag,{value:"Module"}));function Dse(e,t){var n,r=1;e==null&&(e=0),t==null&&(t=0);function i(){var s,o=n.length,a,l=0,u=0;for(s=0;s=(f=(a+u)/2))?a=f:u=f,(m=n>=(d=(l+c)/2))?l=d:c=d,i=s,!(s=s[y=m<<1|g]))return i[y]=o,e;if(h=+e._x.call(null,s.data),p=+e._y.call(null,s.data),t===h&&n===p)return o.next=s,i?i[y]=o:e._root=o,e;do i=i?i[y]=new Array(4):e._root=new Array(4),(g=t>=(f=(a+u)/2))?a=f:u=f,(m=n>=(d=(l+c)/2))?l=d:c=d;while((y=m<<1|g)===(b=(p>=d)<<1|h>=f));return i[b]=s,i[y]=o,e}function Tse(e){var t,n,r=e.length,i,s,o=new Array(r),a=new Array(r),l=1/0,u=1/0,c=-1/0,f=-1/0;for(n=0;nc&&(c=i),sf&&(f=s));if(l>c||u>f)return this;for(this.cover(l,u).cover(c,f),n=0;ne||e>=i||r>t||t>=s;)switch(u=(tc||(a=p.y0)>f||(l=p.x1)=y)<<1|e>=m)&&(p=d[d.length-1],d[d.length-1]=d[d.length-1-g],d[d.length-1-g]=p)}else{var b=e-+this._x.call(null,h.data),x=t-+this._y.call(null,h.data),_=b*b+x*x;if(_=(d=(o+l)/2))?o=d:l=d,(g=f>=(h=(a+u)/2))?a=h:u=h,t=n,!(n=n[m=g<<1|p]))return this;if(!n.length)break;(t[m+1&3]||t[m+2&3]||t[m+3&3])&&(r=t,y=m)}for(;n.data!==e;)if(i=n,!(n=n.next))return this;return(s=n.next)&&delete n.next,i?(s?i.next=s:delete i.next,this):t?(s?t[m]=s:delete t[m],(n=t[0]||t[1]||t[2]||t[3])&&n===(t[3]||t[2]||t[1]||t[0])&&!n.length&&(r?r[y]=n:this._root=n),this):(this._root=s,this)}function Pse(e){for(var t=0,n=e.length;td.index){var M=h-k.x-k.vx,O=p-k.y-k.vy,P=M*M+O*O;P<$*$&&(M===0&&(M=Hl(r),P+=M*M),O===0&&(O=Hl(r),P+=O*O),P=($-(P=Math.sqrt(P)))/P*i,d.vx+=(M*=P)*($=(S*=S)/(m+S)),d.vy+=(O*=P)*$,k.vx-=M*($=1-$),k.vy-=O*$)}return}return _>h+$||Ap+$||Eu.r&&(u.r=u[c].r)}function l(){if(t){var u,c=t.length,f;for(n=new Array(c),u=0;u[t(w,A,o),w])),_;for(m=0,a=new Array(y);m{}};function iP(){for(var e=0,t=arguments.length,n={},r;e=0&&(r=n.slice(i+1),n=n.slice(0,i)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:r}})}v1.prototype=iP.prototype={constructor:v1,on:function(e,t){var n=this._,r=Qse(e+"",n),i,s=-1,o=r.length;if(arguments.length<2){for(;++s0)for(var n=new Array(i),r=0,i,s;r=0&&e._call.call(void 0,t),e=e._next;--Yd}function H4(){Yc=(Wv=Sg.now())+Eb,Yd=Rp=0;try{noe()}finally{Yd=0,ioe(),Yc=0}}function roe(){var e=Sg.now(),t=e-Wv;t>sP&&(Eb-=t,Wv=e)}function ioe(){for(var e,t=qv,n,r=1/0;t;)t._call?(r>t._time&&(r=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:qv=n);Np=e,FE(r)}function FE(e){if(!Yd){Rp&&(Rp=clearTimeout(Rp));var t=e-Yc;t>24?(e<1/0&&(Rp=setTimeout(H4,e-Sg.now()-Eb)),ip&&(ip=clearInterval(ip))):(ip||(Wv=Sg.now(),ip=setInterval(roe,sP)),Yd=1,oP(H4))}}function soe(e,t,n){var r=new Hv,i=t;return t==null?(r.restart(e,t,n),r):(r._restart=r.restart,r.restart=function(s,o,a){o=+o,a=a==null?oC():+a,r._restart(function l(u){u+=i,r._restart(l,i+=o,a),s(u)},o,a)},r.restart(e,t,n),r)}const ooe=1664525,aoe=1013904223,G4=4294967296;function loe(){let e=1;return()=>(e=(ooe*e+aoe)%G4)/G4}function uoe(e){return e.x}function coe(e){return e.y}var foe=10,doe=Math.PI*(3-Math.sqrt(5));function hoe(e){var t,n=1,r=.001,i=1-Math.pow(r,1/300),s=0,o=.6,a=new Map,l=aP(f),u=iP("tick","end"),c=loe();e==null&&(e=[]);function f(){d(),u.call("tick",t),n1?(m==null?a.delete(g):a.set(g,p(m)),t):a.get(g)},find:function(g,m,y){var b=0,x=e.length,_,w,A,E,k;for(y==null?y=1/0:y*=y,b=0;b1?(u.on(g,m),t):u.on(g)}}}function poe(){var e,t,n,r,i=mi(-30),s,o=1,a=1/0,l=.81;function u(h){var p,g=e.length,m=iC(e,uoe,coe).visitAfter(f);for(r=h,p=0;p=a)return;(h.data!==t||h.next)&&(y===0&&(y=Hl(n),_+=y*y),b===0&&(b=Hl(n),_+=b*b),_=0;)n.tick();else if(n.stopped()&&n.restart(),!r)return t.StopPropagation}return this.finish(e,t)},finish(e,t){const n=t.dataflow;for(let a=this._argops,l=0,u=a.length,c;le.touch(t).run()}function boe(e,t){const n=hoe(e),r=n.stop,i=n.restart;let s=!1;return n.stopped=()=>s,n.restart=()=>(s=!1,i()),n.stop=()=>(s=!0,r()),uP(n,t,!0).on("end",()=>s=!0)}function uP(e,t,n,r){var i=Be(t.forces),s,o,a,l;for(s=0,o=DE.length;st(r,n):t)}const Eoe=Object.freeze(Object.defineProperty({__proto__:null,force:aC},Symbol.toStringTag,{value:"Module"}));function Aoe(e,t){return e.parent===t.parent?1:2}function koe(e){return e.reduce(Soe,0)/e.length}function Soe(e,t){return e+t.x}function Coe(e){return 1+e.reduce($oe,0)}function $oe(e,t){return Math.max(e,t.y)}function Foe(e){for(var t;t=e.children;)e=t[0];return e}function Doe(e){for(var t;t=e.children;)e=t[t.length-1];return e}function Moe(){var e=Aoe,t=1,n=1,r=!1;function i(s){var o,a=0;s.eachAfter(function(d){var h=d.children;h?(d.x=koe(h),d.y=Coe(h)):(d.x=o?a+=e(d,o):0,d.y=0,o=d)});var l=Foe(s),u=Doe(s),c=l.x-e(l,u)/2,f=u.x+e(u,l)/2;return s.eachAfter(r?function(d){d.x=(d.x-s.x)*t,d.y=(s.y-d.y)*n}:function(d){d.x=(d.x-c)/(f-c)*t,d.y=(1-(s.y?d.y/s.y:1))*n})}return i.separation=function(s){return arguments.length?(e=s,i):e},i.size=function(s){return arguments.length?(r=!1,t=+s[0],n=+s[1],i):r?null:[t,n]},i.nodeSize=function(s){return arguments.length?(r=!0,t=+s[0],n=+s[1],i):r?[t,n]:null},i}function Toe(e){var t=0,n=e.children,r=n&&n.length;if(!r)t=1;else for(;--r>=0;)t+=n[r].value;e.value=t}function Roe(){return this.eachAfter(Toe)}function Noe(e,t){let n=-1;for(const r of this)e.call(t,r,++n,this);return this}function Ooe(e,t){for(var n=this,r=[n],i,s,o=-1;n=r.pop();)if(e.call(t,n,++o,this),i=n.children)for(s=i.length-1;s>=0;--s)r.push(i[s]);return this}function Loe(e,t){for(var n=this,r=[n],i=[],s,o,a,l=-1;n=r.pop();)if(i.push(n),s=n.children)for(o=0,a=s.length;o=0;)n+=r[i].value;t.value=n})}function Boe(e){return this.eachBefore(function(t){t.children&&t.children.sort(e)})}function zoe(e){for(var t=this,n=joe(t,e),r=[t];t!==n;)t=t.parent,r.push(t);for(var i=r.length;e!==n;)r.splice(i,0,e),e=e.parent;return r}function joe(e,t){if(e===t)return e;var n=e.ancestors(),r=t.ancestors(),i=null;for(e=n.pop(),t=r.pop();e===t;)i=e,e=n.pop(),t=r.pop();return i}function Uoe(){for(var e=this,t=[e];e=e.parent;)t.push(e);return t}function qoe(){return Array.from(this)}function Woe(){var e=[];return this.eachBefore(function(t){t.children||e.push(t)}),e}function Hoe(){var e=this,t=[];return e.each(function(n){n!==e&&t.push({source:n.parent,target:n})}),t}function*Goe(){var e=this,t,n=[e],r,i,s;do for(t=n.reverse(),n=[];e=t.pop();)if(yield e,r=e.children)for(i=0,s=r.length;i=0;--a)i.push(s=o[a]=new Vd(o[a])),s.parent=r,s.depth=r.depth+1;return n.eachBefore(cP)}function Yoe(){return lC(this).eachBefore(Koe)}function Voe(e){return e.children}function Xoe(e){return Array.isArray(e)?e[1]:null}function Koe(e){e.data.value!==void 0&&(e.value=e.data.value),e.data=e.data.data}function cP(e){var t=0;do e.height=t;while((e=e.parent)&&e.height<++t)}function Vd(e){this.data=e,this.depth=this.height=0,this.parent=null}Vd.prototype=lC.prototype={constructor:Vd,count:Roe,each:Noe,eachAfter:Loe,eachBefore:Ooe,find:Ioe,sum:Poe,sort:Boe,path:zoe,ancestors:Uoe,descendants:qoe,leaves:Woe,links:Hoe,copy:Yoe,[Symbol.iterator]:Goe};function y1(e){return e==null?null:fP(e)}function fP(e){if(typeof e!="function")throw new Error;return e}function lc(){return 0}function Yf(e){return function(){return e}}const Zoe=1664525,Joe=1013904223,V4=4294967296;function Qoe(){let e=1;return()=>(e=(Zoe*e+Joe)%V4)/V4}function eae(e){return typeof e=="object"&&"length"in e?e:Array.from(e)}function tae(e,t){let n=e.length,r,i;for(;n;)i=t()*n--|0,r=e[n],e[n]=e[i],e[i]=r;return e}function nae(e,t){for(var n=0,r=(e=tae(Array.from(e),t)).length,i=[],s,o;n0&&n*n>r*r+i*i}function Lx(e,t){for(var n=0;n1e-6?(M+Math.sqrt(M*M-4*$*O))/(2*$):O/M);return{x:r+A+E*P,y:i+k+S*P,r:P}}function X4(e,t,n){var r=e.x-t.x,i,s,o=e.y-t.y,a,l,u=r*r+o*o;u?(s=t.r+n.r,s*=s,l=e.r+n.r,l*=l,s>l?(i=(u+l-s)/(2*u),a=Math.sqrt(Math.max(0,l/u-i*i)),n.x=e.x-i*r-a*o,n.y=e.y-i*o+a*r):(i=(u+s-l)/(2*u),a=Math.sqrt(Math.max(0,s/u-i*i)),n.x=t.x+i*r-a*o,n.y=t.y+i*o+a*r)):(n.x=t.x+n.r,n.y=t.y)}function K4(e,t){var n=e.r+t.r-1e-6,r=t.x-e.x,i=t.y-e.y;return n>0&&n*n>r*r+i*i}function Z4(e){var t=e._,n=e.next._,r=t.r+n.r,i=(t.x*n.r+n.x*t.r)/r,s=(t.y*n.r+n.y*t.r)/r;return i*i+s*s}function km(e){this._=e,this.next=null,this.previous=null}function oae(e,t){if(!(s=(e=eae(e)).length))return 0;var n,r,i,s,o,a,l,u,c,f,d;if(n=e[0],n.x=0,n.y=0,!(s>1))return n.r;if(r=e[1],n.x=-r.r,r.x=n.r,r.y=0,!(s>2))return n.r+r.r;X4(r,n,i=e[2]),n=new km(n),r=new km(r),i=new km(i),n.next=i.previous=r,r.next=n.previous=i,i.next=r.previous=n;e:for(l=3;lhae(n(_,w,i))),b=y.map(nM),x=new Set(y).add("");for(const _ of b)x.has(_)||(x.add(_),y.push(_),b.push(nM(_)),s.push(Px));o=(_,w)=>y[w],a=(_,w)=>b[w]}for(c=0,l=s.length;c=0&&(h=s[y],h.data===Px);--y)h.data=null}if(f.parent=cae,f.eachBefore(function(y){y.depth=y.parent.depth+1,--l}).eachBefore(cP),f.parent=null,l>0)throw new Error("cycle");return f}return r.id=function(i){return arguments.length?(e=y1(i),r):e},r.parentId=function(i){return arguments.length?(t=y1(i),r):t},r.path=function(i){return arguments.length?(n=y1(i),r):n},r}function hae(e){e=`${e}`;let t=e.length;return ME(e,t-1)&&!ME(e,t-2)&&(e=e.slice(0,-1)),e[0]==="/"?e:`/${e}`}function nM(e){let t=e.length;if(t<2)return"";for(;--t>1&&!ME(e,t););return e.slice(0,t)}function ME(e,t){if(e[t]==="/"){let n=0;for(;t>0&&e[--t]==="\\";)++n;if((n&1)===0)return!0}return!1}function pae(e,t){return e.parent===t.parent?1:2}function Bx(e){var t=e.children;return t?t[0]:e.t}function zx(e){var t=e.children;return t?t[t.length-1]:e.t}function gae(e,t,n){var r=n/(t.i-e.i);t.c-=r,t.s+=n,e.c+=r,t.z+=n,t.m+=n}function mae(e){for(var t=0,n=0,r=e.children,i=r.length,s;--i>=0;)s=r[i],s.z+=t,s.m+=t,t+=s.s+(n+=s.c)}function vae(e,t,n){return e.a.parent===t.parent?e.a:n}function b1(e,t){this._=e,this.parent=null,this.children=null,this.A=null,this.a=this,this.z=0,this.m=0,this.c=0,this.s=0,this.t=null,this.i=t}b1.prototype=Object.create(Vd.prototype);function yae(e){for(var t=new b1(e,0),n,r=[t],i,s,o,a;n=r.pop();)if(s=n._.children)for(n.children=new Array(a=s.length),o=a-1;o>=0;--o)r.push(i=n.children[o]=new b1(s[o],o)),i.parent=n;return(t.parent=new b1(null,0)).children=[t],t}function bae(){var e=pae,t=1,n=1,r=null;function i(u){var c=yae(u);if(c.eachAfter(s),c.parent.m=-c.z,c.eachBefore(o),r)u.eachBefore(l);else{var f=u,d=u,h=u;u.eachBefore(function(b){b.xd.x&&(d=b),b.depth>h.depth&&(h=b)});var p=f===d?1:e(f,d)/2,g=p-f.x,m=t/(d.x+p+g),y=n/(h.depth||1);u.eachBefore(function(b){b.x=(b.x+g)*m,b.y=b.depth*y})}return u}function s(u){var c=u.children,f=u.parent.children,d=u.i?f[u.i-1]:null;if(c){mae(u);var h=(c[0].z+c[c.length-1].z)/2;d?(u.z=d.z+e(u._,d._),u.m=u.z-h):u.z=h}else d&&(u.z=d.z+e(u._,d._));u.parent.A=a(u,d,u.parent.A||f[0])}function o(u){u._.x=u.z+u.parent.m,u.m+=u.parent.m}function a(u,c,f){if(c){for(var d=u,h=u,p=c,g=d.parent.children[0],m=d.m,y=h.m,b=p.m,x=g.m,_;p=zx(p),d=Bx(d),p&&d;)g=Bx(g),h=zx(h),h.a=u,_=p.z+b-d.z-m+e(p._,d._),_>0&&(gae(vae(p,u,f),u,_),m+=_,y+=_),b+=p.m,m+=d.m,x+=g.m,y+=h.m;p&&!zx(h)&&(h.t=p,h.m+=b-y),d&&!Bx(g)&&(g.t=d,g.m+=m-x,f=u)}return f}function l(u){u.x*=t,u.y=u.depth*n}return i.separation=function(u){return arguments.length?(e=u,i):e},i.size=function(u){return arguments.length?(r=!1,t=+u[0],n=+u[1],i):r?null:[t,n]},i.nodeSize=function(u){return arguments.length?(r=!0,t=+u[0],n=+u[1],i):r?[t,n]:null},i}function Ab(e,t,n,r,i){for(var s=e.children,o,a=-1,l=s.length,u=e.value&&(i-n)/e.value;++ab&&(b=u),A=m*m*w,x=Math.max(b/A,A/y),x>_){m-=u;break}_=x}o.push(l={value:m,dice:h1?r:1)},n})(gP);function xae(){var e=vP,t=!1,n=1,r=1,i=[0],s=lc,o=lc,a=lc,l=lc,u=lc;function c(d){return d.x0=d.y0=0,d.x1=n,d.y1=r,d.eachBefore(f),i=[0],t&&d.eachBefore(pP),d}function f(d){var h=i[d.depth],p=d.x0+h,g=d.y0+h,m=d.x1-h,y=d.y1-h;m=d-1){var b=s[f];b.x0=p,b.y0=g,b.x1=m,b.y1=y;return}for(var x=u[f],_=h/2+x,w=f+1,A=d-1;w>>1;u[E]<_?w=E+1:A=E}_-u[w-1]y-g){var $=h?(p*S+m*k)/h:m;c(f,w,k,p,g,$,y),c(w,d,S,$,g,m,y)}else{var M=h?(g*S+y*k)/h:y;c(f,w,k,p,g,m,M),c(w,d,S,p,M,m,y)}}}function wae(e,t,n,r,i){(e.depth&1?Ab:S0)(e,t,n,r,i)}const Eae=(function e(t){function n(r,i,s,o,a){if((l=r._squarify)&&l.ratio===t)for(var l,u,c,f,d=-1,h,p=l.length,g=r.value;++d1?r:1)},n})(gP);function TE(e,t,n){const r={};return e.each(i=>{const s=i.data;n(s)&&(r[t(s)]=i)}),e.lookup=r,e}function uC(e){ie.call(this,null,e)}uC.Definition={type:"Nest",metadata:{treesource:!0,changes:!0},params:[{name:"keys",type:"field",array:!0},{name:"generate",type:"boolean"}]};const Aae=e=>e.values;Me(uC,ie,{transform(e,t){t.source||le("Nest transform requires an upstream data source.");var n=e.generate,r=e.modified(),i=t.clone(),s=this.value;return(!s||r||t.changed())&&(s&&s.each(o=>{o.children&&Py(o.data)&&i.rem.push(o.data)}),this.value=s=lC({values:Be(e.keys).reduce((o,a)=>(o.key(a),o),kae()).entries(i.source)},Aae),n&&s.each(o=>{o.children&&(o=Zt(o.data),i.add.push(o),i.source.push(o))}),TE(s,ot,ot)),i.source.root=s,i}});function kae(){const e=[],t={entries:i=>r(n(i,0),0),key:i=>(e.push(i),t)};function n(i,s){if(s>=e.length)return i;const o=i.length,a=e[s++],l={},u={};let c=-1,f,d,h;for(;++ce.length)return i;const o=[];for(const a in i)o.push({key:a,values:r(i[a],s)});return o}return t}function ml(e){ie.call(this,null,e)}const Sae=(e,t)=>e.parent===t.parent?1:2;Me(ml,ie,{transform(e,t){(!t.source||!t.source.root)&&le(this.constructor.name+" transform requires a backing tree data source.");const n=this.layout(e.method),r=this.fields,i=t.source.root,s=e.as||r;e.field?i.sum(e.field):i.count(),e.sort&&i.sort(pf(e.sort,o=>o.data)),Cae(n,this.params,e),n.separation&&n.separation(e.separation!==!1?Sae:gh);try{this.value=n(i)}catch(o){le(o)}return i.each(o=>$ae(o,r,s)),t.reflow(e.modified()).modifies(s).modifies("leaf")}});function Cae(e,t,n){for(let r,i=0,s=t.length;is[ot(o)]=1),r.each(o=>{const a=o.data,l=o.parent&&o.parent.data;l&&s[ot(a)]&&s[ot(l)]&&i.add.push(Zt({source:l,target:a}))}),this.value=i.add):t.changed(t.MOD)&&(t.visit(t.MOD,o=>s[ot(o)]=1),n.forEach(o=>{(s[ot(o.source)]||s[ot(o.target)])&&i.mod.push(o)})),i}});const iM={binary:_ae,dice:S0,slice:Ab,slicedice:wae,squarify:vP,resquarify:Eae},LE=["x0","y0","x1","y1","depth","children"];function gC(e){ml.call(this,e)}gC.Definition={type:"Treemap",metadata:{tree:!0,modifies:!0},params:[{name:"field",type:"field"},{name:"sort",type:"compare"},{name:"method",type:"enum",default:"squarify",values:["squarify","resquarify","binary","dice","slice","slicedice"]},{name:"padding",type:"number",default:0},{name:"paddingInner",type:"number",default:0},{name:"paddingOuter",type:"number",default:0},{name:"paddingTop",type:"number",default:0},{name:"paddingRight",type:"number",default:0},{name:"paddingBottom",type:"number",default:0},{name:"paddingLeft",type:"number",default:0},{name:"ratio",type:"number",default:1.618033988749895},{name:"round",type:"boolean",default:!1},{name:"size",type:"number",array:!0,length:2},{name:"as",type:"string",array:!0,length:LE.length,default:LE}]};Me(gC,ml,{layout(){const e=xae();return e.ratio=t=>{const n=e.tile();n.ratio&&e.tile(n.ratio(t))},e.method=t=>{Ue(iM,t)?e.tile(iM[t]):le("Unrecognized Treemap layout method: "+t)},e},params:["method","ratio","size","round","padding","paddingInner","paddingOuter","paddingTop","paddingRight","paddingBottom","paddingLeft"],fields:LE});const Fae=Object.freeze(Object.defineProperty({__proto__:null,nest:uC,pack:cC,partition:fC,stratify:dC,tree:hC,treelinks:pC,treemap:gC},Symbol.toStringTag,{value:"Module"})),jx=4278190080;function Dae(e,t){const n=e.bitmap();return(t||[]).forEach(r=>n.set(e(r.boundary[0]),e(r.boundary[3]))),[n,void 0]}function Mae(e,t,n,r,i){const s=e.width,o=e.height,a=r||i,l=eu(s,o).getContext("2d"),u=eu(s,o).getContext("2d"),c=a&&eu(s,o).getContext("2d");n.forEach(k=>x1(l,k,!1)),x1(u,t,!1),a&&x1(c,t,!0);const f=Ux(l,s,o),d=Ux(u,s,o),h=a&&Ux(c,s,o),p=e.bitmap(),g=a&&e.bitmap();let m,y,b,x,_,w,A,E;for(y=0;y{i.items.forEach(s=>x1(e,s.items,n))}):gs[r].draw(e,{items:n?t.map(Tae):t})}function Tae(e){const t=By(e,{});return t.stroke&&t.strokeOpacity!==0||t.fill&&t.fillOpacity!==0?{...t,strokeOpacity:1,stroke:"#000",fillOpacity:0}:t}const Na=5,li=31,Cg=32,Rl=new Uint32Array(Cg+1),ro=new Uint32Array(Cg+1);ro[0]=0;Rl[0]=~ro[0];for(let e=1;e<=Cg;++e)ro[e]=ro[e-1]<<1|1,Rl[e]=~ro[e];function Rae(e,t){const n=new Uint32Array(~~((e*t+Cg)/Cg));function r(s,o){n[s]|=o}function i(s,o){n[s]&=o}return{array:n,get:(s,o)=>{const a=o*e+s;return n[a>>>Na]&1<<(a&li)},set:(s,o)=>{const a=o*e+s;r(a>>>Na,1<<(a&li))},clear:(s,o)=>{const a=o*e+s;i(a>>>Na,~(1<<(a&li)))},getRange:(s,o,a,l)=>{let u=l,c,f,d,h;for(;u>=o;--u)if(c=u*e+s,f=u*e+a,d=c>>>Na,h=f>>>Na,d===h){if(n[d]&Rl[c&li]&ro[(f&li)+1])return!0}else{if(n[d]&Rl[c&li]||n[h]&ro[(f&li)+1])return!0;for(let p=d+1;p{let u,c,f,d,h;for(;o<=l;++o)if(u=o*e+s,c=o*e+a,f=u>>>Na,d=c>>>Na,f===d)r(f,Rl[u&li]&ro[(c&li)+1]);else for(r(f,Rl[u&li]),r(d,ro[(c&li)+1]),h=f+1;h{let u,c,f,d,h;for(;o<=l;++o)if(u=o*e+s,c=o*e+a,f=u>>>Na,d=c>>>Na,f===d)i(f,ro[u&li]|Rl[(c&li)+1]);else for(i(f,ro[u&li]),i(d,Rl[(c&li)+1]),h=f+1;hs<0||o<0||l>=t||a>=e}}function Nae(e,t,n){const r=Math.max(1,Math.sqrt(e*t/1e6)),i=~~((e+2*n+r)/r),s=~~((t+2*n+r)/r),o=a=>~~((a+n)/r);return o.invert=a=>a*r-n,o.bitmap=()=>Rae(i,s),o.ratio=r,o.padding=n,o.width=e,o.height=t,o}function Oae(e,t,n,r){const i=e.width,s=e.height;return function(o){const a=o.datum.datum.items[r].items,l=a.length,u=o.datum.fontSize,c=us.width(o.datum,o.datum.text);let f=0,d,h,p,g,m,y,b;for(let x=0;x=f&&(f=b,o.x=m,o.y=y);return m=c/2,y=u/2,d=o.x-m,h=o.x+m,p=o.y-y,g=o.y+y,o.align="center",d<0&&h<=i?o.align="left":0<=d&&ii||t-(o=r/2)<0||t+o>s}function Gl(e,t,n,r,i,s,o,a){const l=i*s/(r*2),u=e(t-l),c=e(t+l),f=e(n-(s=s/2)),d=e(n+s);return o.outOfBounds(u,f,c,d)||o.getRange(u,f,c,d)||a&&a.getRange(u,f,c,d)}function Lae(e,t,n,r){const i=e.width,s=e.height,o=t[0],a=t[1];function l(u,c,f,d,h){const p=e.invert(u),g=e.invert(c);let m=f,y=s,b;if(!Gv(p,g,d,h,i,s)&&!Gl(e,p,g,h,d,m,o,a)&&!Gl(e,p,g,h,d,h,o,null)){for(;y-m>=1;)b=(m+y)/2,Gl(e,p,g,h,d,b,o,a)?y=b:m=b;if(m>f)return[p,g,m,!0]}}return function(u){const c=u.datum.datum.items[r].items,f=c.length,d=u.datum.fontSize,h=us.width(u.datum,u.datum.text);let p=n?d:0,g=!1,m=!1,y=0,b,x,_,w,A,E,k,S,$,M,O,P,T,F,N,U,j;for(let W=0;Wx&&(j=b,b=x,x=j),_>w&&(j=_,_=w,w=j),$=e(b),O=e(x),M=~~(($+O)/2),P=e(_),F=e(w),T=~~((P+F)/2),k=M;k>=$;--k)for(S=T;S>=P;--S)U=l(k,S,p,h,d),U&&([u.x,u.y,p,g]=U);for(k=M;k<=O;++k)for(S=T;S<=F;++S)U=l(k,S,p,h,d),U&&([u.x,u.y,p,g]=U);!g&&!n&&(N=Math.abs(x-b+w-_),A=(b+x)/2,E=(_+w)/2,N>=y&&!Gv(A,E,h,d,i,s)&&!Gl(e,A,E,d,h,d,o,null)&&(y=N,u.x=A,u.y=E,m=!0))}return g||m?(A=h/2,E=d/2,o.setRange(e(u.x-A),e(u.y-E),e(u.x+A),e(u.y+E)),u.align="center",u.baseline="middle",!0):!1}}const Iae=[-1,-1,1,1],Pae=[-1,1,-1,1];function Bae(e,t,n,r){const i=e.width,s=e.height,o=t[0],a=t[1],l=e.bitmap();return function(u){const c=u.datum.datum.items[r].items,f=c.length,d=u.datum.fontSize,h=us.width(u.datum,u.datum.text),p=[];let g=n?d:0,m=!1,y=!1,b=0,x,_,w,A,E,k,S,$,M,O,P,T;for(let F=0;F=1;)P=(M+O)/2,Gl(e,E,k,d,h,P,o,a)?O=P:M=P;M>g&&(u.x=E,u.y=k,g=M,m=!0)}}!m&&!n&&(T=Math.abs(_-x+A-w),E=(x+_)/2,k=(w+A)/2,T>=b&&!Gv(E,k,h,d,i,s)&&!Gl(e,E,k,d,h,d,o,null)&&(b=T,u.x=E,u.y=k,y=!0))}return m||y?(E=h/2,k=d/2,o.setRange(e(u.x-E),e(u.y-k),e(u.x+E),e(u.y+k)),u.align="center",u.baseline="middle",!0):!1}}const zae=["right","center","left"],jae=["bottom","middle","top"];function Uae(e,t,n,r){const i=e.width,s=e.height,o=t[0],a=t[1],l=r.length;return function(u){const c=u.boundary,f=u.datum.fontSize;if(c[2]<0||c[5]<0||c[0]>i||c[3]>s)return!1;let d=u.textWidth??0,h,p,g,m,y,b,x,_,w,A,E,k,S,$,M;for(let O=0;O>>2&3)-1,g=h===0&&p===0||r[O]<0,m=h&&p?Math.SQRT1_2:1,y=r[O]<0?-1:1,b=c[1+h]+r[O]*h*m,E=c[4+p]+y*f*p/2+r[O]*p*m,_=E-f/2,w=E+f/2,k=e(b),$=e(_),M=e(w),!d)if(sM(k,k,$,M,o,a,b,b,_,w,c,g))d=us.width(u.datum,u.datum.text);else continue;if(A=b+y*d*h/2,b=A-d/2,x=A+d/2,k=e(b),S=e(x),sM(k,S,$,M,o,a,b,x,_,w,c,g))return u.x=h?h*y<0?x:b:A,u.y=p?p*y<0?w:_:E,u.align=zae[h*y+1],u.baseline=jae[p*y+1],o.setRange(k,$,S,M),!0}return!1}}function sM(e,t,n,r,i,s,o,a,l,u,c,f){return!(i.outOfBounds(e,n,t,r)||(f&&s||i).getRange(e,n,t,r))}const qx=0,Wx=4,Hx=8,Gx=0,Yx=1,Vx=2,qae={"top-left":qx+Gx,top:qx+Yx,"top-right":qx+Vx,left:Wx+Gx,middle:Wx+Yx,right:Wx+Vx,"bottom-left":Hx+Gx,bottom:Hx+Yx,"bottom-right":Hx+Vx},Wae={naive:Oae,"reduced-search":Lae,floodfill:Bae};function Hae(e,t,n,r,i,s,o,a,l,u,c){if(!e.length)return e;const f=Math.max(r.length,i.length),d=Gae(r,f),h=Yae(i,f),p=Vae(e[0].datum),g=p==="group"&&e[0].datum.items[l].marktype,m=g==="area",y=Xae(p,g,a,l),b=u===null||u===1/0,x=m&&c==="naive";let _=-1,w=-1;const A=e.map($=>{const M=b?us.width($,$.text):void 0;return _=Math.max(_,M),w=Math.max(w,$.fontSize),{datum:$,opacity:0,x:void 0,y:void 0,align:void 0,baseline:void 0,boundary:y($),textWidth:M}});u=u===null||u===1/0?Math.max(_,w)+Math.max(...r):u;const E=Nae(t[0],t[1],u);let k;if(!x){n&&A.sort((O,P)=>n(O.datum,P.datum));let $=!1;for(let O=0;OO.datum);k=s.length||M?Mae(E,M||[],s,$,m):Dae(E,o&&A)}const S=m?Wae[c](E,k,o,l):Uae(E,k,h,d);return A.forEach($=>$.opacity=+S($)),A}function Gae(e,t){const n=new Float64Array(t),r=e.length;for(let i=0;i[s.x,s.x,s.x,s.y,s.y,s.y];return e?e==="line"||e==="area"?s=>i(s.datum):t==="line"?s=>{const o=s.datum.items[r].items;return i(o.length?o[n==="start"?0:o.length-1]:{x:NaN,y:NaN})}:s=>{const o=s.datum.bounds;return[o.x1,(o.x1+o.x2)/2,o.x2,o.y1,(o.y1+o.y2)/2,o.y2]}:i}const IE=["x","y","opacity","align","baseline"],yP=["top-left","left","bottom-left","top","bottom","top-right","right","bottom-right"];function mC(e){ie.call(this,null,e)}mC.Definition={type:"Label",metadata:{modifies:!0},params:[{name:"size",type:"number",array:!0,length:2,required:!0},{name:"sort",type:"compare"},{name:"anchor",type:"string",array:!0,default:yP},{name:"offset",type:"number",array:!0,default:[1]},{name:"padding",type:"number",default:0,null:!0},{name:"lineAnchor",type:"string",values:["start","end"],default:"end"},{name:"markIndex",type:"number",default:0},{name:"avoidBaseMark",type:"boolean",default:!0},{name:"avoidMarks",type:"data",array:!0},{name:"method",type:"string",default:"naive"},{name:"as",type:"string",array:!0,length:IE.length,default:IE}]};Me(mC,ie,{transform(e,t){function n(s){const o=e[s];return Tt(o)&&t.modified(o.fields)}const r=e.modified();if(!(r||t.changed(t.ADD_REM)||n("sort")))return;(!e.size||e.size.length!==2)&&le("Size parameter should be specified as a [width, height] array.");const i=e.as||IE;return Hae(t.materialize(t.SOURCE).source||[],e.size,e.sort,Be(e.offset==null?1:e.offset),Be(e.anchor||yP),e.avoidMarks||[],e.avoidBaseMark!==!1,e.lineAnchor||"end",e.markIndex||0,e.padding===void 0?0:e.padding,e.method||"naive").forEach(s=>{const o=s.datum;o[i[0]]=s.x,o[i[1]]=s.y,o[i[2]]=s.opacity,o[i[3]]=s.align,o[i[4]]=s.baseline}),t.reflow(r).modifies(i)}});const Kae=Object.freeze(Object.defineProperty({__proto__:null,label:mC},Symbol.toStringTag,{value:"Module"}));function bP(e,t){var n=[],r=function(c){return c(a)},i,s,o,a,l,u;if(t==null)n.push(e);else for(i={},s=0,o=e.length;s{SO(u,e.x,e.y,e.bandwidth||.3).forEach(c=>{const f={};for(let d=0;de==="poly"?t:e==="quad"?2:1;function yC(e){ie.call(this,null,e)}yC.Definition={type:"Regression",metadata:{generates:!0},params:[{name:"x",type:"field",required:!0},{name:"y",type:"field",required:!0},{name:"groupby",type:"field",array:!0},{name:"method",type:"string",default:"linear",values:Object.keys(PE)},{name:"order",type:"number",default:3},{name:"extent",type:"number",array:!0,length:2},{name:"params",type:"boolean",default:!1},{name:"as",type:"string",array:!0}]};Me(yC,ie,{transform(e,t){const n=t.fork(t.NO_SOURCE|t.NO_FIELDS);if(!this.value||t.changed()||e.modified()){const r=t.materialize(t.SOURCE).source,i=bP(r,e.groupby),s=(e.groupby||[]).map(Ln),o=e.method||"linear",a=e.order==null?3:e.order,l=Zae(o,a),u=e.as||[Ln(e.x),Ln(e.y)],c=PE[o],f=[];let d=e.extent;Ue(PE,o)||le("Invalid regression method: "+o),d!=null&&o==="log"&&d[0]<=0&&(t.dataflow.warn("Ignoring extent with values <= 0 for log regression."),d=null),i.forEach(h=>{if(h.length<=l){t.dataflow.warn("Skipping regression with more parameters than data points.");return}const g=c(h,e.x,e.y,a);if(e.params){f.push(Zt({keys:h.dims,coef:g.coef,rSquared:g.rSquared}));return}const m=d||aa(h,e.x),y=b=>{const x={};for(let _=0;_y([b,g.predict(b)])):Gy(g.predict,m,25,200).forEach(y)}),this.value&&(n.rem=this.value),this.value=n.add=n.source=f}return n}});const Jae=Object.freeze(Object.defineProperty({__proto__:null,loess:vC,regression:yC},Symbol.toStringTag,{value:"Module"})),tl=11102230246251565e-32,Ur=134217729,Qae=(3+8*tl)*tl;function Xx(e,t,n,r,i){let s,o,a,l,u=t[0],c=r[0],f=0,d=0;c>u==c>-u?(s=u,u=t[++f]):(s=c,c=r[++d]);let h=0;if(fu==c>-u?(o=u+s,a=s-(o-u),u=t[++f]):(o=c+s,a=s-(o-c),c=r[++d]),s=o,a!==0&&(i[h++]=a);fu==c>-u?(o=s+u,l=o-s,a=s-(o-l)+(u-l),u=t[++f]):(o=s+c,l=o-s,a=s-(o-l)+(c-l),c=r[++d]),s=o,a!==0&&(i[h++]=a);for(;f=T||-P>=T||(f=e-S,a=e-(S+f)+(f-i),f=n-$,u=n-($+f)+(f-i),f=t-M,l=t-(M+f)+(f-s),f=r-O,c=r-(O+f)+(f-s),a===0&&l===0&&u===0&&c===0)||(T=rle*o+Qae*Math.abs(P),P+=S*c+O*a-(M*u+$*l),P>=T||-P>=T))return P;_=a*O,d=Ur*a,h=d-(d-a),p=a-h,d=Ur*O,g=d-(d-O),m=O-g,w=p*m-(_-h*g-p*g-h*m),A=l*$,d=Ur*l,h=d-(d-l),p=l-h,d=Ur*$,g=d-(d-$),m=$-g,E=p*m-(A-h*g-p*g-h*m),y=w-E,f=w-y,ui[0]=w-(y+f)+(f-E),b=_+y,f=b-_,x=_-(b-f)+(y-f),y=x-A,f=x-y,ui[1]=x-(y+f)+(f-A),k=b+y,f=k-b,ui[2]=b-(k-f)+(y-f),ui[3]=k;const F=Xx(4,Pf,4,ui,oM);_=S*c,d=Ur*S,h=d-(d-S),p=S-h,d=Ur*c,g=d-(d-c),m=c-g,w=p*m-(_-h*g-p*g-h*m),A=M*u,d=Ur*M,h=d-(d-M),p=M-h,d=Ur*u,g=d-(d-u),m=u-g,E=p*m-(A-h*g-p*g-h*m),y=w-E,f=w-y,ui[0]=w-(y+f)+(f-E),b=_+y,f=b-_,x=_-(b-f)+(y-f),y=x-A,f=x-y,ui[1]=x-(y+f)+(f-A),k=b+y,f=k-b,ui[2]=b-(k-f)+(y-f),ui[3]=k;const N=Xx(F,oM,4,ui,aM);_=a*c,d=Ur*a,h=d-(d-a),p=a-h,d=Ur*c,g=d-(d-c),m=c-g,w=p*m-(_-h*g-p*g-h*m),A=l*u,d=Ur*l,h=d-(d-l),p=l-h,d=Ur*u,g=d-(d-u),m=u-g,E=p*m-(A-h*g-p*g-h*m),y=w-E,f=w-y,ui[0]=w-(y+f)+(f-E),b=_+y,f=b-_,x=_-(b-f)+(y-f),y=x-A,f=x-y,ui[1]=x-(y+f)+(f-A),k=b+y,f=k-b,ui[2]=b-(k-f)+(y-f),ui[3]=k;const U=Xx(N,aM,4,ui,lM);return lM[U-1]}function Sm(e,t,n,r,i,s){const o=(t-s)*(n-i),a=(e-i)*(r-s),l=o-a,u=Math.abs(o+a);return Math.abs(l)>=tle*u?l:-ile(e,t,n,r,i,s,u)}const uM=Math.pow(2,-52),Cm=new Uint32Array(512);class Yv{static from(t,n=ule,r=cle){const i=t.length,s=new Float64Array(i*2);for(let o=0;o>1;if(n>0&&typeof t[0]!="number")throw new Error("Expected coords to contain numbers.");this.coords=t;const r=Math.max(2*n-5,0);this._triangles=new Uint32Array(r*3),this._halfedges=new Int32Array(r*3),this._hashSize=Math.ceil(Math.sqrt(n)),this._hullPrev=new Uint32Array(n),this._hullNext=new Uint32Array(n),this._hullTri=new Uint32Array(n),this._hullHash=new Int32Array(this._hashSize),this._ids=new Uint32Array(n),this._dists=new Float64Array(n),this.update()}update(){const{coords:t,_hullPrev:n,_hullNext:r,_hullTri:i,_hullHash:s}=this,o=t.length>>1;let a=1/0,l=1/0,u=-1/0,c=-1/0;for(let S=0;Su&&(u=$),M>c&&(c=M),this._ids[S]=S}const f=(a+u)/2,d=(l+c)/2;let h,p,g;for(let S=0,$=1/0;S0&&(p=S,$=M)}let b=t[2*p],x=t[2*p+1],_=1/0;for(let S=0;SO&&(S[$++]=P,O=T)}this.hull=S.subarray(0,$),this.triangles=new Uint32Array(0),this.halfedges=new Uint32Array(0);return}if(Sm(m,y,b,x,w,A)<0){const S=p,$=b,M=x;p=g,b=w,x=A,g=S,w=$,A=M}const E=lle(m,y,b,x,w,A);this._cx=E.x,this._cy=E.y;for(let S=0;S0&&Math.abs(P-$)<=uM&&Math.abs(T-M)<=uM||($=P,M=T,O===h||O===p||O===g))continue;let F=0;for(let Z=0,Y=this._hashKey(P,T);Z=0;)if(N=U,N===F){N=-1;break}if(N===-1)continue;let j=this._addTriangle(N,O,r[N],-1,-1,i[N]);i[O]=this._legalize(j+2),i[N]=j,k++;let W=r[N];for(;U=r[W],Sm(P,T,t[2*W],t[2*W+1],t[2*U],t[2*U+1])<0;)j=this._addTriangle(W,O,U,i[O],-1,i[W]),i[O]=this._legalize(j+2),r[W]=W,k--,W=U;if(N===F)for(;U=n[N],Sm(P,T,t[2*U],t[2*U+1],t[2*N],t[2*N+1])<0;)j=this._addTriangle(U,O,N,-1,i[N],i[U]),this._legalize(j+2),i[U]=j,r[N]=N,k--,N=U;this._hullStart=n[O]=N,r[N]=n[W]=O,r[O]=W,s[this._hashKey(P,T)]=O,s[this._hashKey(t[2*N],t[2*N+1])]=N}this.hull=new Uint32Array(k);for(let S=0,$=this._hullStart;S0?3-n:1+n)/4}function Kx(e,t,n,r){const i=e-n,s=t-r;return i*i+s*s}function ole(e,t,n,r,i,s,o,a){const l=e-o,u=t-a,c=n-o,f=r-a,d=i-o,h=s-a,p=l*l+u*u,g=c*c+f*f,m=d*d+h*h;return l*(f*m-g*h)-u*(c*m-g*d)+p*(c*h-f*d)<0}function ale(e,t,n,r,i,s){const o=n-e,a=r-t,l=i-e,u=s-t,c=o*o+a*a,f=l*l+u*u,d=.5/(o*u-a*l),h=(u*c-a*f)*d,p=(o*f-l*c)*d;return h*h+p*p}function lle(e,t,n,r,i,s){const o=n-e,a=r-t,l=i-e,u=s-t,c=o*o+a*a,f=l*l+u*u,d=.5/(o*u-a*l),h=e+(u*c-a*f)*d,p=t+(o*f-l*c)*d;return{x:h,y:p}}function td(e,t,n,r){if(r-n<=20)for(let i=n+1;i<=r;i++){const s=e[i],o=t[s];let a=i-1;for(;a>=n&&t[e[a]]>o;)e[a+1]=e[a--];e[a+1]=s}else{const i=n+r>>1;let s=n+1,o=r;sp(e,i,s),t[e[n]]>t[e[r]]&&sp(e,n,r),t[e[s]]>t[e[r]]&&sp(e,s,r),t[e[n]]>t[e[s]]&&sp(e,n,s);const a=e[s],l=t[a];for(;;){do s++;while(t[e[s]]l);if(o=o-n?(td(e,t,s,r),td(e,t,n,o-1)):(td(e,t,n,o-1),td(e,t,s,r))}}function sp(e,t,n){const r=e[t];e[t]=e[n],e[n]=r}function ule(e){return e[0]}function cle(e){return e[1]}const cM=1e-6;class mc{constructor(){this._x0=this._y0=this._x1=this._y1=null,this._=""}moveTo(t,n){this._+=`M${this._x0=this._x1=+t},${this._y0=this._y1=+n}`}closePath(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")}lineTo(t,n){this._+=`L${this._x1=+t},${this._y1=+n}`}arc(t,n,r){t=+t,n=+n,r=+r;const i=t+r,s=n;if(r<0)throw new Error("negative radius");this._x1===null?this._+=`M${i},${s}`:(Math.abs(this._x1-i)>cM||Math.abs(this._y1-s)>cM)&&(this._+="L"+i+","+s),r&&(this._+=`A${r},${r},0,1,1,${t-r},${n}A${r},${r},0,1,1,${this._x1=i},${this._y1=s}`)}rect(t,n,r,i){this._+=`M${this._x0=this._x1=+t},${this._y0=this._y1=+n}h${+r}v${+i}h${-r}Z`}value(){return this._||null}}class BE{constructor(){this._=[]}moveTo(t,n){this._.push([t,n])}closePath(){this._.push(this._[0].slice())}lineTo(t,n){this._.push([t,n])}value(){return this._.length?this._:null}}let fle=class{constructor(t,[n,r,i,s]=[0,0,960,500]){if(!((i=+i)>=(n=+n))||!((s=+s)>=(r=+r)))throw new Error("invalid bounds");this.delaunay=t,this._circumcenters=new Float64Array(t.points.length*2),this.vectors=new Float64Array(t.points.length*2),this.xmax=i,this.xmin=n,this.ymax=s,this.ymin=r,this._init()}update(){return this.delaunay.update(),this._init(),this}_init(){const{delaunay:{points:t,hull:n,triangles:r},vectors:i}=this;let s,o;const a=this.circumcenters=this._circumcenters.subarray(0,r.length/3*2);for(let g=0,m=0,y=r.length,b,x;g1;)s-=2;for(let o=2;o0){if(n>=this.ymax)return null;(o=(this.ymax-n)/i)0){if(t>=this.xmax)return null;(o=(this.xmax-t)/r)this.xmax?2:0)|(nthis.ymax?8:0)}_simplify(t){if(t&&t.length>4){for(let n=0;n1e-10)return!1}return!0}function mle(e,t,n){return[e+Math.sin(e+t)*n,t+Math.cos(e-t)*n]}class bC{static from(t,n=hle,r=ple,i){return new bC("length"in t?vle(t,n,r,i):Float64Array.from(yle(t,n,r,i)))}constructor(t){this._delaunator=new Yv(t),this.inedges=new Int32Array(t.length/2),this._hullIndex=new Int32Array(t.length/2),this.points=this._delaunator.coords,this._init()}update(){return this._delaunator.update(),this._init(),this}_init(){const t=this._delaunator,n=this.points;if(t.hull&&t.hull.length>2&&gle(t)){this.collinear=Int32Array.from({length:n.length/2},(d,h)=>h).sort((d,h)=>n[2*d]-n[2*h]||n[2*d+1]-n[2*h+1]);const l=this.collinear[0],u=this.collinear[this.collinear.length-1],c=[n[2*l],n[2*l+1],n[2*u],n[2*u+1]],f=1e-8*Math.hypot(c[3]-c[1],c[2]-c[0]);for(let d=0,h=n.length/2;d0&&(this.triangles=new Int32Array(3).fill(-1),this.halfedges=new Int32Array(3).fill(-1),this.triangles[0]=i[0],o[i[0]]=1,i.length===2&&(o[i[1]]=0,this.triangles[1]=i[1],this.triangles[2]=i[1]))}voronoi(t){return new fle(this,t)}*neighbors(t){const{inedges:n,hull:r,_hullIndex:i,halfedges:s,triangles:o,collinear:a}=this;if(a){const f=a.indexOf(t);f>0&&(yield a[f-1]),f=0&&s!==r&&s!==i;)r=s;return s}_step(t,n,r){const{inedges:i,hull:s,_hullIndex:o,halfedges:a,triangles:l,points:u}=this;if(i[t]===-1||!u.length)return(t+1)%(u.length>>1);let c=t,f=Bf(n-u[t*2],2)+Bf(r-u[t*2+1],2);const d=i[t];let h=d;do{let p=l[h];const g=Bf(n-u[p*2],2)+Bf(r-u[p*2+1],2);if(g>5)*e[1]),m=null,y=u.length,b=-1,x=[],_=u.map(A=>({text:t(A),font:n(A),style:i(A),weight:s(A),rotate:o(A),size:~~(r(A)+1e-14),padding:a(A),xoff:0,yoff:0,x1:0,y1:0,x0:0,y0:0,hasText:!1,sprite:null,datum:A})).sort((A,E)=>E.size-A.size);++b>1,w.y=e[1]*(c()+.5)>>1,Ale(p,w,_,b),w.hasText&&h(g,w,m)&&(x.push(w),m?Sle(m,w):m=[{x:w.x+w.x0,y:w.y+w.y0},{x:w.x+w.x1,y:w.y+w.y1}],w.x-=e[0]>>1,w.y-=e[1]>>1)}return x};function d(p){p.width=p.height=1;var g=Math.sqrt(p.getContext("2d").getImageData(0,0,1,1).data.length>>2);p.width=(Ip<<5)/g,p.height=_1/g;var m=p.getContext("2d");return m.fillStyle=m.strokeStyle="red",m.textAlign="center",{context:m,ratio:g}}function h(p,g,m){for(var y=g.x,b=g.y,x=Math.hypot(e[0],e[1]),_=l(e),w=c()<.5?1:-1,A=-w,E,k,S;(E=_(A+=w))&&(k=~~E[0],S=~~E[1],!(Math.min(Math.abs(k),Math.abs(S))>=x));)if(g.x=y+k,g.y=b+S,!(g.x+g.x0<0||g.y+g.y0<0||g.x+g.x1>e[0]||g.y+g.y1>e[1])&&(!m||!kle(g,p,e[0]))&&(!m||Cle(g,m))){for(var $=g.sprite,M=g.width>>5,O=e[0]>>5,P=g.x-(M<<4),T=P&127,F=32-T,N=g.y1-g.y0,U=(g.y+g.y0)*O+(P>>5),j,W=0;W>>T:0);U+=O}return g.sprite=null,!0}return!1}return f.words=function(p){return arguments.length?(u=p,f):u},f.size=function(p){return arguments.length?(e=[+p[0],+p[1]],f):e},f.font=function(p){return arguments.length?(n=Hu(p),f):n},f.fontStyle=function(p){return arguments.length?(i=Hu(p),f):i},f.fontWeight=function(p){return arguments.length?(s=Hu(p),f):s},f.rotate=function(p){return arguments.length?(o=Hu(p),f):o},f.text=function(p){return arguments.length?(t=Hu(p),f):t},f.spiral=function(p){return arguments.length?(l=Dle[p]||p,f):l},f.fontSize=function(p){return arguments.length?(r=Hu(p),f):r},f.padding=function(p){return arguments.length?(a=Hu(p),f):a},f.random=function(p){return arguments.length?(c=p,f):c},f}function Ale(e,t,n,r){if(!t.sprite){var i=e.context,s=e.ratio;i.clearRect(0,0,(Ip<<5)/s,_1/s);var o=0,a=0,l=0,u=n.length,c,f,d,h,p;for(--r;++r>5<<5,d=~~Math.max(Math.abs(b+x),Math.abs(b-x))}else c=c+31>>5<<5;if(d>l&&(l=d),o+c>=Ip<<5&&(o=0,a+=l,l=0),a+d>=_1)break;i.translate((o+(c>>1))/s,(a+(d>>1))/s),t.rotate&&i.rotate(t.rotate*Zx),i.fillText(t.text,0,0),t.padding&&(i.lineWidth=2*t.padding,i.strokeText(t.text,0,0)),i.restore(),t.width=c,t.height=d,t.xoff=o,t.yoff=a,t.x1=c>>1,t.y1=d>>1,t.x0=-t.x1,t.y0=-t.y1,t.hasText=!0,o+=c}for(var w=i.getImageData(0,0,(Ip<<5)/s,_1/s).data,A=[];--r>=0;)if(t=n[r],!!t.hasText){for(c=t.width,f=c>>5,d=t.y1-t.y0,h=0;h>5),$=w[(a+p)*(Ip<<5)+(o+h)<<2]?1<<31-h%32:0;A[S]|=$,E|=$}E?k=p:(t.y0++,d--,p--,a++)}t.y1=t.y0+k,t.sprite=A.slice(0,(t.y1-t.y0)*f)}}}function kle(e,t,n){n>>=5;for(var r=e.sprite,i=e.width>>5,s=e.x-(i<<4),o=s&127,a=32-o,l=e.y1-e.y0,u=(e.y+e.y0)*n+(s>>5),c,f=0;f>>o:0))&t[u+d])return!0;u+=n}return!1}function Sle(e,t){var n=e[0],r=e[1];t.x+t.x0r.x&&(r.x=t.x+t.x1),t.y+t.y1>r.y&&(r.y=t.y+t.y1)}function Cle(e,t){return e.x+e.x1>t[0].x&&e.x+e.x0t[0].y&&e.y+e.y0g(p(m))}i.forEach(p=>{p[o[0]]=NaN,p[o[1]]=NaN,p[o[3]]=0});const u=s.words(i).text(e.text).size(e.size||[500,500]).padding(e.padding||1).spiral(e.spiral||"archimedean").rotate(e.rotate||0).font(e.font||"sans-serif").fontStyle(e.fontStyle||"normal").fontWeight(e.fontWeight||"normal").fontSize(a).random(Ps).layout(),c=s.size(),f=c[0]>>1,d=c[1]>>1,h=u.length;for(let p=0,g,m;pnew Uint8Array(e),Nle=e=>new Uint16Array(e),ng=e=>new Uint32Array(e);function Ole(){let e=8,t=[],n=ng(0),r=$m(0,e),i=$m(0,e);return{data:()=>t,seen:()=>n=Lle(n,t.length),add(s){for(let o=0,a=t.length,l=s.length,u;ot.length,curr:()=>r,prev:()=>i,reset:s=>i[s]=r[s],all:()=>e<257?255:e<65537?65535:4294967295,set(s,o){r[s]|=o},clear(s,o){r[s]&=~o},resize(s,o){const a=r.length;(s>a||o>e)&&(e=Math.max(o,e),r=$m(s,e,r),i=$m(s,e))}}}function Lle(e,t,n){return e.length>=t?e:(n=n||new e.constructor(t),n.set(e),n)}function $m(e,t,n){const r=(t<257?Rle:t<65537?Nle:ng)(e);return n&&r.set(n),r}function fM(e,t,n){const r=1<0)for(m=0;me,size:()=>n}}function Ile(e,t){return e.sort.call(t,(n,r)=>{const i=e[n],s=e[r];return is?1:0}),GY(e,t)}function Ple(e,t,n,r,i,s,o,a,l){let u=0,c=0,f;for(f=0;ut.modified(r.fields));return n?this.reinit(e,t):this.eval(e,t)}else return this.init(e,t)},init(e,t){const n=e.fields,r=e.query,i=this._indices={},s=this._dims=[],o=r.length;let a=0,l,u;for(;a{const s=i.remove(t,n);for(const o in r)r[o].reindex(s)})},update(e,t,n){const r=this._dims,i=e.query,s=t.stamp,o=r.length;let a=0,l,u;for(n.filters=0,u=0;uh)for(m=h,y=Math.min(f,p);mp)for(m=Math.max(f,p),y=d;mf)for(p=f,g=Math.min(u,d);pd)for(p=Math.max(u,d),g=c;pa[c]&n?null:o[c];return s.filter(s.MOD,u),i&i-1?(s.filter(s.ADD,c=>{const f=a[c]&n;return!f&&f^l[c]&n?o[c]:null}),s.filter(s.REM,c=>{const f=a[c]&n;return f&&!(f^(f^l[c]&n))?o[c]:null})):(s.filter(s.ADD,u),s.filter(s.REM,c=>(a[c]&n)===i?o[c]:null)),s.filter(s.SOURCE,c=>u(c._index))}});const Ble=Object.freeze(Object.defineProperty({__proto__:null,crossfilter:wC,resolvefilter:EC},Symbol.toStringTag,{value:"Module"})),zle="RawCode",Vc="Literal",jle="Property",Ule="Identifier",qle="ArrayExpression",Wle="BinaryExpression",wP="CallExpression",Hle="ConditionalExpression",Gle="LogicalExpression",Yle="MemberExpression",Vle="ObjectExpression",Xle="UnaryExpression";function Eo(e){this.type=e}Eo.prototype.visit=function(e){let t,n,r;if(e(this))return 1;for(t=Kle(this),n=0,r=t.length;n";wa[Xc]="Identifier";wa[$u]="Keyword";wa[Sb]="Null";wa[vf]="Numeric";wa[Mi]="Punctuator";wa[F0]="String";wa[Zle]="RegularExpression";var Jle="ArrayExpression",Qle="BinaryExpression",eue="CallExpression",tue="ConditionalExpression",EP="Identifier",nue="Literal",rue="LogicalExpression",iue="MemberExpression",sue="ObjectExpression",oue="Property",aue="UnaryExpression",dr="Unexpected token %0",lue="Unexpected number",uue="Unexpected string",cue="Unexpected identifier",fue="Unexpected reserved word",due="Unexpected end of input",zE="Invalid regular expression",Jx="Invalid regular expression: missing /",AP="Octal literals are not allowed in strict mode.",hue="Duplicate data property in object literal not allowed in strict mode",Tr="ILLEGAL",$g="Disabled.",pue=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),gue=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u08A0-\\u08B2\\u08E4-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58\\u0C59\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C81-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D01-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1CD0-\\u1CD2\\u1CD4-\\u1CF6\\u1CF8\\u1CF9\\u1D00-\\u1DF5\\u1DFC-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u200C\\u200D\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA69D\\uA69F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C4\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2D\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]");function Cb(e,t){if(!e)throw new Error("ASSERT: "+t)}function Ba(e){return e>=48&&e<=57}function AC(e){return"0123456789abcdefABCDEF".includes(e)}function rg(e){return"01234567".includes(e)}function mue(e){return e===32||e===9||e===11||e===12||e===160||e>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].includes(e)}function Fg(e){return e===10||e===13||e===8232||e===8233}function D0(e){return e===36||e===95||e>=65&&e<=90||e>=97&&e<=122||e===92||e>=128&&pue.test(String.fromCharCode(e))}function Vv(e){return e===36||e===95||e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57||e===92||e>=128&&gue.test(String.fromCharCode(e))}const vue={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function kP(){for(;ue1114111||e!=="}")&&Gt({},dr,Tr),t<=65535?String.fromCharCode(t):(n=(t-65536>>10)+55296,r=(t-65536&1023)+56320,String.fromCharCode(n,r))}function SP(){var e,t;for(e=et.charCodeAt(ue++),t=String.fromCharCode(e),e===92&&(et.charCodeAt(ue)!==117&&Gt({},dr,Tr),++ue,e=jE("u"),(!e||e==="\\"||!D0(e.charCodeAt(0)))&&Gt({},dr,Tr),t=e);ue>>=")return ue+=4,{type:Mi,value:o,start:e,end:ue};if(s=o.substr(0,3),s===">>>"||s==="<<="||s===">>=")return ue+=3,{type:Mi,value:s,start:e,end:ue};if(i=s.substr(0,2),r===i[1]&&"+-<>&|".includes(r)||i==="=>")return ue+=2,{type:Mi,value:i,start:e,end:ue};if(i==="//"&&Gt({},dr,Tr),"<>=!+-*%&|^/".includes(r))return++ue,{type:Mi,value:r,start:e,end:ue};Gt({},dr,Tr)}function _ue(e){let t="";for(;ue{if(parseInt(i,16)<=1114111)return"x";Gt({},zE)}).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"));try{new RegExp(n)}catch{Gt({},zE)}try{return new RegExp(e,t)}catch{return null}}function kue(){var e,t,n,r,i;for(e=et[ue],Cb(e==="/","Regular expression literal must start with a slash"),t=et[ue++],n=!1,r=!1;ue=0&&Gt({},zE,n),{value:n,literal:t}}function Cue(){var e,t,n,r;return nn=null,kP(),e=ue,t=kue(),n=Sue(),r=Aue(t.value,n.value),{literal:t.literal+n.literal,value:r,regex:{pattern:t.value,flags:n.value},start:e,end:ue}}function $ue(e){return e.type===Xc||e.type===$u||e.type===kb||e.type===Sb}function CP(){if(kP(),ue>=Jr)return{type:$0,start:ue,end:ue};const e=et.charCodeAt(ue);return D0(e)?xue():e===40||e===41||e===59?Qx():e===39||e===34?Eue():e===46?Ba(et.charCodeAt(ue+1))?hM():Qx():Ba(e)?hM():Qx()}function Oi(){const e=nn;return ue=e.end,nn=CP(),ue=e.end,e}function $P(){const e=ue;nn=CP(),ue=e}function Fue(e){const t=new Eo(Jle);return t.elements=e,t}function pM(e,t,n){const r=new Eo(e==="||"||e==="&&"?rue:Qle);return r.operator=e,r.left=t,r.right=n,r}function Due(e,t){const n=new Eo(eue);return n.callee=e,n.arguments=t,n}function Mue(e,t,n){const r=new Eo(tue);return r.test=e,r.consequent=t,r.alternate=n,r}function kC(e){const t=new Eo(EP);return t.name=e,t}function Pp(e){const t=new Eo(nue);return t.value=e.value,t.raw=et.slice(e.start,e.end),e.regex&&(t.raw==="//"&&(t.raw="/(?:)/"),t.regex=e.regex),t}function gM(e,t,n){const r=new Eo(iue);return r.computed=e==="[",r.object=t,r.property=n,r.computed||(n.member=!0),r}function Tue(e){const t=new Eo(sue);return t.properties=e,t}function mM(e,t,n){const r=new Eo(oue);return r.key=t,r.value=n,r.kind=e,r}function Rue(e,t){const n=new Eo(aue);return n.operator=e,n.argument=t,n.prefix=!0,n}function Gt(e,t){var n,r=Array.prototype.slice.call(arguments,2),i=t.replace(/%(\d)/g,(s,o)=>(Cb(o":case"<=":case">=":case"instanceof":case"in":t=7;break;case"<<":case">>":case">>>":t=8;break;case"+":case"-":t=9;break;case"*":case"/":case"%":t=11;break}return t}function Hue(){var e,t,n,r,i,s,o,a,l,u;if(e=nn,l=w1(),r=nn,i=bM(r),i===0)return l;for(r.prec=i,Oi(),t=[e,nn],o=w1(),s=[l,r,o];(i=bM(nn))>0;){for(;s.length>2&&i<=s[s.length-2].prec;)o=s.pop(),a=s.pop().value,l=s.pop(),t.pop(),n=pM(a,l,o),s.push(n);r=Oi(),r.prec=i,s.push(r),t.push(nn),n=w1(),s.push(n)}for(u=s.length-1,n=s[u],t.pop();u>1;)t.pop(),n=pM(s[u-1].value,s[u-2],n),u-=2;return n}function Kc(){var e,t,n;return e=Hue(),mn("?")&&(Oi(),t=Kc(),Qr(":"),n=Kc(),e=Mue(e,t,n)),e}function SC(){const e=Kc();if(mn(","))throw new Error($g);return e}function FP(e){et=e,ue=0,Jr=et.length,nn=null,$P();const t=SC();if(nn.type!==$0)throw new Error("Unexpect token after expression.");return t}var DP={NaN:"NaN",E:"Math.E",LN2:"Math.LN2",LN10:"Math.LN10",LOG2E:"Math.LOG2E",LOG10E:"Math.LOG10E",PI:"Math.PI",SQRT1_2:"Math.SQRT1_2",SQRT2:"Math.SQRT2",MIN_VALUE:"Number.MIN_VALUE",MAX_VALUE:"Number.MAX_VALUE"};function MP(e){function t(o,a,l,u){let c=e(a[0]);return l&&(c=l+"("+c+")",l.lastIndexOf("new ",0)===0&&(c="("+c+")")),c+"."+o+(u<0?"":u===0?"()":"("+a.slice(1).map(e).join(",")+")")}function n(o,a,l){return u=>t(o,u,a,l)}const r="new Date",i="String",s="RegExp";return{isNaN:"Number.isNaN",isFinite:"Number.isFinite",abs:"Math.abs",acos:"Math.acos",asin:"Math.asin",atan:"Math.atan",atan2:"Math.atan2",ceil:"Math.ceil",cos:"Math.cos",exp:"Math.exp",floor:"Math.floor",hypot:"Math.hypot",log:"Math.log",max:"Math.max",min:"Math.min",pow:"Math.pow",random:"Math.random",round:"Math.round",sin:"Math.sin",sqrt:"Math.sqrt",tan:"Math.tan",clamp:function(o){o.length<3&&le("Missing arguments to clamp function."),o.length>3&&le("Too many arguments to clamp function.");const a=o.map(e);return"Math.max("+a[1]+", Math.min("+a[2]+","+a[0]+"))"},now:"Date.now",utc:"Date.UTC",datetime:r,date:n("getDate",r,0),day:n("getDay",r,0),year:n("getFullYear",r,0),month:n("getMonth",r,0),hours:n("getHours",r,0),minutes:n("getMinutes",r,0),seconds:n("getSeconds",r,0),milliseconds:n("getMilliseconds",r,0),time:n("getTime",r,0),timezoneoffset:n("getTimezoneOffset",r,0),utcdate:n("getUTCDate",r,0),utcday:n("getUTCDay",r,0),utcyear:n("getUTCFullYear",r,0),utcmonth:n("getUTCMonth",r,0),utchours:n("getUTCHours",r,0),utcminutes:n("getUTCMinutes",r,0),utcseconds:n("getUTCSeconds",r,0),utcmilliseconds:n("getUTCMilliseconds",r,0),length:n("length",null,-1),parseFloat:"parseFloat",parseInt:"parseInt",upper:n("toUpperCase",i,0),lower:n("toLowerCase",i,0),substring:n("substring",i),split:n("split",i),trim:n("trim",i,0),btoa:"btoa",atob:"atob",regexp:s,test:n("test",s),if:function(o){o.length<3&&le("Missing arguments to if function."),o.length>3&&le("Too many arguments to if function.");const a=o.map(e);return"("+a[0]+"?"+a[1]+":"+a[2]+")"}}}function Gue(e){const t=e&&e.length-1;return t&&(e[0]==='"'&&e[t]==='"'||e[0]==="'"&&e[t]==="'")?e.slice(1,-1):e}function TP(e){e=e||{};const t=e.allowed?mo(e.allowed):{},n=e.forbidden?mo(e.forbidden):{},r=e.constants||DP,i=(e.functions||MP)(f),s=e.globalvar,o=e.fieldvar,a=Tt(s)?s:p=>`${s}["${p}"]`;let l={},u={},c=0;function f(p){if(Ie(p))return p;const g=d[p.type];return g==null&&le("Unsupported type: "+p.type),g(p)}const d={Literal:p=>p.raw,Identifier:p=>{const g=p.name;return c>0?g:Ue(n,g)?le("Illegal identifier: "+g):Ue(r,g)?r[g]:Ue(t,g)?g:(l[g]=1,a(g))},MemberExpression:p=>{const g=!p.computed,m=f(p.object);g&&(c+=1);const y=f(p.property);return m===o&&(u[Gue(y)]=1),g&&(c-=1),m+(g?"."+y:"["+y+"]")},CallExpression:p=>{p.callee.type!=="Identifier"&&le("Illegal callee type: "+p.callee.type);const g=p.callee.name,m=p.arguments,y=Ue(i,g)&&i[g];return y||le("Unrecognized function: "+g),Tt(y)?y(m):y+"("+m.map(f).join(",")+")"},ArrayExpression:p=>"["+p.elements.map(f).join(",")+"]",BinaryExpression:p=>"("+f(p.left)+" "+p.operator+" "+f(p.right)+")",UnaryExpression:p=>"("+p.operator+f(p.argument)+")",ConditionalExpression:p=>"("+f(p.test)+"?"+f(p.consequent)+":"+f(p.alternate)+")",LogicalExpression:p=>"("+f(p.left)+p.operator+f(p.right)+")",ObjectExpression:p=>{for(const g of p.properties){const m=g.key.name;uk.has(m)&&le("Illegal property: "+m)}return"{"+p.properties.map(f).join(",")+"}"},Property:p=>{c+=1;const g=f(p.key);return c-=1,g+":"+f(p.value)}};function h(p){const g={code:f(p),globals:Object.keys(l),fields:Object.keys(u)};return l={},u={},g}return h.functions=i,h.constants=r,h}const xM=Symbol("vega_selection_getter");function RP(e){return(!e.getter||!e.getter[xM])&&(e.getter=Ls(e.field),e.getter[xM]=!0),e.getter}const CC="intersect",_M="union",Yue="vlMulti",Vue="vlPoint",wM="or",Xue="and",Go="_vgsid_",Dg=Ls(Go),Kue="E",Zue="R",Jue="R-E",Que="R-LE",ece="R-RE",tce="E-LT",nce="E-LTE",rce="E-GT",ice="E-GTE",sce="E-VALID",oce="E-ONE",Xv="index:unit";function EM(e,t){for(var n=t.fields,r=t.values,i=n.length,s=0,o,a;s=r[s])return!1}else if(a.type===nce){if(o>r[s])return!1}else if(a.type===rce){if(o<=r[s])return!1}else if(a.type===ice){if(oMt(t.fields?{values:t.fields.map(r=>RP(r)(n.datum))}:{[Go]:Dg(n.datum)},t))}function dce(e,t,n,r){for(var i=this.context.data[e],s=i?i.values.value:[],o={},a={},l={},u,c,f,d,h,p,g,m,y,b,x=s.length,_=0,w,A;_(E[c[S].field]=k,E),{})))}else h=Go,p=Dg(u),g=o[h]||(o[h]={}),m=g[d]||(g[d]=[]),m.push(p),n&&(m=a[d]||(a[d]=[]),m.push({[Go]:p}));if(t=t||_M,o[Go]?o[Go]=t_[`${Go}_${t}`](...Object.values(o[Go])):Object.keys(o).forEach(E=>{o[E]=Object.keys(o[E]).map(k=>o[E][k]).reduce((k,S)=>k===void 0?S:t_[`${l[E]}_${t}`](k,S))}),s=Object.keys(a),n&&s.length){const E=r?Vue:Yue;o[E]=t===_M?{[wM]:s.reduce((k,S)=>(k.push(...a[S]),k),[])}:{[Xue]:s.map(k=>({[wM]:a[k]}))}}return o}var t_={[`${Go}_union`]:tV,[`${Go}_intersect`]:QY,E_union:function(e,t){if(!e.length)return t;for(var n=0,r=t.length;nt.includes(n)):t},R_union:function(e,t){var n=Vr(t[0]),r=Vr(t[1]);return n>r&&(n=t[1],r=t[0]),e.length?(e[0]>n&&(e[0]=n),e[1]r&&(n=t[1],r=t[0]),e.length?rr&&(e[1]=r),e):[n,r]}};const hce=":",pce="@";function $C(e,t,n,r){t[0].type!==Vc&&le("First argument to selection functions must be a string literal.");const i=t[0].value,s=t.length>=2&&Wt(t).value,o="unit",a=pce+o,l=hce+i;s===CC&&!Ue(r,a)&&(r[a]=n.getData(i).indataRef(n,o)),Ue(r,l)||(r[l]=n.getData(i).tuplesRef())}function OP(e){const t=this.context.data[e];return t?t.values.value:[]}function gce(e,t,n){const r=this.context.data[e]["index:"+t],i=r?r.value.get(n):void 0;return i&&i.count}function mce(e,t){const n=this.context.dataflow,r=this.context.data[e],i=r.input;return n.pulse(i,n.changeset().remove(ds).insert(t)),1}function vce(e,t,n){if(e){const r=this.context.dataflow,i=e.mark.source;r.pulse(i,r.changeset().encode(e,t))}return n!==void 0?n:e}const M0=e=>function(t,n){const r=this.context.dataflow.locale();return t===null?"null":r[e](n)(t)},yce=M0("format"),LP=M0("timeFormat"),bce=M0("utcFormat"),xce=M0("timeParse"),_ce=M0("utcParse"),Fm=new Date(2e3,0,1);function Fb(e,t,n){return!Number.isInteger(e)||!Number.isInteger(t)?"":(Fm.setYear(2e3),Fm.setMonth(e),Fm.setDate(t),LP.call(this,Fm,n))}function wce(e){return Fb.call(this,e,1,"%B")}function Ece(e){return Fb.call(this,e,1,"%b")}function Ace(e){return Fb.call(this,0,2+e,"%A")}function kce(e){return Fb.call(this,0,2+e,"%a")}const Sce=":",Cce="@",UE="%",IP="$";function FC(e,t,n,r){t[0].type!==Vc&&le("First argument to data functions must be a string literal.");const i=t[0].value,s=Sce+i;if(!Ue(s,r))try{r[s]=n.getData(i).tuplesRef()}catch{}}function $ce(e,t,n,r){t[0].type!==Vc&&le("First argument to indata must be a string literal."),t[1].type!==Vc&&le("Second argument to indata must be a string literal.");const i=t[0].value,s=t[1].value,o=Cce+s;Ue(o,r)||(r[o]=n.getData(i).indataRef(n,s))}function bi(e,t,n,r){if(t[0].type===Vc)AM(n,r,t[0].value);else for(e in n.scales)AM(n,r,e)}function AM(e,t,n){const r=UE+n;if(!Ue(t,r))try{t[r]=e.scaleRef(n)}catch{}}function Ea(e,t){if(Ie(e)){const n=t.scales[e];return n&&CD(n.value)?n.value:void 0}else if(Tt(e))return CD(e)?e:void 0}function Fce(e,t,n){t.__bandwidth=i=>i&&i.bandwidth?i.bandwidth():0,n._bandwidth=bi,n._range=bi,n._scale=bi;const r=i=>"_["+(i.type===Vc?$e(UE+i.value):$e(UE)+"+"+e(i))+"]";return{_bandwidth:i=>`this.__bandwidth(${r(i[0])})`,_range:i=>`${r(i[0])}.range()`,_scale:i=>`${r(i[0])}(${e(i[1])})`}}function DC(e,t){return function(n,r,i){if(n){const s=Ea(n,(i||this).context);return s&&s.path[e](r)}else return t(r)}}const Dce=DC("area",Vre),Mce=DC("bounds",Jre),Tce=DC("centroid",iie);function Rce(e,t){const n=Ea(e,(t||this).context);return n&&n.scale()}function Nce(e){const t=this.context.group;let n=!1;if(t)for(;e;){if(e===t){n=!0;break}e=e.mark.group}return n}function MC(e,t,n){try{e[t].apply(e,["EXPRESSION"].concat([].slice.call(n)))}catch(r){e.warn(r)}return n[n.length-1]}function Oce(){return MC(this.context.dataflow,"warn",arguments)}function Lce(){return MC(this.context.dataflow,"info",arguments)}function Ice(){return MC(this.context.dataflow,"debug",arguments)}function n_(e){const t=e/255;return t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4)}function qE(e){const t=lu(e),n=n_(t.r),r=n_(t.g),i=n_(t.b);return .2126*n+.7152*r+.0722*i}function Pce(e,t){const n=qE(e),r=qE(t),i=Math.max(n,r),s=Math.min(n,r);return(i+.05)/(s+.05)}function Bce(){const e=[].slice.call(arguments);return e.unshift({}),Mt(...e)}function PP(e,t){return e===t||e!==e&&t!==t?!0:de(e)?de(t)&&e.length===t.length?zce(e,t):!1:Le(e)&&Le(t)?BP(e,t):!1}function zce(e,t){for(let n=0,r=e.length;nBP(e,t)}function jce(e,t,n,r,i,s){const o=this.context.dataflow,a=this.context.data[e],l=a.input,u=o.stamp();let c=a.changes,f,d;if(o._trigger===!1||!(l.value.length||t||r))return 0;if((!c||c.stamp{a.modified=!0,o.pulse(l,c).run()},!0,1)),n&&(f=n===!0?ds:de(n)||Py(n)?n:kM(n),c.remove(f)),t&&c.insert(t),r&&(f=kM(r),l.value.some(f)?c.remove(f):c.insert(r)),i)for(d in s)c.modify(i,d,s[d]);return 1}function Uce(e){const t=e.touches,n=t[0].clientX-t[1].clientX,r=t[0].clientY-t[1].clientY;return Math.hypot(n,r)}function qce(e){const t=e.touches;return Math.atan2(t[0].clientY-t[1].clientY,t[0].clientX-t[1].clientX)}const SM={};function Wce(e,t){const n=SM[t]||(SM[t]=Ls(t));return de(e)?e.map(n):n(e)}function Db(e){return de(e)||ArrayBuffer.isView(e)?e:null}function TC(e){return Db(e)||(Ie(e)?e:null)}function Hce(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r1?t-1:0),r=1;r1?t-1:0),r=1;r1?t-1:0),r=1;rs.stop(u(c),e(c))),s}function ofe(e,t,n){const r=Ea(e,(n||this).context);return function(i){return r?r.path.context(i)(t):""}}function afe(e){let t=null;return function(n){return n?xg(n,t=t||jd(e)):e}}const zP=e=>e.data;function jP(e,t){const n=OP.call(t,e);return n.root&&n.root.lookup||{}}function lfe(e,t,n){const r=jP(e,this),i=r[t],s=r[n];return i&&s?i.path(s).map(zP):void 0}function ufe(e,t){const n=jP(e,this)[t];return n?n.ancestors().map(zP):void 0}const UP=()=>typeof window<"u"&&window||null;function cfe(){const e=UP();return e?e.screen:{}}function ffe(){const e=UP();return e?[e.innerWidth,e.innerHeight]:[void 0,void 0]}function dfe(){const e=this.context.dataflow,t=e.container&&e.container();return t?[t.clientWidth,t.clientHeight]:[void 0,void 0]}function qP(e,t,n){if(!e)return[];const[r,i]=e,s=new Vn().set(r[0],r[1],i[0],i[1]),o=n||this.context.dataflow.scenegraph().root;return kL(o,s,hfe(t))}function hfe(e){let t=null;if(e){const n=Be(e.marktype),r=Be(e.markname);t=i=>(!n.length||n.some(s=>i.marktype===s))&&(!r.length||r.some(s=>i.name===s))}return t}function pfe(e,t,n){let r=arguments.length>3&&arguments[3]!==void 0?arguments[3]:5;e=Be(e);const i=e[e.length-1];return i===void 0||Math.hypot(i[0]-t,i[1]-n)>r?[...e,[t,n]]:e}function gfe(e){return Be(e).reduce((t,n,r)=>{let[i,s]=n;return t+=r==0?`M ${i},${s} `:r===e.length-1?" Z":`L ${i},${s} `},"")}function mfe(e,t,n){const{x:r,y:i,mark:s}=n,o=new Vn().set(Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);for(const[l,u]of t)lo.x2&&(o.x2=l),uo.y2&&(o.y2=u);return o.translate(r,i),qP([[o.x1,o.y1],[o.x2,o.y2]],e,s).filter(l=>vfe(l.x,l.y,t))}function vfe(e,t,n){let r=0;for(let i=0,s=n.length-1;it!=a>t&&e<(o-l)*(t-u)/(a-u)+l&&r++}return r&1}const Mg={random(){return Ps()},cumulativeNormal:qy,cumulativeLogNormal:Gk,cumulativeUniform:Kk,densityNormal:jk,densityLogNormal:Hk,densityUniform:Xk,quantileNormal:Wy,quantileLogNormal:Yk,quantileUniform:Zk,sampleNormal:Uy,sampleLogNormal:Wk,sampleUniform:Vk,isArray:de,isBoolean:wu,isDate:Zl,isDefined(e){return e!==void 0},isNumber:Vt,isObject:Le,isRegExp:yk,isString:Ie,isTuple:Py,isValid(e){return e!=null&&e===e},toBoolean:xk,toDate(e){return _k(e)},toNumber:Vr,toString:wk,indexof:Gce,join:Hce,lastindexof:Yce,replace:Xce,reverse:Kce,sort:Zce,slice:Vce,flush:XR,lerp:ZR,merge:Bce,pad:eN,peek:Wt,pluck:Wce,span:i0,inrange:Zf,truncate:tN,rgb:lu,lab:tv,hcl:nv,hsl:Q1,luminance:qE,contrast:Pce,sequence:ss,format:yce,utcFormat:bce,utcParse:_ce,utcOffset:RN,utcSequence:LN,timeFormat:LP,timeParse:xce,timeOffset:TN,timeSequence:ON,timeUnitSpecifier:_N,monthFormat:wce,monthAbbrevFormat:Ece,dayFormat:Ace,dayAbbrevFormat:kce,quarter:HR,utcquarter:GR,week:EN,utcweek:SN,dayofyear:wN,utcdayofyear:kN,warn:Oce,info:Lce,debug:Ice,extent(e){return aa(e)},inScope:Nce,intersect:qP,clampRange:YR,pinchDistance:Uce,pinchAngle:qce,screen:cfe,containerSize:dfe,windowSize:ffe,bandspace:Jce,setdata:mce,pathShape:afe,panLinear:jR,panLog:UR,panPow:qR,panSymlog:WR,zoomLinear:hk,zoomLog:pk,zoomPow:B1,zoomSymlog:gk,encode:vce,modify:jce,lassoAppend:pfe,lassoPath:gfe,intersectLasso:mfe},yfe=["view","item","group","xy","x","y"],bfe="event.vega.",WP="this.",RC={},HP={forbidden:["_"],allowed:["datum","event","item"],fieldvar:"datum",globalvar:e=>`_[${$e(IP+e)}]`,functions:xfe,constants:DP,visitors:RC},WE=TP(HP);function xfe(e){const t=MP(e);yfe.forEach(n=>t[n]=bfe+n);for(const n in Mg)t[n]=WP+n;return Mt(t,Fce(e,Mg,RC)),t}function Hn(e,t,n){return arguments.length===1?Mg[e]:(Mg[e]=t,n&&(RC[e]=n),WE&&(WE.functions[e]=WP+e),this)}Hn("bandwidth",Qce,bi);Hn("copy",efe,bi);Hn("domain",tfe,bi);Hn("range",rfe,bi);Hn("invert",nfe,bi);Hn("scale",ife,bi);Hn("gradient",sfe,bi);Hn("geoArea",Dce,bi);Hn("geoBounds",Mce,bi);Hn("geoCentroid",Tce,bi);Hn("geoShape",ofe,bi);Hn("geoScale",Rce,bi);Hn("indata",gce,$ce);Hn("data",OP,FC);Hn("treePath",lfe,FC);Hn("treeAncestors",ufe,FC);Hn("vlSelectionTest",ace,$C);Hn("vlSelectionIdTest",cce,$C);Hn("vlSelectionResolve",dce,$C);Hn("vlSelectionTuples",fce);function da(e,t){const n={};let r;try{e=Ie(e)?e:$e(e)+"",r=FP(e)}catch{le("Expression parse error: "+e)}r.visit(s=>{if(s.type!==wP)return;const o=s.callee.name,a=HP.visitors[o];a&&a(o,s.arguments,t,n)});const i=WE(r);return i.globals.forEach(s=>{const o=IP+s;!Ue(n,o)&&t.getSignal(s)&&(n[o]=t.signalRef(s))}),{$expr:Mt({code:i.code},t.options.ast?{ast:r}:null),$fields:i.fields,$params:n}}function _fe(e){const t=this,n=e.operators||[];return e.background&&(t.background=e.background),e.eventConfig&&(t.eventConfig=e.eventConfig),e.locale&&(t.locale=e.locale),n.forEach(r=>t.parseOperator(r)),n.forEach(r=>t.parseOperatorParameters(r)),(e.streams||[]).forEach(r=>t.parseStream(r)),(e.updates||[]).forEach(r=>t.parseUpdate(r)),t.resolve()}const wfe=mo(["rule"]),CM=mo(["group","image","rect"]);function Efe(e,t){let n="";return wfe[t]||(e.x2&&(e.x?(CM[t]&&(n+="if(o.x>o.x2)$=o.x,o.x=o.x2,o.x2=$;"),n+="o.width=o.x2-o.x;"):n+="o.x=o.x2-(o.width||0);"),e.xc&&(n+="o.x=o.xc-(o.width||0)/2;"),e.y2&&(e.y?(CM[t]&&(n+="if(o.y>o.y2)$=o.y,o.y=o.y2,o.y2=$;"),n+="o.height=o.y2-o.y;"):n+="o.y=o.y2-(o.height||0);"),e.yc&&(n+="o.y=o.yc-(o.height||0)/2;")),n}function NC(e){return(e+"").toLowerCase()}function Afe(e){return NC(e)==="operator"}function kfe(e){return NC(e)==="collect"}function op(e,t,n){n.endsWith(";")||(n="return("+n+");");const r=Function(...t.concat(n));return e&&e.functions?r.bind(e.functions):r}function Sfe(e,t,n,r){return`((u = ${e}) < (v = ${t}) || u == null) && v != null ? ${n} + : (u > v || v == null) && u != null ? ${r} + : ((v = v instanceof Date ? +v : v), (u = u instanceof Date ? +u : u)) !== u && v === v ? ${n} + : v !== v && u === u ? ${r} : `}var Cfe={operator:(e,t)=>op(e,["_"],t.code),parameter:(e,t)=>op(e,["datum","_"],t.code),event:(e,t)=>op(e,["event"],t.code),handler:(e,t)=>{const n=`var datum=event.item&&event.item.datum;return ${t.code};`;return op(e,["_","event"],n)},encode:(e,t)=>{const{marktype:n,channels:r}=t;let i="var o=item,datum=o.datum,m=0,$;";for(const s in r){const o="o["+$e(s)+"]";i+=`$=${r[s].code};if(${o}!==$)${o}=$,m=1;`}return i+=Efe(r,n),i+="return m;",op(e,["item","_"],i)},codegen:{get(e){const t=`[${e.map($e).join("][")}]`,n=Function("_",`return _${t};`);return n.path=t,n},comparator(e,t){let n;const r=(s,o)=>{const a=t[o];let l,u;return s.path?(l=`a${s.path}`,u=`b${s.path}`):((n=n||{})["f"+o]=s,l=`this.f${o}(a)`,u=`this.f${o}(b)`),Sfe(l,u,-a,a)},i=Function("a","b","var u, v; return "+e.map(r).join("")+"0;");return n?i.bind(n):i}}};function $fe(e){const t=this;Afe(e.type)||!e.type?t.operator(e,e.update?t.operatorExpression(e.update):null):t.transform(e,e.type)}function Ffe(e){const t=this;if(e.params){const n=t.get(e.id);n||le("Invalid operator id: "+e.id),t.dataflow.connect(n,n.parameters(t.parseParameters(e.params),e.react,e.initonly))}}function Dfe(e,t){t=t||{};const n=this;for(const r in e){const i=e[r];t[r]=de(i)?i.map(s=>$M(s,n,t)):$M(i,n,t)}return t}function $M(e,t,n){if(!e||!Le(e))return e;for(let r=0,i=FM.length,s;ri&&i.$tupleid?ot:i);return t.fn[n]||(t.fn[n]=mk(r,e.$order,t.expr.codegen))}function Lfe(e,t){const n=e.$encode,r={};for(const i in n){const s=n[i];r[i]=Yi(t.encodeExpression(s.$expr),s.$fields),r[i].output=s.$output}return r}function Ife(e,t){return t}function Pfe(e,t){const n=e.$subflow;return function(r,i,s){const o=t.fork().parse(n),a=o.get(n.operators[0].id),l=o.signals.parent;return l&&l.set(s),a.detachSubflow=()=>t.detach(o),a}}function Bfe(){return ot}function zfe(e){var t=this,n=e.filter!=null?t.eventExpression(e.filter):void 0,r=e.stream!=null?t.get(e.stream):void 0,i;e.source?r=t.events(e.source,e.type,n):e.merge&&(i=e.merge.map(s=>t.get(s)),r=i[0].merge.apply(i[0],i.slice(1))),e.between&&(i=e.between.map(s=>t.get(s)),r=r.between(i[0],i[1])),e.filter&&(r=r.filter(n)),e.throttle!=null&&(r=r.throttle(+e.throttle)),e.debounce!=null&&(r=r.debounce(+e.debounce)),r==null&&le("Invalid stream definition: "+JSON.stringify(e)),e.consume&&r.consume(!0),t.stream(e,r)}function jfe(e){var t=this,n=Le(n=e.source)?n.$ref:n,r=t.get(n),i=null,s=e.update,o=void 0;r||le("Source not defined: "+e.source),i=e.target&&e.target.$expr?t.eventExpression(e.target.$expr):t.get(e.target),s&&s.$expr&&(s.$params&&(o=t.parseParameters(s.$params)),s=t.handlerExpression(s.$expr)),t.update(e,r,i,s,o)}const Ufe={skip:!0};function qfe(e){var t=this,n={};if(e.signals){var r=n.signals={};Object.keys(t.signals).forEach(s=>{const o=t.signals[s];e.signals(s,o)&&(r[s]=o.value)})}if(e.data){var i=n.data={};Object.keys(t.data).forEach(s=>{const o=t.data[s];e.data(s,o)&&(i[s]=o.input.value)})}return t.subcontext&&e.recurse!==!1&&(n.subcontext=t.subcontext.map(s=>s.getState(e))),n}function Wfe(e){var t=this,n=t.dataflow,r=e.data,i=e.signals;Object.keys(i||{}).forEach(s=>{n.update(t.signals[s],i[s],Ufe)}),Object.keys(r||{}).forEach(s=>{n.pulse(t.data[s].input,n.changeset().remove(ds).insert(r[s]))}),(e.subcontext||[]).forEach((s,o)=>{const a=t.subcontext[o];a&&a.setState(s)})}function GP(e,t,n,r){return new YP(e,t,n,r)}function YP(e,t,n,r){this.dataflow=e,this.transforms=t,this.events=e.events.bind(e),this.expr=r||Cfe,this.signals={},this.scales={},this.nodes={},this.data={},this.fn={},n&&(this.functions=Object.create(n),this.functions.context=this)}function DM(e){this.dataflow=e.dataflow,this.transforms=e.transforms,this.events=e.events,this.expr=e.expr,this.signals=Object.create(e.signals),this.scales=Object.create(e.scales),this.nodes=Object.create(e.nodes),this.data=Object.create(e.data),this.fn=Object.create(e.fn),e.functions&&(this.functions=Object.create(e.functions),this.functions.context=this)}YP.prototype=DM.prototype={fork(){const e=new DM(this);return(this.subcontext||(this.subcontext=[])).push(e),e},detach(e){this.subcontext=this.subcontext.filter(n=>n!==e);const t=Object.keys(e.nodes);for(const n of t)e.nodes[n]._targets=null;for(const n of t)e.nodes[n].detach();e.nodes=null},get(e){return this.nodes[e]},set(e,t){return this.nodes[e]=t},add(e,t){const n=this,r=n.dataflow,i=e.value;if(n.set(e.id,t),kfe(e.type)&&i&&(i.$ingest?r.ingest(t,i.$ingest,i.$format):i.$request?r.preload(t,i.$request,i.$format):r.pulse(t,r.changeset().insert(i))),e.root&&(n.root=t),e.parent){let s=n.get(e.parent.$ref);s?(r.connect(s,[t]),t.targets().add(s)):(n.unresolved=n.unresolved||[]).push(()=>{s=n.get(e.parent.$ref),r.connect(s,[t]),t.targets().add(s)})}if(e.signal&&(n.signals[e.signal]=t),e.scale&&(n.scales[e.scale]=t),e.data)for(const s in e.data){const o=n.data[s]||(n.data[s]={});e.data[s].forEach(a=>o[a]=t)}},resolve(){return(this.unresolved||[]).forEach(e=>e()),delete this.unresolved,this},operator(e,t){this.add(e,this.dataflow.add(e.value,t))},transform(e,t){this.add(e,this.dataflow.add(this.transforms[NC(t)]))},stream(e,t){this.set(e.id,t)},update(e,t,n,r,i){this.dataflow.on(t,n,r,i,e.options)},operatorExpression(e){return this.expr.operator(this,e)},parameterExpression(e){return this.expr.parameter(this,e)},eventExpression(e){return this.expr.event(this,e)},handlerExpression(e){return this.expr.handler(this,e)},encodeExpression(e){return this.expr.encode(this,e)},parse:_fe,parseOperator:$fe,parseOperatorParameters:Ffe,parseParameters:Dfe,parseStream:zfe,parseUpdate:jfe,getState:qfe,setState:Wfe};function Hfe(e){const t=e.container();t&&(t.setAttribute("role","graphics-document"),t.setAttribute("aria-roleDescription","visualization"),VP(t,e.description()))}function VP(e,t){e&&(t==null?e.removeAttribute("aria-label"):e.setAttribute("aria-label",t))}function Gfe(e){e.add(null,t=>(e._background=t.bg,e._resize=1,t.bg),{bg:e._signals.background})}const r_="default";function Yfe(e){const t=e._signals.cursor||(e._signals.cursor=e.add({user:r_,item:null}));e.on(e.events("view","pointermove"),t,(n,r)=>{const i=t.value,s=i?Ie(i)?i:i.user:r_,o=r.item&&r.item.cursor||null;return i&&s===i.user&&o==i.item?i:{user:s,item:o}}),e.add(null,function(n){let r=n.cursor,i=this.value;return Ie(r)||(i=r.item,r=r.user),HE(e,r&&r!==r_?r:i||r),i},{cursor:t})}function HE(e,t){const n=e.globalCursor()?typeof document<"u"&&document.body:e.container();if(n)return t==null?n.style.removeProperty("cursor"):n.style.cursor=t}function Kv(e,t){var n=e._runtime.data;return Ue(n,t)||le("Unrecognized data set: "+t),n[t]}function Vfe(e,t){return arguments.length<2?Kv(this,e).values.value:Mb.call(this,e,Eu().remove(ds).insert(t))}function Mb(e,t){uO(t)||le("Second argument to changes must be a changeset.");const n=Kv(this,e);return n.modified=!0,this.pulse(n.input,t)}function Xfe(e,t){return Mb.call(this,e,Eu().insert(t))}function Kfe(e,t){return Mb.call(this,e,Eu().remove(t))}function XP(e){var t=e.padding();return Math.max(0,e._viewWidth+t.left+t.right)}function KP(e){var t=e.padding();return Math.max(0,e._viewHeight+t.top+t.bottom)}function Tb(e){var t=e.padding(),n=e._origin;return[t.left+n[0],t.top+n[1]]}function Zfe(e){var t=Tb(e),n=XP(e),r=KP(e);e._renderer.background(e.background()),e._renderer.resize(n,r,t),e._handler.origin(t),e._resizeListeners.forEach(i=>{try{i(n,r)}catch(s){e.error(s)}})}function Jfe(e,t,n){var r=e._renderer,i=r&&r.canvas(),s,o,a;return i&&(a=Tb(e),o=t.changedTouches?t.changedTouches[0]:t,s=vb(o,i),s[0]-=a[0],s[1]-=a[1]),t.dataflow=e,t.item=n,t.vega=Qfe(e,n,s),t}function Qfe(e,t,n){const r=t?t.mark.marktype==="group"?t:t.mark.group:null;function i(o){var a=r,l;if(o){for(l=t;l;l=l.mark.group)if(l.mark.name===o){a=l;break}}return a&&a.mark&&a.mark.interactive?a:{}}function s(o){if(!o)return n;Ie(o)&&(o=i(o));const a=n.slice();for(;o;)a[0]-=o.x||0,a[1]-=o.y||0,o=o.mark&&o.mark.group;return a}return{view:ri(e),item:ri(t||{}),group:i,xy:s,x:o=>s(o)[0],y:o=>s(o)[1]}}const MM="view",ede="timer",tde="window",nde={trap:!1};function rde(e){const t=Mt({defaults:{}},e),n=(r,i)=>{i.forEach(s=>{de(r[s])&&(r[s]=mo(r[s]))})};return n(t.defaults,["prevent","allow"]),n(t,["view","window","selector"]),t}function ZP(e,t,n,r){e._eventListeners.push({type:n,sources:Be(t),handler:r})}function ide(e,t){var n=e._eventConfig.defaults,r=n.prevent,i=n.allow;return r===!1||i===!0?!1:r===!0||i===!1?!0:r?r[t]:i?!i[t]:e.preventDefault()}function Dm(e,t,n){const r=e._eventConfig&&e._eventConfig[t];return r===!1||Le(r)&&!r[n]?(e.warn(`Blocked ${t} ${n} event listener.`),!1):!0}function sde(e,t,n){var r=this,i=new jy(n),s=function(u,c){r.runAsync(null,()=>{e===MM&&ide(r,t)&&u.preventDefault(),i.receive(Jfe(r,u,c))})},o;if(e===ede)Dm(r,"timer",t)&&r.timer(s,t);else if(e===MM)Dm(r,"view",t)&&r.addEventListener(t,s,nde);else if(e===tde?Dm(r,"window",t)&&typeof window<"u"&&(o=[window]):typeof document<"u"&&Dm(r,"selector",t)&&(o=Array.from(document.querySelectorAll(e))),!o)r.warn("Can not resolve event source: "+e);else{for(var a=0,l=o.length;a=0;)t[i].stop();for(i=r.length;--i>=0;)for(o=r[i],s=o.sources.length;--s>=0;)o.sources[s].removeEventListener(o.type,o.handler);for(e&&e.call(this,this._handler,null,null,null),i=n.length;--i>=0;)l=n[i].type,a=n[i].handler,this._handler.off(l,a);return this}function cs(e,t,n){const r=document.createElement(e);for(const i in t)r.setAttribute(i,t[i]);return n!=null&&(r.textContent=n),r}const lde="vega-bind",ude="vega-bind-name",cde="vega-bind-radio";function fde(e,t,n){if(!t)return;const r=n.param;let i=n.state;return i||(i=n.state={elements:null,active:!1,set:null,update:o=>{o!=e.signal(r.signal)&&e.runAsync(null,()=>{i.source=!0,e.signal(r.signal,o)})}},r.debounce&&(i.update=vk(r.debounce,i.update))),(r.input==null&&r.element?dde:pde)(i,t,r,e),i.active||(e.on(e._signals[r.signal],null,()=>{i.source?i.source=!1:i.set(e.signal(r.signal))}),i.active=!0),i}function dde(e,t,n,r){const i=n.event||"input",s=()=>e.update(t.value);r.signal(n.signal,t.value),t.addEventListener(i,s),ZP(r,t,i,s),e.set=o=>{t.value=o,t.dispatchEvent(hde(i))}}function hde(e){return typeof Event<"u"?new Event(e):{type:e}}function pde(e,t,n,r){const i=r.signal(n.signal),s=cs("div",{class:lde}),o=n.input==="radio"?s:s.appendChild(cs("label"));o.appendChild(cs("span",{class:ude},n.name||n.signal)),t.appendChild(s);let a=gde;switch(n.input){case"checkbox":a=mde;break;case"select":a=vde;break;case"radio":a=yde;break;case"range":a=bde;break}a(e,o,n,i)}function gde(e,t,n,r){const i=cs("input");for(const s in n)s!=="signal"&&s!=="element"&&i.setAttribute(s==="input"?"type":s,n[s]);i.setAttribute("name",n.signal),i.value=r,t.appendChild(i),i.addEventListener("input",()=>e.update(i.value)),e.elements=[i],e.set=s=>i.value=s}function mde(e,t,n,r){const i={type:"checkbox",name:n.signal};r&&(i.checked=!0);const s=cs("input",i);t.appendChild(s),s.addEventListener("change",()=>e.update(s.checked)),e.elements=[s],e.set=o=>s.checked=!!o||null}function vde(e,t,n,r){const i=cs("select",{name:n.signal}),s=n.labels||[];n.options.forEach((o,a)=>{const l={value:o};Zv(o,r)&&(l.selected=!0),i.appendChild(cs("option",l,(s[a]||o)+""))}),t.appendChild(i),i.addEventListener("change",()=>{e.update(n.options[i.selectedIndex])}),e.elements=[i],e.set=o=>{for(let a=0,l=n.options.length;a{const l={type:"radio",name:n.signal,value:o};Zv(o,r)&&(l.checked=!0);const u=cs("input",l);u.addEventListener("change",()=>e.update(o));const c=cs("label",{},(s[a]||o)+"");return c.prepend(u),i.appendChild(c),u}),e.set=o=>{const a=e.elements,l=a.length;for(let u=0;u{l.textContent=a.value,e.update(+a.value)};a.addEventListener("input",u),a.addEventListener("change",u),e.elements=[a],e.set=c=>{a.value=c,l.textContent=c}}function Zv(e,t){return e===t||e+""==t+""}function JP(e,t,n,r,i,s){return t=t||new r(e.loader()),t.initialize(n,XP(e),KP(e),Tb(e),i,s).background(e.background())}function OC(e,t){return t?function(){try{t.apply(this,arguments)}catch(n){e.error(n)}}:null}function xde(e,t,n,r){const i=new r(e.loader(),OC(e,e.tooltip())).scene(e.scenegraph().root).initialize(n,Tb(e),e);return t&&t.handlers().forEach(s=>{i.on(s.type,s.handler)}),i}function _de(e,t){const n=this,r=n._renderType,i=n._eventConfig.bind,s=yb(r);e=n._el=e?i_(n,e,!0):null,Hfe(n),s||n.error("Unrecognized renderer type: "+r);const o=s.handler||E0,a=e?s.renderer:s.headless;return n._renderer=a?JP(n,n._renderer,e,a):null,n._handler=xde(n,n._handler,e,o),n._redraw=!0,e&&i!=="none"&&(t=t?n._elBind=i_(n,t,!0):e.appendChild(cs("form",{class:"vega-bindings"})),n._bind.forEach(l=>{l.param.element&&i!=="container"&&(l.element=i_(n,l.param.element,!!l.param.input))}),n._bind.forEach(l=>{fde(n,l.element||t,l)})),n}function i_(e,t,n){if(typeof t=="string")if(typeof document<"u"){if(t=document.querySelector(t),!t)return e.error("Signal bind element not found: "+t),null}else return e.error("DOM document instance not found."),null;if(t&&n)try{t.textContent=""}catch(r){t=null,e.error(r)}return t}const ap=e=>+e||0,wde=e=>({top:e,bottom:e,left:e,right:e});function OM(e){return Le(e)?{top:ap(e.top),bottom:ap(e.bottom),left:ap(e.left),right:ap(e.right)}:wde(ap(e))}async function LC(e,t,n,r){const i=yb(t),s=i&&i.headless;return s||le("Unrecognized renderer type: "+t),await e.runAsync(),JP(e,null,null,s,n,r).renderAsync(e._scenegraph.root)}async function Ede(e,t){e!==Ul.Canvas&&e!==Ul.SVG&&e!==Ul.PNG&&le("Unrecognized image type: "+e);const n=await LC(this,e,t);return e===Ul.SVG?Ade(n.svg(),"image/svg+xml"):n.canvas().toDataURL("image/png")}function Ade(e,t){const n=new Blob([e],{type:t});return window.URL.createObjectURL(n)}async function kde(e,t){return(await LC(this,Ul.Canvas,e,t)).canvas()}async function Sde(e){return(await LC(this,Ul.SVG,e)).svg()}function Cde(e,t,n){return GP(e,Od,Mg,n).parse(t)}function $de(e){var t=this._runtime.scales;return Ue(t,e)||le("Unrecognized scale or projection: "+e),t[e].value}var QP="width",eB="height",IC="padding",LM={skip:!0};function tB(e,t){var n=e.autosize(),r=e.padding();return t-(n&&n.contains===IC?r.left+r.right:0)}function nB(e,t){var n=e.autosize(),r=e.padding();return t-(n&&n.contains===IC?r.top+r.bottom:0)}function Fde(e){var t=e._signals,n=t[QP],r=t[eB],i=t[IC];function s(){e._autosize=e._resize=1}e._resizeWidth=e.add(null,a=>{e._width=a.size,e._viewWidth=tB(e,a.size),s()},{size:n}),e._resizeHeight=e.add(null,a=>{e._height=a.size,e._viewHeight=nB(e,a.size),s()},{size:r});const o=e.add(null,s,{pad:i});e._resizeWidth.rank=n.rank+1,e._resizeHeight.rank=r.rank+1,o.rank=i.rank+1}function Dde(e,t,n,r,i,s){this.runAfter(o=>{let a=0;o._autosize=0,o.width()!==n&&(a=1,o.signal(QP,n,LM),o._resizeWidth.skip(!0)),o.height()!==r&&(a=1,o.signal(eB,r,LM),o._resizeHeight.skip(!0)),o._viewWidth!==e&&(o._resize=1,o._viewWidth=e),o._viewHeight!==t&&(o._resize=1,o._viewHeight=t),(o._origin[0]!==i[0]||o._origin[1]!==i[1])&&(o._resize=1,o._origin=i),a&&o.run("enter"),s&&o.runAfter(l=>l.resize())},!1,1)}function Mde(e){return this._runtime.getState(e||{data:Tde,signals:Rde,recurse:!0})}function Tde(e,t){return t.modified&&de(t.input.value)&&!e.startsWith("_:vega:_")}function Rde(e,t){return!(e==="parent"||t instanceof Od.proxy)}function Nde(e){return this.runAsync(null,t=>{t._trigger=!1,t._runtime.setState(e)},t=>{t._trigger=!0}),this}function Ode(e,t){function n(r){e({timestamp:Date.now(),elapsed:r})}this._timers.push(soe(n,t))}function Lde(e,t,n,r){const i=e.element();i&&i.setAttribute("title",Ide(r))}function Ide(e){return e==null?"":de(e)?rB(e):Le(e)&&!Zl(e)?Pde(e):e+""}function Pde(e){return Object.keys(e).map(t=>{const n=e[t];return t+": "+(de(n)?rB(n):iB(n))}).join(` +`)}function rB(e){return"["+e.map(iB).join(", ")+"]"}function iB(e){return de(e)?"[…]":Le(e)&&!Zl(e)?"{…}":e}function Bde(){if(this.renderer()==="canvas"&&this._renderer._canvas){let e=null;const t=()=>{e!=null&&e();const n=matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);n.addEventListener("change",t),e=()=>{n.removeEventListener("change",t)},this._renderer._canvas.getContext("2d").pixelRatio=window.devicePixelRatio||1,this._redraw=!0,this._resize=1,this.resize().runAsync()};t()}}function sB(e,t){const n=this;if(t=t||{},sd.call(n),t.loader&&n.loader(t.loader),t.logger&&n.logger(t.logger),t.logLevel!=null&&n.logLevel(t.logLevel),t.locale||e.locale){const s=Mt({},e.locale,t.locale);n.locale(QN(s.number,s.time))}n._el=null,n._elBind=null,n._renderType=t.renderer||Ul.Canvas,n._scenegraph=new J9;const r=n._scenegraph.root;n._renderer=null,n._tooltip=t.tooltip||Lde,n._redraw=!0,n._handler=new E0().scene(r),n._globalCursor=!1,n._preventDefault=!1,n._timers=[],n._eventListeners=[],n._resizeListeners=[],n._eventConfig=rde(e.eventConfig),n.globalCursor(n._eventConfig.globalCursor);const i=Cde(n,e,t.expr);n._runtime=i,n._signals=i.signals,n._bind=(e.bindings||[]).map(s=>({state:null,param:Mt({},s)})),i.root&&i.root.set(r),r.source=i.data.root.input,n.pulse(i.data.root.input,n.changeset().insert(r.items)),n._width=n.width(),n._height=n.height(),n._viewWidth=tB(n,n._width),n._viewHeight=nB(n,n._height),n._origin=[0,0],n._resize=0,n._autosize=1,Fde(n),Gfe(n),Yfe(n),n.description(e.description),t.hover&&n.hover(),t.container&&n.initialize(t.container,t.bind),t.watchPixelRatio&&n._watchPixelRatio()}function Mm(e,t){return Ue(e._signals,t)?e._signals[t]:le("Unrecognized signal name: "+$e(t))}function oB(e,t){const n=(e._targets||[]).filter(r=>r._update&&r._update.handler===t);return n.length?n[0]:null}function IM(e,t,n,r){let i=oB(n,r);return i||(i=OC(e,()=>r(t,n.value)),i.handler=r,e.on(n,null,i)),e}function PM(e,t,n){const r=oB(t,n);return r&&t._targets.remove(r),e}Me(sB,sd,{async evaluate(e,t,n){if(await sd.prototype.evaluate.call(this,e,t),this._redraw||this._resize)try{this._renderer&&(this._resize&&(this._resize=0,Zfe(this)),await this._renderer.renderAsync(this._scenegraph.root)),this._redraw=!1}catch(r){this.error(r)}return n&&s1(this,n),this},dirty(e){this._redraw=!0,this._renderer&&this._renderer.dirty(e)},description(e){if(arguments.length){const t=e!=null?e+"":null;return t!==this._desc&&VP(this._el,this._desc=t),this}return this._desc},container(){return this._el},scenegraph(){return this._scenegraph},origin(){return this._origin.slice()},signal(e,t,n){const r=Mm(this,e);return arguments.length===1?r.value:this.update(r,t,n)},width(e){return arguments.length?this.signal("width",e):this.signal("width")},height(e){return arguments.length?this.signal("height",e):this.signal("height")},padding(e){return arguments.length?this.signal("padding",OM(e)):OM(this.signal("padding"))},autosize(e){return arguments.length?this.signal("autosize",e):this.signal("autosize")},background(e){return arguments.length?this.signal("background",e):this.signal("background")},renderer(e){return arguments.length?(yb(e)||le("Unrecognized renderer type: "+e),e!==this._renderType&&(this._renderType=e,this._resetRenderer()),this):this._renderType},tooltip(e){return arguments.length?(e!==this._tooltip&&(this._tooltip=e,this._resetRenderer()),this):this._tooltip},loader(e){return arguments.length?(e!==this._loader&&(sd.prototype.loader.call(this,e),this._resetRenderer()),this):this._loader},resize(){return this._autosize=1,this.touch(Mm(this,"autosize"))},_resetRenderer(){this._renderer&&(this._renderer=null,this.initialize(this._el,this._elBind))},_resizeView:Dde,addEventListener(e,t,n){let r=t;return n&&n.trap===!1||(r=OC(this,t),r.raw=t),this._handler.on(e,r),this},removeEventListener(e,t){for(var n=this._handler.handlers(e),r=n.length,i,s;--r>=0;)if(s=n[r].type,i=n[r].handler,e===s&&(t===i||t===i.raw)){this._handler.off(s,i);break}return this},addResizeListener(e){const t=this._resizeListeners;return t.includes(e)||t.push(e),this},removeResizeListener(e){var t=this._resizeListeners,n=t.indexOf(e);return n>=0&&t.splice(n,1),this},addSignalListener(e,t){return IM(this,e,Mm(this,e),t)},removeSignalListener(e,t){return PM(this,Mm(this,e),t)},addDataListener(e,t){return IM(this,e,Kv(this,e).values,t)},removeDataListener(e,t){return PM(this,Kv(this,e).values,t)},globalCursor(e){if(arguments.length){if(this._globalCursor!==!!e){const t=HE(this,null);this._globalCursor=!!e,t&&HE(this,t)}return this}else return this._globalCursor},preventDefault(e){return arguments.length?(this._preventDefault=e,this):this._preventDefault},timer:Ode,events:sde,finalize:ade,hover:ode,data:Vfe,change:Mb,insert:Xfe,remove:Kfe,scale:$de,initialize:_de,toImageURL:Ede,toCanvas:kde,toSVG:Sde,getState:Mde,setState:Nde,_watchPixelRatio:Bde});const zde="view",Jv="[",Qv="]",aB="{",lB="}",jde=":",uB=",",Ude="@",qde=">",Wde=/[[\]{}]/,Hde={"*":1,arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1};let cB,fB;function Fu(e,t,n){return cB=t||zde,fB=n||Hde,dB(e.trim()).map(GE)}function Gde(e){return fB[e]}function ig(e,t,n,r,i){const s=e.length;let o=0,a;for(;t=0?--o:r&&r.indexOf(a)>=0&&++o}return t}function dB(e){const t=[],n=e.length;let r=0,i=0;for(;i' after between selector: "+e;r=r.map(GE);const i=GE(e.slice(1).trim());return i.between?{between:r,stream:i}:(i.between=r,i)}function Vde(e){const t={source:cB},n=[];let r=[0,0],i=0,s=0,o=e.length,a=0,l,u;if(e[o-1]===lB){if(a=e.lastIndexOf(aB),a>=0){try{r=Xde(e.substring(a+1,o-1))}catch{throw"Invalid throttle specification: "+e}e=e.slice(0,a).trim(),o=e.length}else throw"Unmatched right brace: "+e;a=0}if(!o)throw e;if(e[0]===Ude&&(i=++a),l=ig(e,a,jde),l1?(t.type=n[1],i?t.markname=n[0].slice(1):Gde(n[0])?t.marktype=n[0]:t.source=n[0]):t.type=n[0],t.type.slice(-1)==="!"&&(t.consume=!0,t.type=t.type.slice(0,-1)),u!=null&&(t.filter=u),r[0]&&(t.throttle=r[0]),r[1]&&(t.debounce=r[1]),t}function Xde(e){const t=e.split(uB);if(!e.length||t.length>2)throw e;return t.map(n=>{const r=+n;if(r!==r)throw e;return r})}function Kde(e){return Le(e)?e:{type:e||"pad"}}const lp=e=>+e||0,Zde=e=>({top:e,bottom:e,left:e,right:e});function Jde(e){return Le(e)?e.signal?e:{top:lp(e.top),bottom:lp(e.bottom),left:lp(e.left),right:lp(e.right)}:Zde(lp(e))}const hr=e=>Le(e)&&!de(e)?Mt({},e):{value:e};function BM(e,t,n,r){return n!=null?(Le(n)&&!de(n)||de(n)&&n.length&&Le(n[0])?e.update[t]=n:e[r||"enter"][t]={value:n},1):0}function Ir(e,t,n){for(const r in t)BM(e,r,t[r]);for(const r in n)BM(e,r,n[r],"update")}function Dh(e,t,n){for(const r in t)n&&Ue(n,r)||(e[r]=Mt(e[r]||{},t[r]));return e}function Vf(e,t){return t&&(t.enter&&t.enter[e]||t.update&&t.update[e])}const PC="mark",BC="frame",zC="scope",Qde="axis",ehe="axis-domain",the="axis-grid",nhe="axis-label",rhe="axis-tick",ihe="axis-title",she="legend",ohe="legend-band",ahe="legend-entry",lhe="legend-gradient",hB="legend-label",uhe="legend-symbol",che="legend-title",fhe="title",dhe="title-text",hhe="title-subtitle";function phe(e,t,n,r,i){const s={},o={};let a,l,u,c;l="lineBreak",t==="text"&&i[l]!=null&&!Vf(l,e)&&s_(s,l,i[l]),(n=="legend"||String(n).startsWith("axis"))&&(n=null),c=n===BC?i.group:n===PC?Mt({},i.mark,i[t]):null;for(l in c)u=Vf(l,e)||(l==="fill"||l==="stroke")&&(Vf("fill",e)||Vf("stroke",e)),u||s_(s,l,c[l]);Be(r).forEach(f=>{const d=i.style&&i.style[f];for(const h in d)Vf(h,e)||s_(s,h,d[h])}),e=Mt({},e);for(l in s)c=s[l],c.signal?(a=a||{})[l]=c:o[l]=c;return e.enter=Mt(o,e.enter),a&&(e.update=Mt(a,e.update)),e}function s_(e,t,n){e[t]=n&&n.signal?{signal:n.signal}:{value:n}}const pB=e=>Ie(e)?$e(e):e.signal?`(${e.signal})`:gB(e);function Rb(e){if(e.gradient!=null)return mhe(e);let t=e.signal?`(${e.signal})`:e.color?ghe(e.color):e.field!=null?gB(e.field):e.value!==void 0?$e(e.value):void 0;return e.scale!=null&&(t=vhe(e,t)),t===void 0&&(t=null),e.exponent!=null&&(t=`pow(${t},${E1(e.exponent)})`),e.mult!=null&&(t+=`*${E1(e.mult)}`),e.offset!=null&&(t+=`+${E1(e.offset)}`),e.round&&(t=`round(${t})`),t}const Tm=(e,t,n,r)=>`(${e}(${[t,n,r].map(Rb).join(",")})+'')`;function ghe(e){return e.c?Tm("hcl",e.h,e.c,e.l):e.h||e.s?Tm("hsl",e.h,e.s,e.l):e.l||e.a?Tm("lab",e.l,e.a,e.b):e.r||e.g||e.b?Tm("rgb",e.r,e.g,e.b):null}function mhe(e){const t=[e.start,e.stop,e.count].map(n=>n==null?null:$e(n));for(;t.length&&Wt(t)==null;)t.pop();return t.unshift(pB(e.gradient)),`gradient(${t.join(",")})`}function E1(e){return Le(e)?"("+Rb(e)+")":e}function gB(e){return mB(Le(e)?e:{datum:e})}function mB(e){let t,n,r;if(e.signal)t="datum",r=e.signal;else if(e.group||e.parent){for(n=Math.max(1,e.level||1),t="item";n-- >0;)t+=".mark.group";e.parent?(r=e.parent,t+=".datum"):r=e.group}else e.datum?(t="datum",r=e.datum):le("Invalid field reference: "+$e(e));return e.signal||(r=Ie(r)?va(r).map($e).join("]["):mB(r)),t+"["+r+"]"}function vhe(e,t){const n=pB(e.scale);return e.range!=null?t=`lerp(_range(${n}), ${+e.range})`:(t!==void 0&&(t=`_scale(${n}, ${t})`),e.band&&(t=(t?t+"+":"")+`_bandwidth(${n})`+(+e.band==1?"":"*"+E1(e.band)),e.extra&&(t=`(datum.extra ? _scale(${n}, datum.extra.value) : ${t})`)),t==null&&(t="0")),t}function yhe(e){let t="";return e.forEach(n=>{const r=Rb(n);t+=n.test?`(${n.test})?${r}:`:r}),Wt(t)===":"&&(t+="null"),t}function vB(e,t,n,r,i,s){const o={};s=s||{},s.encoders={$encode:o},e=phe(e,t,n,r,i.config);for(const a in e)o[a]=bhe(e[a],t,s,i);return s}function bhe(e,t,n,r){const i={},s={};for(const o in e)e[o]!=null&&(i[o]=_he(xhe(e[o]),r,n,s));return{$expr:{marktype:t,channels:i},$fields:Object.keys(s),$output:Object.keys(e)}}function xhe(e){return de(e)?yhe(e):Rb(e)}function _he(e,t,n,r){const i=da(e,t);return i.$fields.forEach(s=>r[s]=1),Mt(n,i.$params),i.$expr}const whe="outer",Ehe=["value","update","init","react","bind"];function zM(e,t){le(e+' for "outer" push: '+$e(t))}function yB(e,t){const n=e.name;if(e.push===whe)t.signals[n]||zM("No prior signal definition",n),Ehe.forEach(r=>{e[r]!==void 0&&zM("Invalid property ",r)});else{const r=t.addSignal(n,e.value);e.react===!1&&(r.react=!1),e.bind&&t.addBinding(n,e.bind)}}function YE(e,t,n,r){this.id=-1,this.type=e,this.value=t,this.params=n,r&&(this.parent=r)}function Nb(e,t,n,r){return new YE(e,t,n,r)}function ey(e,t){return Nb("operator",e,t)}function st(e){const t={$ref:e.id};return e.id<0&&(e.refs=e.refs||[]).push(t),t}function Tg(e,t){return t?{$field:e,$name:t}:{$field:e}}const VE=Tg("key");function jM(e,t){return{$compare:e,$order:t}}function Ahe(e,t){const n={$key:e};return t&&(n.$flat=!0),n}const khe="ascending",She="descending";function Che(e){return Le(e)?(e.order===She?"-":"+")+Ob(e.op,e.field):""}function Ob(e,t){return(e&&e.signal?"$"+e.signal:e||"")+(e&&t?"_":"")+(t&&t.signal?"$"+t.signal:t||"")}const jC="scope",XE="view";function nr(e){return e&&e.signal}function $he(e){return e&&e.expr}function A1(e){if(nr(e))return!0;if(Le(e)){for(const t in e)if(A1(e[t]))return!0}return!1}function to(e,t){return e??t}function Sc(e){return e&&e.signal||e}const UM="timer";function Rg(e,t){return(e.merge?Dhe:e.stream?Mhe:e.type?The:le("Invalid stream specification: "+$e(e)))(e,t)}function Fhe(e){return e===jC?XE:e||XE}function Dhe(e,t){const n=e.merge.map(i=>Rg(i,t)),r=UC({merge:n},e,t);return t.addStream(r).id}function Mhe(e,t){const n=Rg(e.stream,t),r=UC({stream:n},e,t);return t.addStream(r).id}function The(e,t){let n;e.type===UM?(n=t.event(UM,e.throttle),e={between:e.between,filter:e.filter}):n=t.event(Fhe(e.source),e.type);const r=UC({stream:n},e,t);return Object.keys(r).length===1?n:t.addStream(r).id}function UC(e,t,n){let r=t.between;return r&&(r.length!==2&&le('Stream "between" parameter must have 2 entries: '+$e(t)),e.between=[Rg(r[0],n),Rg(r[1],n)]),r=t.filter?[].concat(t.filter):[],(t.marktype||t.markname||t.markrole)&&r.push(Rhe(t.marktype,t.markname,t.markrole)),t.source===jC&&r.push("inScope(event.item)"),r.length&&(e.filter=da("("+r.join(")&&(")+")",n).$expr),(r=t.throttle)!=null&&(e.throttle=+r),(r=t.debounce)!=null&&(e.debounce=+r),t.consume&&(e.consume=!0),e}function Rhe(e,t,n){const r="event.item";return r+(e&&e!=="*"?"&&"+r+".mark.marktype==='"+e+"'":"")+(n?"&&"+r+".mark.role==='"+n+"'":"")+(t?"&&"+r+".mark.name==='"+t+"'":"")}const Nhe={code:"_.$value",ast:{type:"Identifier",value:"value"}};function Ohe(e,t,n){const r=e.encode,i={target:n};let s=e.events,o=e.update,a=[];s||le("Signal update missing events specification."),Ie(s)&&(s=Fu(s,t.isSubscope()?jC:XE)),s=Be(s).filter(l=>l.signal||l.scale?(a.push(l),0):1),a.length>1&&(a=[Ihe(a)]),s.length&&a.push(s.length>1?{merge:s}:s[0]),r!=null&&(o&&le("Signal encode and update are mutually exclusive."),o="encode(item(),"+$e(r)+")"),i.update=Ie(o)?da(o,t):o.expr!=null?da(o.expr,t):o.value!=null?o.value:o.signal!=null?{$expr:Nhe,$params:{$value:t.signalRef(o.signal)}}:le("Invalid signal update specification."),e.force&&(i.options={force:!0}),a.forEach(l=>t.addUpdate(Mt(Lhe(l,t),i)))}function Lhe(e,t){return{source:e.signal?t.signalRef(e.signal):e.scale?t.scaleRef(e.scale):Rg(e,t)}}function Ihe(e){return{signal:"["+e.map(t=>t.scale?'scale("'+t.scale+'")':t.signal)+"]"}}function Phe(e,t){const n=t.getSignal(e.name);let r=e.update;e.init&&(r?le("Signals can not include both init and update expressions."):(r=e.init,n.initonly=!0)),r&&(r=da(r,t),n.update=r.$expr,n.params=r.$params),e.on&&e.on.forEach(i=>Ohe(i,t,n.id))}const un=e=>(t,n,r)=>Nb(e,n,t||void 0,r),bB=un("aggregate"),Bhe=un("axisticks"),xB=un("bound"),Ao=un("collect"),qM=un("compare"),zhe=un("datajoin"),_B=un("encode"),jhe=un("expression"),Uhe=un("facet"),qhe=un("field"),Whe=un("key"),Hhe=un("legendentries"),Ghe=un("load"),Yhe=un("mark"),Vhe=un("multiextent"),Xhe=un("multivalues"),Khe=un("overlap"),Zhe=un("params"),wB=un("prefacet"),Jhe=un("projection"),Qhe=un("proxy"),epe=un("relay"),EB=un("render"),tpe=un("scale"),yf=un("sieve"),npe=un("sortitems"),AB=un("viewlayout"),rpe=un("values");let ipe=0;const kB={min:"min",max:"max",count:"sum"};function spe(e,t){const n=e.type||"linear";c9(n)||le("Unrecognized scale type: "+$e(n)),t.addScale(e.name,{type:n,domain:void 0})}function ope(e,t){const n=t.getScale(e.name).params;let r;n.domain=SB(e.domain,e,t),e.range!=null&&(n.range=$B(e,t,n)),e.interpolate!=null&&mpe(e.interpolate,n),e.nice!=null&&(n.nice=gpe(e.nice,t)),e.bins!=null&&(n.bins=ppe(e.bins,t));for(r in e)Ue(n,r)||r==="name"||(n[r]=$s(e[r],t))}function $s(e,t){return Le(e)?e.signal?t.signalRef(e.signal):le("Unsupported object: "+$e(e)):e}function k1(e,t){return e.signal?t.signalRef(e.signal):e.map(n=>$s(n,t))}function Lb(e){le("Can not find data set: "+$e(e))}function SB(e,t,n){if(!e){(t.domainMin!=null||t.domainMax!=null)&&le("No scale domain defined for domainMin/domainMax to override.");return}return e.signal?n.signalRef(e.signal):(de(e)?ape:e.fields?upe:lpe)(e,t,n)}function ape(e,t,n){return e.map(r=>$s(r,n))}function lpe(e,t,n){const r=n.getData(e.data);return r||Lb(e.data),zd(t.type)?r.valuesRef(n,e.field,CB(e.sort,!1)):h9(t.type)?r.domainRef(n,e.field):r.extentRef(n,e.field)}function upe(e,t,n){const r=e.data,i=e.fields.reduce((s,o)=>(o=Ie(o)?{data:r,field:o}:de(o)||o.signal?cpe(o,n):o,s.push(o),s),[]);return(zd(t.type)?fpe:h9(t.type)?dpe:hpe)(e,n,i)}function cpe(e,t){const n="_:vega:_"+ipe++,r=Ao({});if(de(e))r.value={$ingest:e};else if(e.signal){const i="setdata("+$e(n)+","+e.signal+")";r.params.input=t.signalRef(i)}return t.addDataPipeline(n,[r,yf({})]),{data:n,field:"data"}}function fpe(e,t,n){const r=CB(e.sort,!0);let i,s;const o=n.map(u=>{const c=t.getData(u.data);return c||Lb(u.data),c.countsRef(t,u.field,r)}),a={groupby:VE,pulse:o};r&&(i=r.op||"count",s=r.field?Ob(i,r.field):"count",a.ops=[kB[i]],a.fields=[t.fieldRef(s)],a.as=[s]),i=t.add(bB(a));const l=t.add(Ao({pulse:st(i)}));return s=t.add(rpe({field:VE,sort:t.sortRef(r),pulse:st(l)})),st(s)}function CB(e,t){return e&&(!e.field&&!e.op?Le(e)?e.field="key":e={field:"key"}:!e.field&&e.op!=="count"?le("No field provided for sort aggregate op: "+e.op):t&&e.field&&e.op&&!kB[e.op]&&le("Multiple domain scales can not be sorted using "+e.op)),e}function dpe(e,t,n){const r=n.map(i=>{const s=t.getData(i.data);return s||Lb(i.data),s.domainRef(t,i.field)});return st(t.add(Xhe({values:r})))}function hpe(e,t,n){const r=n.map(i=>{const s=t.getData(i.data);return s||Lb(i.data),s.extentRef(t,i.field)});return st(t.add(Vhe({extents:r})))}function ppe(e,t){return e.signal||de(e)?k1(e,t):t.objectProperty(e)}function gpe(e,t){return e.signal?t.signalRef(e.signal):Le(e)?{interval:$s(e.interval),step:$s(e.step)}:$s(e)}function mpe(e,t){t.interpolate=$s(e.type||e),e.gamma!=null&&(t.interpolateGamma=$s(e.gamma))}function $B(e,t,n){const r=t.config.range;let i=e.range;if(i.signal)return t.signalRef(i.signal);if(Ie(i)){if(r&&Ue(r,i))return e=Mt({},e,{range:r[i]}),$B(e,t,n);i==="width"?i=[0,{signal:"width"}]:i==="height"?i=zd(e.type)?[0,{signal:"height"}]:[{signal:"height"},0]:le("Unrecognized scale range value: "+$e(i))}else if(i.scheme){n.scheme=de(i.scheme)?k1(i.scheme,t):$s(i.scheme,t),i.extent&&(n.schemeExtent=k1(i.extent,t)),i.count&&(n.schemeCount=$s(i.count,t));return}else if(i.step){n.rangeStep=$s(i.step,t);return}else{if(zd(e.type)&&!de(i))return SB(i,e,t);de(i)||le("Unsupported range type: "+$e(i))}return i.map(s=>(de(s)?k1:$s)(s,t))}function vpe(e,t){const n=t.config.projection||{},r={};for(const i in e)i!=="name"&&(r[i]=KE(e[i],i,t));for(const i in n)r[i]==null&&(r[i]=KE(n[i],i,t));t.addProjection(e.name,r)}function KE(e,t,n){return de(e)?e.map(r=>KE(r,t,n)):Le(e)?e.signal?n.signalRef(e.signal):t==="fit"?e:le("Unsupported parameter object: "+$e(e)):e}const ko="top",Mh="left",Th="right",hu="bottom",FB="center",ype="vertical",bpe="start",xpe="middle",_pe="end",ZE="index",qC="label",wpe="offset",Xd="perc",Epe="perc2",Rs="value",T0="guide-label",WC="guide-title",Ape="group-title",kpe="group-subtitle",WM="symbol",S1="gradient",JE="discrete",QE="size",Spe="shape",Cpe="fill",$pe="stroke",Fpe="strokeWidth",Dpe="strokeDash",Mpe="opacity",HC=[QE,Spe,Cpe,$pe,Fpe,Dpe,Mpe],R0={name:1,style:1,interactive:1},Ht={value:0},Ns={value:1},Ib="group",DB="rect",GC="rule",Tpe="symbol",bf="text";function Ng(e){return e.type=Ib,e.interactive=e.interactive||!1,e}function Vi(e,t){const n=(r,i)=>to(e[r],to(t[r],i));return n.isVertical=r=>ype===to(e.direction,t.direction||(r?t.symbolDirection:t.gradientDirection)),n.gradientLength=()=>to(e.gradientLength,t.gradientLength||t.gradientWidth),n.gradientThickness=()=>to(e.gradientThickness,t.gradientThickness||t.gradientHeight),n.entryColumns=()=>to(e.columns,to(t.columns,+n.isVertical(!0))),n}function MB(e,t){const n=t&&(t.update&&t.update[e]||t.enter&&t.enter[e]);return n&&n.signal?n:n?n.value:null}function Rpe(e,t,n){const r=t.config.style[n];return r&&r[e]}function Pb(e,t,n){return`item.anchor === '${bpe}' ? ${e} : item.anchor === '${_pe}' ? ${t} : ${n}`}const YC=Pb($e(Mh),$e(Th),$e(FB));function Npe(e){const t=e("tickBand");let n=e("tickOffset"),r,i;return t?t.signal?(r={signal:`(${t.signal}) === 'extent' ? 1 : 0.5`},i={signal:`(${t.signal}) === 'extent'`},Le(n)||(n={signal:`(${t.signal}) === 'extent' ? 0 : ${n}`})):t==="extent"?(r=1,i=!0,n=0):(r=.5,i=!1):(r=e("bandPosition"),i=e("tickExtra")),{extra:i,band:r,offset:n}}function TB(e,t){return t?e?Le(e)?Object.assign({},e,{offset:TB(e.offset,t)}):{value:e,offset:t}:t:e}function ms(e,t){return t?(e.name=t.name,e.style=t.style||e.style,e.interactive=!!t.interactive,e.encode=Dh(e.encode,t,R0)):e.interactive=!1,e}function Ope(e,t,n,r){const i=Vi(e,n),s=i.isVertical(),o=i.gradientThickness(),a=i.gradientLength();let l,u,c,f,d;s?(u=[0,1],c=[0,0],f=o,d=a):(u=[0,0],c=[1,0],f=a,d=o);const h={enter:l={opacity:Ht,x:Ht,y:Ht,width:hr(f),height:hr(d)},update:Mt({},l,{opacity:Ns,fill:{gradient:t,start:u,stop:c}}),exit:{opacity:Ht}};return Ir(h,{stroke:i("gradientStrokeColor"),strokeWidth:i("gradientStrokeWidth")},{opacity:i("gradientOpacity")}),ms({type:DB,role:lhe,encode:h},r)}function Lpe(e,t,n,r,i){const s=Vi(e,n),o=s.isVertical(),a=s.gradientThickness(),l=s.gradientLength();let u,c,f,d,h="";o?(u="y",f="y2",c="x",d="width",h="1-"):(u="x",f="x2",c="y",d="height");const p={opacity:Ht,fill:{scale:t,field:Rs}};p[u]={signal:h+"datum."+Xd,mult:l},p[c]=Ht,p[f]={signal:h+"datum."+Epe,mult:l},p[d]=hr(a);const g={enter:p,update:Mt({},p,{opacity:Ns}),exit:{opacity:Ht}};return Ir(g,{stroke:s("gradientStrokeColor"),strokeWidth:s("gradientStrokeWidth")},{opacity:s("gradientOpacity")}),ms({type:DB,role:ohe,key:Rs,from:i,encode:g},r)}const Ipe=`datum.${Xd}<=0?"${Mh}":datum.${Xd}>=1?"${Th}":"${FB}"`,Ppe=`datum.${Xd}<=0?"${hu}":datum.${Xd}>=1?"${ko}":"${xpe}"`;function HM(e,t,n,r){const i=Vi(e,t),s=i.isVertical(),o=hr(i.gradientThickness()),a=i.gradientLength();let l=i("labelOverlap"),u,c,f,d,h="";const p={enter:u={opacity:Ht},update:c={opacity:Ns,text:{field:qC}},exit:{opacity:Ht}};return Ir(p,{fill:i("labelColor"),fillOpacity:i("labelOpacity"),font:i("labelFont"),fontSize:i("labelFontSize"),fontStyle:i("labelFontStyle"),fontWeight:i("labelFontWeight"),limit:to(e.labelLimit,t.gradientLabelLimit)}),s?(u.align={value:"left"},u.baseline=c.baseline={signal:Ppe},f="y",d="x",h="1-"):(u.align=c.align={signal:Ipe},u.baseline={value:"top"},f="x",d="y"),u[f]=c[f]={signal:h+"datum."+Xd,mult:a},u[d]=c[d]=o,o.offset=to(e.labelOffset,t.gradientLabelOffset)||0,l=l?{separation:i("labelSeparation"),method:l,order:"datum."+ZE}:void 0,ms({type:bf,role:hB,style:T0,key:Rs,from:r,encode:p,overlap:l},n)}function Bpe(e,t,n,r,i){const s=Vi(e,t),o=n.entries,a=!!(o&&o.interactive),l=o?o.name:void 0,u=s("clipHeight"),c=s("symbolOffset"),f={data:"value"},d=`(${i}) ? datum.${wpe} : datum.${QE}`,h=u?hr(u):{field:QE},p=`datum.${ZE}`,g=`max(1, ${i})`;let m,y,b,x,_;h.mult=.5,m={enter:y={opacity:Ht,x:{signal:d,mult:.5,offset:c},y:h},update:b={opacity:Ns,x:y.x,y:y.y},exit:{opacity:Ht}};let w=null,A=null;e.fill||(w=t.symbolBaseFillColor,A=t.symbolBaseStrokeColor),Ir(m,{fill:s("symbolFillColor",w),shape:s("symbolType"),size:s("symbolSize"),stroke:s("symbolStrokeColor",A),strokeDash:s("symbolDash"),strokeDashOffset:s("symbolDashOffset"),strokeWidth:s("symbolStrokeWidth")},{opacity:s("symbolOpacity")}),HC.forEach($=>{e[$]&&(b[$]=y[$]={scale:e[$],field:Rs})});const E=ms({type:Tpe,role:uhe,key:Rs,from:f,clip:u?!0:void 0,encode:m},n.symbols),k=hr(c);k.offset=s("labelOffset"),m={enter:y={opacity:Ht,x:{signal:d,offset:k},y:h},update:b={opacity:Ns,text:{field:qC},x:y.x,y:y.y},exit:{opacity:Ht}},Ir(m,{align:s("labelAlign"),baseline:s("labelBaseline"),fill:s("labelColor"),fillOpacity:s("labelOpacity"),font:s("labelFont"),fontSize:s("labelFontSize"),fontStyle:s("labelFontStyle"),fontWeight:s("labelFontWeight"),limit:s("labelLimit")});const S=ms({type:bf,role:hB,style:T0,key:Rs,from:f,encode:m},n.labels);return m={enter:{noBound:{value:!u},width:Ht,height:u?hr(u):Ht,opacity:Ht},exit:{opacity:Ht},update:b={opacity:Ns,row:{signal:null},column:{signal:null}}},s.isVertical(!0)?(x=`ceil(item.mark.items.length / ${g})`,b.row.signal=`${p}%${x}`,b.column.signal=`floor(${p} / ${x})`,_={field:["row",p]}):(b.row.signal=`floor(${p} / ${g})`,b.column.signal=`${p} % ${g}`,_={field:p}),b.column.signal=`(${i})?${b.column.signal}:${p}`,r={facet:{data:r,name:"value",groupby:ZE}},Ng({role:zC,from:r,encode:Dh(m,o,R0),marks:[E,S],name:l,interactive:a,sort:_})}function zpe(e,t){const n=Vi(e,t);return{align:n("gridAlign"),columns:n.entryColumns(),center:{row:!0,column:!1},padding:{row:n("rowPadding"),column:n("columnPadding")}}}const VC='item.orient === "left"',XC='item.orient === "right"',Bb=`(${VC} || ${XC})`,jpe=`datum.vgrad && ${Bb}`,Upe=Pb('"top"','"bottom"','"middle"'),qpe=Pb('"right"','"left"','"center"'),Wpe=`datum.vgrad && ${XC} ? (${qpe}) : (${Bb} && !(datum.vgrad && ${VC})) ? "left" : ${YC}`,Hpe=`item._anchor || (${Bb} ? "middle" : "start")`,Gpe=`${jpe} ? (${VC} ? -90 : 90) : 0`,Ype=`${Bb} ? (datum.vgrad ? (${XC} ? "bottom" : "top") : ${Upe}) : "top"`;function Vpe(e,t,n,r){const i=Vi(e,t),s={enter:{opacity:Ht},update:{opacity:Ns,x:{field:{group:"padding"}},y:{field:{group:"padding"}}},exit:{opacity:Ht}};return Ir(s,{orient:i("titleOrient"),_anchor:i("titleAnchor"),anchor:{signal:Hpe},angle:{signal:Gpe},align:{signal:Wpe},baseline:{signal:Ype},text:e.title,fill:i("titleColor"),fillOpacity:i("titleOpacity"),font:i("titleFont"),fontSize:i("titleFontSize"),fontStyle:i("titleFontStyle"),fontWeight:i("titleFontWeight"),limit:i("titleLimit"),lineHeight:i("titleLineHeight")},{align:i("titleAlign"),baseline:i("titleBaseline")}),ms({type:bf,role:che,style:WC,from:r,encode:s},n)}function Xpe(e,t){let n;return Le(e)&&(e.signal?n=e.signal:e.path?n="pathShape("+GM(e.path)+")":e.sphere&&(n="geoShape("+GM(e.sphere)+', {type: "Sphere"})')),n?t.signalRef(n):!!e}function GM(e){return Le(e)&&e.signal?e.signal:$e(e)}function RB(e){const t=e.role||"";return t.startsWith("axis")||t.startsWith("legend")||t.startsWith("title")?t:e.type===Ib?zC:t||PC}function Kpe(e){return{marktype:e.type,name:e.name||void 0,role:e.role||RB(e),zindex:+e.zindex||void 0,aria:e.aria,description:e.description}}function Zpe(e,t){return e&&e.signal?t.signalRef(e.signal):e!==!1}function KC(e,t){const n=dO(e.type);n||le("Unrecognized transform type: "+$e(e.type));const r=Nb(n.type.toLowerCase(),null,NB(n,e,t));return e.signal&&t.addSignal(e.signal,t.proxy(r)),r.metadata=n.metadata||{},r}function NB(e,t,n){const r={},i=e.params.length;for(let s=0;sYM(e,s,n)):YM(e,i,n)}function YM(e,t,n){const r=e.type;if(nr(t))return XM(r)?le("Expression references can not be signals."):o_(r)?n.fieldRef(t):KM(r)?n.compareRef(t):n.signalRef(t.signal);{const i=e.expr||o_(r);return i&&tge(t)?n.exprRef(t.expr,t.as):i&&nge(t)?Tg(t.field,t.as):XM(r)?da(t,n):rge(r)?st(n.getData(t).values):o_(r)?Tg(t):KM(r)?n.compareRef(t):t}}function Qpe(e,t,n){return Ie(t.from)||le('Lookup "from" parameter must be a string literal.'),n.getData(t.from).lookupRef(n,t.key)}function ege(e,t,n){const r=t[e.name];return e.array?(de(r)||le("Expected an array of sub-parameters. Instead: "+$e(r)),r.map(i=>VM(e,i,n))):VM(e,r,n)}function VM(e,t,n){const r=e.params.length;let i;for(let o=0;oe&&e.expr,nge=e=>e&&e.field,rge=e=>e==="data",XM=e=>e==="expr",o_=e=>e==="field",KM=e=>e==="compare";function ige(e,t,n){let r,i,s,o,a;return e?(r=e.facet)&&(t||le("Only group marks can be faceted."),r.field!=null?o=a=C1(r,n):(e.data?a=st(n.getData(e.data).aggregate):(s=KC(Mt({type:"aggregate",groupby:Be(r.groupby)},r.aggregate),n),s.params.key=n.keyRef(r.groupby),s.params.pulse=C1(r,n),o=a=st(n.add(s))),i=n.keyRef(r.groupby,!0))):o=st(n.add(Ao(null,[{}]))),o||(o=C1(e,n)),{key:i,pulse:o,parent:a}}function C1(e,t){return e.$ref?e:e.data&&e.data.$ref?e.data:st(t.getData(e.data).output)}function Zc(e,t,n,r,i){this.scope=e,this.input=t,this.output=n,this.values=r,this.aggregate=i,this.index={}}Zc.fromEntries=function(e,t){const n=t.length,r=t[n-1],i=t[n-2];let s=t[0],o=null,a=1;for(s&&s.type==="load"&&(s=t[1]),e.add(t[0]);af??"null").join(",")+"),0)",c=da(u,t);l.update=c.$expr,l.params=c.$params}function zb(e,t){const n=RB(e),r=e.type===Ib,i=e.from&&e.from.facet,s=e.overlap;let o=e.layout||n===zC||n===BC,a,l,u,c,f,d,h;const p=n===PC||o||i,g=ige(e.from,r,t);l=t.add(zhe({key:g.key||(e.key?Tg(e.key):void 0),pulse:g.pulse,clean:!r}));const m=st(l);l=u=t.add(Ao({pulse:m})),l=t.add(Yhe({markdef:Kpe(e),interactive:Zpe(e.interactive,t),clip:Xpe(e.clip,t),context:{$context:!0},groups:t.lookup(),parent:t.signals.parent?t.signalRef("parent"):null,index:t.markpath(),pulse:st(l)}));const y=st(l);l=c=t.add(_B(vB(e.encode,e.type,n,e.style,t,{mod:!1,pulse:y}))),l.params.parent=t.encode(),e.transform&&e.transform.forEach(A=>{const E=KC(A,t),k=E.metadata;(k.generates||k.changes)&&le("Mark transforms should not generate new data."),k.nomod||(c.params.mod=!0),E.params.pulse=st(l),t.add(l=E)}),e.sort&&(l=t.add(npe({sort:t.compareRef(e.sort),pulse:st(l)})));const b=st(l);(i||o)&&(o=t.add(AB({layout:t.objectProperty(e.layout),legends:t.legends,mark:y,pulse:b})),d=st(o));const x=t.add(xB({mark:y,pulse:d||b}));h=st(x),r&&(p&&(a=t.operators,a.pop(),o&&a.pop()),t.pushState(b,d||h,m),i?sge(e,t,g):p?oge(e,t,g):t.parse(e),t.popState(),p&&(o&&a.push(o),a.push(x))),s&&(h=age(s,h,t));const _=t.add(EB({pulse:h})),w=t.add(yf({pulse:st(_)},void 0,t.parent()));e.name!=null&&(f=e.name,t.addData(f,new Zc(t,u,_,w)),e.on&&e.on.forEach(A=>{(A.insert||A.remove||A.toggle)&&le("Marks only support modify triggers."),LB(A,t,f)}))}function age(e,t,n){const r=e.method,i=e.bound,s=e.separation,o={separation:nr(s)?n.signalRef(s.signal):s,method:nr(r)?n.signalRef(r.signal):r,pulse:t};if(e.order&&(o.sort=n.compareRef({field:e.order})),i){const a=i.tolerance;o.boundTolerance=nr(a)?n.signalRef(a.signal):+a,o.boundScale=n.scaleRef(i.scale),o.boundOrient=i.orient}return st(n.add(Khe(o)))}function lge(e,t){const n=t.config.legend,r=e.encode||{},i=Vi(e,n),s=r.legend||{},o=s.name||void 0,a=s.interactive,l=s.style,u={};let c=0,f,d,h;HC.forEach(x=>e[x]?(u[x]=e[x],c=c||e[x]):0),c||le("Missing valid scale for legend.");const p=uge(e,t.scaleType(c)),g={title:e.title!=null,scales:u,type:p,vgrad:p!=="symbol"&&i.isVertical()},m=st(t.add(Ao(null,[g]))),y={enter:{x:{value:0},y:{value:0}}},b=st(t.add(Hhe(d={type:p,scale:t.scaleRef(c),count:t.objectProperty(i("tickCount")),limit:t.property(i("symbolLimit")),values:t.objectProperty(e.values),minstep:t.property(e.tickMinStep),formatType:t.property(e.formatType),formatSpecifier:t.property(e.format)})));return p===S1?(h=[Ope(e,c,n,r.gradient),HM(e,n,r.labels,b)],d.count=d.count||t.signalRef(`max(2,2*floor((${Sc(i.gradientLength())})/100))`)):p===JE?h=[Lpe(e,c,n,r.gradient,b),HM(e,n,r.labels,b)]:(f=zpe(e,n),h=[Bpe(e,n,r,b,Sc(f.columns))],d.size=dge(e,t,h[0].marks)),h=[Ng({role:ahe,from:m,encode:y,marks:h,layout:f,interactive:a})],g.title&&h.push(Vpe(e,n,r.title,m)),zb(Ng({role:she,from:m,encode:Dh(fge(i,e,n),s,R0),marks:h,aria:i("aria"),description:i("description"),zindex:i("zindex"),name:o,interactive:a,style:l}),t)}function uge(e,t){let n=e.type||WM;return!e.type&&cge(e)===1&&(e.fill||e.stroke)&&(n=ZS(t)?S1:Ww(t)?JE:WM),n!==S1?n:Ww(t)?JE:S1}function cge(e){return HC.reduce((t,n)=>t+(e[n]?1:0),0)}function fge(e,t,n){const r={enter:{},update:{}};return Ir(r,{orient:e("orient"),offset:e("offset"),padding:e("padding"),titlePadding:e("titlePadding"),cornerRadius:e("cornerRadius"),fill:e("fillColor"),stroke:e("strokeColor"),strokeWidth:n.strokeWidth,strokeDash:n.strokeDash,x:e("legendX"),y:e("legendY"),format:t.format,formatType:t.formatType}),r}function dge(e,t,n){const r=Sc(JM("size",e,n)),i=Sc(JM("strokeWidth",e,n)),s=Sc(hge(n[1].encode,t,T0));return da(`max(ceil(sqrt(${r})+${i}),${s})`,t)}function JM(e,t,n){return t[e]?`scale("${t[e]}",datum)`:MB(e,n[0].encode)}function hge(e,t,n){return MB("fontSize",e)||Rpe("fontSize",t,n)}const pge=`item.orient==="${Mh}"?-90:item.orient==="${Th}"?90:0`;function gge(e,t){e=Ie(e)?{text:e}:e;const n=Vi(e,t.config.title),r=e.encode||{},i=r.group||{},s=i.name||void 0,o=i.interactive,a=i.style,l=[],u={},c=st(t.add(Ao(null,[u])));return l.push(yge(e,n,mge(e),c)),e.subtitle&&l.push(bge(e,n,r.subtitle,c)),zb(Ng({role:fhe,from:c,encode:vge(n,i),marks:l,aria:n("aria"),description:n("description"),zindex:n("zindex"),name:s,interactive:o,style:a}),t)}function mge(e){const t=e.encode;return t&&t.title||Mt({name:e.name,interactive:e.interactive,style:e.style},t)}function vge(e,t){const n={enter:{},update:{}};return Ir(n,{orient:e("orient"),anchor:e("anchor"),align:{signal:YC},angle:{signal:pge},limit:e("limit"),frame:e("frame"),offset:e("offset")||0,padding:e("subtitlePadding")}),Dh(n,t,R0)}function yge(e,t,n,r){const i={value:0},s=e.text,o={enter:{opacity:i},update:{opacity:{value:1}},exit:{opacity:i}};return Ir(o,{text:s,align:{signal:"item.mark.group.align"},angle:{signal:"item.mark.group.angle"},limit:{signal:"item.mark.group.limit"},baseline:"top",dx:t("dx"),dy:t("dy"),fill:t("color"),font:t("font"),fontSize:t("fontSize"),fontStyle:t("fontStyle"),fontWeight:t("fontWeight"),lineHeight:t("lineHeight")},{align:t("align"),angle:t("angle"),baseline:t("baseline")}),ms({type:bf,role:dhe,style:Ape,from:r,encode:o},n)}function bge(e,t,n,r){const i={value:0},s=e.subtitle,o={enter:{opacity:i},update:{opacity:{value:1}},exit:{opacity:i}};return Ir(o,{text:s,align:{signal:"item.mark.group.align"},angle:{signal:"item.mark.group.angle"},limit:{signal:"item.mark.group.limit"},baseline:"top",dx:t("dx"),dy:t("dy"),fill:t("subtitleColor"),font:t("subtitleFont"),fontSize:t("subtitleFontSize"),fontStyle:t("subtitleFontStyle"),fontWeight:t("subtitleFontWeight"),lineHeight:t("subtitleLineHeight")},{align:t("align"),angle:t("angle"),baseline:t("baseline")}),ms({type:bf,role:hhe,style:kpe,from:r,encode:o},n)}function xge(e,t){const n=[];e.transform&&e.transform.forEach(r=>{n.push(KC(r,t))}),e.on&&e.on.forEach(r=>{LB(r,t,e.name)}),t.addDataPipeline(e.name,_ge(e,t,n))}function _ge(e,t,n){const r=[];let i=null,s=!1,o=!1,a,l,u,c,f;for(e.values?nr(e.values)||A1(e.format)?(r.push(QM(t,e)),r.push(i=Gu())):r.push(i=Gu({$ingest:e.values,$format:e.format})):e.url?A1(e.url)||A1(e.format)?(r.push(QM(t,e)),r.push(i=Gu())):r.push(i=Gu({$request:e.url,$format:e.format})):e.source&&(i=a=Be(e.source).map(d=>st(t.getData(d).output)),r.push(null)),l=0,u=n.length;le===hu||e===ko,jb=(e,t,n)=>nr(e)?kge(e.signal,t,n):e===Mh||e===ko?t:n,pr=(e,t,n)=>nr(e)?Ege(e.signal,t,n):IB(e)?t:n,fo=(e,t,n)=>nr(e)?Age(e.signal,t,n):IB(e)?n:t,PB=(e,t,n)=>nr(e)?Sge(e.signal,t,n):e===ko?{value:t}:{value:n},wge=(e,t,n)=>nr(e)?Cge(e.signal,t,n):e===Th?{value:t}:{value:n},Ege=(e,t,n)=>BB(`${e} === '${ko}' || ${e} === '${hu}'`,t,n),Age=(e,t,n)=>BB(`${e} !== '${ko}' && ${e} !== '${hu}'`,t,n),kge=(e,t,n)=>ZC(`${e} === '${Mh}' || ${e} === '${ko}'`,t,n),Sge=(e,t,n)=>ZC(`${e} === '${ko}'`,t,n),Cge=(e,t,n)=>ZC(`${e} === '${Th}'`,t,n),BB=(e,t,n)=>(t=t!=null?hr(t):t,n=n!=null?hr(n):n,e6(t)&&e6(n)?(t=t?t.signal||$e(t.value):null,n=n?n.signal||$e(n.value):null,{signal:`${e} ? (${t}) : (${n})`}):[Mt({test:e},t)].concat(n||[])),e6=e=>e==null||Object.keys(e).length===1,ZC=(e,t,n)=>({signal:`${e} ? (${nd(t)}) : (${nd(n)})`}),$ge=(e,t,n,r,i)=>({signal:(r!=null?`${e} === '${Mh}' ? (${nd(r)}) : `:"")+(n!=null?`${e} === '${hu}' ? (${nd(n)}) : `:"")+(i!=null?`${e} === '${Th}' ? (${nd(i)}) : `:"")+(t!=null?`${e} === '${ko}' ? (${nd(t)}) : `:"")+"(null)"}),nd=e=>nr(e)?e.signal:e==null?null:$e(e),Fge=(e,t)=>t===0?0:nr(e)?{signal:`(${e.signal}) * ${t}`}:{value:e*t},ud=(e,t)=>{const n=e.signal;return n&&n.endsWith("(null)")?{signal:n.slice(0,-6)+t.signal}:e};function zf(e,t,n,r){let i;if(t&&Ue(t,e))return t[e];if(Ue(n,e))return n[e];if(e.startsWith("title")){switch(e){case"titleColor":i="fill";break;case"titleFont":case"titleFontSize":case"titleFontWeight":i=e[5].toLowerCase()+e.slice(6)}return r[WC][i]}else if(e.startsWith("label")){switch(e){case"labelColor":i="fill";break;case"labelFont":case"labelFontSize":i=e[5].toLowerCase()+e.slice(6)}return r[T0][i]}return null}function t6(e){const t={};for(const n of e)if(n)for(const r in n)t[r]=1;return Object.keys(t)}function Dge(e,t){var n=t.config,r=n.style,i=n.axis,s=t.scaleType(e.scale)==="band"&&n.axisBand,o=e.orient,a,l,u;if(nr(o)){const f=t6([n.axisX,n.axisY]),d=t6([n.axisTop,n.axisBottom,n.axisLeft,n.axisRight]);a={};for(u of f)a[u]=pr(o,zf(u,n.axisX,i,r),zf(u,n.axisY,i,r));l={};for(u of d)l[u]=$ge(o.signal,zf(u,n.axisTop,i,r),zf(u,n.axisBottom,i,r),zf(u,n.axisLeft,i,r),zf(u,n.axisRight,i,r))}else a=o===ko||o===hu?n.axisX:n.axisY,l=n["axis"+o[0].toUpperCase()+o.slice(1)];return a||l||s?Mt({},i,a,l,s):i}function Mge(e,t,n,r){const i=Vi(e,t),s=e.orient;let o,a;const l={enter:o={opacity:Ht},update:a={opacity:Ns},exit:{opacity:Ht}};Ir(l,{stroke:i("domainColor"),strokeCap:i("domainCap"),strokeDash:i("domainDash"),strokeDashOffset:i("domainDashOffset"),strokeWidth:i("domainWidth"),strokeOpacity:i("domainOpacity")});const u=n6(e,0),c=n6(e,1);return o.x=a.x=pr(s,u,Ht),o.x2=a.x2=pr(s,c),o.y=a.y=fo(s,u,Ht),o.y2=a.y2=fo(s,c),ms({type:GC,role:ehe,from:r,encode:l},n)}function n6(e,t){return{scale:e.scale,range:t}}function Tge(e,t,n,r,i){const s=Vi(e,t),o=e.orient,a=e.gridScale,l=jb(o,1,-1),u=Rge(e.offset,l);let c,f,d;const h={enter:c={opacity:Ht},update:d={opacity:Ns},exit:f={opacity:Ht}};Ir(h,{stroke:s("gridColor"),strokeCap:s("gridCap"),strokeDash:s("gridDash"),strokeDashOffset:s("gridDashOffset"),strokeOpacity:s("gridOpacity"),strokeWidth:s("gridWidth")});const p={scale:e.scale,field:Rs,band:i.band,extra:i.extra,offset:i.offset,round:s("tickRound")},g=pr(o,{signal:"height"},{signal:"width"}),m=a?{scale:a,range:0,mult:l,offset:u}:{value:0,offset:u},y=a?{scale:a,range:1,mult:l,offset:u}:Mt(g,{mult:l,offset:u});return c.x=d.x=pr(o,p,m),c.y=d.y=fo(o,p,m),c.x2=d.x2=fo(o,y),c.y2=d.y2=pr(o,y),f.x=pr(o,p),f.y=fo(o,p),ms({type:GC,role:the,key:Rs,from:r,encode:h},n)}function Rge(e,t){if(t!==1)if(!Le(e))e=nr(t)?{signal:`(${t.signal}) * (${e||0})`}:t*(e||0);else{let n=e=Mt({},e);for(;n.mult!=null;)if(Le(n.mult))n=n.mult=Mt({},n.mult);else return n.mult=nr(t)?{signal:`(${n.mult}) * (${t.signal})`}:n.mult*t,e;n.mult=t}return e}function Nge(e,t,n,r,i,s){const o=Vi(e,t),a=e.orient,l=jb(a,-1,1);let u,c,f;const d={enter:u={opacity:Ht},update:f={opacity:Ns},exit:c={opacity:Ht}};Ir(d,{stroke:o("tickColor"),strokeCap:o("tickCap"),strokeDash:o("tickDash"),strokeDashOffset:o("tickDashOffset"),strokeOpacity:o("tickOpacity"),strokeWidth:o("tickWidth")});const h=hr(i);h.mult=l;const p={scale:e.scale,field:Rs,band:s.band,extra:s.extra,offset:s.offset,round:o("tickRound")};return f.y=u.y=pr(a,Ht,p),f.y2=u.y2=pr(a,h),c.x=pr(a,p),f.x=u.x=fo(a,Ht,p),f.x2=u.x2=fo(a,h),c.y=fo(a,p),ms({type:GC,role:rhe,key:Rs,from:r,encode:d},n)}function a_(e,t,n,r,i){return{signal:'flush(range("'+e+'"), scale("'+e+'", datum.value), '+t+","+n+","+r+","+i+")"}}function Oge(e,t,n,r,i,s){const o=Vi(e,t),a=e.orient,l=e.scale,u=jb(a,-1,1),c=Sc(o("labelFlush")),f=Sc(o("labelFlushOffset")),d=o("labelAlign"),h=o("labelBaseline");let p=c===0||!!c,g;const m=hr(i);m.mult=u,m.offset=hr(o("labelPadding")||0),m.offset.mult=u;const y={scale:l,field:Rs,band:.5,offset:TB(s.offset,o("labelOffset"))},b=pr(a,p?a_(l,c,'"left"','"right"','"center"'):{value:"center"},wge(a,"left","right")),x=pr(a,PB(a,"bottom","top"),p?a_(l,c,'"top"','"bottom"','"middle"'):{value:"middle"}),_=a_(l,c,`-(${f})`,f,0);p=p&&f;const w={opacity:Ht,x:pr(a,y,m),y:fo(a,y,m)},A={enter:w,update:g={opacity:Ns,text:{field:qC},x:w.x,y:w.y,align:b,baseline:x},exit:{opacity:Ht,x:w.x,y:w.y}};Ir(A,{dx:!d&&p?pr(a,_):null,dy:!h&&p?fo(a,_):null}),Ir(A,{angle:o("labelAngle"),fill:o("labelColor"),fillOpacity:o("labelOpacity"),font:o("labelFont"),fontSize:o("labelFontSize"),fontWeight:o("labelFontWeight"),fontStyle:o("labelFontStyle"),limit:o("labelLimit"),lineHeight:o("labelLineHeight")},{align:d,baseline:h});const E=o("labelBound");let k=o("labelOverlap");return k=k||E?{separation:o("labelSeparation"),method:k,order:"datum.index",bound:E?{scale:l,orient:a,tolerance:E}:null}:void 0,g.align!==b&&(g.align=ud(g.align,b)),g.baseline!==x&&(g.baseline=ud(g.baseline,x)),ms({type:bf,role:nhe,style:T0,key:Rs,from:r,encode:A,overlap:k},n)}function Lge(e,t,n,r){const i=Vi(e,t),s=e.orient,o=jb(s,-1,1);let a,l;const u={enter:a={opacity:Ht,anchor:hr(i("titleAnchor",null)),align:{signal:YC}},update:l=Mt({},a,{opacity:Ns,text:hr(e.title)}),exit:{opacity:Ht}},c={signal:`lerp(range("${e.scale}"), ${Pb(0,1,.5)})`};return l.x=pr(s,c),l.y=fo(s,c),a.angle=pr(s,Ht,Fge(o,90)),a.baseline=pr(s,PB(s,hu,ko),{value:hu}),l.angle=a.angle,l.baseline=a.baseline,Ir(u,{fill:i("titleColor"),fillOpacity:i("titleOpacity"),font:i("titleFont"),fontSize:i("titleFontSize"),fontStyle:i("titleFontStyle"),fontWeight:i("titleFontWeight"),limit:i("titleLimit"),lineHeight:i("titleLineHeight")},{align:i("titleAlign"),angle:i("titleAngle"),baseline:i("titleBaseline")}),Ige(i,s,u,n),u.update.align=ud(u.update.align,a.align),u.update.angle=ud(u.update.angle,a.angle),u.update.baseline=ud(u.update.baseline,a.baseline),ms({type:bf,role:ihe,style:WC,from:r,encode:u},n)}function Ige(e,t,n,r){const i=(a,l)=>a!=null?(n.update[l]=ud(hr(a),n.update[l]),!1):!Vf(l,r),s=i(e("titleX"),"x"),o=i(e("titleY"),"y");n.enter.auto=o===s?hr(o):pr(t,hr(o),hr(s))}function Pge(e,t){const n=Dge(e,t),r=e.encode||{},i=r.axis||{},s=i.name||void 0,o=i.interactive,a=i.style,l=Vi(e,n),u=Npe(l),c={scale:e.scale,ticks:!!l("ticks"),labels:!!l("labels"),grid:!!l("grid"),domain:!!l("domain"),title:e.title!=null},f=st(t.add(Ao({},[c]))),d=st(t.add(Bhe({scale:t.scaleRef(e.scale),extra:t.property(u.extra),count:t.objectProperty(e.tickCount),values:t.objectProperty(e.values),minstep:t.property(e.tickMinStep),formatType:t.property(e.formatType),formatSpecifier:t.property(e.format)}))),h=[];let p;return c.grid&&h.push(Tge(e,n,r.grid,d,u)),c.ticks&&(p=l("tickSize"),h.push(Nge(e,n,r.ticks,d,p,u))),c.labels&&(p=c.ticks?p:0,h.push(Oge(e,n,r.labels,d,p,u))),c.domain&&h.push(Mge(e,n,r.domain,f)),c.title&&h.push(Lge(e,n,r.title,f)),zb(Ng({role:Qde,from:f,encode:Dh(Bge(l,e),i,R0),marks:h,aria:l("aria"),description:l("description"),zindex:l("zindex"),name:s,interactive:o,style:a}),t)}function Bge(e,t){const n={enter:{},update:{}};return Ir(n,{orient:e("orient"),offset:e("offset")||0,position:to(t.position,0),titlePadding:e("titlePadding"),minExtent:e("minExtent"),maxExtent:e("maxExtent"),range:{signal:`abs(span(range("${t.scale}")))`},translate:e("translate"),format:t.format,formatType:t.formatType}),n}function zB(e,t,n){const r=Be(e.signals),i=Be(e.scales);return n||r.forEach(s=>yB(s,t)),Be(e.projections).forEach(s=>vpe(s,t)),i.forEach(s=>spe(s,t)),Be(e.data).forEach(s=>xge(s,t)),i.forEach(s=>ope(s,t)),(n||r).forEach(s=>Phe(s,t)),Be(e.axes).forEach(s=>Pge(s,t)),Be(e.marks).forEach(s=>zb(s,t)),Be(e.legends).forEach(s=>lge(s,t)),e.title&&gge(e.title,t),t.parseLambdas(),t}const zge=e=>Dh({enter:{x:{value:0},y:{value:0}},update:{width:{signal:"width"},height:{signal:"height"}}},e);function jge(e,t){const n=t.config,r=st(t.root=t.add(ey())),i=Uge(e,n);i.forEach(u=>yB(u,t)),t.description=e.description||n.description,t.eventConfig=n.events,t.legends=t.objectProperty(n.legend&&n.legend.layout),t.locale=n.locale;const s=t.add(Ao()),o=t.add(_B(vB(zge(e.encode),Ib,BC,e.style,t,{pulse:st(s)}))),a=t.add(AB({layout:t.objectProperty(e.layout),legends:t.legends,autosize:t.signalRef("autosize"),mark:r,pulse:st(o)}));t.operators.pop(),t.pushState(st(o),st(a),null),zB(e,t,i),t.operators.push(a);let l=t.add(xB({mark:r,pulse:st(a)}));return l=t.add(EB({pulse:st(l)})),l=t.add(yf({pulse:st(l)})),t.addData("root",new Zc(t,s,s,l)),t}function cp(e,t){return t&&t.signal?{name:e,update:t.signal}:{name:e,value:t}}function Uge(e,t){const n=o=>to(e[o],t[o]),r=[cp("background",n("background")),cp("autosize",Kde(n("autosize"))),cp("padding",Jde(n("padding"))),cp("width",n("width")||0),cp("height",n("height")||0)],i=r.reduce((o,a)=>(o[a.name]=a,o),{}),s={};return Be(e.signals).forEach(o=>{Ue(i,o.name)?o=Mt(i[o.name],o):r.push(o),s[o.name]=o}),Be(t.signals).forEach(o=>{!Ue(s,o.name)&&!Ue(i,o.name)&&r.push(o)}),r}function jB(e,t){this.config=e||{},this.options=t||{},this.bindings=[],this.field={},this.signals={},this.lambdas={},this.scales={},this.events={},this.data={},this.streams=[],this.updates=[],this.operators=[],this.eventConfig=null,this.locale=null,this._id=0,this._subid=0,this._nextsub=[0],this._parent=[],this._encode=[],this._lookup=[],this._markpath=[]}function r6(e){this.config=e.config,this.options=e.options,this.legends=e.legends,this.field=Object.create(e.field),this.signals=Object.create(e.signals),this.lambdas=Object.create(e.lambdas),this.scales=Object.create(e.scales),this.events=Object.create(e.events),this.data=Object.create(e.data),this.streams=[],this.updates=[],this.operators=[],this._id=0,this._subid=++e._nextsub[0],this._nextsub=e._nextsub,this._parent=e._parent.slice(),this._encode=e._encode.slice(),this._lookup=e._lookup.slice(),this._markpath=e._markpath}jB.prototype=r6.prototype={parse(e){return zB(e,this)},fork(){return new r6(this)},isSubscope(){return this._subid>0},toRuntime(){return this.finish(),{description:this.description,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig,locale:this.locale}},id(){return(this._subid?this._subid+":":0)+this._id++},add(e){return this.operators.push(e),e.id=this.id(),e.refs&&(e.refs.forEach(t=>{t.$ref=e.id}),e.refs=null),e},proxy(e){const t=e instanceof YE?st(e):e;return this.add(Qhe({value:t}))},addStream(e){return this.streams.push(e),e.id=this.id(),e},addUpdate(e){return this.updates.push(e),e},finish(){let e,t;this.root&&(this.root.root=!0);for(e in this.signals)this.signals[e].signal=e;for(e in this.scales)this.scales[e].scale=e;function n(r,i,s){let o,a;r&&(o=r.data||(r.data={}),a=o[i]||(o[i]=[]),a.push(s))}for(e in this.data){t=this.data[e],n(t.input,e,"input"),n(t.output,e,"output"),n(t.values,e,"values");for(const r in t.index)n(t.index[r],e,"index:"+r)}return this},pushState(e,t,n){this._encode.push(st(this.add(yf({pulse:e})))),this._parent.push(t),this._lookup.push(n?st(this.proxy(n)):null),this._markpath.push(-1)},popState(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop()},parent(){return Wt(this._parent)},encode(){return Wt(this._encode)},lookup(){return Wt(this._lookup)},markpath(){const e=this._markpath;return++e[e.length-1]},fieldRef(e,t){if(Ie(e))return Tg(e,t);e.signal||le("Unsupported field reference: "+$e(e));const n=e.signal;let r=this.field[n];if(!r){const i={name:this.signalRef(n)};t&&(i.as=t),this.field[n]=r=st(this.add(qhe(i)))}return r},compareRef(e){let t=!1;const n=s=>nr(s)?(t=!0,this.signalRef(s.signal)):$he(s)?(t=!0,this.exprRef(s.expr)):s,r=Be(e.field).map(n),i=Be(e.order).map(n);return t?st(this.add(qM({fields:r,orders:i}))):jM(r,i)},keyRef(e,t){let n=!1;const r=s=>nr(s)?(n=!0,st(i[s.signal])):s,i=this.signals;return e=Be(e).map(r),n?st(this.add(Whe({fields:e,flat:t}))):Ahe(e,t)},sortRef(e){if(!e)return e;const t=Ob(e.op,e.field),n=e.order||khe;return n.signal?st(this.add(qM({fields:t,orders:this.signalRef(n.signal)}))):jM(t,n)},event(e,t){const n=e+":"+t;if(!this.events[n]){const r=this.id();this.streams.push({id:r,source:e,type:t}),this.events[n]=r}return this.events[n]},hasOwnSignal(e){return Ue(this.signals,e)},addSignal(e,t){this.hasOwnSignal(e)&&le("Duplicate signal name: "+$e(e));const n=t instanceof YE?t:this.add(ey(t));return this.signals[e]=n},getSignal(e){return this.signals[e]||le("Unrecognized signal name: "+$e(e)),this.signals[e]},signalRef(e){return this.signals[e]?st(this.signals[e]):(Ue(this.lambdas,e)||(this.lambdas[e]=this.add(ey(null))),st(this.lambdas[e]))},parseLambdas(){const e=Object.keys(this.lambdas);for(let t=0,n=e.length;t0?",":"")+(Le(i)?i.signal||JC(i):$e(i))}return n+"]"}function Wge(e){let t="{",n=0,r,i;for(r in e)i=e[r],t+=(++n>1?",":"")+$e(r)+":"+(Le(i)?i.signal||JC(i):$e(i));return t+"}"}function Hge(){const e="sans-serif",r="#4c78a8",i="#000",s="#888",o="#ddd";return{description:"Vega visualization",padding:0,autosize:"pad",background:null,events:{defaults:{allow:["wheel"]}},group:null,mark:null,arc:{fill:r},area:{fill:r},image:null,line:{stroke:r,strokeWidth:2},path:{stroke:r},rect:{fill:r},rule:{stroke:i},shape:{stroke:r},symbol:{fill:r,size:64},text:{fill:i,font:e,fontSize:11},trail:{fill:r,size:2},style:{"guide-label":{fill:i,font:e,fontSize:10},"guide-title":{fill:i,font:e,fontSize:11,fontWeight:"bold"},"group-title":{fill:i,font:e,fontSize:13,fontWeight:"bold"},"group-subtitle":{fill:i,font:e,fontSize:12},point:{size:30,strokeWidth:2,shape:"circle"},circle:{size:30,strokeWidth:2},square:{size:30,strokeWidth:2,shape:"square"},cell:{fill:"transparent",stroke:o},view:{fill:"transparent"}},title:{orient:"top",anchor:"middle",offset:4,subtitlePadding:3},axis:{minExtent:0,maxExtent:200,bandPosition:.5,domain:!0,domainWidth:1,domainColor:s,grid:!1,gridWidth:1,gridColor:o,labels:!0,labelAngle:0,labelLimit:180,labelOffset:0,labelPadding:2,ticks:!0,tickColor:s,tickOffset:0,tickRound:!0,tickSize:5,tickWidth:1,titlePadding:4},axisBand:{tickOffset:-.5},projection:{type:"mercator"},legend:{orient:"right",padding:0,gridAlign:"each",columnPadding:10,rowPadding:2,symbolDirection:"vertical",gradientDirection:"vertical",gradientLength:200,gradientThickness:16,gradientStrokeColor:o,gradientStrokeWidth:0,gradientLabelOffset:2,labelAlign:"left",labelBaseline:"middle",labelLimit:160,labelOffset:4,labelOverlap:!0,symbolLimit:30,symbolType:"circle",symbolSize:100,symbolOffset:0,symbolStrokeWidth:1.5,symbolBaseFillColor:"transparent",symbolBaseStrokeColor:s,titleLimit:180,titleOrient:"top",titlePadding:5,layout:{offset:18,direction:"horizontal",left:{direction:"vertical"},right:{direction:"vertical"}}},range:{category:{scheme:"tableau10"},ordinal:{scheme:"blues"},heatmap:{scheme:"yellowgreenblue"},ramp:{scheme:"blues"},diverging:{scheme:"blueorange",extent:[1,0]},symbol:["circle","square","triangle-up","cross","diamond","triangle-right","triangle-down","triangle-left"]}}}function Gge(e,t,n){return Le(e)||le("Input Vega specification must be an object."),t=mh(Hge(),t,e.config),jge(e,new jB(t,n)).toRuntime()}var Yge="5.33.1";Mt(Od,LZ,dre,Wre,Fse,Eoe,Kae,Fae,Jae,wle,Tle,Ble);const Vge=Object.freeze(Object.defineProperty({__proto__:null,Bounds:Vn,CanvasHandler:E0,CanvasRenderer:pv,DATE:Ui,DAY:Yr,DAYOFYEAR:ca,Dataflow:sd,Debug:LR,DisallowedObjectProperties:uk,Error:ck,EventStream:jy,Gradient:$9,GroupItem:cb,HOURS:hs,Handler:w3,HybridHandler:bL,HybridRenderer:tE,Info:OR,Item:ub,MILLISECONDS:vo,MINUTES:ps,MONTH:Zr,Marks:gs,MultiPulse:Lk,None:NR,Operator:cn,Parameters:zy,Pulse:Ql,QUARTER:ji,RenderType:Ul,Renderer:w0,ResourceLoader:O9,SECONDS:Is,SVGHandler:oL,SVGRenderer:$3,SVGStringRenderer:yL,Scenegraph:J9,TIME_UNITS:Sk,Transform:ie,View:sB,WEEK:er,Warn:fk,YEAR:Nr,accessor:Yi,accessorFields:Kr,accessorName:Ln,array:Be,ascending:yh,bandwidthNRD:zk,bin:gO,bootstrapCI:mO,boundClip:FL,boundContext:y0,boundItem:Kw,boundMark:V9,boundStroke:gl,changeset:Eu,clampRange:YR,codegenExpression:TP,compare:mk,constant:ri,cumulativeLogNormal:Gk,cumulativeNormal:qy,cumulativeUniform:Kk,dayofyear:wN,debounce:vk,defaultLocale:Mk,definition:dO,densityLogNormal:Hk,densityNormal:jk,densityUniform:Xk,domChild:Qn,domClear:As,domCreate:zl,domFind:_3,dotbin:vO,error:le,expressionFunction:Hn,extend:Mt,extent:aa,extentIndex:VR,falsy:Cl,fastmap:bh,field:Ls,flush:XR,font:gb,fontFamily:_0,fontSize:xa,format:i1,formatLocale:G1,formats:Nk,hasOwnProperty:Ue,id:r0,identity:ni,inferType:tO,inferTypes:nO,ingest:Zt,inherits:Me,inrange:Zf,interpolate:JS,interpolateColors:ab,interpolateRange:p9,intersect:kL,intersectBoxLine:Jf,intersectPath:o3,intersectPoint:a3,intersectRule:I9,isArray:de,isBoolean:wu,isDate:Zl,isFunction:Tt,isIterable:KR,isNumber:Vt,isObject:Le,isRegExp:yk,isString:Ie,isTuple:Py,key:bk,lerp:ZR,lineHeight:cu,loader:Ly,locale:QN,logger:dk,lruCache:JR,markup:C3,merge:QR,mergeConfig:mh,multiLineOffset:y3,one:gh,pad:eN,panLinear:jR,panLog:UR,panPow:qR,panSymlog:WR,parse:Gge,parseExpression:FP,parseSelector:Fu,path:Vy,pathCurves:r3,pathEqual:DL,pathParse:jd,pathRectangle:M9,pathRender:xg,pathSymbols:D9,pathTrail:T9,peek:Wt,point:vb,projection:Y3,quantileLogNormal:Yk,quantileNormal:Wy,quantileUniform:Zk,quantiles:Pk,quantizeInterpolator:g9,quarter:HR,quartiles:Bk,get random(){return Ps},randomInteger:zK,randomKDE:qk,randomLCG:BK,randomLogNormal:bO,randomMixture:xO,randomNormal:Uk,randomUniform:_O,read:sO,regressionConstant:Jk,regressionExp:EO,regressionLinear:Qk,regressionLoess:SO,regressionLog:wO,regressionPoly:kO,regressionPow:AO,regressionQuad:eS,renderModule:yb,repeat:yp,resetDefaultLocale:LX,resetSVGClipId:N9,resetSVGDefIds:Dne,responseType:iO,runtimeContext:GP,sampleCurve:Gy,sampleLogNormal:Wk,sampleNormal:Uy,sampleUniform:Vk,scale:Kt,sceneEqual:F3,sceneFromJSON:K9,scenePickVisit:ov,sceneToJSON:X9,sceneVisit:yo,sceneZOrder:l3,scheme:QS,serializeXML:pL,setHybridRendererOptions:Sne,setRandom:IK,span:i0,splitAccessPath:va,stringValue:$e,textMetrics:us,timeBin:BN,timeFloor:FN,timeFormatLocale:pg,timeInterval:Eh,timeOffset:TN,timeSequence:ON,timeUnitSpecifier:_N,timeUnits:Ck,toBoolean:xk,toDate:_k,toNumber:Vr,toSet:mo,toString:wk,transform:hO,transforms:Od,truncate:tN,truthy:ds,tupleid:ot,typeParsers:Tw,utcFloor:DN,utcInterval:Ah,utcOffset:RN,utcSequence:LN,utcdayofyear:kN,utcquarter:GR,utcweek:SN,version:Yge,visitArray:Dl,week:EN,writeConfig:vh,zero:Ol,zoomLinear:hk,zoomLog:pk,zoomPow:B1,zoomSymlog:gk},Symbol.toStringTag,{value:"Module"}));function Xge(e,t,n){let r;t.x2&&(t.x?(n&&e.x>e.x2&&(r=e.x,e.x=e.x2,e.x2=r),e.width=e.x2-e.x):e.x=e.x2-(e.width||0)),t.xc&&(e.x=e.xc-(e.width||0)/2),t.y2&&(t.y?(n&&e.y>e.y2&&(r=e.y,e.y=e.y2,e.y2=r),e.height=e.y2-e.y):e.y=e.y2-(e.height||0)),t.yc&&(e.y=e.yc-(e.height||0)/2)}var Kge={NaN:NaN,E:Math.E,LN2:Math.LN2,LN10:Math.LN10,LOG2E:Math.LOG2E,LOG10E:Math.LOG10E,PI:Math.PI,SQRT1_2:Math.SQRT1_2,SQRT2:Math.SQRT2,MIN_VALUE:Number.MIN_VALUE,MAX_VALUE:Number.MAX_VALUE},Zge={"*":(e,t)=>e*t,"+":(e,t)=>e+t,"-":(e,t)=>e-t,"/":(e,t)=>e/t,"%":(e,t)=>e%t,">":(e,t)=>e>t,"<":(e,t)=>ee<=t,">=":(e,t)=>e>=t,"==":(e,t)=>e==t,"!=":(e,t)=>e!=t,"===":(e,t)=>e===t,"!==":(e,t)=>e!==t,"&":(e,t)=>e&t,"|":(e,t)=>e|t,"^":(e,t)=>e^t,"<<":(e,t)=>e<>":(e,t)=>e>>t,">>>":(e,t)=>e>>>t},Jge={"+":e=>+e,"-":e=>-e,"~":e=>~e,"!":e=>!e};const Qge=Array.prototype.slice,Yu=(e,t,n)=>{const r=n?n(t[0]):t[0];return r[e].apply(r,Qge.call(t,1))},e0e=(e,t,n,r,i,s,o)=>new Date(e,t||0,n??1,r||0,i||0,s||0,o||0);var t0e={isNaN:Number.isNaN,isFinite:Number.isFinite,abs:Math.abs,acos:Math.acos,asin:Math.asin,atan:Math.atan,atan2:Math.atan2,ceil:Math.ceil,cos:Math.cos,exp:Math.exp,floor:Math.floor,log:Math.log,max:Math.max,min:Math.min,pow:Math.pow,random:Math.random,round:Math.round,sin:Math.sin,sqrt:Math.sqrt,tan:Math.tan,clamp:(e,t,n)=>Math.max(t,Math.min(n,e)),now:Date.now,utc:Date.UTC,datetime:e0e,date:e=>new Date(e).getDate(),day:e=>new Date(e).getDay(),year:e=>new Date(e).getFullYear(),month:e=>new Date(e).getMonth(),hours:e=>new Date(e).getHours(),minutes:e=>new Date(e).getMinutes(),seconds:e=>new Date(e).getSeconds(),milliseconds:e=>new Date(e).getMilliseconds(),time:e=>new Date(e).getTime(),timezoneoffset:e=>new Date(e).getTimezoneOffset(),utcdate:e=>new Date(e).getUTCDate(),utcday:e=>new Date(e).getUTCDay(),utcyear:e=>new Date(e).getUTCFullYear(),utcmonth:e=>new Date(e).getUTCMonth(),utchours:e=>new Date(e).getUTCHours(),utcminutes:e=>new Date(e).getUTCMinutes(),utcseconds:e=>new Date(e).getUTCSeconds(),utcmilliseconds:e=>new Date(e).getUTCMilliseconds(),length:e=>e.length,join:function(){return Yu("join",arguments)},indexof:function(){return Yu("indexOf",arguments)},lastindexof:function(){return Yu("lastIndexOf",arguments)},slice:function(){return Yu("slice",arguments)},reverse:e=>e.slice().reverse(),sort:e=>e.slice().sort(yh),parseFloat,parseInt,upper:e=>String(e).toUpperCase(),lower:e=>String(e).toLowerCase(),substring:function(){return Yu("substring",arguments,String)},split:function(){return Yu("split",arguments,String)},replace:function(){return Yu("replace",arguments,String)},trim:e=>String(e).trim(),btoa:e=>btoa(e),atob:e=>atob(e),regexp:RegExp,test:(e,t)=>RegExp(e).test(t)};const n0e=["view","item","group","xy","x","y"],eA=new Set([Function,eval,setTimeout,setInterval]);typeof setImmediate=="function"&&eA.add(setImmediate);const r0e={Literal:(e,t)=>t.value,Identifier:(e,t)=>{const n=t.name;return e.memberDepth>0?n:n==="datum"?e.datum:n==="event"?e.event:n==="item"?e.item:Kge[n]||e.params["$"+n]},MemberExpression:(e,t)=>{const n=!t.computed,r=e(t.object);n&&(e.memberDepth+=1);const i=e(t.property);if(n&&(e.memberDepth-=1),eA.has(r[i])){console.error(`Prevented interpretation of member "${i}" which could lead to insecure code execution`);return}return r[i]},CallExpression:(e,t)=>{const n=t.arguments;let r=t.callee.name;return r.startsWith("_")&&(r=r.slice(1)),r==="if"?e(n[0])?e(n[1]):e(n[2]):(e.fn[r]||t0e[r]).apply(e.fn,n.map(e))},ArrayExpression:(e,t)=>t.elements.map(e),BinaryExpression:(e,t)=>Zge[t.operator](e(t.left),e(t.right)),UnaryExpression:(e,t)=>Jge[t.operator](e(t.argument)),ConditionalExpression:(e,t)=>e(t.test)?e(t.consequent):e(t.alternate),LogicalExpression:(e,t)=>t.operator==="&&"?e(t.left)&&e(t.right):e(t.left)||e(t.right),ObjectExpression:(e,t)=>t.properties.reduce((n,r)=>{e.memberDepth+=1;const i=e(r.key);e.memberDepth-=1;const s=e(r.value);return uk.has(i)?console.error(`Prevented interpretation of property "${i}" which could lead to insecure code execution`):eA.has(s)?console.error(`Prevented interpretation of method "${s}" which could lead to insecure code execution`):n[i]=s,n},{})};function fp(e,t,n,r,i,s){const o=a=>r0e[a.type](o,a);return o.memberDepth=0,o.fn=Object.create(t),o.params=n,o.datum=r,o.event=i,o.item=s,n0e.forEach(a=>o.fn[a]=function(){return i.vega[a](...arguments)}),o(e)}var i0e={operator(e,t){const n=t.ast,r=e.functions;return i=>fp(n,r,i)},parameter(e,t){const n=t.ast,r=e.functions;return(i,s)=>fp(n,r,s,i)},event(e,t){const n=t.ast,r=e.functions;return i=>fp(n,r,void 0,void 0,i)},handler(e,t){const n=t.ast,r=e.functions;return(i,s)=>{const o=s.item&&s.item.datum;return fp(n,r,i,o,s)}},encode(e,t){const{marktype:n,channels:r}=t,i=e.functions,s=n==="group"||n==="image"||n==="rect";return(o,a)=>{const l=o.datum;let u=0,c;for(const f in r)c=fp(r[f].ast,i,a,l,void 0,o),o[f]!==c&&(o[f]=c,u=1);return n!=="rule"&&Xge(o,r,s),u}}};const s0e="5.23.0",o0e={version:s0e};function QC(e){return Ae(e,"or")}function e$(e){return Ae(e,"and")}function t$(e){return Ae(e,"not")}function $1(e,t){if(t$(e))$1(e.not,t);else if(e$(e))for(const n of e.and)$1(n,t);else if(QC(e))for(const n of e.or)$1(n,t);else t(e)}function cd(e,t){return t$(e)?{not:cd(e.not,t)}:e$(e)?{and:e.and.map(n=>cd(n,t))}:QC(e)?{or:e.or.map(n=>cd(n,t))}:t(e)}const _t=structuredClone;function UB(e){throw new Error(e)}function Kd(e,t){const n={};for(const r of t)Ue(e,r)&&(n[r]=e[r]);return n}function Bi(e,t){const n={...e};for(const r of t)delete n[r];return n}Set.prototype.toJSON=function(){return`Set(${[...this].map(e=>ln(e)).join(",")})`};function Ut(e){if(Vt(e))return e;const t=Ie(e)?e:ln(e);if(t.length<250)return t;let n=0;for(let r=0;ra===0?o:`[${o}]`),s=i.map((o,a)=>i.slice(0,a+1).join(""));for(const o of s)t.add(o)}return t}function i$(e,t){return e===void 0||t===void 0?!0:r$(nA(e),nA(t))}function an(e){return Ee(e).length===0}const Ee=Object.keys,Or=Object.values,pu=Object.entries;function Og(e){return e===!0||e===!1}function _n(e){const t=e.replace(/\W/g,"_");return(e.match(/^\d+/)?"_":"")+t}function sg(e,t){return t$(e)?`!(${sg(e.not,t)})`:e$(e)?`(${e.and.map(n=>sg(n,t)).join(") && (")})`:QC(e)?`(${e.or.map(n=>sg(n,t)).join(") || (")})`:t(e)}function ty(e,t){if(t.length===0)return!0;const n=t.shift();return n in e&&ty(e[n],t)&&delete e[n],an(e)}function N0(e){return e.charAt(0).toUpperCase()+e.substr(1)}function s$(e,t="datum"){const n=va(e),r=[];for(let i=1;i<=n.length;i++){const s=`[${n.slice(0,i).map($e).join("][")}]`;r.push(`${t}${s}`)}return r.join(" && ")}function HB(e,t="datum"){return`${t}[${$e(va(e).join("."))}]`}function en(e){return`datum['${e.replaceAll("'","\\'")}']`}function u0e(e){return e.replace(/(\[|\]|\.|'|")/g,"\\$1")}function zs(e){return`${va(e).map(u0e).join("\\.")}`}function Jc(e,t,n){return e.replace(new RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"g"),n)}function Rh(e){return`${va(e).join(".")}`}function Jd(e){return e?va(e).length:0}function qn(...e){return e.find(t=>t!==void 0)}let GB=42;function YB(e){const t=++GB;return e?String(e)+t:t}function c0e(){GB=42}function VB(e){return XB(e)?e:`__${e}`}function XB(e){return e.startsWith("__")}function Lg(e){if(e!==void 0)return(e%360+360)%360}function Ub(e){return Vt(e)?!0:!isNaN(e)&&!isNaN(parseFloat(e))}const i6=Object.getPrototypeOf(structuredClone({}));function os(e,t){if(e===t)return!0;if(e&&t&&typeof e=="object"&&typeof t=="object"){if(e.constructor.name!==t.constructor.name)return!1;let n,r;if(Array.isArray(e)){if(n=e.length,n!=t.length)return!1;for(r=n;r--!==0;)if(!os(e[r],t[r]))return!1;return!0}if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(const s of e.entries())if(!t.has(s[0]))return!1;for(const s of e.entries())if(!os(s[1],t.get(s[0])))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(const s of e.entries())if(!t.has(s[0]))return!1;return!0}if(ArrayBuffer.isView(e)&&ArrayBuffer.isView(t)){if(n=e.length,n!=t.length)return!1;for(r=n;r--!==0;)if(e[r]!==t[r])return!1;return!0}if(e.constructor===RegExp)return e.source===t.source&&e.flags===t.flags;if(e.valueOf!==Object.prototype.valueOf&&e.valueOf!==i6.valueOf)return e.valueOf()===t.valueOf();if(e.toString!==Object.prototype.toString&&e.toString!==i6.toString)return e.toString()===t.toString();const i=Object.keys(e);if(n=i.length,n!==Object.keys(t).length)return!1;for(r=n;r--!==0;)if(!Object.prototype.hasOwnProperty.call(t,i[r]))return!1;for(r=n;r--!==0;){const s=i[r];if(!os(e[s],t[s]))return!1}return!0}return e!==e&&t!==t}function ln(e){const t=[];return(function n(r){if(r&&r.toJSON&&typeof r.toJSON=="function"&&(r=r.toJSON()),r===void 0)return;if(typeof r=="number")return isFinite(r)?""+r:"null";if(typeof r!="object")return JSON.stringify(r);let i,s;if(Array.isArray(r)){for(s="[",i=0;iKb(e[t])?_n(`_${t}_${pu(e[t])}`):_n(`_${t}_${e[t]}`)).join("")}function dn(e){return e===!0||wf(e)&&!e.binned}function Sr(e){return e==="binned"||wf(e)&&e.binned===!0}function wf(e){return Le(e)}function Kb(e){return Ae(e,"param")}function s6(e){switch(e){case nl:case rl:case bl:case Wi:case ka:case Sa:case Nu:case xl:case Tu:case Ru:case Hi:return 6;case Ou:return 4;default:return 10}}function P0(e){return Ae(e,"expr")}function $r(e,{level:t}={level:0}){const n=Ee(e||{}),r={};for(const i of n)r[i]=t===0?rs(e[i]):$r(e[i],{level:t-1});return r}function uz(e){const{anchor:t,frame:n,offset:r,orient:i,angle:s,limit:o,color:a,subtitleColor:l,subtitleFont:u,subtitleFontSize:c,subtitleFontStyle:f,subtitleFontWeight:d,subtitleLineHeight:h,subtitlePadding:p,...g}=e,m={...g,...a?{fill:a}:{}},y={...t?{anchor:t}:{},...n?{frame:n}:{},...r?{offset:r}:{},...i?{orient:i}:{},...s!==void 0?{angle:s}:{},...o!==void 0?{limit:o}:{}},b={...l?{subtitleColor:l}:{},...u?{subtitleFont:u}:{},...c?{subtitleFontSize:c}:{},...f?{subtitleFontStyle:f}:{},...d?{subtitleFontWeight:d}:{},...h?{subtitleLineHeight:h}:{},...p?{subtitlePadding:p}:{}},x=Kd(e,["align","baseline","dx","dy","limit"]);return{titleMarkConfig:m,subtitleMarkConfig:x,nonMarkTitleProperties:y,subtitle:b}}function Nl(e){return Ie(e)||de(e)&&Ie(e[0])}function nt(e){return Ae(e,"signal")}function Ef(e){return Ae(e,"step")}function O0e(e){return de(e)?!1:Ae(e,"fields")&&!Ae(e,"data")}function L0e(e){return de(e)?!1:Ae(e,"fields")&&Ae(e,"data")}function Ka(e){return de(e)?!1:Ae(e,"field")&&Ae(e,"data")}const I0e={aria:1,description:1,ariaRole:1,ariaRoleDescription:1,blend:1,opacity:1,fill:1,fillOpacity:1,stroke:1,strokeCap:1,strokeWidth:1,strokeOpacity:1,strokeDash:1,strokeDashOffset:1,strokeJoin:1,strokeOffset:1,strokeMiterLimit:1,startAngle:1,endAngle:1,padAngle:1,innerRadius:1,outerRadius:1,size:1,shape:1,interpolate:1,tension:1,orient:1,align:1,baseline:1,text:1,dir:1,dx:1,dy:1,ellipsis:1,limit:1,radius:1,theta:1,angle:1,font:1,fontSize:1,fontWeight:1,fontStyle:1,lineBreak:1,lineHeight:1,cursor:1,href:1,tooltip:1,cornerRadius:1,cornerRadiusTopLeft:1,cornerRadiusTopRight:1,cornerRadiusBottomLeft:1,cornerRadiusBottomRight:1,aspect:1,width:1,height:1,url:1,smooth:1},P0e=Ee(I0e),B0e={arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1},rA=["cornerRadius","cornerRadiusTopLeft","cornerRadiusTopRight","cornerRadiusBottomLeft","cornerRadiusBottomRight"];function cz(e){const t=de(e.condition)?e.condition.map(o6):o6(e.condition);return{...rs(e),condition:t}}function rs(e){if(P0(e)){const{expr:t,...n}=e;return{signal:t,...n}}return e}function o6(e){if(P0(e)){const{expr:t,...n}=e;return{signal:t,...n}}return e}function vn(e){if(P0(e)){const{expr:t,...n}=e;return{signal:t,...n}}return nt(e)?e:e!==void 0?{value:e}:void 0}function z0e(e){return nt(e)?e.signal:$e(e)}function a6(e){return nt(e)?e.signal:$e(e.value)}function uo(e){return nt(e)?e.signal:e==null?null:$e(e)}function j0e(e,t,n){for(const r of n){const i=ha(r,t.markDef,t.config);i!==void 0&&(e[r]=vn(i))}return e}function fz(e){return[].concat(e.type,e.style??[])}function on(e,t,n,r={}){const{vgChannel:i,ignoreVgConfig:s}=r;return i&&Ae(t,i)?t[i]:t[e]!==void 0?t[e]:s&&(!i||i===e)?void 0:ha(e,t,n,r)}function ha(e,t,n,{vgChannel:r}={}){const i=iA(e,t,n.style);return qn(r?i:void 0,i,r?n[t.type][r]:void 0,n[t.type][e],r?n.mark[r]:n.mark[e])}function iA(e,t,n){return dz(e,fz(t),n)}function dz(e,t,n){t=Be(t);let r;for(const i of t){const s=n[i];Ae(s,e)&&(r=s[e])}return r}function hz(e,t){return Be(e).reduce((n,r)=>(n.field.push(Re(r,t)),n.order.push(r.sort??"ascending"),n),{field:[],order:[]})}function pz(e,t){const n=[...e];return t.forEach(r=>{for(const i of n)if(os(i,r))return;n.push(r)}),n}function gz(e,t){return os(e,t)||!t?e:e?[...Be(e),...Be(t)].join(", "):t}function mz(e,t){const n=e.value,r=t.value;if(n==null||r===null)return{explicit:e.explicit,value:null};if((Nl(n)||nt(n))&&(Nl(r)||nt(r)))return{explicit:e.explicit,value:gz(n,r)};if(Nl(n)||nt(n))return{explicit:e.explicit,value:n};if(Nl(r)||nt(r))return{explicit:e.explicit,value:r};if(!Nl(n)&&!nt(n)&&!Nl(r)&&!nt(r))return{explicit:e.explicit,value:pz(n,r)};throw new Error("It should never reach here")}function g$(e){return`Invalid specification ${ln(e)}. Make sure the specification includes at least one of the following properties: "mark", "layer", "facet", "hconcat", "vconcat", "concat", or "repeat".`}const U0e='Autosize "fit" only works for single views and layered views.';function l6(e){return`${e=="width"?"Width":"Height"} "container" only works for single views and layered views.`}function u6(e){const t=e=="width"?"Width":"Height",n=e=="width"?"x":"y";return`${t} "container" only works well with autosize "fit" or "fit-${n}".`}function c6(e){return e?`Dropping "fit-${e}" because spec has discrete ${Gi(e)}.`:'Dropping "fit" because spec has discrete size.'}function m$(e){return`Unknown field for ${e}. Cannot calculate view size.`}function f6(e){return`Cannot project a selection on encoding channel "${e}", which has no field.`}function q0e(e,t){return`Cannot project a selection on encoding channel "${e}" as it uses an aggregate function ("${t}").`}function W0e(e){return`The "nearest" transform is not supported for ${e} marks.`}function vz(e){return`Selection not supported for ${e} yet.`}function H0e(e){return`Cannot find a selection named "${e}".`}const G0e="Scale bindings are currently only supported for scales with unbinned, continuous domains.",Y0e="Sequntial scales are deprecated. The available quantitative scale type values are linear, log, pow, sqrt, symlog, time and utc",V0e="Legend bindings are only supported for selections over an individual field or encoding channel.";function X0e(e){return`Lookups can only be performed on selection parameters. "${e}" is a variable parameter.`}function K0e(e){return`Cannot define and lookup the "${e}" selection in the same view. Try moving the lookup into a second, layered view?`}const Z0e="The same selection must be used to override scale domains in a layered view.",J0e='Interval selections should be initialized using "x", "y", "longitude", or "latitude" keys.';function Q0e(e){return`Unknown repeated value "${e}".`}function d6(e){return`The "columns" property cannot be used when "${e}" has nested row/column.`}const eme="Multiple timer selections in one unit spec are not supported. Ignoring all but the first.",v$="Animation involving facet, layer, or concat is currently unsupported.";function tme(e){return`A "field" or "encoding" must be specified when using a selection as a scale domain. Using "field": ${$e(e)}.`}function nme(e,t,n,r){return(e.length?"Multiple ":"No ")+`matching ${$e(t)} encoding found for selection ${$e(n.param)}. Using "field": ${$e(r)}.`}const rme="Axes cannot be shared in concatenated or repeated views yet (https://github.com/vega/vega-lite/issues/2415).";function ime(e){return`Unrecognized parse "${e}".`}function h6(e,t,n){return`An ancestor parsed field "${e}" as ${n} but a child wants to parse the field as ${t}.`}const sme="Attempt to add the same child twice.";function ome(e){return`Ignoring an invalid transform: ${ln(e)}.`}const ame='If "from.fields" is not specified, "as" has to be a string that specifies the key to be used for the data from the secondary source.';function p6(e){return`Config.customFormatTypes is not true, thus custom format type and format for channel ${e} are dropped.`}function lme(e){const{parentProjection:t,projection:n}=e;return`Layer's shared projection ${ln(t)} is overridden by a child projection ${ln(n)}.`}const ume="Arc marks uses theta channel rather than angle, replacing angle with theta.";function cme(e){return`${e}Offset dropped because ${e} is continuous`}function fme(e,t,n){return`Channel ${e} is a ${t}. Converted to {value: ${ln(n)}}.`}function yz(e){return`Invalid field type "${e}".`}function dme(e,t){return`Invalid field type "${e}" for aggregate: "${t}", using "quantitative" instead.`}function hme(e){return`Invalid aggregation operator "${e}".`}function bz(e,t){const{fill:n,stroke:r}=t;return`Dropping color ${e} as the plot also has ${n&&r?"fill and stroke":n?"fill":"stroke"}.`}function pme(e){return`Position range does not support relative band size for ${e}.`}function sA(e,t){return`Dropping ${ln(e)} from channel "${t}" since it does not contain any data field, datum, value, or signal.`}const gme="Line marks cannot encode size with a non-groupby field. You may want to use trail marks instead.";function Zb(e,t,n){return`${e} dropped as it is incompatible with "${t}".`}function mme(e){return`${e}-encoding is dropped as ${e} is not a valid encoding channel.`}function vme(e){return`${e} encoding should be discrete (ordinal / nominal / binned).`}function yme(e){return`${e} encoding should be discrete (ordinal / nominal / binned) or use a discretizing scale (e.g. threshold).`}function bme(e){return`Facet encoding dropped as ${e.join(" and ")} ${e.length>1?"are":"is"} also specified.`}function c_(e,t){return`Using discrete channel "${e}" to encode "${t}" field can be misleading as it does not encode ${t==="ordinal"?"order":"magnitude"}.`}function xme(e){return`The ${e} for range marks cannot be an expression`}function _me(e,t){return`Line mark is for continuous lines and thus cannot be used with ${e&&t?"x2 and y2":e?"x2":"y2"}. We will use the rule mark (line segments) instead.`}function wme(e,t){return`Specified orient "${e}" overridden with "${t}".`}function Eme(e){return`Cannot use the scale property "${e}" with non-color channel.`}function Ame(e){return`Cannot use the relative band size with ${e} scale.`}function kme(e){return`Using unaggregated domain with raw field has no effect (${ln(e)}).`}function Sme(e){return`Unaggregated domain not applicable for "${e}" since it produces values outside the origin domain of the source data.`}function Cme(e){return`Unaggregated domain is currently unsupported for log scale (${ln(e)}).`}function $me(e){return`Cannot apply size to non-oriented mark "${e}".`}function Fme(e,t,n){return`Channel "${e}" does not work with "${t}" scale. We are using "${n}" scale instead.`}function Dme(e,t){return`FieldDef does not work with "${e}" scale. We are using "${t}" scale instead.`}function xz(e,t,n){return`${n}-scale's "${t}" is dropped as it does not work with ${e} scale.`}function _z(e){return`The step for "${e}" is dropped because the ${e==="width"?"x":"y"} is continuous.`}function Mme(e,t,n,r){return`Conflicting ${t.toString()} property "${e.toString()}" (${ln(n)} and ${ln(r)}). Using ${ln(n)}.`}function Tme(e,t,n,r){return`Conflicting ${t.toString()} property "${e.toString()}" (${ln(n)} and ${ln(r)}). Using the union of the two domains.`}function Rme(e){return`Setting the scale to be independent for "${e}" means we also have to set the guide (axis or legend) to be independent.`}function Nme(e){return`Dropping sort property ${ln(e)} as unioned domains only support boolean or op "count", "min", and "max".`}const g6="Domains that should be unioned has conflicting sort properties. Sort will be set to true.",Ome="Detected faceted independent scales that union domain of multiple fields from different data sources. We will use the first field. The result view size may be incorrect.",Lme="Detected faceted independent scales that union domain of the same fields from different source. We will assume that this is the same field from a different fork of the same data source. However, if this is not the case, the result view size may be incorrect.",Ime="Detected faceted independent scales that union domain of multiple fields from the same data source. We will use the first field. The result view size may be incorrect.";function Pme(e){return`Cannot stack "${e}" if there is already "${e}2".`}function Bme(e){return`Stack is applied to a non-linear scale (${e}).`}function zme(e){return`Stacking is applied even though the aggregate function is non-summative ("${e}").`}function ny(e,t){return`Invalid ${e}: ${ln(t)}.`}function jme(e){return`Dropping day from datetime ${ln(e)} as day cannot be combined with other units.`}function Ume(e,t){return`${t?"extent ":""}${t&&e?"and ":""}${e?"center ":""}${t&&e?"are ":"is "}not needed when data are aggregated.`}function qme(e,t,n){return`${e} is not usually used with ${t} for ${n}.`}function Wme(e,t){return`Continuous axis should not have customized aggregation function ${e}; ${t} already agregates the axis.`}function m6(e){return`1D error band does not support ${e}.`}function wz(e){return`Channel ${e} is required for "binned" bin.`}function Hme(e){return`Channel ${e} should not be used with "binned" bin.`}function Gme(e){return`Domain for ${e} is required for threshold scale.`}const Ez=dk(fk);let ef=Ez;function Yme(e){return ef=e,ef}function Vme(){return ef=Ez,ef}function y$(...e){ef.error(...e)}function Se(...e){ef.warn(...e)}function Xme(...e){ef.debug(...e)}function Af(e){if(e&&Le(e)){for(const t of x$)if(Ae(e,t))return!0}return!1}const Az=["january","february","march","april","may","june","july","august","september","october","november","december"],Kme=Az.map(e=>e.substr(0,3)),kz=["sunday","monday","tuesday","wednesday","thursday","friday","saturday"],Zme=kz.map(e=>e.substr(0,3));function Jme(e){if(Ub(e)&&(e=+e),Vt(e))return e>4&&Se(ny("quarter",e)),e-1;throw new Error(ny("quarter",e))}function Qme(e){if(Ub(e)&&(e=+e),Vt(e))return e-1;{const t=e.toLowerCase(),n=Az.indexOf(t);if(n!==-1)return n;const r=t.substr(0,3),i=Kme.indexOf(r);if(i!==-1)return i;throw new Error(ny("month",e))}}function e1e(e){if(Ub(e)&&(e=+e),Vt(e))return e%7;{const t=e.toLowerCase(),n=kz.indexOf(t);if(n!==-1)return n;const r=t.substr(0,3),i=Zme.indexOf(r);if(i!==-1)return i;throw new Error(ny("day",e))}}function b$(e,t){const n=[];if(t&&e.day!==void 0&&Ee(e).length>1&&(Se(jme(e)),e=_t(e),delete e.day),e.year!==void 0?n.push(e.year):n.push(2012),e.month!==void 0){const r=t?Qme(e.month):e.month;n.push(r)}else if(e.quarter!==void 0){const r=t?Jme(e.quarter):e.quarter;n.push(Vt(r)?r*3:`${r}*3`)}else n.push(0);if(e.date!==void 0)n.push(e.date);else if(e.day!==void 0){const r=t?e1e(e.day):e.day;n.push(Vt(r)?r+1:`${r}+1`)}else n.push(1);for(const r of["hours","minutes","seconds","milliseconds"]){const i=e[r];n.push(typeof i>"u"?0:i)}return n}function tf(e){const n=b$(e,!0).join(", ");return e.utc?`utc(${n})`:`datetime(${n})`}function t1e(e){const n=b$(e,!1).join(", ");return e.utc?`utc(${n})`:`datetime(${n})`}function n1e(e){const t=b$(e,!0);return e.utc?+new Date(Date.UTC(...t)):+new Date(...t)}const Sz={year:1,quarter:1,month:1,week:1,day:1,dayofyear:1,date:1,hours:1,minutes:1,seconds:1,milliseconds:1},x$=Ee(Sz);function r1e(e){return Ue(Sz,e)}function kf(e){return Le(e)?e.binned:Cz(e)}function Cz(e){return e&&e.startsWith("binned")}function _$(e){return e.startsWith("utc")}function i1e(e){return e.substring(3)}const s1e={"year-month":"%b %Y ","year-month-date":"%b %d, %Y "};function Jb(e){return x$.filter(t=>Fz(e,t))}function $z(e){const t=Jb(e);return t[t.length-1]}function Fz(e,t){const n=e.indexOf(t);return!(n<0||n>0&&t==="seconds"&&e.charAt(n-1)==="i"||e.length>n+3&&t==="day"&&e.charAt(n+3)==="o"||n>0&&t==="year"&&e.charAt(n-1)==="f")}function o1e(e,t,{end:n}={end:!1}){const r=s$(t),i=_$(e)?"utc":"";function s(l){return l==="quarter"?`(${i}quarter(${r})-1)`:`${i}${l}(${r})`}let o;const a={};for(const l of x$)Fz(e,l)&&(a[l]=s(l),o=l);return n&&(a[o]+="+1"),t1e(a)}function Dz(e){if(!e)return;const t=Jb(e);return`timeUnitSpecifier(${ln(t)}, ${ln(s1e)})`}function a1e(e,t,n){if(!e)return;const r=Dz(e);return`${n||_$(e)?"utc":"time"}Format(${t}, ${r})`}function mr(e){if(!e)return;let t;return Ie(e)?Cz(e)?t={unit:e.substring(6),binned:!0}:t={unit:e}:Le(e)&&(t={...e,...e.unit?{unit:e.unit}:{}}),_$(t.unit)&&(t.utc=!0,t.unit=i1e(t.unit)),t}function l1e(e){const{utc:t,...n}=mr(e);return n.unit?(t?"utc":"")+Ee(n).map(r=>_n(`${r==="unit"?"":`_${r}_`}${n[r]}`)).join(""):(t?"utc":"")+"timeunit"+Ee(n).map(r=>_n(`_${r}_${n[r]}`)).join("")}function Mz(e,t=n=>n){const n=mr(e),r=$z(n.unit);if(r&&r!=="day"){const i={year:2001,month:1,date:1,hours:0,minutes:0,seconds:0,milliseconds:0},{step:s,part:o}=Tz(r,n.step),a={...i,[o]:+i[o]+s};return`${t(tf(a))} - ${t(tf(i))}`}}const u1e={year:1,month:1,date:1,hours:1,minutes:1,seconds:1,milliseconds:1};function c1e(e){return Ue(u1e,e)}function Tz(e,t=1){if(c1e(e))return{part:e,step:t};switch(e){case"day":case"dayofyear":return{part:"date",step:t};case"quarter":return{part:"month",step:t*3};case"week":return{part:"date",step:t*7}}}function f1e(e){return Ae(e,"param")}function w$(e){return!!(e!=null&&e.field)&&e.equal!==void 0}function E$(e){return!!(e!=null&&e.field)&&e.lt!==void 0}function A$(e){return!!(e!=null&&e.field)&&e.lte!==void 0}function k$(e){return!!(e!=null&&e.field)&&e.gt!==void 0}function S$(e){return!!(e!=null&&e.field)&&e.gte!==void 0}function C$(e){if(e!=null&&e.field){if(de(e.range)&&e.range.length===2)return!0;if(nt(e.range))return!0}return!1}function $$(e){return!!(e!=null&&e.field)&&(de(e.oneOf)||de(e.in))}function d1e(e){return!!(e!=null&&e.field)&&e.valid!==void 0}function Rz(e){return $$(e)||w$(e)||C$(e)||E$(e)||k$(e)||A$(e)||S$(e)}function Io(e,t){return l2(e,{timeUnit:t,wrapTime:!0})}function h1e(e,t){return e.map(n=>Io(n,t))}function Nz(e,t=!0){const{field:n}=e,r=mr(e.timeUnit),{unit:i,binned:s}=r||{},o=Re(e,{expr:"datum"}),a=i?`time(${s?o:o1e(i,n)})`:o;if(w$(e))return`${a}===${Io(e.equal,i)}`;if(E$(e)){const l=e.lt;return`${a}<${Io(l,i)}`}else if(k$(e)){const l=e.gt;return`${a}>${Io(l,i)}`}else if(A$(e)){const l=e.lte;return`${a}<=${Io(l,i)}`}else if(S$(e)){const l=e.gte;return`${a}>=${Io(l,i)}`}else{if($$(e))return`indexof([${h1e(e.oneOf,i).join(",")}], ${a}) !== -1`;if(d1e(e))return Qb(a,e.valid);if(C$(e)){const{range:l}=$r(e),u=nt(l)?{signal:`${l.signal}[0]`}:l[0],c=nt(l)?{signal:`${l.signal}[1]`}:l[1];if(u!==null&&c!==null&&t)return"inrange("+a+", ["+Io(u,i)+", "+Io(c,i)+"])";const f=[];return u!==null&&f.push(`${a} >= ${Io(u,i)}`),c!==null&&f.push(`${a} <= ${Io(c,i)}`),f.length>0?f.join(" && "):"true"}}throw new Error(`Invalid field predicate: ${ln(e)}`)}function Qb(e,t=!0){return t?`isValid(${e}) && isFinite(+${e})`:`!isValid(${e}) || !isFinite(+${e})`}function p1e(e){return Rz(e)&&e.timeUnit?{...e,timeUnit:mr(e.timeUnit)}:e}const B0={quantitative:"quantitative",ordinal:"ordinal",temporal:"temporal",nominal:"nominal",geojson:"geojson"};function g1e(e){return e==="quantitative"||e==="temporal"}function Oz(e){return e==="ordinal"||e==="nominal"}const nf=B0.quantitative,F$=B0.ordinal,eh=B0.temporal,D$=B0.nominal,Oh=B0.geojson;function m1e(e){if(e)switch(e=e.toLowerCase(),e){case"q":case nf:return"quantitative";case"t":case eh:return"temporal";case"o":case F$:return"ordinal";case"n":case D$:return"nominal";case Oh:return"geojson"}}const Fr={LINEAR:"linear",LOG:"log",POW:"pow",SQRT:"sqrt",TIME:"time",UTC:"utc",POINT:"point",BAND:"band"},oA={linear:"numeric",log:"numeric",pow:"numeric",sqrt:"numeric",symlog:"numeric",identity:"numeric",sequential:"numeric",time:"time",utc:"time",ordinal:"ordinal","bin-ordinal":"bin-ordinal",point:"ordinal-position",band:"ordinal-position",quantile:"discretizing",quantize:"discretizing",threshold:"discretizing"};function v1e(e,t){const n=oA[e],r=oA[t];return n===r||n==="ordinal-position"&&r==="time"||r==="ordinal-position"&&n==="time"}const y1e={linear:0,log:1,pow:1,sqrt:1,symlog:1,identity:1,sequential:1,time:0,utc:0,point:10,band:11,ordinal:0,"bin-ordinal":0,quantile:0,quantize:0,threshold:0};function v6(e){return y1e[e]}const Lz=new Set(["linear","log","pow","sqrt","symlog"]),Iz=new Set([...Lz,"time","utc"]);function Pz(e){return Lz.has(e)}const Bz=new Set(["quantile","quantize","threshold"]),b1e=new Set([...Iz,...Bz,"sequential","identity"]),x1e=new Set(["ordinal","bin-ordinal","point","band"]);function yr(e){return x1e.has(e)}function bo(e){return b1e.has(e)}function Qo(e){return Iz.has(e)}function th(e){return Bz.has(e)}const _1e={pointPadding:.5,barBandPaddingInner:.1,rectBandPaddingInner:0,tickBandPaddingInner:.25,bandWithNestedOffsetPaddingInner:.2,bandWithNestedOffsetPaddingOuter:.2,minBandSize:2,minFontSize:8,maxFontSize:40,minOpacity:.3,maxOpacity:.8,minSize:4,minStrokeWidth:1,maxStrokeWidth:4,quantileCount:4,quantizeCount:4,zero:!0,framesPerSecond:2,animationDuration:5};function w1e(e){return!Ie(e)&&Ae(e,"name")}function zz(e){return Ae(e,"param")}function E1e(e){return Ae(e,"unionWith")}function A1e(e){return Le(e)&&"field"in e}const k1e={type:1,domain:1,domainMax:1,domainMin:1,domainMid:1,domainRaw:1,align:1,range:1,rangeMax:1,rangeMin:1,scheme:1,bins:1,reverse:1,round:1,clamp:1,nice:1,base:1,exponent:1,constant:1,interpolate:1,zero:1,padding:1,paddingInner:1,paddingOuter:1},{type:fFe,domain:dFe,range:hFe,rangeMax:pFe,rangeMin:gFe,scheme:mFe,...S1e}=k1e,C1e=Ee(S1e);function aA(e,t){switch(t){case"type":case"domain":case"reverse":case"range":return!0;case"scheme":case"interpolate":return!["point","band","identity"].includes(e);case"bins":return!["point","band","identity","ordinal"].includes(e);case"round":return Qo(e)||e==="band"||e==="point";case"padding":case"rangeMin":case"rangeMax":return Qo(e)||["point","band"].includes(e);case"paddingOuter":case"align":return["point","band"].includes(e);case"paddingInner":return e==="band";case"domainMax":case"domainMid":case"domainMin":case"domainRaw":case"clamp":return Qo(e);case"nice":return Qo(e)||e==="quantize"||e==="threshold";case"exponent":return e==="pow";case"base":return e==="log";case"constant":return e==="symlog";case"zero":return bo(e)&&!It(["log","time","utc","threshold","quantile"],e)}}function jz(e,t){switch(t){case"interpolate":case"scheme":case"domainMid":return fd(e)?void 0:Eme(t);case"align":case"type":case"bins":case"domain":case"domainMax":case"domainMin":case"domainRaw":case"range":case"base":case"exponent":case"constant":case"nice":case"padding":case"paddingInner":case"paddingOuter":case"rangeMax":case"rangeMin":case"reverse":case"round":case"clamp":case"zero":return}}function $1e(e,t){return It([F$,D$],t)?e===void 0||yr(e):t===eh?It([Fr.TIME,Fr.UTC,void 0],e):t===nf?Pz(e)||th(e)||e===void 0:!0}function F1e(e,t,n=!1){if(!$a(e))return!1;switch(e){case wn:case xr:case Du:case Nh:case Ws:case Co:return Qo(t)||t==="band"?!0:t==="point"?!n:!1;case Mu:return It(["linear","band"],t);case bl:case Nu:case xl:case Tu:case Ru:case xf:return Qo(t)||th(t)||It(["band","point","ordinal"],t);case Wi:case ka:case Sa:return t!=="band";case Ou:case Hi:return t==="ordinal"||th(t)}}function D1e(e){return Le(e)&&"value"in e}const ki={arc:"arc",area:"area",bar:"bar",image:"image",line:"line",point:"point",rect:"rect",rule:"rule",text:"text",tick:"tick",trail:"trail",circle:"circle",square:"square",geoshape:"geoshape"},Uz=ki.arc,e2=ki.area,t2=ki.bar,M1e=ki.image,n2=ki.line,r2=ki.point,T1e=ki.rect,ry=ki.rule,qz=ki.text,M$=ki.tick,R1e=ki.trail,T$=ki.circle,R$=ki.square,Wz=ki.geoshape;function Iu(e){return["line","area","trail"].includes(e)}function Ig(e){return["rect","bar","image","arc","tick"].includes(e)}const N1e=new Set(Ee(ki));function pa(e){return Ae(e,"type")}const O1e=["stroke","strokeWidth","strokeDash","strokeDashOffset","strokeOpacity","strokeJoin","strokeMiterLimit"],L1e=["fill","fillOpacity"],I1e=[...O1e,...L1e],P1e={color:1,filled:1,invalid:1,order:1,radius2:1,theta2:1,timeUnitBandSize:1,timeUnitBandPosition:1},y6=Ee(P1e),f_=["binSpacing","continuousBandSize","discreteBandSize","minBandSize"],B1e={area:["line","point"],bar:f_,rect:f_,line:["point"],tick:["bandSize","thickness",...f_]},z1e={color:"#4c78a8",invalid:"break-paths-show-path-domains",timeUnitBandSize:1},j1e={mark:1,arc:1,area:1,bar:1,circle:1,image:1,line:1,point:1,rect:1,rule:1,square:1,text:1,tick:1,trail:1,geoshape:1},Hz=Ee(j1e);function rf(e){return Ae(e,"band")}const U1e={horizontal:["cornerRadiusTopRight","cornerRadiusBottomRight"],vertical:["cornerRadiusTopLeft","cornerRadiusTopRight"]},q1e=5,N$={binSpacing:0,continuousBandSize:q1e,minBandSize:.25,timeUnitBandPosition:.5},W1e={...N$,binSpacing:1},H1e={...N$,thickness:1};function G1e(e){return pa(e)?e.type:e}function Gz(e,{isPath:t}){return e===void 0||e==="break-paths-show-path-domains"?t?"break-paths-show-domains":"filter":e===null?"show":e}function O$({markDef:e,config:t,scaleChannel:n,scaleType:r,isCountAggregate:i}){var a,l;if(!r||!bo(r)||i)return"always-valid";const s=Gz(on("invalid",e,t),{isPath:Iu(e.type)});return((l=(a=t.scale)==null?void 0:a.invalid)==null?void 0:l[n])!==void 0?"show":s}function Y1e(e){return e==="break-paths-filter-domains"||e==="break-paths-show-domains"}function Yz({scaleName:e,scale:t,mode:n}){const r=`domain('${e}')`;if(!t||!e)return;const i=`${r}[0]`,s=`peek(${r})`,o=t.domainHasZero();return o==="definitely"?{scale:e,value:0}:o==="maybe"?{signal:`scale('${e}', inrange(0, ${r}) ? 0 : ${n==="zeroOrMin"?i:s})`}:{signal:`scale('${e}', ${n==="zeroOrMin"?i:s})`}}function Vz({scaleChannel:e,channelDef:t,scale:n,scaleName:r,markDef:i,config:s}){var c;const o=n==null?void 0:n.get("type"),a=_o(t),l=Xb(a==null?void 0:a.aggregate),u=O$({scaleChannel:e,markDef:i,config:s,scaleType:o,isCountAggregate:l});if(a&&u==="show"){const f=((c=s.scale.invalid)==null?void 0:c[e])??"zero-or-min";return{test:Qb(Re(a,{expr:"datum"}),!1),...V1e(f,n,r)}}}function V1e(e,t,n){if(D1e(e)){const{value:r}=e;return nt(r)?{signal:r.signal}:{value:r}}return Yz({scale:t,scaleName:n,mode:"zeroOrMin"})}function L$(e){const{channel:t,channelDef:n,markDef:r,scale:i,scaleName:s,config:o}=e,a=_f(t),l=I$(e),u=Vz({scaleChannel:a,channelDef:n,scale:i,scaleName:s,markDef:r,config:o});return u!==void 0?[u,l]:l}function X1e(e){const{datum:t}=e;return Af(t)?tf(t):`${ln(t)}`}function Cc(e,t,n,r){const i={};if(t&&(i.scale=t),Fa(e)){const{datum:s}=e;Af(s)?i.signal=tf(s):nt(s)?i.signal=s.signal:P0(s)?i.signal=s.expr:i.value=s}else i.field=Re(e,n);if(r){const{offset:s,band:o}=r;s&&(i.offset=s),o&&(i.band=o)}return i}function iy({scaleName:e,fieldOrDatumDef:t,fieldOrDatumDef2:n,offset:r,startSuffix:i,endSuffix:s="end",bandPosition:o=.5}){const a=!nt(o)&&0{switch(t.fieldTitle){case"plain":return e.field;case"functional":return cve(e);default:return uve(e,t)}};let aj=oj;function lj(e){aj=e}function fve(){lj(oj)}function dd(e,t,{allowDisabling:n,includeDefault:r=!0}){var a;const i=(a=j$(e))==null?void 0:a.title;if(!Ce(e))return i??e.title;const s=e,o=r?U$(s,t):void 0;return n?qn(i,s.title,o):i??s.title??o}function j$(e){if(rh(e)&&e.axis)return e.axis;if(ij(e)&&e.legend)return e.legend;if(B$(e)&&e.header)return e.header}function U$(e,t){return aj(e,t)}function ay(e){if(sj(e)){const{format:t,formatType:n}=e;return{format:t,formatType:n}}else{const t=j$(e)??{},{format:n,formatType:r}=t;return{format:n,formatType:r}}}function dve(e,t){var s;switch(t){case"latitude":case"longitude":return"quantitative";case"row":case"column":case"facet":case"shape":case"strokeDash":return"nominal";case"order":return"ordinal"}if(z$(e)&&de(e.sort))return"ordinal";const{aggregate:n,bin:r,timeUnit:i}=e;if(i)return"temporal";if(r||n&&!Lu(n)&&!dl(n))return"quantitative";if(Sf(e)&&((s=e.scale)!=null&&s.type))switch(oA[e.scale.type]){case"numeric":case"discretizing":return"quantitative";case"time":return"temporal"}return"nominal"}function _o(e){if(Ce(e))return e;if(o2(e))return e.condition}function tr(e){if(kt(e))return e;if(q0(e))return e.condition}function uj(e,t,n,r={}){if(Ie(e)||Vt(e)||wu(e)){const i=Ie(e)?"string":Vt(e)?"number":"boolean";return Se(fme(t,i,e)),{value:e}}return kt(e)?ly(e,t,n,r):q0(e)?{...e,condition:ly(e.condition,t,n,r)}:e}function ly(e,t,n,r){if(sj(e)){const{format:i,formatType:s,...o}=e;if(sf(s)&&!n.customFormatTypes)return Se(p6(t)),ly(o,t,n,r)}else{const i=rh(e)?"axis":ij(e)?"legend":B$(e)?"header":null;if(i&&e[i]){const{format:s,formatType:o,...a}=e[i];if(sf(o)&&!n.customFormatTypes)return Se(p6(t)),ly({...e,[i]:a},t,n,r)}}return Ce(e)?q$(e,t,r):hve(e)}function hve(e){let t=e.type;if(t)return e;const{datum:n}=e;return t=Vt(n)?"quantitative":Ie(n)?"nominal":Af(n)?"temporal":void 0,{...e,type:t}}function q$(e,t,{compositeMark:n=!1}={}){const{aggregate:r,timeUnit:i,bin:s,field:o}=e,a={...e};if(!n&&r&&!p$(r)&&!Lu(r)&&!dl(r)&&(Se(hme(r)),delete a.aggregate),i&&(a.timeUnit=mr(i)),o&&(a.field=`${o}`),dn(s)&&(a.bin=a2(s,t)),Sr(s)&&!Wn(t)&&Se(Hme(t)),wi(a)){const{type:l}=a,u=m1e(l);l!==u&&(a.type=u),l!=="quantitative"&&Xb(r)&&(Se(dme(l,r)),a.type="quantitative")}else if(!nz(t)){const l=dve(a,t);a.type=l}if(wi(a)){const{compatible:l,warning:u}=pve(a,t)||{};l===!1&&Se(u)}if(z$(a)&&Ie(a.sort)){const{sort:l}=a;if(x6(l))return{...a,sort:{encoding:l}};const u=l.substring(1);if(l.charAt(0)==="-"&&x6(u))return{...a,sort:{encoding:u,order:"descending"}}}if(B$(a)){const{header:l}=a;if(l){const{orient:u,...c}=l;if(u)return{...a,header:{...c,labelOrient:l.labelOrient||u,titleOrient:l.titleOrient||u}}}}return a}function a2(e,t){return wu(e)?{maxbins:s6(t)}:e==="binned"?{binned:!0}:!e.maxbins&&!e.step?{...e,maxbins:s6(t)}:e}const jf={compatible:!0};function pve(e,t){const n=e.type;if(n==="geojson"&&t!=="shape")return{compatible:!1,warning:`Channel ${t} should not be used with a geojson data.`};switch(t){case nl:case rl:case qb:return oy(e)?jf:{compatible:!1,warning:vme(t)};case wn:case xr:case Du:case Nh:case Wi:case ka:case Sa:case O0:case L0:case Wb:case Qc:case Hb:case Gb:case xf:case Ws:case Co:case Yb:return jf;case Fo:case js:case $o:case Do:return n!==nf?{compatible:!1,warning:`Channel ${t} should be used with a quantitative field only, not ${e.type} field.`}:jf;case xl:case Tu:case Ru:case Nu:case bl:case yl:case vl:case So:case Aa:case Mu:return n==="nominal"&&!e.sort?{compatible:!1,warning:`Channel ${t} should not be used with an unsorted discrete field.`}:jf;case Hi:case Ou:return!oy(e)&&!ave(e)?{compatible:!1,warning:yme(t)}:jf;case Qd:return e.type==="nominal"&&!("sort"in e)?{compatible:!1,warning:"Channel order is inappropriate for nominal field, which has no inherent order."}:jf}}function ih(e){const{formatType:t}=ay(e);return t==="time"||!t&&gve(e)}function gve(e){return e&&(e.type==="temporal"||Ce(e)&&!!e.timeUnit)}function l2(e,{timeUnit:t,type:n,wrapTime:r,undefinedIfExprNotRequired:i}){var l;const s=t&&((l=mr(t))==null?void 0:l.unit);let o=s||n==="temporal",a;return P0(e)?a=e.expr:nt(e)?a=e.signal:Af(e)?(o=!0,a=tf(e)):(Ie(e)||Vt(e))&&o&&(a=`datetime(${ln(e)})`,r1e(s)&&(Vt(e)&&e<1e4||Ie(e)&&isNaN(Date.parse(e)))&&(a=tf({[s]:e}))),a?r&&o?`time(${a})`:a:i?void 0:ln(e)}function cj(e,t){const{type:n}=e;return t.map(r=>{const i=Ce(e)&&!kf(e.timeUnit)?e.timeUnit:void 0,s=l2(r,{timeUnit:i,type:n,undefinedIfExprNotRequired:!0});return s!==void 0?{signal:s}:r})}function W0(e,t){return dn(e.bin)?$a(t)&&["ordinal","nominal"].includes(e.type):(console.warn("Only call this method for binned field defs."),!1)}const E6={labelAlign:{part:"labels",vgProp:"align"},labelBaseline:{part:"labels",vgProp:"baseline"},labelColor:{part:"labels",vgProp:"fill"},labelFont:{part:"labels",vgProp:"font"},labelFontSize:{part:"labels",vgProp:"fontSize"},labelFontStyle:{part:"labels",vgProp:"fontStyle"},labelFontWeight:{part:"labels",vgProp:"fontWeight"},labelOpacity:{part:"labels",vgProp:"opacity"},labelOffset:null,labelPadding:null,gridColor:{part:"grid",vgProp:"stroke"},gridDash:{part:"grid",vgProp:"strokeDash"},gridDashOffset:{part:"grid",vgProp:"strokeDashOffset"},gridOpacity:{part:"grid",vgProp:"opacity"},gridWidth:{part:"grid",vgProp:"strokeWidth"},tickColor:{part:"ticks",vgProp:"stroke"},tickDash:{part:"ticks",vgProp:"strokeDash"},tickDashOffset:{part:"ticks",vgProp:"strokeDashOffset"},tickOpacity:{part:"ticks",vgProp:"opacity"},tickSize:null,tickWidth:{part:"ticks",vgProp:"strokeWidth"}};function H0(e){return e==null?void 0:e.condition}const fj=["domain","grid","labels","ticks","title"],mve={grid:"grid",gridCap:"grid",gridColor:"grid",gridDash:"grid",gridDashOffset:"grid",gridOpacity:"grid",gridScale:"grid",gridWidth:"grid",orient:"main",bandPosition:"both",aria:"main",description:"main",domain:"main",domainCap:"main",domainColor:"main",domainDash:"main",domainDashOffset:"main",domainOpacity:"main",domainWidth:"main",format:"main",formatType:"main",labelAlign:"main",labelAngle:"main",labelBaseline:"main",labelBound:"main",labelColor:"main",labelFlush:"main",labelFlushOffset:"main",labelFont:"main",labelFontSize:"main",labelFontStyle:"main",labelFontWeight:"main",labelLimit:"main",labelLineHeight:"main",labelOffset:"main",labelOpacity:"main",labelOverlap:"main",labelPadding:"main",labels:"main",labelSeparation:"main",maxExtent:"main",minExtent:"main",offset:"both",position:"main",tickCap:"main",tickColor:"main",tickDash:"main",tickDashOffset:"main",tickMinStep:"both",tickOffset:"both",tickOpacity:"main",tickRound:"both",ticks:"main",tickSize:"main",tickWidth:"both",title:"main",titleAlign:"main",titleAnchor:"main",titleAngle:"main",titleBaseline:"main",titleColor:"main",titleFont:"main",titleFontSize:"main",titleFontStyle:"main",titleFontWeight:"main",titleLimit:"main",titleLineHeight:"main",titleOpacity:"main",titlePadding:"main",titleX:"main",titleY:"main",encode:"both",scale:"both",tickBand:"both",tickCount:"both",tickExtra:"both",translate:"both",values:"both",zindex:"both"},dj={orient:1,aria:1,bandPosition:1,description:1,domain:1,domainCap:1,domainColor:1,domainDash:1,domainDashOffset:1,domainOpacity:1,domainWidth:1,format:1,formatType:1,grid:1,gridCap:1,gridColor:1,gridDash:1,gridDashOffset:1,gridOpacity:1,gridWidth:1,labelAlign:1,labelAngle:1,labelBaseline:1,labelBound:1,labelColor:1,labelFlush:1,labelFlushOffset:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelLineHeight:1,labelOffset:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labels:1,labelSeparation:1,maxExtent:1,minExtent:1,offset:1,position:1,tickBand:1,tickCap:1,tickColor:1,tickCount:1,tickDash:1,tickDashOffset:1,tickExtra:1,tickMinStep:1,tickOffset:1,tickOpacity:1,tickRound:1,ticks:1,tickSize:1,tickWidth:1,title:1,titleAlign:1,titleAnchor:1,titleAngle:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleLineHeight:1,titleOpacity:1,titlePadding:1,titleX:1,titleY:1,translate:1,values:1,zindex:1},vve={...dj,style:1,labelExpr:1,encoding:1};function A6(e){return Ue(vve,e)}const yve={axis:1,axisBand:1,axisBottom:1,axisDiscrete:1,axisLeft:1,axisPoint:1,axisQuantitative:1,axisRight:1,axisTemporal:1,axisTop:1,axisX:1,axisXBand:1,axisXDiscrete:1,axisXPoint:1,axisXQuantitative:1,axisXTemporal:1,axisY:1,axisYBand:1,axisYDiscrete:1,axisYPoint:1,axisYQuantitative:1,axisYTemporal:1},hj=Ee(yve);function wl(e){return Ae(e,"mark")}class u2{constructor(t,n){this.name=t,this.run=n}hasMatchingType(t){return wl(t)?G1e(t.mark)===this.name:!1}}function $c(e,t){const n=e&&e[t];return n?de(n)?Zd(n,r=>!!r.field):Ce(n)||o2(n):!1}function pj(e,t){const n=e&&e[t];return n?de(n)?Zd(n,r=>!!r.field):Ce(n)||Fa(n)||q0(n):!1}function gj(e,t){if(Wn(t)){const n=e[t];if((Ce(n)||Fa(n))&&(Oz(n.type)||Ce(n)&&n.timeUnit)){const r=u$(t);return pj(e,r)}}return!1}function mj(e){return Zd(h0e,t=>{if($c(e,t)){const n=e[t];if(de(n))return Zd(n,r=>!!r.aggregate);{const r=_o(n);return r&&!!r.aggregate}}return!1})}function vj(e,t){const n=[],r=[],i=[],s=[],o={};return W$(e,(a,l)=>{if(Ce(a)){const{field:u,aggregate:c,bin:f,timeUnit:d,...h}=a;if(c||d||f){const p=j$(a),g=p==null?void 0:p.title;let m=Re(a,{forAs:!0});const y={...g?[]:{title:dd(a,t,{allowDisabling:!0})},...h,field:m};if(c){let b;if(Lu(c)?(b="argmax",m=Re({op:"argmax",field:c.argmax},{forAs:!0}),y.field=`${m}.${u}`):dl(c)?(b="argmin",m=Re({op:"argmin",field:c.argmin},{forAs:!0}),y.field=`${m}.${u}`):c!=="boxplot"&&c!=="errorbar"&&c!=="errorband"&&(b=c),b){const x={op:b,as:m};u&&(x.field=u),s.push(x)}}else if(n.push(m),wi(a)&&dn(f)){if(r.push({bin:f,field:u,as:m}),n.push(Re(a,{binSuffix:"end"})),W0(a,l)&&n.push(Re(a,{binSuffix:"range"})),Wn(l)){const b={field:`${m}_end`};o[`${l}2`]=b}y.bin="binned",nz(l)||(y.type=nf)}else if(d&&!kf(d)){i.push({timeUnit:d,field:u,as:m});const b=wi(a)&&a.type!==eh&&"time";b&&(l===O0||l===Qc?y.formatType=b:A0e(l)?y.legend={formatType:b,...y.legend}:Wn(l)&&(y.axis={formatType:b,...y.axis}))}o[l]=y}else n.push(u),o[l]=e[l]}else o[l]=e[l]}),{bins:r,timeUnits:i,aggregate:s,groupby:n,encoding:o}}function bve(e,t,n){const r=S0e(t,n);if(r){if(r==="binned"){const i=e[t===So?wn:xr];return!!(Ce(i)&&Ce(e[t])&&Sr(i.bin))}}else return!1;return!0}function xve(e,t,n,r){const i={};for(const s of Ee(e))tz(s)||Se(mme(s));for(let s of b0e){if(!e[s])continue;const o=e[s];if(I0(s)){const a=y0e(s),l=i[a];if(Ce(l)&&g1e(l.type)&&Ce(o)&&!l.timeUnit){Se(cme(a));continue}}if(s==="angle"&&t==="arc"&&!e.theta&&(Se(ume),s=Ws),!bve(e,s,t)){Se(Zb(s,t));continue}if(s===bl&&t==="line"){const a=_o(e[s]);if(a!=null&&a.aggregate){Se(gme);continue}}if(s===Wi&&(n?"fill"in e:"stroke"in e)){Se(bz("encoding",{fill:"fill"in e,stroke:"stroke"in e}));continue}if(s===L0||s===Qd&&!de(o)&&!xo(o)||s===Qc&&de(o)){if(o){if(s===Qd){const a=e[s];if(rj(a)){i[s]=a;continue}}i[s]=Be(o).reduce((a,l)=>(Ce(l)?a.push(q$(l,s)):Se(sA(l,s)),a),[])}}else{if(s===Qc&&o===null)i[s]=null;else if(!Ce(o)&&!Fa(o)&&!xo(o)&&!U0(o)&&!nt(o)){Se(sA(o,s));continue}i[s]=uj(o,s,r)}}return i}function c2(e,t){const n={};for(const r of Ee(e)){const i=uj(e[r],r,t,{compositeMark:!0});n[r]=i}return n}function _ve(e){const t=[];for(const n of Ee(e))if($c(e,n)){const r=e[n],i=Be(r);for(const s of i)Ce(s)?t.push(s):o2(s)&&t.push(s.condition)}return t}function W$(e,t,n){if(e)for(const r of Ee(e)){const i=e[r];if(de(i))for(const s of i)t.call(n,s,r);else t.call(n,i,r)}}function wve(e,t,n,r){return e?Ee(e).reduce((i,s)=>{const o=e[s];return de(o)?o.reduce((a,l)=>t.call(r,a,l,s),i):t.call(r,i,o,s)},n):n}function yj(e,t){return Ee(t).reduce((n,r)=>{switch(r){case wn:case xr:case Hb:case Yb:case Gb:case So:case Aa:case Du:case Nh:case Ws:case yl:case Co:case vl:case Mu:case $o:case Fo:case Do:case js:case O0:case Hi:case xf:case Qc:return n;case Qd:if(e==="line"||e==="trail")return n;case L0:case Wb:{const i=t[r];if(de(i)||Ce(i))for(const s of Be(i))s.aggregate||n.push(Re(s,{}));return n}case bl:if(e==="trail")return n;case Wi:case ka:case Sa:case xl:case Tu:case Ru:case Ou:case Nu:{const i=_o(t[r]);return i&&!i.aggregate&&n.push(Re(i,{})),n}}},[])}function Eve(e){const{tooltip:t,...n}=e;if(!t)return{filteredEncoding:n};let r,i;if(de(t)){for(const s of t)s.aggregate?(r||(r=[]),r.push(s)):(i||(i=[]),i.push(s));r&&(n.tooltip=r)}else t.aggregate?n.tooltip=t:i=t;return de(i)&&i.length===1&&(i=i[0]),{customTooltipWithoutAggregatedField:i,filteredEncoding:n}}function uA(e,t,n,r=!0){if("tooltip"in n)return{tooltip:n.tooltip};const i=e.map(({fieldPrefix:o,titlePrefix:a})=>{const l=r?` of ${H$(t)}`:"";return{field:o+t.field,type:t.type,title:nt(a)?{signal:`${a}"${escape(l)}"`}:a+l}}),s=_ve(n).map(sve);return{tooltip:[...i,...Jo(s,Ut)]}}function H$(e){const{title:t,field:n}=e;return qn(t,n)}function G$(e,t,n,r,i){const{scale:s,axis:o}=n;return({partName:a,mark:l,positionPrefix:u,endPositionPrefix:c=void 0,extraEncoding:f={}})=>{const d=H$(n);return bj(e,a,i,{mark:l,encoding:{[t]:{field:`${u}_${n.field}`,type:n.type,...d!==void 0?{title:d}:{},...s!==void 0?{scale:s}:{},...o!==void 0?{axis:o}:{}},...Ie(c)?{[`${t}2`]:{field:`${c}_${n.field}`}}:{},...r,...f}})}}function bj(e,t,n,r){const{clip:i,color:s,opacity:o}=e,a=e.type;return e[t]||e[t]===void 0&&n[t]?[{...r,mark:{...n[t],...i?{clip:i}:{},...s?{color:s}:{},...o?{opacity:o}:{},...pa(r.mark)?r.mark:{type:r.mark},style:`${a}-${String(t)}`,...wu(e[t])?{}:e[t]}}]:[]}function xj(e,t,n){const{encoding:r}=e,i=t==="vertical"?"y":"x",s=r[i],o=r[`${i}2`],a=r[`${i}Error`],l=r[`${i}Error2`];return{continuousAxisChannelDef:Rm(s,n),continuousAxisChannelDef2:Rm(o,n),continuousAxisChannelDefError:Rm(a,n),continuousAxisChannelDefError2:Rm(l,n),continuousAxis:i}}function Rm(e,t){if(e!=null&&e.aggregate){const{aggregate:n,...r}=e;return n!==t&&Se(Wme(n,t)),r}else return e}function _j(e,t){const{mark:n,encoding:r}=e,{x:i,y:s}=r;if(pa(n)&&n.orient)return n.orient;if(Yl(i)){if(Yl(s)){const o=Ce(i)&&i.aggregate,a=Ce(s)&&s.aggregate;if(!o&&a===t)return"vertical";if(!a&&o===t)return"horizontal";if(o===t&&a===t)throw new Error("Both x and y cannot have aggregate");return ih(s)&&!ih(i)?"horizontal":"vertical"}return"horizontal"}else{if(Yl(s))return"vertical";throw new Error(`Need a valid continuous axis for ${t}s`)}}const uy="boxplot",Ave=["box","median","outliers","rule","ticks"],kve=new u2(uy,Ej);function wj(e){return Vt(e)?"tukey":e}function Ej(e,{config:t}){e={...e,encoding:c2(e.encoding,t)};const{mark:n,encoding:r,params:i,projection:s,...o}=e,a=pa(n)?n:{type:n};i&&Se(vz("boxplot"));const l=a.extent??t.boxplot.extent,u=on("size",a,t),c=a.invalid,f=wj(l),{bins:d,timeUnits:h,transform:p,continuousAxisChannelDef:g,continuousAxis:m,groupby:y,aggregate:b,encodingWithoutContinuousAxis:x,ticksOrient:_,boxOrient:w,customTooltipWithoutAggregatedField:A}=Sve(e,l,t),E=Rh(g.field),{color:k,size:S,...$}=x,M=te=>G$(a,m,g,te,t.boxplot),O=M($),P=M(x),T=(Le(t.boxplot.box)?t.boxplot.box.color:t.mark.color)||"#4c78a8",F=M({...$,...S?{size:S}:{},color:{condition:{test:`${en(`lower_box_${g.field}`)} >= ${en(`upper_box_${g.field}`)}`,...k||{value:T}}}}),N=uA([{fieldPrefix:f==="min-max"?"upper_whisker_":"max_",titlePrefix:"Max"},{fieldPrefix:"upper_box_",titlePrefix:"Q3"},{fieldPrefix:"mid_box_",titlePrefix:"Median"},{fieldPrefix:"lower_box_",titlePrefix:"Q1"},{fieldPrefix:f==="min-max"?"lower_whisker_":"min_",titlePrefix:"Min"}],g,x),U={type:"tick",color:"black",opacity:1,orient:_,invalid:c,aria:!1},j=f==="min-max"?N:uA([{fieldPrefix:"upper_whisker_",titlePrefix:"Upper Whisker"},{fieldPrefix:"lower_whisker_",titlePrefix:"Lower Whisker"}],g,x),W=[...O({partName:"rule",mark:{type:"rule",invalid:c,aria:!1},positionPrefix:"lower_whisker",endPositionPrefix:"lower_box",extraEncoding:j}),...O({partName:"rule",mark:{type:"rule",invalid:c,aria:!1},positionPrefix:"upper_box",endPositionPrefix:"upper_whisker",extraEncoding:j}),...O({partName:"ticks",mark:U,positionPrefix:"lower_whisker",extraEncoding:j}),...O({partName:"ticks",mark:U,positionPrefix:"upper_whisker",extraEncoding:j})],Z=[...f!=="tukey"?W:[],...P({partName:"box",mark:{type:"bar",...u?{size:u}:{},orient:w,invalid:c,ariaRoleDescription:"box"},positionPrefix:"lower_box",endPositionPrefix:"upper_box",extraEncoding:N}),...F({partName:"median",mark:{type:"tick",invalid:c,...Le(t.boxplot.median)&&t.boxplot.median.color?{color:t.boxplot.median.color}:{},...u?{size:u}:{},orient:_,aria:!1},positionPrefix:"mid_box",extraEncoding:N})];if(f==="min-max")return{...o,transform:(o.transform??[]).concat(p),layer:Z};const Y=en(`lower_box_${g.field}`),J=en(`upper_box_${g.field}`),ve=`(${J} - ${Y})`,Te=`${Y} - ${l} * ${ve}`,Fe=`${J} + ${l} * ${ve}`,He=en(g.field),ut={joinaggregate:Aj(g.field),groupby:y},wt={transform:[{filter:`(${Te} <= ${He}) && (${He} <= ${Fe})`},{aggregate:[{op:"min",field:g.field,as:`lower_whisker_${E}`},{op:"max",field:g.field,as:`upper_whisker_${E}`},{op:"min",field:`lower_box_${g.field}`,as:`lower_box_${E}`},{op:"max",field:`upper_box_${g.field}`,as:`upper_box_${E}`},...b],groupby:y}],layer:W},{tooltip:xe,...je}=$,{scale:fe,axis:V}=g,B=H$(g),L=Bi(V,["title"]),X=bj(a,"outliers",t.boxplot,{transform:[{filter:`(${He} < ${Te}) || (${He} > ${Fe})`}],mark:"point",encoding:{[m]:{field:g.field,type:g.type,...B!==void 0?{title:B}:{},...fe!==void 0?{scale:fe}:{},...an(L)?{}:{axis:L}},...je,...k?{color:k}:{},...A?{tooltip:A}:{}}})[0];let G;const z=[...d,...h,ut];return X?G={transform:z,layer:[X,wt]}:(G=wt,G.transform.unshift(...z)),{...o,layer:[G,{transform:p,layer:Z}]}}function Aj(e){const t=Rh(e);return[{op:"q1",field:e,as:`lower_box_${t}`},{op:"q3",field:e,as:`upper_box_${t}`}]}function Sve(e,t,n){const r=_j(e,uy),{continuousAxisChannelDef:i,continuousAxis:s}=xj(e,r,uy),o=i.field,a=Rh(o),l=wj(t),u=[...Aj(o),{op:"median",field:o,as:`mid_box_${a}`},{op:"min",field:o,as:(l==="min-max"?"lower_whisker_":"min_")+a},{op:"max",field:o,as:(l==="min-max"?"upper_whisker_":"max_")+a}],c=l==="min-max"||l==="tukey"?[]:[{calculate:`${en(`upper_box_${a}`)} - ${en(`lower_box_${a}`)}`,as:`iqr_${a}`},{calculate:`min(${en(`upper_box_${a}`)} + ${en(`iqr_${a}`)} * ${t}, ${en(`max_${a}`)})`,as:`upper_whisker_${a}`},{calculate:`max(${en(`lower_box_${a}`)} - ${en(`iqr_${a}`)} * ${t}, ${en(`min_${a}`)})`,as:`lower_whisker_${a}`}],{[s]:f,...d}=e.encoding,{customTooltipWithoutAggregatedField:h,filteredEncoding:p}=Eve(d),{bins:g,timeUnits:m,aggregate:y,groupby:b,encoding:x}=vj(p,n),_=r==="vertical"?"horizontal":"vertical",w=r,A=[...g,...m,{aggregate:[...y,...u],groupby:b},...c];return{bins:g,timeUnits:m,transform:A,groupby:b,aggregate:y,continuousAxisChannelDef:i,continuousAxis:s,encodingWithoutContinuousAxis:x,ticksOrient:_,boxOrient:w,customTooltipWithoutAggregatedField:h}}const Y$="errorbar",Cve=["ticks","rule"],$ve=new u2(Y$,kj);function kj(e,{config:t}){e={...e,encoding:c2(e.encoding,t)};const{transform:n,continuousAxisChannelDef:r,continuousAxis:i,encodingWithoutContinuousAxis:s,ticksOrient:o,markDef:a,outerSpec:l,tooltipEncoding:u}=Sj(e,Y$,t);delete s.size;const c=G$(a,i,r,s,t.errorbar),f=a.thickness,d=a.size,h={type:"tick",orient:o,aria:!1,...f!==void 0?{thickness:f}:{},...d!==void 0?{size:d}:{}},p=[...c({partName:"ticks",mark:h,positionPrefix:"lower",extraEncoding:u}),...c({partName:"ticks",mark:h,positionPrefix:"upper",extraEncoding:u}),...c({partName:"rule",mark:{type:"rule",ariaRoleDescription:"errorbar",...f!==void 0?{size:f}:{}},positionPrefix:"lower",endPositionPrefix:"upper",extraEncoding:u})];return{...l,transform:n,...p.length>1?{layer:p}:{...p[0]}}}function Fve(e,t){const{encoding:n}=e;if(Dve(n))return{orient:_j(e,t),inputType:"raw"};const r=Mve(n),i=Tve(n),s=n.x,o=n.y;if(r){if(i)throw new Error(`${t} cannot be both type aggregated-upper-lower and aggregated-error`);const a=n.x2,l=n.y2;if(kt(a)&&kt(l))throw new Error(`${t} cannot have both x2 and y2`);if(kt(a)){if(Yl(s))return{orient:"horizontal",inputType:"aggregated-upper-lower"};throw new Error(`Both x and x2 have to be quantitative in ${t}`)}else if(kt(l)){if(Yl(o))return{orient:"vertical",inputType:"aggregated-upper-lower"};throw new Error(`Both y and y2 have to be quantitative in ${t}`)}throw new Error("No ranged axis")}else{const a=n.xError,l=n.xError2,u=n.yError,c=n.yError2;if(kt(l)&&!kt(a))throw new Error(`${t} cannot have xError2 without xError`);if(kt(c)&&!kt(u))throw new Error(`${t} cannot have yError2 without yError`);if(kt(a)&&kt(u))throw new Error(`${t} cannot have both xError and yError with both are quantiative`);if(kt(a)){if(Yl(s))return{orient:"horizontal",inputType:"aggregated-error"};throw new Error("All x, xError, and xError2 (if exist) have to be quantitative")}else if(kt(u)){if(Yl(o))return{orient:"vertical",inputType:"aggregated-error"};throw new Error("All y, yError, and yError2 (if exist) have to be quantitative")}throw new Error("No ranged axis")}}function Dve(e){return(kt(e.x)||kt(e.y))&&!kt(e.x2)&&!kt(e.y2)&&!kt(e.xError)&&!kt(e.xError2)&&!kt(e.yError)&&!kt(e.yError2)}function Mve(e){return kt(e.x2)||kt(e.y2)}function Tve(e){return kt(e.xError)||kt(e.xError2)||kt(e.yError)||kt(e.yError2)}function Sj(e,t,n){const{mark:r,encoding:i,params:s,projection:o,...a}=e,l=pa(r)?r:{type:r};s&&Se(vz(t));const{orient:u,inputType:c}=Fve(e,t),{continuousAxisChannelDef:f,continuousAxisChannelDef2:d,continuousAxisChannelDefError:h,continuousAxisChannelDefError2:p,continuousAxis:g}=xj(e,u,t),{errorBarSpecificAggregate:m,postAggregateCalculates:y,tooltipSummary:b,tooltipTitleWithFieldName:x}=Rve(l,f,d,h,p,c,t,n),{[g]:_,[g==="x"?"x2":"y2"]:w,[g==="x"?"xError":"yError"]:A,[g==="x"?"xError2":"yError2"]:E,...k}=i,{bins:S,timeUnits:$,aggregate:M,groupby:O,encoding:P}=vj(k,n),T=[...M,...m],F=c!=="raw"?[]:O,N=uA(b,f,P,x);return{transform:[...a.transform??[],...S,...$,...T.length===0?[]:[{aggregate:T,groupby:F}],...y],groupby:F,continuousAxisChannelDef:f,continuousAxis:g,encodingWithoutContinuousAxis:P,ticksOrient:u==="vertical"?"horizontal":"vertical",markDef:l,outerSpec:a,tooltipEncoding:N}}function Rve(e,t,n,r,i,s,o,a){let l=[],u=[];const c=t.field;let f,d=!1;if(s==="raw"){const h=e.center?e.center:e.extent?e.extent==="iqr"?"median":"mean":a.errorbar.center,p=e.extent?e.extent:h==="mean"?"stderr":"iqr";if(h==="median"!=(p==="iqr")&&Se(qme(h,p,o)),p==="stderr"||p==="stdev")l=[{op:p,field:c,as:`extent_${c}`},{op:h,field:c,as:`center_${c}`}],u=[{calculate:`${en(`center_${c}`)} + ${en(`extent_${c}`)}`,as:`upper_${c}`},{calculate:`${en(`center_${c}`)} - ${en(`extent_${c}`)}`,as:`lower_${c}`}],f=[{fieldPrefix:"center_",titlePrefix:N0(h)},{fieldPrefix:"upper_",titlePrefix:k6(h,p,"+")},{fieldPrefix:"lower_",titlePrefix:k6(h,p,"-")}],d=!0;else{let g,m,y;p==="ci"?(g="mean",m="ci0",y="ci1"):(g="median",m="q1",y="q3"),l=[{op:m,field:c,as:`lower_${c}`},{op:y,field:c,as:`upper_${c}`},{op:g,field:c,as:`center_${c}`}],f=[{fieldPrefix:"upper_",titlePrefix:dd({field:c,aggregate:y,type:"quantitative"},a,{allowDisabling:!1})},{fieldPrefix:"lower_",titlePrefix:dd({field:c,aggregate:m,type:"quantitative"},a,{allowDisabling:!1})},{fieldPrefix:"center_",titlePrefix:dd({field:c,aggregate:g,type:"quantitative"},a,{allowDisabling:!1})}]}}else{(e.center||e.extent)&&Se(Ume(e.center,e.extent)),s==="aggregated-upper-lower"?(f=[],u=[{calculate:en(n.field),as:`upper_${c}`},{calculate:en(c),as:`lower_${c}`}]):s==="aggregated-error"&&(f=[{fieldPrefix:"",titlePrefix:c}],u=[{calculate:`${en(c)} + ${en(r.field)}`,as:`upper_${c}`}],i?u.push({calculate:`${en(c)} + ${en(i.field)}`,as:`lower_${c}`}):u.push({calculate:`${en(c)} - ${en(r.field)}`,as:`lower_${c}`}));for(const h of u)f.push({fieldPrefix:h.as.substring(0,6),titlePrefix:Jc(Jc(h.calculate,"datum['",""),"']","")})}return{postAggregateCalculates:u,errorBarSpecificAggregate:l,tooltipSummary:f,tooltipTitleWithFieldName:d}}function k6(e,t,n){return`${N0(e)} ${n} ${t}`}const V$="errorband",Nve=["band","borders"],Ove=new u2(V$,Cj);function Cj(e,{config:t}){e={...e,encoding:c2(e.encoding,t)};const{transform:n,continuousAxisChannelDef:r,continuousAxis:i,encodingWithoutContinuousAxis:s,markDef:o,outerSpec:a,tooltipEncoding:l}=Sj(e,V$,t),u=o,c=G$(u,i,r,s,t.errorband),f=e.encoding.x!==void 0&&e.encoding.y!==void 0;let d={type:f?"area":"rect"},h={type:f?"line":"rule"};const p={...u.interpolate?{interpolate:u.interpolate}:{},...u.tension&&u.interpolate?{tension:u.tension}:{}};return f?(d={...d,...p,ariaRoleDescription:"errorband"},h={...h,...p,aria:!1}):u.interpolate?Se(m6("interpolate")):u.tension&&Se(m6("tension")),{...a,transform:n,layer:[...c({partName:"band",mark:d,positionPrefix:"lower",endPositionPrefix:"upper",extraEncoding:l}),...c({partName:"borders",mark:h,positionPrefix:"lower",extraEncoding:l}),...c({partName:"borders",mark:h,positionPrefix:"upper",extraEncoding:l})]}}const $j={};function X$(e,t,n){const r=new u2(e,t);$j[e]={normalizer:r,parts:n}}function Lve(){return Ee($j)}X$(uy,Ej,Ave);X$(Y$,kj,Cve);X$(V$,Cj,Nve);const Ive=["gradientHorizontalMaxLength","gradientHorizontalMinLength","gradientVerticalMaxLength","gradientVerticalMinLength","unselectedOpacity"],Fj={titleAlign:"align",titleAnchor:"anchor",titleAngle:"angle",titleBaseline:"baseline",titleColor:"color",titleFont:"font",titleFontSize:"fontSize",titleFontStyle:"fontStyle",titleFontWeight:"fontWeight",titleLimit:"limit",titleLineHeight:"lineHeight",titleOrient:"orient",titlePadding:"offset"},Dj={labelAlign:"align",labelAnchor:"anchor",labelAngle:"angle",labelBaseline:"baseline",labelColor:"color",labelFont:"font",labelFontSize:"fontSize",labelFontStyle:"fontStyle",labelFontWeight:"fontWeight",labelLimit:"limit",labelLineHeight:"lineHeight",labelOrient:"orient",labelPadding:"offset"},Pve=Ee(Fj),Bve=Ee(Dj),zve={header:1,headerRow:1,headerColumn:1,headerFacet:1},Mj=Ee(zve),Tj=["size","shape","fill","stroke","strokeDash","strokeWidth","opacity"],jve={gradientHorizontalMaxLength:200,gradientHorizontalMinLength:100,gradientVerticalMaxLength:200,gradientVerticalMinLength:64,unselectedOpacity:.35},Uve={aria:1,clipHeight:1,columnPadding:1,columns:1,cornerRadius:1,description:1,direction:1,fillColor:1,format:1,formatType:1,gradientLength:1,gradientOpacity:1,gradientStrokeColor:1,gradientStrokeWidth:1,gradientThickness:1,gridAlign:1,labelAlign:1,labelBaseline:1,labelColor:1,labelFont:1,labelFontSize:1,labelFontStyle:1,labelFontWeight:1,labelLimit:1,labelOffset:1,labelOpacity:1,labelOverlap:1,labelPadding:1,labelSeparation:1,legendX:1,legendY:1,offset:1,orient:1,padding:1,rowPadding:1,strokeColor:1,symbolDash:1,symbolDashOffset:1,symbolFillColor:1,symbolLimit:1,symbolOffset:1,symbolOpacity:1,symbolSize:1,symbolStrokeColor:1,symbolStrokeWidth:1,symbolType:1,tickCount:1,tickMinStep:1,title:1,titleAlign:1,titleAnchor:1,titleBaseline:1,titleColor:1,titleFont:1,titleFontSize:1,titleFontStyle:1,titleFontWeight:1,titleLimit:1,titleLineHeight:1,titleOpacity:1,titleOrient:1,titlePadding:1,type:1,values:1,zindex:1},wo="_vgsid_",qve={point:{on:"click",fields:[wo],toggle:"event.shiftKey",resolve:"global",clear:"dblclick"},interval:{on:"[pointerdown, window:pointerup] > window:pointermove!",encodings:["x","y"],translate:"[pointerdown, window:pointerup] > window:pointermove!",zoom:"wheel!",mark:{fill:"#333",fillOpacity:.125,stroke:"white"},resolve:"global",clear:"dblclick"}};function K$(e){return e==="legend"||!!(e!=null&&e.legend)}function d_(e){return K$(e)&&Le(e)}function Z$(e){return!!(e!=null&&e.select)}function Rj(e){const t=[];for(const n of e||[]){if(Z$(n))continue;const{expr:r,bind:i,...s}=n;if(i&&r){const o={...s,bind:i,init:r};t.push(o)}else{const o={...s,...r?{update:r}:{},...i?{bind:i}:{}};t.push(o)}}return t}function Wve(e){return f2(e)||Q$(e)||J$(e)}function J$(e){return Ae(e,"concat")}function f2(e){return Ae(e,"vconcat")}function Q$(e){return Ae(e,"hconcat")}function Nj({step:e,offsetIsDiscrete:t}){return t?e.for??"offset":"position"}function ga(e){return Ae(e,"step")}function S6(e){return Ae(e,"view")||Ae(e,"width")||Ae(e,"height")}const C6=20,Hve={align:1,bounds:1,center:1,columns:1,spacing:1},Gve=Ee(Hve);function Yve(e,t,n){const r=n[t],i={},{spacing:s,columns:o}=r;s!==void 0&&(i.spacing=s),o!==void 0&&(s2(e)&&!j0(e.facet)||J$(e))&&(i.columns=o),f2(e)&&(i.columns=1);for(const a of Gve)if(e[a]!==void 0)if(a==="spacing"){const l=e[a];i[a]=Vt(l)?l:{row:l.row??s,column:l.column??s}}else i[a]=e[a];return i}function cA(e,t){return e[t]??e[t==="width"?"continuousWidth":"continuousHeight"]}function fA(e,t){const n=cy(e,t);return ga(n)?n.step:Oj}function cy(e,t){const n=e[t]??e[t==="width"?"discreteWidth":"discreteHeight"];return qn(n,{step:e.step})}const Oj=20,Vve={continuousWidth:200,continuousHeight:200,step:Oj},Xve={background:"white",padding:5,timeFormat:"%b %d, %Y",countTitle:"Count of Records",view:Vve,mark:z1e,arc:{},area:{},bar:W1e,circle:{},geoshape:{},image:{},line:{},point:{},rect:N$,rule:{color:"black"},square:{},text:{color:"black"},tick:H1e,trail:{},boxplot:{size:14,extent:1.5,box:{},median:{color:"white"},outliers:{},rule:{},ticks:null},errorbar:{center:"mean",rule:!0,ticks:!1},errorband:{band:{opacity:.3},borders:!1},scale:_1e,projection:{},legend:jve,header:{titlePadding:10,labelPadding:10},headerColumn:{},headerRow:{},headerFacet:{},selection:qve,style:{},title:{},facet:{spacing:C6},concat:{spacing:C6},normalizedNumberFormat:".0%"},Oa=["#4c78a8","#f58518","#e45756","#72b7b2","#54a24b","#eeca3b","#b279a2","#ff9da6","#9d755d","#bab0ac"],$6={text:11,guideLabel:10,guideTitle:11,groupTitle:13,groupSubtitle:12},F6={blue:Oa[0],orange:Oa[1],red:Oa[2],teal:Oa[3],green:Oa[4],yellow:Oa[5],purple:Oa[6],pink:Oa[7],brown:Oa[8],gray0:"#000",gray1:"#111",gray2:"#222",gray3:"#333",gray4:"#444",gray5:"#555",gray6:"#666",gray7:"#777",gray8:"#888",gray9:"#999",gray10:"#aaa",gray11:"#bbb",gray12:"#ccc",gray13:"#ddd",gray14:"#eee",gray15:"#fff"};function Kve(e={}){return{signals:[{name:"color",value:Le(e)?{...F6,...e}:F6}],mark:{color:{signal:"color.blue"}},rule:{color:{signal:"color.gray0"}},text:{color:{signal:"color.gray0"}},style:{"guide-label":{fill:{signal:"color.gray0"}},"guide-title":{fill:{signal:"color.gray0"}},"group-title":{fill:{signal:"color.gray0"}},"group-subtitle":{fill:{signal:"color.gray0"}},cell:{stroke:{signal:"color.gray8"}}},axis:{domainColor:{signal:"color.gray13"},gridColor:{signal:"color.gray8"},tickColor:{signal:"color.gray13"}},range:{category:[{signal:"color.blue"},{signal:"color.orange"},{signal:"color.red"},{signal:"color.teal"},{signal:"color.green"},{signal:"color.yellow"},{signal:"color.purple"},{signal:"color.pink"},{signal:"color.brown"},{signal:"color.grey8"}]}}}function Zve(e){return{signals:[{name:"fontSize",value:Le(e)?{...$6,...e}:$6}],text:{fontSize:{signal:"fontSize.text"}},style:{"guide-label":{fontSize:{signal:"fontSize.guideLabel"}},"guide-title":{fontSize:{signal:"fontSize.guideTitle"}},"group-title":{fontSize:{signal:"fontSize.groupTitle"}},"group-subtitle":{fontSize:{signal:"fontSize.groupSubtitle"}}}}}function Jve(e){return{text:{font:e},style:{"guide-label":{font:e},"guide-title":{font:e},"group-title":{font:e},"group-subtitle":{font:e}}}}function Lj(e){const t=Ee(e||{}),n={};for(const r of t){const i=e[r];n[r]=H0(i)?cz(i):rs(i)}return n}function Qve(e){const t=Ee(e),n={};for(const r of t)n[r]=Lj(e[r]);return n}const eye=[...Hz,...hj,...Mj,"background","padding","legend","lineBreak","scale","style","title","view"];function Ij(e={}){const{color:t,font:n,fontSize:r,selection:i,...s}=e,o=mh({},_t(Xve),n?Jve(n):{},t?Kve(t):{},r?Zve(r):{},s||{});i&&vh(o,"selection",i,!0);const a=Bi(o,eye);for(const l of["background","lineBreak","padding"])o[l]&&(a[l]=rs(o[l]));for(const l of Hz)o[l]&&(a[l]=$r(o[l]));for(const l of hj)o[l]&&(a[l]=Lj(o[l]));for(const l of Mj)o[l]&&(a[l]=$r(o[l]));if(o.legend&&(a.legend=$r(o.legend)),o.scale){const{invalid:l,...u}=o.scale,c=$r(l,{level:1});a.scale={...$r(u),...Ee(c).length>0?{invalid:c}:{}}}return o.style&&(a.style=Qve(o.style)),o.title&&(a.title=$r(o.title)),o.view&&(a.view=$r(o.view)),a}const tye=new Set(["view",...N1e]),nye=["color","fontSize","background","padding","facet","concat","numberFormat","numberFormatType","normalizedNumberFormat","normalizedNumberFormatType","timeFormat","countTitle","header","axisQuantitative","axisTemporal","axisDiscrete","axisPoint","axisXBand","axisXPoint","axisXDiscrete","axisXQuantitative","axisXTemporal","axisYBand","axisYPoint","axisYDiscrete","axisYQuantitative","axisYTemporal","scale","selection","overlay"],rye={view:["continuousWidth","continuousHeight","discreteWidth","discreteHeight","step"],...B1e};function iye(e){e=_t(e);for(const t of nye)delete e[t];if(e.axis)for(const t in e.axis)H0(e.axis[t])&&delete e.axis[t];if(e.legend)for(const t of Ive)delete e.legend[t];if(e.mark){for(const t of y6)delete e.mark[t];e.mark.tooltip&&Le(e.mark.tooltip)&&delete e.mark.tooltip}e.params&&(e.signals=(e.signals||[]).concat(Rj(e.params)),delete e.params);for(const t of tye){for(const r of y6)delete e[t][r];const n=rye[t];if(n)for(const r of n)delete e[t][r];oye(e,t)}for(const t of Lve())delete e[t];sye(e);for(const t in e)Le(e[t])&&an(e[t])&&delete e[t];return an(e)?void 0:e}function sye(e){const{titleMarkConfig:t,subtitleMarkConfig:n,subtitle:r}=uz(e.title);an(t)||(e.style["group-title"]={...e.style["group-title"],...t}),an(n)||(e.style["group-subtitle"]={...e.style["group-subtitle"],...n}),an(r)?delete e.title:e.title=r}function oye(e,t,n,r){const i=e[t];t==="view"&&(n="cell");const s={...i,...e.style[n??t]};an(s)||(e.style[n??t]=s),delete e[t]}function d2(e){return Ae(e,"layer")}function aye(e){return Ae(e,"repeat")}function lye(e){return!de(e.repeat)&&Ae(e.repeat,"layer")}class eF{map(t,n){return s2(t)?this.mapFacet(t,n):aye(t)?this.mapRepeat(t,n):Q$(t)?this.mapHConcat(t,n):f2(t)?this.mapVConcat(t,n):J$(t)?this.mapConcat(t,n):this.mapLayerOrUnit(t,n)}mapLayerOrUnit(t,n){if(d2(t))return this.mapLayer(t,n);if(wl(t))return this.mapUnit(t,n);throw new Error(g$(t))}mapLayer(t,n){return{...t,layer:t.layer.map(r=>this.mapLayerOrUnit(r,n))}}mapHConcat(t,n){return{...t,hconcat:t.hconcat.map(r=>this.map(r,n))}}mapVConcat(t,n){return{...t,vconcat:t.vconcat.map(r=>this.map(r,n))}}mapConcat(t,n){const{concat:r,...i}=t;return{...i,concat:r.map(s=>this.map(s,n))}}mapFacet(t,n){return{...t,spec:this.map(t.spec,n)}}mapRepeat(t,n){return{...t,spec:this.map(t.spec,n)}}}const uye={zero:1,center:1,normalize:1};function cye(e){return Ue(uye,e)}const fye=new Set([Uz,t2,e2,ry,r2,T$,R$,n2,qz,M$]),dye=new Set([t2,e2,Uz]);function Uf(e){return Ce(e)&&nh(e)==="quantitative"&&!e.bin}function D6(e,t,{orient:n,type:r}){const i=t==="x"?"y":"radius",s=t==="x"&&["bar","area"].includes(r),o=e[t],a=e[i];if(Ce(o)&&Ce(a))if(Uf(o)&&Uf(a)){if(o.stack)return t;if(a.stack)return i;const l=Ce(o)&&!!o.aggregate,u=Ce(a)&&!!a.aggregate;if(l!==u)return l?t:i;if(s){if(n==="vertical")return i;if(n==="horizontal")return t}}else{if(Uf(o))return t;if(Uf(a))return i}else{if(Uf(o))return s&&n==="vertical"?void 0:t;if(Uf(a))return s&&n==="horizontal"?void 0:i}}function hye(e){switch(e){case"x":return"y";case"y":return"x";case"theta":return"radius";case"radius":return"theta"}}function Pj(e,t){var g,m;const n=pa(e)?e:{type:e},r=n.type;if(!fye.has(r))return null;const i=D6(t,"x",n)||D6(t,"theta",n);if(!i)return null;const s=t[i],o=Ce(s)?Re(s,{}):void 0,a=hye(i),l=[],u=new Set;if(t[a]){const y=t[a],b=Ce(y)?Re(y,{}):void 0;b&&b!==o&&(l.push(a),u.add(b))}const c=a==="x"?"xOffset":"yOffset",f=t[c],d=Ce(f)?Re(f,{}):void 0;d&&d!==o&&(l.push(c),u.add(d));const h=x0e.reduce((y,b)=>{if(b!=="tooltip"&&$c(t,b)){const x=t[b];for(const _ of Be(x)){const w=_o(_);if(w.aggregate)continue;const A=Re(w,{});(!A||!u.has(A))&&y.push({channel:b,fieldDef:w})}}return y},[]);let p;return s.stack!==void 0?wu(s.stack)?p=s.stack?"zero":null:p=s.stack:dye.has(r)&&(p="zero"),!p||!cye(p)||mj(t)&&h.length===0?null:((g=s==null?void 0:s.scale)!=null&&g.type&&((m=s==null?void 0:s.scale)==null?void 0:m.type)!==Fr.LINEAR&&s!=null&&s.stack&&Se(Bme(s.scale.type)),kt(t[Ca(i)])?(s.stack!==void 0&&Se(Pme(i)),null):(Ce(s)&&s.aggregate&&!R0e.has(s.aggregate)&&Se(zme(s.aggregate)),{groupbyChannels:l,groupbyFields:u,fieldChannel:i,impute:s.impute===null?!1:Iu(r),stackBy:h,offset:p}))}function Bj(e,t,n){const r=$r(e),i=on("orient",r,n);if(r.orient=vye(r.type,t,i),i!==void 0&&i!==r.orient&&Se(wme(r.orient,i)),r.type==="bar"&&r.orient){const l=on("cornerRadiusEnd",r,n);if(l!==void 0){const u=r.orient==="horizontal"&&t.x2||r.orient==="vertical"&&t.y2?["cornerRadius"]:U1e[r.orient];for(const c of u)r[c]=l;r.cornerRadiusEnd!==void 0&&delete r.cornerRadiusEnd}}const s=on("opacity",r,n),o=on("fillOpacity",r,n);return s===void 0&&o===void 0&&(r.opacity=gye(r.type,t)),on("cursor",r,n)===void 0&&(r.cursor=pye(r,t,n)),r}function pye(e,t,n){return t.href||e.href||on("href",e,n)?"pointer":e.cursor}function gye(e,t){if(It([r2,M$,T$,R$],e)&&!mj(t))return .7}function mye(e,t,{graticule:n}){if(n)return!1;const r=ha("filled",e,t),i=e.type;return qn(r,i!==r2&&i!==n2&&i!==ry)}function vye(e,t,n){switch(e){case r2:case T$:case R$:case qz:case T1e:case M1e:return}const{x:r,y:i,x2:s,y2:o}=t;switch(e){case t2:if(Ce(r)&&(Sr(r.bin)||Ce(i)&&i.aggregate&&!r.aggregate))return"vertical";if(Ce(i)&&(Sr(i.bin)||Ce(r)&&r.aggregate&&!i.aggregate))return"horizontal";if(o||s){if(n)return n;if(!s)return(Ce(r)&&r.type===nf&&!dn(r.bin)||sy(r))&&Ce(i)&&Sr(i.bin)?"horizontal":"vertical";if(!o)return(Ce(i)&&i.type===nf&&!dn(i.bin)||sy(i))&&Ce(r)&&Sr(r.bin)?"vertical":"horizontal"}case ry:if(s&&!(Ce(r)&&Sr(r.bin))&&o&&!(Ce(i)&&Sr(i.bin)))return;case e2:if(o)return Ce(i)&&Sr(i.bin)?"horizontal":"vertical";if(s)return Ce(r)&&Sr(r.bin)?"vertical":"horizontal";if(e===ry){if(r&&!i)return"vertical";if(i&&!r)return"horizontal"}case n2:case M$:{const a=w6(r),l=w6(i);if(n)return n;if(a&&!l)return e!=="tick"?"horizontal":"vertical";if(!a&&l)return e!=="tick"?"vertical":"horizontal";if(a&&l)return"vertical";{const u=wi(r)&&r.type===eh,c=wi(i)&&i.type===eh;if(u&&!c)return"vertical";if(!u&&c)return"horizontal"}return}}return"vertical"}function yye(e){const{point:t,line:n,...r}=e;return Ee(r).length>1?r:r.type}function bye(e){for(const t of["line","area","rule","trail"])e[t]&&(e={...e,[t]:Bi(e[t],["point","line"])});return e}function h_(e,t={},n){return e.point==="transparent"?{opacity:0}:e.point?Le(e.point)?e.point:{}:e.point!==void 0?null:t.point||n.shape?Le(t.point)?t.point:{}:void 0}function M6(e,t={}){return e.line?e.line===!0?{}:e.line:e.line!==void 0?null:t.line?t.line===!0?{}:t.line:void 0}class xye{constructor(){this.name="path-overlay"}hasMatchingType(t,n){if(wl(t)){const{mark:r,encoding:i}=t,s=pa(r)?r:{type:r};switch(s.type){case"line":case"rule":case"trail":return!!h_(s,n[s.type],i);case"area":return!!h_(s,n[s.type],i)||!!M6(s,n[s.type])}}return!1}run(t,n,r){const{config:i}=n,{params:s,projection:o,mark:a,name:l,encoding:u,...c}=t,f=c2(u,i),d=pa(a)?a:{type:a},h=h_(d,i[d.type],f),p=d.type==="area"&&M6(d,i[d.type]),g=[{name:l,...s?{params:s}:{},mark:yye({...d.type==="area"&&d.opacity===void 0&&d.fillOpacity===void 0?{opacity:.7}:{},...d}),encoding:Bi(f,["shape"])}],m=Pj(Bj(d,f,i),f);let y=f;if(m){const{fieldChannel:b,offset:x}=m;y={...f,[b]:{...f[b],...x?{stack:x}:{}}}}return y=Bi(y,["y2","x2"]),p&&g.push({...o?{projection:o}:{},mark:{type:"line",...Kd(d,["clip","interpolate","tension","tooltip"]),...p},encoding:y}),h&&g.push({...o?{projection:o}:{},mark:{type:"point",opacity:1,filled:!0,...Kd(d,["clip","tooltip"]),...h},encoding:y}),r({...c,layer:g},{...n,config:bye(i)})}}function _ye(e,t){return t?j0(e)?jj(e,t):zj(e,t):e}function p_(e,t){return t?jj(e,t):e}function dA(e,t,n){const r=t[e];if(rve(r)){if(r.repeat in n)return{...t,[e]:n[r.repeat]};Se(Q0e(r.repeat));return}return t}function zj(e,t){if(e=dA("field",e,t),e!==void 0){if(e===null)return null;if(z$(e)&&il(e.sort)){const n=dA("field",e.sort,t);e={...e,...n?{sort:n}:{}}}return e}}function T6(e,t){if(Ce(e))return zj(e,t);{const n=dA("datum",e,t);return n!==e&&!n.type&&(n.type="nominal"),n}}function R6(e,t){if(kt(e)){const n=T6(e,t);if(n)return n;if(U0(e))return{condition:e.condition}}else{if(q0(e)){const n=T6(e.condition,t);if(n)return{...e,condition:n};{const{condition:r,...i}=e;return i}}return e}}function jj(e,t){const n={};for(const r in e)if(Ae(e,r)){const i=e[r];if(de(i))n[r]=i.map(s=>R6(s,t)).filter(s=>s);else{const s=R6(i,t);s!==void 0&&(n[r]=s)}}return n}class wye{constructor(){this.name="RuleForRangedLine"}hasMatchingType(t){if(wl(t)){const{encoding:n,mark:r}=t;if(r==="line"||pa(r)&&r.type==="line")for(const i of v0e){const s=_f(i),o=n[s];if(n[i]&&(Ce(o)&&!Sr(o.bin)||Fa(o)))return!0}}return!1}run(t,n,r){const{encoding:i,mark:s}=t;return Se(_me(!!i.x2,!!i.y2)),r({...t,mark:Le(s)?{...s,type:"rule"}:"rule"},n)}}class Eye extends eF{constructor(){super(...arguments),this.nonFacetUnitNormalizers=[kve,$ve,Ove,new xye,new wye]}map(t,n){if(wl(t)){const r=$c(t.encoding,nl),i=$c(t.encoding,rl),s=$c(t.encoding,qb);if(r||i||s)return this.mapFacetedUnit(t,n)}return super.map(t,n)}mapUnit(t,n){const{parentEncoding:r,parentProjection:i}=n,s=p_(t.encoding,n.repeater),o={...t,...t.name?{name:[n.repeaterPrefix,t.name].filter(l=>l).join("_")}:{},...s?{encoding:s}:{}};if(r||i)return this.mapUnitWithParentEncodingOrProjection(o,n);const a=this.mapLayerOrUnit.bind(this);for(const l of this.nonFacetUnitNormalizers)if(l.hasMatchingType(o,n.config))return l.run(o,n,a);return o}mapRepeat(t,n){return lye(t)?this.mapLayerRepeat(t,n):this.mapNonLayerRepeat(t,n)}mapLayerRepeat(t,n){const{repeat:r,spec:i,...s}=t,{row:o,column:a,layer:l}=r,{repeater:u={},repeaterPrefix:c=""}=n;return o||a?this.mapRepeat({...t,repeat:{...o?{row:o}:{},...a?{column:a}:{}},spec:{repeat:{layer:l},spec:i}},n):{...s,layer:l.map(f=>{const d={...u,layer:f},h=`${(i.name?`${i.name}_`:"")+c}child__layer_${_n(f)}`,p=this.mapLayerOrUnit(i,{...n,repeater:d,repeaterPrefix:h});return p.name=h,p})}}mapNonLayerRepeat(t,n){const{repeat:r,spec:i,data:s,...o}=t;!de(r)&&t.columns&&(t=Bi(t,["columns"]),Se(d6("repeat")));const a=[],{repeater:l={},repeaterPrefix:u=""}=n,c=!de(r)&&r.row||[l?l.row:null],f=!de(r)&&r.column||[l?l.column:null],d=de(r)&&r||[l?l.repeat:null];for(const p of d)for(const g of c)for(const m of f){const y={repeat:p,row:g,column:m,layer:l.layer},b=(i.name?`${i.name}_`:"")+u+"child__"+(de(r)?`${_n(p)}`:(r.row?`row_${_n(g)}`:"")+(r.column?`column_${_n(m)}`:"")),x=this.map(i,{...n,repeater:y,repeaterPrefix:b});x.name=b,a.push(Bi(x,["data"]))}const h=de(r)?t.columns:r.column?r.column.length:1;return{data:i.data??s,align:"all",...o,columns:h,concat:a}}mapFacet(t,n){const{facet:r}=t;return j0(r)&&t.columns&&(t=Bi(t,["columns"]),Se(d6("facet"))),super.mapFacet(t,n)}mapUnitWithParentEncodingOrProjection(t,n){const{encoding:r,projection:i}=t,{parentEncoding:s,parentProjection:o,config:a}=n,l=O6({parentProjection:o,projection:i}),u=N6({parentEncoding:s,encoding:p_(r,n.repeater)});return this.mapUnit({...t,...l?{projection:l}:{},...u?{encoding:u}:{}},{config:a})}mapFacetedUnit(t,n){const{row:r,column:i,facet:s,...o}=t.encoding,{mark:a,width:l,projection:u,height:c,view:f,params:d,encoding:h,...p}=t,{facetMapping:g,layout:m}=this.getFacetMappingAndLayout({row:r,column:i,facet:s},n),y=p_(o,n.repeater);return this.mapFacet({...p,...m,facet:g,spec:{...l?{width:l}:{},...c?{height:c}:{},...f?{view:f}:{},...u?{projection:u}:{},mark:a,encoding:y,...d?{params:d}:{}}},n)}getFacetMappingAndLayout(t,n){const{row:r,column:i,facet:s}=t;if(r||i){s&&Se(bme([...r?[nl]:[],...i?[rl]:[]]));const o={},a={};for(const l of[nl,rl]){const u=t[l];if(u){const{align:c,center:f,spacing:d,columns:h,...p}=u;o[l]=p;for(const g of["align","center","spacing"])u[g]!==void 0&&(a[g]??(a[g]={}),a[g][l]=u[g])}}return{facetMapping:o,layout:a}}else{const{align:o,center:a,spacing:l,columns:u,...c}=s;return{facetMapping:_ye(c,n.repeater),layout:{...o?{align:o}:{},...a?{center:a}:{},...l?{spacing:l}:{},...u?{columns:u}:{}}}}}mapLayer(t,{parentEncoding:n,parentProjection:r,...i}){const{encoding:s,projection:o,...a}=t,l={...i,parentEncoding:N6({parentEncoding:n,encoding:s,layer:!0}),parentProjection:O6({parentProjection:r,projection:o})};return super.mapLayer({...a,...t.name?{name:[l.repeaterPrefix,t.name].filter(u=>u).join("_")}:{}},l)}}function N6({parentEncoding:e,encoding:t={},layer:n}){let r={};if(e){const i=new Set([...Ee(e),...Ee(t)]);for(const s of i){const o=t[s],a=e[s];if(kt(o)){const l={...a,...o};r[s]=l}else q0(o)?r[s]={...o,condition:{...a,...o.condition}}:o||o===null?r[s]=o:(n||xo(a)||nt(a)||kt(a)||de(a))&&(r[s]=a)}}else r=t;return!r||an(r)?void 0:r}function O6(e){const{parentProjection:t,projection:n}=e;return t&&n&&Se(lme({parentProjection:t,projection:n})),n??t}function tF(e){return Ae(e,"filter")}function Aye(e){return Ae(e,"stop")}function Uj(e){return Ae(e,"lookup")}function kye(e){return Ae(e,"data")}function Sye(e){return Ae(e,"param")}function Cye(e){return Ae(e,"pivot")}function $ye(e){return Ae(e,"density")}function Fye(e){return Ae(e,"quantile")}function Dye(e){return Ae(e,"regression")}function Mye(e){return Ae(e,"loess")}function Tye(e){return Ae(e,"sample")}function Rye(e){return Ae(e,"window")}function Nye(e){return Ae(e,"joinaggregate")}function Oye(e){return Ae(e,"flatten")}function Lye(e){return Ae(e,"calculate")}function qj(e){return Ae(e,"bin")}function Iye(e){return Ae(e,"impute")}function Pye(e){return Ae(e,"timeUnit")}function Bye(e){return Ae(e,"aggregate")}function zye(e){return Ae(e,"stack")}function jye(e){return Ae(e,"fold")}function Uye(e){return Ae(e,"extent")&&!Ae(e,"density")&&!Ae(e,"regression")}function qye(e){return e.map(t=>tF(t)?{filter:cd(t.filter,p1e)}:t)}class Wye extends eF{map(t,n){return n.emptySelections??(n.emptySelections={}),n.selectionPredicates??(n.selectionPredicates={}),t=L6(t,n),super.map(t,n)}mapLayerOrUnit(t,n){if(t=L6(t,n),t.encoding){const r={};for(const[i,s]of pu(t.encoding))r[i]=Wj(s,n);t={...t,encoding:r}}return super.mapLayerOrUnit(t,n)}mapUnit(t,n){const{selection:r,...i}=t;return r?{...i,params:pu(r).map(([s,o])=>{const{init:a,bind:l,empty:u,...c}=o;c.type==="single"?(c.type="point",c.toggle=!1):c.type==="multi"&&(c.type="point"),n.emptySelections[s]=u!=="none";for(const f of Or(n.selectionPredicates[s]??{}))f.empty=u!=="none";return{name:s,value:a,select:c,bind:l}})}:t}}function L6(e,t){const{transform:n,...r}=e;if(n){const i=n.map(s=>{if(tF(s))return{filter:hA(s,t)};if(qj(s)&&wf(s.bin))return{...s,bin:Hj(s.bin)};if(Uj(s)){const{selection:o,...a}=s.from;return o?{...s,from:{param:o,...a}}:s}return s});return{...r,transform:i}}return e}function Wj(e,t){var r,i;const n=_t(e);if(Ce(n)&&wf(n.bin)&&(n.bin=Hj(n.bin)),Sf(n)&&((i=(r=n.scale)==null?void 0:r.domain)!=null&&i.selection)){const{selection:s,...o}=n.scale.domain;n.scale.domain={...o,...s?{param:s}:{}}}if(U0(n))if(de(n.condition))n.condition=n.condition.map(s=>{const{selection:o,param:a,test:l,...u}=s;return a?s:{...u,test:hA(s,t)}});else{const{selection:s,param:o,test:a,...l}=Wj(n.condition,t);n.condition=o?n.condition:{...l,test:hA(n.condition,t)}}return n}function Hj(e){const t=e.extent;if(t!=null&&t.selection){const{selection:n,...r}=t;return{...e,extent:{...r,param:n}}}return e}function hA(e,t){const n=r=>cd(r,i=>{var s;const o=t.emptySelections[i]??!0,a={param:i,empty:o};return(s=t.selectionPredicates)[i]??(s[i]=[]),t.selectionPredicates[i].push(a),a});return e.selection?n(e.selection):cd(e.test||e.filter,r=>r.selection?n(r.selection):r)}class pA extends eF{map(t,n){const r=n.selections??[];if(t.params&&!wl(t)){const i=[];for(const s of t.params)Z$(s)?r.push(s):i.push(s);t.params=i}return n.selections=r,super.map(t,n)}mapUnit(t,n){const r=n.selections;if(!r||!r.length)return t;const i=(n.path??[]).concat(t.name),s=[];for(const o of r)if(!o.views||!o.views.length)s.push(o);else for(const a of o.views)(Ie(a)&&(a===t.name||i.includes(a))||de(a)&&a.map(l=>i.indexOf(l)).every((l,u,c)=>l!==-1&&(u===0||l>c[u-1])))&&s.push(o);return s.length&&(t.params=s),t}}for(const e of["mapFacet","mapRepeat","mapHConcat","mapVConcat","mapLayer"]){const t=pA.prototype[e];pA.prototype[e]=function(n,r){return t.call(this,n,Hye(n,r))}}function Hye(e,t){return e.name?{...t,path:(t.path??[]).concat(e.name)}:t}function Gj(e,t){t===void 0&&(t=Ij(e.config));const n=Xye(e,t),{width:r,height:i}=e,s=Kye(n,{width:r,height:i,autosize:e.autosize},t);return{...n,...s?{autosize:s}:{}}}const Gye=new Eye,Yye=new Wye,Vye=new pA;function Xye(e,t={}){const n={config:t};return Vye.map(Gye.map(Yye.map(e,n),n),n)}function I6(e){return Ie(e)?{type:e}:e??{}}function Kye(e,t,n){let{width:r,height:i}=t;const s=wl(e)||d2(e),o={};s?r=="container"&&i=="container"?(o.type="fit",o.contains="padding"):r=="container"?(o.type="fit-x",o.contains="padding"):i=="container"&&(o.type="fit-y",o.contains="padding"):(r=="container"&&(Se(l6("width")),r=void 0),i=="container"&&(Se(l6("height")),i=void 0));const a={type:"pad",...o,...n?I6(n.autosize):{},...I6(e.autosize)};if(a.type==="fit"&&!s&&(Se(U0e),a.type="pad"),r=="container"&&!(a.type=="fit"||a.type=="fit-x")&&Se(u6("width")),i=="container"&&!(a.type=="fit"||a.type=="fit-y")&&Se(u6("height")),!os(a,{type:"pad"}))return a}function Zye(e){return["fit","fit-x","fit-y"].includes(e)}function Jye(e){return e?`fit-${Vb(e)}`:"fit"}const Qye=["background","padding"];function P6(e,t){const n={};for(const r of Qye)e&&e[r]!==void 0&&(n[r]=rs(e[r]));return t&&(n.params=e.params),n}class El{constructor(t={},n={}){this.explicit=t,this.implicit=n}clone(){return new El(_t(this.explicit),_t(this.implicit))}combine(){return{...this.explicit,...this.implicit}}get(t){return qn(this.explicit[t],this.implicit[t])}getWithExplicit(t){return this.explicit[t]!==void 0?{explicit:!0,value:this.explicit[t]}:this.implicit[t]!==void 0?{explicit:!1,value:this.implicit[t]}:{explicit:!1,value:void 0}}setWithExplicit(t,{value:n,explicit:r}){n!==void 0&&this.set(t,n,r)}set(t,n,r){return delete this[r?"implicit":"explicit"][t],this[r?"explicit":"implicit"][t]=n,this}copyKeyFromSplit(t,{explicit:n,implicit:r}){n[t]!==void 0?this.set(t,n[t],!0):r[t]!==void 0&&this.set(t,r[t],!1)}copyKeyFromObject(t,n){n[t]!==void 0&&this.set(t,n[t],!0)}copyAll(t){for(const n of Ee(t.combine())){const r=t.getWithExplicit(n);this.setWithExplicit(n,r)}}}function jo(e){return{explicit:!0,value:e}}function Zi(e){return{explicit:!1,value:e}}function Yj(e){return(t,n,r,i)=>{const s=e(t.value,n.value);return s>0?t:s<0?n:h2(t,n,r,i)}}function h2(e,t,n,r){return e.explicit&&t.explicit&&Se(Mme(n,r,e.value,t.value)),e}function vu(e,t,n,r,i=h2){return e===void 0||e.value===void 0?t:e.explicit&&!t.explicit?e:t.explicit&&!e.explicit?t:os(e.value,t.value)?e:i(e,t,n,r)}class ebe extends El{constructor(t={},n={},r=!1){super(t,n),this.explicit=t,this.implicit=n,this.parseNothing=r}clone(){const t=super.clone();return t.parseNothing=this.parseNothing,t}}function sh(e){return Ae(e,"url")}function Pg(e){return Ae(e,"values")}function Vj(e){return Ae(e,"name")&&!sh(e)&&!Pg(e)&&!nu(e)}function nu(e){return e&&(Xj(e)||Kj(e)||nF(e))}function Xj(e){return Ae(e,"sequence")}function Kj(e){return Ae(e,"sphere")}function nF(e){return Ae(e,"graticule")}var Fn;(function(e){e[e.Raw=0]="Raw",e[e.Main=1]="Main",e[e.Row=2]="Row",e[e.Column=3]="Column",e[e.Lookup=4]="Lookup",e[e.PreFilterInvalid=5]="PreFilterInvalid",e[e.PostFilterInvalid=6]="PostFilterInvalid"})(Fn||(Fn={}));function Zj({invalid:e,isPath:t}){switch(Gz(e,{isPath:t})){case"filter":return{marks:"exclude-invalid-values",scales:"exclude-invalid-values"};case"break-paths-show-domains":return{marks:t?"include-invalid-values":"exclude-invalid-values",scales:"include-invalid-values"};case"break-paths-filter-domains":return{marks:t?"include-invalid-values":"exclude-invalid-values",scales:"exclude-invalid-values"};case"show":return{marks:"include-invalid-values",scales:"include-invalid-values"}}}function tbe(e){const{marks:t,scales:n}=Zj(e);return t===n?Fn.Main:n==="include-invalid-values"?Fn.PreFilterInvalid:Fn.PostFilterInvalid}class sn{constructor(t,n){this.debugName=n,this._children=[],this._parent=null,t&&(this.parent=t)}clone(){throw new Error("Cannot clone node")}get parent(){return this._parent}set parent(t){this._parent=t,t&&t.addChild(this)}get children(){return this._children}numChildren(){return this._children.length}addChild(t,n){if(this._children.includes(t)){Se(sme);return}n!==void 0?this._children.splice(n,0,t):this._children.push(t)}removeChild(t){const n=this._children.indexOf(t);return this._children.splice(n,1),n}remove(){let t=this._parent.removeChild(this);for(const n of this._children)n._parent=this._parent,this._parent.addChild(n,t++)}insertAsParentOf(t){const n=t.parent;n.removeChild(this),this.parent=n,t.parent=this}swapWithParent(){const t=this._parent,n=t.parent;for(const i of this._children)i.parent=t;this._children=[],t.removeChild(this);const r=t.parent.removeChild(t);this._parent=n,n.addChild(this,r),t.parent=this}}class zi extends sn{clone(){const t=new this.constructor;return t.debugName=`clone_${this.debugName}`,t._source=this._source,t._name=`clone_${this._name}`,t.type=this.type,t.refCounts=this.refCounts,t.refCounts[t._name]=0,t}constructor(t,n,r,i){super(t,n),this.type=r,this.refCounts=i,this._source=this._name=n,this.refCounts&&!(this._name in this.refCounts)&&(this.refCounts[this._name]=0)}dependentFields(){return new Set}producedFields(){return new Set}hash(){return this._hash===void 0&&(this._hash=`Output ${YB()}`),this._hash}getSource(){return this.refCounts[this._name]++,this._source}isRequired(){return!!this.refCounts[this._name]}setSource(t){this._source=t}}function g_(e){return e.as!==void 0}function B6(e){return`${e}_end`}class ra extends sn{clone(){return new ra(null,_t(this.timeUnits))}constructor(t,n){super(t),this.timeUnits=n}static makeFromEncoding(t,n){const r=n.reduceFieldDef((i,s,o)=>{const{field:a,timeUnit:l}=s;if(l){let u;if(kf(l)){if($n(n)){const{mark:c,markDef:f,config:d}=n,h=mu({fieldDef:s,markDef:f,config:d});(Ig(c)||h)&&(u={timeUnit:mr(l),field:a})}}else u={as:Re(s,{forAs:!0}),field:a,timeUnit:l};if($n(n)){const{mark:c,markDef:f,config:d}=n,h=mu({fieldDef:s,markDef:f,config:d});Ig(c)&&Wn(o)&&h!==.5&&(u.rectBandPosition=h)}u&&(i[Ut(u)]=u)}return i},{});return an(r)?null:new ra(t,r)}static makeFromTransform(t,n){const{timeUnit:r,...i}={...n},s=mr(r),o={...i,timeUnit:s};return new ra(t,{[Ut(o)]:o})}merge(t){this.timeUnits={...this.timeUnits};for(const n in t.timeUnits)this.timeUnits[n]||(this.timeUnits[n]=t.timeUnits[n]);for(const n of t.children)t.removeChild(n),n.parent=this;t.remove()}removeFormulas(t){const n={};for(const[r,i]of pu(this.timeUnits)){const s=g_(i)?i.as:`${i.field}_end`;t.has(s)||(n[r]=i)}this.timeUnits=n}producedFields(){return new Set(Or(this.timeUnits).map(t=>g_(t)?t.as:B6(t.field)))}dependentFields(){return new Set(Or(this.timeUnits).map(t=>t.field))}hash(){return`TimeUnit ${Ut(this.timeUnits)}`}assemble(){const t=[];for(const n of Or(this.timeUnits)){const{rectBandPosition:r}=n,i=mr(n.timeUnit);if(g_(n)){const{field:s,as:o}=n,{unit:a,utc:l,...u}=i,c=[o,`${o}_end`];t.push({field:zs(s),type:"timeunit",...a?{units:Jb(a)}:{},...l?{timezone:"utc"}:{},...u,as:c}),t.push(...z6(c,r,i))}else if(n){const{field:s}=n,o=s.replaceAll("\\.","."),a=Jj({timeUnit:i,field:o}),l=B6(o);t.push({type:"formula",expr:a,as:l}),t.push(...z6([o,l],r,i))}}return t}}const p2="offsetted_rect_start",g2="offsetted_rect_end";function Jj({timeUnit:e,field:t,reverse:n}){const{unit:r,utc:i}=e,s=$z(r),{part:o,step:a}=Tz(s,e.step);return`${i?"utcOffset":"timeOffset"}('${o}', ${en(t)}, ${n?-a:a})`}function z6([e,t],n,r){if(n!==void 0&&n!==.5){const i=en(e),s=en(t);return[{type:"formula",expr:j6([Jj({timeUnit:r,field:e,reverse:!0}),i],n+.5),as:`${e}_${p2}`},{type:"formula",expr:j6([i,s],n+.5),as:`${e}_${g2}`}]}return[]}function j6([e,t],n){return`${1-n} * ${e} + ${n} * ${t}`}const G0="_tuple_fields";class nbe{constructor(...t){this.items=t,this.hasChannel={},this.hasField={},this.hasSelectionId=!1}}const rbe={defined:()=>!0,parse:(e,t,n)=>{const r=t.name,i=t.project??(t.project=new nbe),s={},o={},a=new Set,l=(p,g)=>{const m=g==="visual"?p.channel:p.field;let y=_n(`${r}_${m}`);for(let b=1;a.has(y);b++)y=_n(`${r}_${m}_${b}`);return a.add(y),{[g]:y}},u=t.type,c=e.config.selection[u],f=n.value!==void 0?Be(n.value):null;let{fields:d,encodings:h}=Le(n.select)?n.select:{};if(!d&&!h&&f){for(const p of f)if(Le(p))for(const g of Ee(p))m0e(g)?(h||(h=[])).push(g):u==="interval"?(Se(J0e),h=c.encodings):(d??(d=[])).push(g)}!d&&!h&&(h=c.encodings,"fields"in c&&(d=c.fields));for(const p of h??[]){const g=e.fieldDef(p);if(g){let m=g.field;if(g.aggregate){Se(q0e(p,g.aggregate));continue}else if(!m){Se(f6(p));continue}if(g.timeUnit&&!kf(g.timeUnit)){m=e.vgField(p);const y={timeUnit:g.timeUnit,as:m,field:g.field};o[Ut(y)]=y}if(!s[m]){const y=u==="interval"&&$a(p)&&bo(e.getScaleComponent(p).get("type"))?"R":g.bin?"R-RE":"E",b={field:m,channel:p,type:y,index:i.items.length};b.signals={...l(b,"data"),...l(b,"visual")},i.items.push(s[m]=b),i.hasField[m]=s[m],i.hasSelectionId=i.hasSelectionId||m===wo,QB(p)?(b.geoChannel=p,b.channel=JB(p),i.hasChannel[b.channel]=s[m]):i.hasChannel[p]=s[m]}}else Se(f6(p))}for(const p of d??[]){if(i.hasField[p])continue;const g={type:"E",field:p,index:i.items.length};g.signals={...l(g,"data")},i.items.push(g),i.hasField[p]=g,i.hasSelectionId=i.hasSelectionId||p===wo}f&&(t.init=f.map(p=>i.items.map(g=>Le(p)?p[g.geoChannel||g.channel]!==void 0?p[g.geoChannel||g.channel]:p[g.field]:p))),an(o)||(i.timeUnit=new ra(null,o))},signals:(e,t,n)=>{const r=t.name+G0;return n.filter(s=>s.name===r).length>0||t.project.hasSelectionId?n:n.concat({name:r,value:t.project.items.map(nU)})}},Qj="_curr",F1="anim_value",Xf="anim_clock",gA="eased_anim_clock",eU="min_extent",tU="max_range_extent",m_="last_tick_at",v_="is_playing",ibe=1/60*1e3,sbe=(e,t)=>[{name:gA,update:Xf},{name:`${e}_domain`,init:`domain('${t}')`},{name:eU,init:`extent(${e}_domain)[0]`},{name:tU,init:`extent(range('${t}'))[1]`},{name:F1,update:`invert('${t}', ${gA})`}],obe={defined:e=>e.type==="point",topLevelSignals:(e,t,n)=>(ia(t)&&(n=n.concat([{name:Xf,init:"0",on:[{events:{type:"timer",throttle:ibe},update:`${v_} ? (${Xf} + (now() - ${m_}) > ${tU} ? 0 : ${Xf} + (now() - ${m_})) : ${Xf}`}]},{name:m_,init:"now()",on:[{events:[{signal:Xf},{signal:v_}],update:"now()"}]},{name:v_,init:"true"}])),n),signals:(e,t,n)=>{const r=t.name,i=r+G0,s=t.project,o="(item().isVoronoi ? datum.datum : datum)",a=Or(e.component.selection??{}).reduce((c,f)=>f.type==="interval"?c.concat(f.name+hd):c,[]).map(c=>`indexof(item().mark.name, '${c}') < 0`).join(" && "),l=`datum && item().mark.marktype !== 'group' && indexof(item().mark.role, 'legend') < 0${a?` && ${a}`:""}`;let u=`unit: ${Fc(e)}, `;if(t.project.hasSelectionId)u+=`${wo}: ${o}[${$e(wo)}]`;else if(ia(t))u+=`fields: ${i}, values: [${F1} ? ${F1} : ${eU}]`;else{const c=s.items.map(f=>{const d=e.fieldDef(f.channel);return d!=null&&d.bin?`[${o}[${$e(e.vgField(f.channel,{}))}], ${o}[${$e(e.vgField(f.channel,{binSuffix:"end"}))}]]`:`${o}[${$e(f.field)}]`}).join(", ");u+=`fields: ${i}, values: [${c}]`}if(ia(t))return n.concat(sbe(t.name,e.scaleName(Mu)),[{name:r+pl,on:[{events:[{signal:gA},{signal:F1}],update:`{${u}}`,force:!0}]}]);{const c=t.events;return n.concat([{name:r+pl,on:c?[{events:c,update:`${l} ? {${u}} : null`,force:!0}]:[]}])}}};function nU(e){const{signals:t,hasLegend:n,index:r,...i}=e;return i.field=zs(i.field),i}function of(e,t=!0,n=ni){if(de(e)){const r=e.map(i=>of(i,t,n));return t?`[${r.join(", ")}]`:r}else if(Af(e))return n(t?tf(e):n1e(e));return t?n(ln(e)):e}function abe(e,t){for(const n of Or(e.component.selection??{})){const r=n.name;let i=`${r}${pl}, ${n.resolve==="global"?"true":`{unit: ${Fc(e)}}`}`;for(const s of v2)s.defined(n)&&(s.signals&&(t=s.signals(e,n,t)),s.modifyExpr&&(i=s.modifyExpr(e,n,i)));t.push({name:r+Nbe,on:[{events:{signal:n.name+pl},update:`modify(${$e(n.name+af)}, ${i})`}]})}return rF(t)}function lbe(e,t){if(e.component.selection&&Ee(e.component.selection).length){const n=$e(e.getName("cell"));t.unshift({name:"facet",value:{},on:[{events:Fu("pointermove","scope"),update:`isTuple(facet) ? facet : group(${n}).datum`}]})}return rF(t)}function ube(e,t){let n=!1;for(const r of Or(e.component.selection??{})){const i=r.name,s=$e(i+af);if(t.filter(a=>a.name===i).length===0){const a=r.resolve==="global"?"union":r.resolve,l=r.type==="point"?", true, true)":")";t.push({name:r.name,update:`${bU}(${s}, ${$e(a)}${l}`})}n=!0;for(const a of v2)a.defined(r)&&a.topLevelSignals&&(t=a.topLevelSignals(e,r,t))}return n&&t.filter(i=>i.name==="unit").length===0&&t.unshift({name:"unit",value:{},on:[{events:"pointermove",update:"isTuple(group()) ? group() : unit"}]}),rF(t)}function cbe(e,t){const n=[],r=[],i=Fc(e,{escape:!1});for(const s of Or(e.component.selection??{})){const o={name:s.name+af};if(s.project.hasSelectionId&&(o.transform=[{type:"collect",sort:{field:wo}}]),s.init){const l=s.project.items.map(nU);o.values=s.project.hasSelectionId?s.init.map(u=>({unit:i,[wo]:of(u,!1)[0]})):s.init.map(u=>({unit:i,fields:l,values:of(u,!1)}))}if([...n,...t].filter(l=>l.name===s.name+af).length||n.push(o),ia(s)&&t.length){const l=e.lookupDataSource(e.getDataName(Fn.Main)),u=t.find(f=>f.name===l),c=u.transform.find(f=>f.type==="filter"&&f.expr.includes("vlSelectionTest"));if(c){u.transform=u.transform.filter(d=>d!==c);const f={name:u.name+Qj,source:u.name,transform:[c]};r.push(f)}}}return n.concat(t,r)}function rU(e,t){for(const n of Or(e.component.selection??{}))for(const r of v2)r.defined(n)&&r.marks&&(t=r.marks(e,n,t));return t}function fbe(e,t){for(const n of e.children)$n(n)&&(t=rU(n,t));return t}function dbe(e,t,n,r){const i=DU(e,t.param,t);return{signal:bo(n.get("type"))&&de(r)&&r[0]>r[1]?`isValid(${i}) && reverse(${i})`:i}}function rF(e){return e.map(t=>(t.on&&!t.on.length&&delete t.on,t))}const sl={defined:e=>e.type==="interval"&&e.resolve==="global"&&e.bind&&e.bind==="scales",parse:(e,t)=>{const n=t.scales=[];for(const r of t.project.items){const i=r.channel;if(!$a(i))continue;const s=e.getScaleComponent(i),o=s?s.get("type"):void 0;if(o=="sequential"&&Se(Y0e),!s||!bo(o)){Se(G0e);continue}s.set("selectionExtent",{param:t.name,field:r.field},!0),n.push(r)}},topLevelSignals:(e,t,n)=>{const r=t.scales.filter(o=>n.filter(a=>a.name===o.signals.data).length===0);if(!e.parent||vA(e)||r.length===0)return n;const i=n.find(o=>o.name===t.name);let s=i.update;if(s.includes(bU))i.update=`{${r.map(o=>`${$e(zs(o.field))}: ${o.signals.data}`).join(", ")}}`;else{for(const o of r){const a=`${$e(zs(o.field))}: ${o.signals.data}`;s.includes(a)||(s=`${s.substring(0,s.length-1)}, ${a}}`)}i.update=s}return n.concat(r.map(o=>({name:o.signals.data})))},signals:(e,t,n)=>{if(e.parent&&!vA(e))for(const r of t.scales){const i=n.find(s=>s.name===r.signals.data);i.push="outer",delete i.value,delete i.update}return n}};function mA(e,t){return`domain(${$e(e.scaleName(t))})`}function vA(e){return e.parent&&zh(e.parent)&&(!e.parent.parent||vA(e.parent.parent))}const hd="_brush",iU="_scale_trigger",dp="geo_interval_init_tick",sU="_init",hbe="_center",pbe={defined:e=>e.type==="interval",parse:(e,t,n)=>{var r;if(e.hasProjection){const i={...Le(n.select)?n.select:{}};i.fields=[wo],i.encodings||(i.encodings=n.value?Ee(n.value):[Fo,$o]),n.select={type:"interval",...i}}if(t.translate&&!sl.defined(t)){const i=`!event.item || event.item.mark.name !== ${$e(t.name+hd)}`;for(const s of t.events){if(!s.between){Se(`${s} is not an ordered event stream for interval selections.`);continue}const o=Be((r=s.between[0]).filter??(r.filter=[]));o.includes(i)||o.push(i)}}},signals:(e,t,n)=>{const r=t.name,i=r+pl,s=Or(t.project.hasChannel).filter(a=>a.channel===wn||a.channel===xr),o=t.init?t.init[0]:null;if(n.push(...s.reduce((a,l)=>a.concat(gbe(e,t,l,o&&o[l.index])),[])),e.hasProjection){const a=$e(e.projectionName()),l=e.projectionName()+hbe,{x:u,y:c}=t.project.hasChannel,f=u&&u.signals.visual,d=c&&c.signals.visual,h=u?o&&o[u.index]:`${l}[0]`,p=c?o&&o[c.index]:`${l}[1]`,g=w=>e.getSizeSignalRef(w).signal,m=`[[${f?f+"[0]":"0"}, ${d?d+"[0]":"0"}],[${f?f+"[1]":g("width")}, ${d?d+"[1]":g("height")}]]`;o&&(n.unshift({name:r+sU,init:`[scale(${a}, [${u?h[0]:h}, ${c?p[0]:p}]), scale(${a}, [${u?h[1]:h}, ${c?p[1]:p}])]`}),(!u||!c)&&(n.find(A=>A.name===l)||n.unshift({name:l,update:`invert(${a}, [${g("width")}/2, ${g("height")}/2])`})));const y=`intersect(${m}, {markname: ${$e(e.getName("marks"))}}, unit.mark)`,b=`{unit: ${Fc(e)}}`,x=`vlSelectionTuples(${y}, ${b})`,_=s.map(w=>w.signals.visual);return n.concat({name:i,on:[{events:[..._.length?[{signal:_.join(" || ")}]:[],...o?[{signal:dp}]:[]],update:x}]})}else{if(!sl.defined(t)){const u=r+iU,c=s.map(f=>{const d=f.channel,{data:h,visual:p}=f.signals,g=$e(e.scaleName(d)),m=e.getScaleComponent(d).get("type"),y=bo(m)?"+":"";return`(!isArray(${h}) || (${y}invert(${g}, ${p})[0] === ${y}${h}[0] && ${y}invert(${g}, ${p})[1] === ${y}${h}[1]))`});c.length&&n.push({name:u,value:{},on:[{events:s.map(f=>({scale:e.scaleName(f.channel)})),update:c.join(" && ")+` ? ${u} : {}`}]})}const a=s.map(u=>u.signals.data),l=`unit: ${Fc(e)}, fields: ${r+G0}, values`;return n.concat({name:i,...o?{init:`{${l}: ${of(o)}}`}:{},...a.length?{on:[{events:[{signal:a.join(" || ")}],update:`${a.join(" && ")} ? {${l}: [${a}]} : null`}]}:{}})}},topLevelSignals:(e,t,n)=>($n(e)&&e.hasProjection&&t.init&&(n.filter(i=>i.name===dp).length||n.unshift({name:dp,value:null,on:[{events:"timer{1}",update:`${dp} === null ? {} : ${dp}`}]})),n),marks:(e,t,n)=>{const r=t.name,{x:i,y:s}=t.project.hasChannel,o=i==null?void 0:i.signals.visual,a=s==null?void 0:s.signals.visual,l=`data(${$e(t.name+af)})`;if(sl.defined(t)||!i&&!s)return n;const u={x:i!==void 0?{signal:`${o}[0]`}:{value:0},y:s!==void 0?{signal:`${a}[0]`}:{value:0},x2:i!==void 0?{signal:`${o}[1]`}:{field:{group:"width"}},y2:s!==void 0?{signal:`${a}[1]`}:{field:{group:"height"}}};if(t.resolve==="global")for(const m of Ee(u))u[m]=[{test:`${l}.length && ${l}[0].unit === ${Fc(e)}`,...u[m]},{value:0}];const{fill:c,fillOpacity:f,cursor:d,...h}=t.mark,p=Ee(h).reduce((m,y)=>(m[y]=[{test:[i!==void 0&&`${o}[0] !== ${o}[1]`,s!==void 0&&`${a}[0] !== ${a}[1]`].filter(b=>b).join(" && "),value:h[y]},{value:null}],m),{}),g=d??(t.translate?"move":null);return[{name:`${r+hd}_bg`,type:"rect",clip:!0,encode:{enter:{fill:{value:c},fillOpacity:{value:f}},update:u}},...n,{name:r+hd,type:"rect",clip:!0,encode:{enter:{...g?{cursor:{value:g}}:{},fill:{value:"transparent"}},update:{...u,...p}}}]}};function gbe(e,t,n,r){const i=!e.hasProjection,s=n.channel,o=n.signals.visual,a=$e(i?e.scaleName(s):e.projectionName()),l=d=>`scale(${a}, ${d})`,u=e.getSizeSignalRef(s===wn?"width":"height").signal,c=`${s}(unit)`,f=t.events.reduce((d,h)=>[...d,{events:h.between[0],update:`[${c}, ${c}]`},{events:h,update:`[${o}[0], clamp(${c}, 0, ${u})]`}],[]);if(i){const d=n.signals.data,h=sl.defined(t),p=e.getScaleComponent(s),g=p?p.get("type"):void 0,m=r?{init:of(r,!0,l)}:{value:[]};return f.push({events:{signal:t.name+iU},update:bo(g)?`[${l(`${d}[0]`)}, ${l(`${d}[1]`)}]`:"[0, 0]"}),h?[{name:d,on:[]}]:[{name:o,...m,on:f},{name:d,...r?{init:of(r)}:{},on:[{events:{signal:o},update:`${o}[0] === ${o}[1] ? null : invert(${a}, ${o})`}]}]}else{const d=s===wn?0:1,h=t.name+sU,p=r?{init:`[${h}[0][${d}], ${h}[1][${d}]]`}:{value:[]};return[{name:o,...p,on:f}]}}function Lh({model:e,channelDef:t,vgChannel:n,invalidValueRef:r,mainRefFn:i}){const s=U0(t)&&t.condition;let o=[];s&&(o=Be(s).map(u=>{const c=i(u);if(nve(u)){const{param:f,empty:d}=u;return{test:FU(e,{param:f,empty:d}),...c}}else return{test:py(e,u.test),...c}})),r!==void 0&&o.push(r);const a=i(t);return a!==void 0&&o.push(a),o.length>1||o.length===1&&o[0].test?{[n]:o}:o.length===1?{[n]:o[0]}:{}}function iF(e,t="text"){const n=e.encoding[t];return Lh({model:e,channelDef:n,vgChannel:t,mainRefFn:r=>m2(r,e.config),invalidValueRef:void 0})}function m2(e,t,n="datum"){if(e){if(xo(e))return vn(e.value);if(kt(e)){const{format:r,formatType:i}=ay(e);return P$({fieldOrDatumDef:e,format:r,formatType:i,expr:n,config:t})}}}function oU(e,t={}){const{encoding:n,markDef:r,config:i,stack:s}=e,o=n.tooltip;if(de(o))return{tooltip:U6({tooltip:o},s,i,t)};{const a=t.reactiveGeom?"datum.datum":"datum";return Lh({model:e,channelDef:o,vgChannel:"tooltip",mainRefFn:u=>{const c=m2(u,i,a);if(c)return c;if(u===null)return;let f=on("tooltip",r,i);if(f===!0&&(f={content:"encoding"}),Ie(f))return{value:f};if(Le(f))return nt(f)?f:f.content==="encoding"?U6(n,s,i,t):{signal:a}},invalidValueRef:void 0})}}function aU(e,t,n,{reactiveGeom:r}={}){const i={...n,...n.tooltipFormat},s=new Set,o=r?"datum.datum":"datum",a=[];function l(c,f){const d=_f(f),h=wi(c)?c:{...c,type:e[d].type},p=h.title||U$(h,i),g=Be(p).join(", ").replaceAll(/"/g,'\\"');let m;if(Wn(f)){const y=f==="x"?"x2":"y2",b=_o(e[y]);if(Sr(h.bin)&&b){const x=Re(h,{expr:o}),_=Re(b,{expr:o}),{format:w,formatType:A}=ay(h);m=z0(x,_,w,A,i),s.add(y)}}if((Wn(f)||f===Ws||f===Co)&&t&&t.fieldChannel===f&&t.offset==="normalize"){const{format:y,formatType:b}=ay(h);m=P$({fieldOrDatumDef:h,format:y,formatType:b,expr:o,config:i,normalizeStack:!0}).signal}m??(m=m2(h,i,o).signal),a.push({channel:f,key:g,value:m})}W$(e,(c,f)=>{Ce(c)?l(c,f):o2(c)&&l(c.condition,f)});const u={};for(const{channel:c,key:f,value:d}of a)!s.has(c)&&!u[f]&&(u[f]=d);return u}function U6(e,t,n,{reactiveGeom:r}={}){const i=aU(e,t,n,{reactiveGeom:r}),s=pu(i).map(([o,a])=>`"${o}": ${a}`);return s.length>0?{signal:`{${s.join(", ")}}`}:void 0}function mbe(e){const{markDef:t,config:n}=e,r=on("aria",t,n);return r===!1?{}:{...r?{aria:r}:{},...vbe(e),...ybe(e)}}function vbe(e){const{mark:t,markDef:n,config:r}=e;if(r.aria===!1)return{};const i=on("ariaRoleDescription",n,r);return i!=null?{ariaRoleDescription:{value:i}}:Ue(B0e,t)?{}:{ariaRoleDescription:{value:t}}}function ybe(e){const{encoding:t,markDef:n,config:r,stack:i}=e,s=t.description;if(s)return Lh({model:e,channelDef:s,vgChannel:"description",mainRefFn:l=>m2(l,e.config),invalidValueRef:void 0});const o=on("description",n,r);if(o!=null)return{description:vn(o)};if(r.aria===!1)return{};const a=aU(t,i,r);if(!an(a))return{description:{signal:pu(a).map(([l,u],c)=>`"${c>0?"; ":""}${l}: " + (${u})`).join(" + ")}}}function Dr(e,t,n={}){const{markDef:r,encoding:i,config:s}=t,{vgChannel:o}=n;let{defaultRef:a,defaultValue:l}=n;const u=i[e];a===void 0&&(l??(l=on(e,r,s,{vgChannel:o,ignoreVgConfig:!U0(u)})),l!==void 0&&(a=vn(l)));const c={markDef:r,config:s,scaleName:t.scaleName(e),scale:t.getScaleComponent(e)},f=Vz({...c,scaleChannel:e,channelDef:u});return Lh({model:t,channelDef:u,vgChannel:o??e,invalidValueRef:f,mainRefFn:h=>I$({...c,channel:e,channelDef:h,stack:null,defaultRef:a})})}function lU(e,t={filled:void 0}){const{markDef:n,encoding:r,config:i}=e,{type:s}=n,o=t.filled??on("filled",n,i),a=It(["bar","point","circle","square","geoshape"],s)?"transparent":void 0,l=on(o===!0?"color":void 0,n,i,{vgChannel:"fill"})??i.mark[o===!0&&"color"]??a,u=on(o===!1?"color":void 0,n,i,{vgChannel:"stroke"})??i.mark[o===!1&&"color"],c=o?"fill":"stroke",f={...l?{fill:vn(l)}:{},...u?{stroke:vn(u)}:{}};return n.color&&(o?n.fill:n.stroke)&&Se(bz("property",{fill:"fill"in n,stroke:"stroke"in n})),{...f,...Dr("color",e,{vgChannel:c,defaultValue:o?l:u}),...Dr("fill",e,{defaultValue:r.fill?l:void 0}),...Dr("stroke",e,{defaultValue:r.stroke?u:void 0})}}function bbe(e){const{encoding:t,mark:n}=e,r=t.order;return!Iu(n)&&xo(r)?Lh({model:e,channelDef:r,vgChannel:"zindex",mainRefFn:i=>vn(i.value),invalidValueRef:void 0}):{}}function oh({channel:e,markDef:t,encoding:n={},model:r,bandPosition:i}){const s=`${e}Offset`,o=t[s],a=n[s];if((s==="xOffset"||s==="yOffset")&&a)return{offsetType:"encoding",offset:I$({channel:s,channelDef:a,markDef:t,config:r==null?void 0:r.config,scaleName:r.scaleName(s),scale:r.getScaleComponent(s),stack:null,defaultRef:vn(o),bandPosition:i})};const l=t[s];return l?{offsetType:"visual",offset:l}:{}}function vi(e,t,{defaultPos:n,vgChannel:r}){const{encoding:i,markDef:s,config:o,stack:a}=t,l=i[e],u=i[Ca(e)],c=t.scaleName(e),f=t.getScaleComponent(e),{offset:d,offsetType:h}=oh({channel:e,markDef:s,encoding:i,model:t,bandPosition:.5}),p=sF({model:t,defaultPos:n,channel:e,scaleName:c,scale:f}),g=!l&&Wn(e)&&(i.latitude||i.longitude)?{field:t.getName(e)}:xbe({channel:e,channelDef:l,channel2Def:u,markDef:s,config:o,scaleName:c,scale:f,stack:a,offset:d,defaultRef:p,bandPosition:h==="encoding"?0:void 0});return g?{[r||e]:g}:void 0}function xbe(e){const{channel:t,channelDef:n,scaleName:r,stack:i,offset:s,markDef:o}=e;if(kt(n)&&i&&t===i.fieldChannel){if(Ce(n)){let a=n.bandPosition;if(a===void 0&&o.type==="text"&&(t==="radius"||t==="theta")&&(a=.5),a!==void 0)return iy({scaleName:r,fieldOrDatumDef:n,startSuffix:"start",bandPosition:a,offset:s})}return Cc(n,r,{suffix:"end"},{offset:s})}return L$(e)}function sF({model:e,defaultPos:t,channel:n,scaleName:r,scale:i}){const{markDef:s,config:o}=e;return()=>{const a=_f(n),l=gu(n),u=on(n,s,o,{vgChannel:l});if(u!==void 0)return og(n,u);switch(t){case"zeroOrMin":return q6({scaleName:r,scale:i,mode:"zeroOrMin",mainChannel:a,config:o});case"zeroOrMax":return q6({scaleName:r,scale:i,mode:{zeroOrMax:{widthSignal:e.width.signal,heightSignal:e.height.signal}},mainChannel:a,config:o});case"mid":return{...e[Gi(n)],mult:.5}}}}function q6({mainChannel:e,config:t,...n}){const r=Yz(n),{mode:i}=n;if(r)return r;switch(e){case"radius":{if(i==="zeroOrMin")return{value:0};const{widthSignal:s,heightSignal:o}=i.zeroOrMax;return{signal:`min(${s},${o})/2`}}case"theta":return i==="zeroOrMin"?{value:0}:{signal:"2*PI"};case"x":return i==="zeroOrMin"?{value:0}:{field:{group:"width"}};case"y":return i==="zeroOrMin"?{field:{group:"height"}}:{value:0}}}const _be={left:"x",center:"xc",right:"x2"},wbe={top:"y",middle:"yc",bottom:"y2"};function uU(e,t,n,r="middle"){if(e==="radius"||e==="theta")return gu(e);const i=e==="x"?"align":"baseline",s=on(i,t,n);let o;return nt(s)?(Se(xme(i)),o=void 0):o=s,e==="x"?_be[o||(r==="top"?"left":"center")]:wbe[o||r]}function fy(e,t,{defaultPos:n,defaultPos2:r,range:i}){return i?cU(e,t,{defaultPos:n,defaultPos2:r}):vi(e,t,{defaultPos:n})}function cU(e,t,{defaultPos:n,defaultPos2:r}){const{markDef:i,config:s}=t,o=Ca(e),a=Gi(e),l=Ebe(t,r,o),u=l[a]?uU(e,i,s):gu(e);return{...vi(e,t,{defaultPos:n,vgChannel:u}),...l}}function Ebe(e,t,n){const{encoding:r,mark:i,markDef:s,stack:o,config:a}=e,l=_f(n),u=Gi(n),c=gu(n),f=r[l],d=e.scaleName(l),h=e.getScaleComponent(l),{offset:p}=n in r||n in s?oh({channel:n,markDef:s,encoding:r,model:e}):oh({channel:l,markDef:s,encoding:r,model:e});if(!f&&(n==="x2"||n==="y2")&&(r.latitude||r.longitude)){const m=Gi(n),y=e.markDef[m];return y!=null?{[m]:{value:y}}:{[c]:{field:e.getName(n)}}}const g=Abe({channel:n,channelDef:f,channel2Def:r[n],markDef:s,config:a,scaleName:d,scale:h,stack:o,offset:p,defaultRef:void 0});return g!==void 0?{[c]:g}:Nm(n,s)||Nm(n,{[n]:iA(n,s,a.style),[u]:iA(u,s,a.style)})||Nm(n,a[i])||Nm(n,a.mark)||{[c]:sF({model:e,defaultPos:t,channel:n,scaleName:d,scale:h})()}}function Abe({channel:e,channelDef:t,channel2Def:n,markDef:r,config:i,scaleName:s,scale:o,stack:a,offset:l,defaultRef:u}){return kt(t)&&a&&e.charAt(0)===a.fieldChannel.charAt(0)?Cc(t,s,{suffix:"start"},{offset:l}):L$({channel:e,channelDef:n,scaleName:s,scale:o,stack:a,markDef:r,config:i,offset:l,defaultRef:u})}function Nm(e,t){const n=Gi(e),r=gu(e);if(t[r]!==void 0)return{[r]:og(e,t[r])};if(t[e]!==void 0)return{[r]:og(e,t[e])};if(t[n]){const i=t[n];if(rf(i))Se(pme(n));else return{[n]:og(e,i)}}}function hl(e,t){const{config:n,encoding:r,markDef:i}=e,s=i.type,o=Ca(t),a=Gi(t),l=r[t],u=r[o],c=e.getScaleComponent(t),f=c?c.get("type"):void 0,d=i.orient,h=r[a]??r.size??on("size",i,n,{vgChannel:a}),p=rz(t),g=s==="bar"&&(t==="x"?d==="vertical":d==="horizontal")||s==="tick"&&(t==="y"?d==="vertical":d==="horizontal");return Ce(l)&&(dn(l.bin)||Sr(l.bin)||l.timeUnit&&!u)&&!(h&&!rf(h))&&!r[p]&&!yr(f)?Cbe({fieldDef:l,fieldDef2:u,channel:t,model:e}):(kt(l)&&yr(f)||g)&&!u?Sbe(l,t,e):cU(t,e,{defaultPos:"zeroOrMax",defaultPos2:"zeroOrMin"})}function kbe(e,t,n,r,i,s,o){if(rf(i))if(n){const l=n.get("type");if(l==="band"){let u=`bandwidth('${t}')`;i.band!==1&&(u=`${i.band} * ${u}`);const c=ha("minBandSize",{type:o},r);return{signal:c?`max(${uo(c)}, ${u})`:u}}else i.band!==1&&(Se(Ame(l)),i=void 0)}else return{mult:i.band,field:{group:e}};else{if(nt(i))return i;if(i)return{value:i}}if(n){const l=n.get("range");if(Ef(l)&&Vt(l.step))return{value:l.step-2}}if(!s){const{bandPaddingInner:l,barBandPaddingInner:u,rectBandPaddingInner:c,tickBandPaddingInner:f}=r.scale,d=qn(l,o==="tick"?f:o==="bar"?u:c);if(nt(d))return{signal:`(1 - (${d.signal})) * ${e}`};if(Vt(d))return{signal:`${1-d} * ${e}`}}return{value:fA(r.view,e)-2}}function Sbe(e,t,n){var S,$;const{markDef:r,encoding:i,config:s,stack:o}=n,a=r.orient,l=n.scaleName(t),u=n.getScaleComponent(t),c=Gi(t),f=Ca(t),d=rz(t),h=n.scaleName(d),p=n.getScaleComponent(u$(t)),g=r.type==="tick"||a==="horizontal"&&t==="y"||a==="vertical"&&t==="x";let m;(i.size||r.size)&&(g?m=Dr("size",n,{vgChannel:c,defaultRef:vn(r.size)}):Se($me(r.type)));const y=!!m,b=tj({channel:t,fieldDef:e,markDef:r,config:s,scaleType:(S=u||p)==null?void 0:S.get("type"),useVlSizeChannel:g});m=m||{[c]:kbe(c,h||l,p||u,s,b,!!e,r.type)};const x=(($=u||p)==null?void 0:$.get("type"))==="band"&&rf(b)&&!y?"top":"middle",_=uU(t,r,s,x),w=_==="xc"||_==="yc",{offset:A,offsetType:E}=oh({channel:t,markDef:r,encoding:i,model:n,bandPosition:w?.5:0}),k=L$({channel:t,channelDef:e,markDef:r,config:s,scaleName:l,scale:u,stack:o,offset:A,defaultRef:sF({model:n,defaultPos:"mid",channel:t,scaleName:l,scale:u}),bandPosition:w?E==="encoding"?0:.5:nt(b)?{signal:`(1-${b})/2`}:rf(b)?(1-b.band)/2:0});if(c)return{[_]:k,...m};{const M=gu(f),O=m[c],P=A?{...O,offset:A}:O;return{[_]:k,[M]:de(k)?[k[0],{...k[1],offset:P}]:{...k,offset:P}}}}function W6(e,t,n,r,i,s,o){if(ZB(e))return 0;const a=e==="x"||e==="y2",l=a?-t/2:t/2;if(nt(n)||nt(i)||nt(r)||s){const u=uo(n),c=uo(i),f=uo(r),d=uo(s),p=s?`(${o} < ${d} ? ${a?"":"-"}0.5 * (${d} - (${o})) : ${l})`:l,g=f?`${f} + `:"",m=u?`(${u} ? -1 : 1) * `:"",y=c?`(${c} + ${p})`:p;return{signal:g+m+y}}else return i=i||0,r+(n?-i-l:+i+l)}function Cbe({fieldDef:e,fieldDef2:t,channel:n,model:r}){var $;const{config:i,markDef:s,encoding:o}=r,a=r.getScaleComponent(n),l=r.scaleName(n),u=a?a.get("type"):void 0,c=a.get("reverse"),f=tj({channel:n,fieldDef:e,markDef:s,config:i,scaleType:u}),d=($=r.component.axes[n])==null?void 0:$[0],h=(d==null?void 0:d.get("translate"))??.5,p=Wn(n)?on("binSpacing",s,i)??0:0,g=Ca(n),m=gu(n),y=gu(g),b=ha("minBandSize",s,i),{offset:x}=oh({channel:n,markDef:s,encoding:o,model:r,bandPosition:0}),{offset:_}=oh({channel:g,markDef:s,encoding:o,model:r,bandPosition:0}),w=K1e({fieldDef:e,scaleName:l}),A=W6(n,p,c,h,x,b,w),E=W6(g,p,c,h,_??x,b,w),k=nt(f)?{signal:`(1-${f.signal})/2`}:rf(f)?(1-f.band)/2:.5,S=mu({fieldDef:e,fieldDef2:t,markDef:s,config:i});if(dn(e.bin)||e.timeUnit){const M=e.timeUnit&&S!==.5;return{[y]:H6({fieldDef:e,scaleName:l,bandPosition:k,offset:E,useRectOffsetField:M}),[m]:H6({fieldDef:e,scaleName:l,bandPosition:nt(k)?{signal:`1-${k.signal}`}:1-k,offset:A,useRectOffsetField:M})}}else if(Sr(e.bin)){const M=Cc(e,l,{},{offset:E});if(Ce(t))return{[y]:M,[m]:Cc(t,l,{},{offset:A})};if(wf(e.bin)&&e.bin.step)return{[y]:M,[m]:{signal:`scale("${l}", ${Re(e,{expr:"datum"})} + ${e.bin.step})`,offset:A}}}Se(wz(g))}function H6({fieldDef:e,scaleName:t,bandPosition:n,offset:r,useRectOffsetField:i}){return iy({scaleName:t,fieldOrDatumDef:e,bandPosition:n,offset:r,...i?{startSuffix:p2,endSuffix:g2}:{}})}const $be=new Set(["aria","width","height"]);function Hs(e,t){const{fill:n=void 0,stroke:r=void 0}=t.color==="include"?lU(e):{};return{...Fbe(e.markDef,t),...G6("fill",n),...G6("stroke",r),...Dr("opacity",e),...Dr("fillOpacity",e),...Dr("strokeOpacity",e),...Dr("strokeWidth",e),...Dr("strokeDash",e),...bbe(e),...oU(e),...iF(e,"href"),...mbe(e)}}function G6(e,t){return t?{[e]:t}:{}}function Fbe(e,t){return P0e.reduce((n,r)=>(!$be.has(r)&&Ae(e,r)&&t[r]!=="ignore"&&(n[r]=vn(e[r])),n),{})}function oF(e){const{config:t,markDef:n}=e,r=new Set;if(e.forEachFieldDef((i,s)=>{var u;let o;if(!$a(s)||!(o=e.getScaleType(s)))return;const a=Xb(i.aggregate),l=O$({scaleChannel:s,markDef:n,config:t,scaleType:o,isCountAggregate:a});if(Y1e(l)){const c=e.vgField(s,{expr:"datum",binSuffix:(u=e.stack)!=null&&u.impute?"mid":void 0});c&&r.add(c)}}),r.size>0)return{defined:{signal:[...r].map(s=>Qb(s,!0)).join(" && ")}}}function Y6(e,t){if(t!==void 0)return{[e]:vn(t)}}const y_="voronoi",fU={defined:e=>e.type==="point"&&e.nearest,parse:(e,t)=>{if(t.events)for(const n of t.events)n.markname=e.getName(y_)},marks:(e,t,n)=>{const{x:r,y:i}=t.project.hasChannel,s=e.mark;if(Iu(s))return Se(W0e(s)),n;const o={name:e.getName(y_),type:"path",interactive:!0,from:{data:e.getName("marks")},encode:{update:{fill:{value:"transparent"},strokeWidth:{value:.35},stroke:{value:"transparent"},isVoronoi:{value:!0},...oU(e,{reactiveGeom:!0})}},transform:[{type:"voronoi",x:{expr:r||!i?"datum.datum.x || 0":"0"},y:{expr:i||!r?"datum.datum.y || 0":"0"},size:[e.getSizeSignalRef("width"),e.getSizeSignalRef("height")]}]};let a=0,l=!1;return n.forEach((u,c)=>{const f=u.name??"";f===e.component.mark[0].name?a=c:f.includes(y_)&&(l=!0)}),l||n.splice(a+1,0,o),n}},dU={defined:e=>e.type==="point"&&e.resolve==="global"&&e.bind&&e.bind!=="scales"&&!K$(e.bind),parse:(e,t,n)=>xU(t,n),topLevelSignals:(e,t,n)=>{const r=t.name,i=t.project,s=t.bind,o=t.init&&t.init[0],a=fU.defined(t)?"(item().isVoronoi ? datum.datum : datum)":"datum";return i.items.forEach((l,u)=>{const c=_n(`${r}_${l.field}`);n.filter(d=>d.name===c).length||n.unshift({name:c,...o?{init:of(o[u])}:{value:null},on:t.events?[{events:t.events,update:`datum && item().mark.marktype !== 'group' ? ${a}[${$e(l.field)}] : null`}]:[],bind:s[l.field]??s[l.channel]??s})}),n},signals:(e,t,n)=>{const r=t.name,i=t.project,s=n.find(u=>u.name===r+pl),o=r+G0,a=i.items.map(u=>_n(`${r}_${u.field}`)),l=a.map(u=>`${u} !== null`).join(" && ");return a.length&&(s.update=`${l} ? {fields: ${o}, values: [${a.join(", ")}]} : null`),delete s.value,delete s.on,n}},dy="_toggle",hU={defined:e=>e.type==="point"&&!ia(e)&&!!e.toggle,signals:(e,t,n)=>n.concat({name:t.name+dy,value:!1,on:[{events:t.events,update:t.toggle}]}),modifyExpr:(e,t)=>{const n=t.name+pl,r=t.name+dy;return`${r} ? null : ${n}, `+(t.resolve==="global"?`${r} ? null : true, `:`${r} ? null : {unit: ${Fc(e)}}, `)+`${r} ? ${n} : null`}},Dbe={defined:e=>e.clear!==void 0&&e.clear!==!1&&!ia(e),parse:(e,t)=>{t.clear&&(t.clear=Ie(t.clear)?Fu(t.clear,"view"):t.clear)},topLevelSignals:(e,t,n)=>{if(dU.defined(t))for(const r of t.project.items){const i=n.findIndex(s=>s.name===_n(`${t.name}_${r.field}`));i!==-1&&n[i].on.push({events:t.clear,update:"null"})}return n},signals:(e,t,n)=>{function r(i,s){i!==-1&&n[i].on&&n[i].on.push({events:t.clear,update:s})}if(t.type==="interval")for(const i of t.project.items){const s=n.findIndex(o=>o.name===i.signals.visual);if(r(s,"[0, 0]"),s===-1){const o=n.findIndex(a=>a.name===i.signals.data);r(o,"null")}}else{let i=n.findIndex(s=>s.name===t.name+pl);r(i,"null"),hU.defined(t)&&(i=n.findIndex(s=>s.name===t.name+dy),r(i,"false"))}return n}},pU={defined:e=>{const t=e.resolve==="global"&&e.bind&&K$(e.bind),n=e.project.items.length===1&&e.project.items[0].field!==wo;return t&&!n&&Se(V0e),t&&n},parse:(e,t,n)=>{const r=_t(n);if(r.select=Ie(r.select)?{type:r.select,toggle:t.toggle}:{...r.select,toggle:t.toggle},xU(t,r),Le(n.select)&&(n.select.on||n.select.clear)){const o='event.item && indexof(event.item.mark.role, "legend") < 0';for(const a of t.events)a.filter=Be(a.filter??[]),a.filter.includes(o)||a.filter.push(o)}const i=d_(t.bind)?t.bind.legend:"click",s=Ie(i)?Fu(i,"view"):Be(i);t.bind={legend:{merge:s}}},topLevelSignals:(e,t,n)=>{const r=t.name,i=d_(t.bind)&&t.bind.legend,s=o=>a=>{const l=_t(a);return l.markname=o,l};for(const o of t.project.items){if(!o.hasLegend)continue;const a=`${_n(o.field)}_legend`,l=`${r}_${a}`;if(n.filter(c=>c.name===l).length===0){const c=i.merge.map(s(`${a}_symbols`)).concat(i.merge.map(s(`${a}_labels`))).concat(i.merge.map(s(`${a}_entries`)));n.unshift({name:l,...t.init?{}:{value:null},on:[{events:c,update:"isDefined(datum.value) ? datum.value : item().items[0].items[0].datum.value",force:!0},{events:i.merge,update:`!event.item || !datum ? null : ${l}`,force:!0}]})}}return n},signals:(e,t,n)=>{const r=t.name,i=t.project,s=n.find(d=>d.name===r+pl),o=r+G0,a=i.items.filter(d=>d.hasLegend).map(d=>_n(`${r}_${_n(d.field)}_legend`)),u=`${a.map(d=>`${d} !== null`).join(" && ")} ? {fields: ${o}, values: [${a.join(", ")}]} : null`;t.events&&a.length>0?s.on.push({events:a.map(d=>({signal:d})),update:u}):a.length>0&&(s.update=u,delete s.value,delete s.on);const c=n.find(d=>d.name===r+dy),f=d_(t.bind)&&t.bind.legend;return c&&(t.events?c.on.push({...c.on[0],events:f}):c.on[0].events=f),n}};function Mbe(e,t,n){var i;const r=(i=e.fieldDef(t))==null?void 0:i.field;for(const s of Or(e.component.selection??{})){const o=s.project.hasField[r]??s.project.hasChannel[t];if(o&&pU.defined(s)){const a=n.get("selections")??[];a.push(s.name),n.set("selections",a,!1),o.hasLegend=!0}}}const gU="_translate_anchor",mU="_translate_delta",Tbe={defined:e=>e.type==="interval"&&e.translate,signals:(e,t,n)=>{const r=t.name,i=sl.defined(t),s=r+gU,{x:o,y:a}=t.project.hasChannel;let l=Fu(t.translate,"scope");return i||(l=l.map(u=>(u.between[0].markname=r+hd,u))),n.push({name:s,value:{},on:[{events:l.map(u=>u.between[0]),update:"{x: x(unit), y: y(unit)"+(o!==void 0?`, extent_x: ${i?mA(e,wn):`slice(${o.signals.visual})`}`:"")+(a!==void 0?`, extent_y: ${i?mA(e,xr):`slice(${a.signals.visual})`}`:"")+"}"}]},{name:r+mU,value:{},on:[{events:l,update:`{x: ${s}.x - x(unit), y: ${s}.y - y(unit)}`}]}),o!==void 0&&V6(e,t,o,"width",n),a!==void 0&&V6(e,t,a,"height",n),n}};function V6(e,t,n,r,i){const s=t.name,o=s+gU,a=s+mU,l=n.channel,u=sl.defined(t),c=i.find(w=>w.name===n.signals[u?"data":"visual"]),f=e.getSizeSignalRef(r).signal,d=e.getScaleComponent(l),h=d&&d.get("type"),p=d&&d.get("reverse"),g=u?l===wn?p?"":"-":p?"-":"":"",m=`${o}.extent_${l}`,y=`${g}${a}.${l} / ${u?`${f}`:`span(${m})`}`,b=!u||!d?"panLinear":h==="log"?"panLog":h==="symlog"?"panSymlog":h==="pow"?"panPow":"panLinear",x=u?h==="pow"?`, ${d.get("exponent")??1}`:h==="symlog"?`, ${d.get("constant")??1}`:"":"",_=`${b}(${m}, ${y}${x})`;c.on.push({events:{signal:a},update:u?_:`clampRange(${_}, 0, ${f})`})}const vU="_zoom_anchor",yU="_zoom_delta",Rbe={defined:e=>e.type==="interval"&&e.zoom,signals:(e,t,n)=>{const r=t.name,i=sl.defined(t),s=r+yU,{x:o,y:a}=t.project.hasChannel,l=$e(e.scaleName(wn)),u=$e(e.scaleName(xr));let c=Fu(t.zoom,"scope");return i||(c=c.map(f=>(f.markname=r+hd,f))),n.push({name:r+vU,on:[{events:c,update:i?"{"+[l?`x: invert(${l}, x(unit))`:"",u?`y: invert(${u}, y(unit))`:""].filter(f=>f).join(", ")+"}":"{x: x(unit), y: y(unit)}"}]},{name:s,on:[{events:c,force:!0,update:"pow(1.001, event.deltaY * pow(16, event.deltaMode))"}]}),o!==void 0&&X6(e,t,o,"width",n),a!==void 0&&X6(e,t,a,"height",n),n}};function X6(e,t,n,r,i){const s=t.name,o=n.channel,a=sl.defined(t),l=i.find(b=>b.name===n.signals[a?"data":"visual"]),u=e.getSizeSignalRef(r).signal,c=e.getScaleComponent(o),f=c&&c.get("type"),d=a?mA(e,o):l.name,h=s+yU,p=`${s}${vU}.${o}`,g=!a||!c?"zoomLinear":f==="log"?"zoomLog":f==="symlog"?"zoomSymlog":f==="pow"?"zoomPow":"zoomLinear",m=a?f==="pow"?`, ${c.get("exponent")??1}`:f==="symlog"?`, ${c.get("constant")??1}`:"":"",y=`${g}(${d}, ${p}, ${h}${m})`;l.on.push({events:{signal:h},update:a?y:`clampRange(${y}, 0, ${u})`})}const af="_store",pl="_tuple",Nbe="_modify",bU="vlSelectionResolve",v2=[obe,pbe,rbe,hU,dU,sl,pU,Dbe,Tbe,Rbe,fU];function Obe(e){let t=e.parent;for(;t&&!fs(t);)t=t.parent;return t}function Fc(e,{escape:t}={escape:!0}){let n=t?$e(e.name):e.name;const r=Obe(e);if(r){const{facet:i}=r;for(const s of Fs)i[s]&&(n+=` + '__facet_${s}_' + (facet[${$e(r.vgField(s))}])`)}return n}function aF(e){return Or(e.component.selection??{}).reduce((t,n)=>t||n.project.hasSelectionId,!1)}function xU(e,t){(Ie(t.select)||!t.select.on)&&delete e.events,(Ie(t.select)||!t.select.clear)&&delete e.clear,(Ie(t.select)||!t.select.toggle)&&delete e.toggle}function ia(e){var t;return(t=e.events)==null?void 0:t.find(n=>"type"in n&&n.type==="timer")}const Lbe="RawCode",Ibe="Literal",Pbe="Property",Bbe="Identifier",zbe="ArrayExpression",jbe="BinaryExpression",Ube="CallExpression",qbe="ConditionalExpression",Wbe="LogicalExpression",Hbe="MemberExpression",Gbe="ObjectExpression",Ybe="UnaryExpression";function Mo(e){this.type=e}Mo.prototype.visit=function(e){let t,n,r;if(e(this))return 1;for(t=Vbe(this),n=0,r=t.length;n";Da[lf]="Identifier";Da[Pu]="Keyword";Da[b2]="Null";Da[Cf]="Numeric";Da[Ti]="Punctuator";Da[V0]="String";Da[Xbe]="RegularExpression";var Kbe="ArrayExpression",Zbe="BinaryExpression",Jbe="CallExpression",Qbe="ConditionalExpression",_U="Identifier",e2e="Literal",t2e="LogicalExpression",n2e="MemberExpression",r2e="ObjectExpression",i2e="Property",s2e="UnaryExpression",gr="Unexpected token %0",o2e="Unexpected number",a2e="Unexpected string",l2e="Unexpected identifier",u2e="Unexpected reserved word",c2e="Unexpected end of input",yA="Invalid regular expression",b_="Invalid regular expression: missing /",wU="Octal literals are not allowed in strict mode.",f2e="Duplicate data property in object literal not allowed in strict mode",Rr="ILLEGAL",Bg="Disabled.",d2e=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B2\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6EF\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),h2e=new RegExp("[\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0300-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u0483-\\u0487\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0610-\\u061A\\u0620-\\u0669\\u066E-\\u06D3\\u06D5-\\u06DC\\u06DF-\\u06E8\\u06EA-\\u06FC\\u06FF\\u0710-\\u074A\\u074D-\\u07B1\\u07C0-\\u07F5\\u07FA\\u0800-\\u082D\\u0840-\\u085B\\u08A0-\\u08B2\\u08E4-\\u0963\\u0966-\\u096F\\u0971-\\u0983\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BC-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CE\\u09D7\\u09DC\\u09DD\\u09DF-\\u09E3\\u09E6-\\u09F1\\u0A01-\\u0A03\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A59-\\u0A5C\\u0A5E\\u0A66-\\u0A75\\u0A81-\\u0A83\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABC-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AD0\\u0AE0-\\u0AE3\\u0AE6-\\u0AEF\\u0B01-\\u0B03\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3C-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B5C\\u0B5D\\u0B5F-\\u0B63\\u0B66-\\u0B6F\\u0B71\\u0B82\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD0\\u0BD7\\u0BE6-\\u0BEF\\u0C00-\\u0C03\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C58\\u0C59\\u0C60-\\u0C63\\u0C66-\\u0C6F\\u0C81-\\u0C83\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBC-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CDE\\u0CE0-\\u0CE3\\u0CE6-\\u0CEF\\u0CF1\\u0CF2\\u0D01-\\u0D03\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4E\\u0D57\\u0D60-\\u0D63\\u0D66-\\u0D6F\\u0D7A-\\u0D7F\\u0D82\\u0D83\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DE6-\\u0DEF\\u0DF2\\u0DF3\\u0E01-\\u0E3A\\u0E40-\\u0E4E\\u0E50-\\u0E59\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB9\\u0EBB-\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EC8-\\u0ECD\\u0ED0-\\u0ED9\\u0EDC-\\u0EDF\\u0F00\\u0F18\\u0F19\\u0F20-\\u0F29\\u0F35\\u0F37\\u0F39\\u0F3E-\\u0F47\\u0F49-\\u0F6C\\u0F71-\\u0F84\\u0F86-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u1000-\\u1049\\u1050-\\u109D\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u135D-\\u135F\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16EE-\\u16F8\\u1700-\\u170C\\u170E-\\u1714\\u1720-\\u1734\\u1740-\\u1753\\u1760-\\u176C\\u176E-\\u1770\\u1772\\u1773\\u1780-\\u17D3\\u17D7\\u17DC\\u17DD\\u17E0-\\u17E9\\u180B-\\u180D\\u1810-\\u1819\\u1820-\\u1877\\u1880-\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1920-\\u192B\\u1930-\\u193B\\u1946-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u19D0-\\u19D9\\u1A00-\\u1A1B\\u1A20-\\u1A5E\\u1A60-\\u1A7C\\u1A7F-\\u1A89\\u1A90-\\u1A99\\u1AA7\\u1AB0-\\u1ABD\\u1B00-\\u1B4B\\u1B50-\\u1B59\\u1B6B-\\u1B73\\u1B80-\\u1BF3\\u1C00-\\u1C37\\u1C40-\\u1C49\\u1C4D-\\u1C7D\\u1CD0-\\u1CD2\\u1CD4-\\u1CF6\\u1CF8\\u1CF9\\u1D00-\\u1DF5\\u1DFC-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u200C\\u200D\\u203F\\u2040\\u2054\\u2071\\u207F\\u2090-\\u209C\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2160-\\u2188\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D7F-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2DE0-\\u2DFF\\u2E2F\\u3005-\\u3007\\u3021-\\u302F\\u3031-\\u3035\\u3038-\\u303C\\u3041-\\u3096\\u3099\\u309A\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA62B\\uA640-\\uA66F\\uA674-\\uA67D\\uA67F-\\uA69D\\uA69F-\\uA6F1\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA78E\\uA790-\\uA7AD\\uA7B0\\uA7B1\\uA7F7-\\uA827\\uA840-\\uA873\\uA880-\\uA8C4\\uA8D0-\\uA8D9\\uA8E0-\\uA8F7\\uA8FB\\uA900-\\uA92D\\uA930-\\uA953\\uA960-\\uA97C\\uA980-\\uA9C0\\uA9CF-\\uA9D9\\uA9E0-\\uA9FE\\uAA00-\\uAA36\\uAA40-\\uAA4D\\uAA50-\\uAA59\\uAA60-\\uAA76\\uAA7A-\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEF\\uAAF2-\\uAAF6\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB5F\\uAB64\\uAB65\\uABC0-\\uABEA\\uABEC\\uABED\\uABF0-\\uABF9\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE00-\\uFE0F\\uFE20-\\uFE2D\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF10-\\uFF19\\uFF21-\\uFF3A\\uFF3F\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]");function x2(e,t){if(!e)throw new Error("ASSERT: "+t)}function za(e){return e>=48&&e<=57}function lF(e){return"0123456789abcdefABCDEF".includes(e)}function ag(e){return"01234567".includes(e)}function p2e(e){return e===32||e===9||e===11||e===12||e===160||e>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].includes(e)}function zg(e){return e===10||e===13||e===8232||e===8233}function X0(e){return e===36||e===95||e>=65&&e<=90||e>=97&&e<=122||e===92||e>=128&&d2e.test(String.fromCharCode(e))}function hy(e){return e===36||e===95||e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57||e===92||e>=128&&h2e.test(String.fromCharCode(e))}const g2e={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function EU(){for(;ce1114111||e!=="}")&&Yt({},gr,Rr),t<=65535?String.fromCharCode(t):(n=(t-65536>>10)+55296,r=(t-65536&1023)+56320,String.fromCharCode(n,r))}function AU(){var e,t;for(e=tt.charCodeAt(ce++),t=String.fromCharCode(e),e===92&&(tt.charCodeAt(ce)!==117&&Yt({},gr,Rr),++ce,e=bA("u"),(!e||e==="\\"||!X0(e.charCodeAt(0)))&&Yt({},gr,Rr),t=e);ce>>=")return ce+=4,{type:Ti,value:o,start:e,end:ce};if(s=o.substr(0,3),s===">>>"||s==="<<="||s===">>=")return ce+=3,{type:Ti,value:s,start:e,end:ce};if(i=s.substr(0,2),r===i[1]&&"+-<>&|".includes(r)||i==="=>")return ce+=2,{type:Ti,value:i,start:e,end:ce};if(i==="//"&&Yt({},gr,Rr),"<>=!+-*%&|^/".includes(r))return++ce,{type:Ti,value:r,start:e,end:ce};Yt({},gr,Rr)}function b2e(e){let t="";for(;ce{if(parseInt(i,16)<=1114111)return"x";Yt({},yA)}).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"));try{new RegExp(n)}catch{Yt({},yA)}try{return new RegExp(e,t)}catch{return null}}function E2e(){var e,t,n,r,i;for(e=tt[ce],x2(e==="/","Regular expression literal must start with a slash"),t=tt[ce++],n=!1,r=!1;ce=0&&Yt({},yA,n),{value:n,literal:t}}function k2e(){var e,t,n,r;return rn=null,EU(),e=ce,t=E2e(),n=A2e(),r=w2e(t.value,n.value),{literal:t.literal+n.literal,value:r,regex:{pattern:t.value,flags:n.value},start:e,end:ce}}function S2e(e){return e.type===lf||e.type===Pu||e.type===y2||e.type===b2}function kU(){if(EU(),ce>=ei)return{type:Y0,start:ce,end:ce};const e=tt.charCodeAt(ce);return X0(e)?y2e():e===40||e===41||e===59?x_():e===39||e===34?_2e():e===46?za(tt.charCodeAt(ce+1))?K6():x_():za(e)?K6():x_()}function Li(){const e=rn;return ce=e.end,rn=kU(),ce=e.end,e}function SU(){const e=ce;rn=kU(),ce=e}function C2e(e){const t=new Mo(Kbe);return t.elements=e,t}function Z6(e,t,n){const r=new Mo(e==="||"||e==="&&"?t2e:Zbe);return r.operator=e,r.left=t,r.right=n,r}function $2e(e,t){const n=new Mo(Jbe);return n.callee=e,n.arguments=t,n}function F2e(e,t,n){const r=new Mo(Qbe);return r.test=e,r.consequent=t,r.alternate=n,r}function uF(e){const t=new Mo(_U);return t.name=e,t}function Bp(e){const t=new Mo(e2e);return t.value=e.value,t.raw=tt.slice(e.start,e.end),e.regex&&(t.raw==="//"&&(t.raw="/(?:)/"),t.regex=e.regex),t}function J6(e,t,n){const r=new Mo(n2e);return r.computed=e==="[",r.object=t,r.property=n,r.computed||(n.member=!0),r}function D2e(e){const t=new Mo(r2e);return t.properties=e,t}function Q6(e,t,n){const r=new Mo(i2e);return r.key=t,r.value=n,r.kind=e,r}function M2e(e,t){const n=new Mo(s2e);return n.operator=e,n.argument=t,n.prefix=!0,n}function Yt(e,t){var n,r=Array.prototype.slice.call(arguments,2),i=t.replace(/%(\d)/g,(s,o)=>(x2(o":case"<=":case">=":case"instanceof":case"in":t=7;break;case"<<":case">>":case">>>":t=8;break;case"+":case"-":t=9;break;case"*":case"/":case"%":t=11;break}return t}function q2e(){var e,t,n,r,i,s,o,a,l,u;if(e=rn,l=D1(),r=rn,i=n8(r),i===0)return l;for(r.prec=i,Li(),t=[e,rn],o=D1(),s=[l,r,o];(i=n8(rn))>0;){for(;s.length>2&&i<=s[s.length-2].prec;)o=s.pop(),a=s.pop().value,l=s.pop(),t.pop(),n=Z6(a,l,o),s.push(n);r=Li(),r.prec=i,s.push(r),t.push(rn),n=D1(),s.push(n)}for(u=s.length-1,n=s[u],t.pop();u>1;)t.pop(),n=Z6(s[u-1].value,s[u-2],n),u-=2;return n}function uf(){var e,t,n;return e=q2e(),yn("?")&&(Li(),t=uf(),ti(":"),n=uf(),e=F2e(e,t,n)),e}function cF(){const e=uf();if(yn(","))throw new Error(Bg);return e}function W2e(e){tt=e,ce=0,ei=tt.length,rn=null,SU();const t=cF();if(rn.type!==Y0)throw new Error("Unexpect token after expression.");return t}function xA(e){const t=[];return e.type==="Identifier"?[e.name]:e.type==="Literal"?[e.value]:(e.type==="MemberExpression"&&(t.push(...xA(e.object)),t.push(...xA(e.property))),t)}function CU(e){return e.object.type==="MemberExpression"?CU(e.object):e.object.name==="datum"}function $U(e){const t=W2e(e),n=new Set;return t.visit(r=>{r.type==="MemberExpression"&&CU(r)&&n.add(xA(r).slice(1).join("."))}),n}class Ih extends sn{clone(){return new Ih(null,this.model,_t(this.filter))}constructor(t,n,r){super(t),this.model=n,this.filter=r,this.expr=py(this.model,this.filter,this),this._dependentFields=$U(this.expr)}dependentFields(){return this._dependentFields}producedFields(){return new Set}assemble(){return{type:"filter",expr:this.expr}}hash(){return`Filter ${this.expr}`}}function H2e(e,t){const n={},r=e.config.selection;if(!t||!t.length)return n;let i=0;for(const s of t){const o=_n(s.name),a=s.select,l=Ie(a)?a:a.type,u=Le(a)?_t(a):{type:l},c=r[l];for(const h in c)h==="fields"||h==="encodings"||(h==="mark"&&(u.mark={...c.mark,...u.mark}),(u[h]===void 0||u[h]===!0)&&(u[h]=_t(c[h]??u[h])));const f=n[o]={...u,name:o,type:l,init:s.value,bind:s.bind,events:Ie(u.on)?Fu(u.on,"scope"):Be(_t(u.on))};if(ia(f)&&(i++,i>1)){delete n[o];continue}const d=_t(s);for(const h of v2)h.defined(f)&&h.parse&&h.parse(e,f,d)}return i>1&&Se(eme),n}function FU(e,t,n,r="datum"){const i=Ie(t)?t:t.param,s=_n(i),o=$e(s+af);let a;try{a=e.getSelectionComponent(s,i)}catch{return`!!${s}`}if(a.project.timeUnit){const d=n??e.component.data.raw,h=a.project.timeUnit.clone();d.parent?h.insertAsParentOf(d):d.parent=h}const l=a.project.hasSelectionId?"vlSelectionIdTest(":"vlSelectionTest(",u=a.resolve==="global"?")":`, ${$e(a.resolve)})`,c=`${l}${o}, ${r}${u}`,f=`length(data(${o}))`;return t.empty===!1?`${f} && ${c}`:`!${f} || ${c}`}function DU(e,t,n){const r=_n(t),i=n.encoding;let s=n.field,o;try{o=e.getSelectionComponent(r,t)}catch{return r}if(!i&&!s)s=o.project.items[0].field,o.project.items.length>1&&Se(tme(s));else if(i&&!s){const a=o.project.items.filter(l=>l.channel===i);!a.length||a.length>1?(s=o.project.items[0].field,Se(nme(a,i,n,s))):s=a[0].field}return`${o.name}[${$e(zs(s))}]`}function G2e(e,t){for(const[n,r]of pu(e.component.selection??{})){const i=e.getName(`lookup_${n}`);e.component.data.outputNodes[i]=r.materialized=new zi(new Ih(t,e,{param:n}),i,Fn.Lookup,e.component.data.outputNodeRefCounts)}}function py(e,t,n){return sg(t,r=>Ie(r)?r:f1e(r)?FU(e,r,n):Nz(r))}function Y2e(e,t){if(e)return de(e)&&!Nl(e)?e.map(n=>U$(n,t)).join(", "):e}function w_(e,t,n,r){var i,s;e.encode??(e.encode={}),(i=e.encode)[t]??(i[t]={}),(s=e.encode[t]).update??(s.update={}),e.encode[t].update[n]=r}function zp(e,t,n,r={header:!1}){var f,d;const{disable:i,orient:s,scale:o,labelExpr:a,title:l,zindex:u,...c}=e.combine();if(!i){for(const h in c){const p=h,g=mve[p],m=c[p];if(g&&g!==t&&g!=="both")delete c[p];else if(H0(m)){const{condition:y,...b}=m,x=Be(y),_=E6[p];if(_){const{vgProp:w,part:A}=_,E=[...x.map(k=>{const{test:S,...$}=k;return{test:py(null,S),...$}}),b];w_(c,A,w,E),delete c[p]}else if(_===null){const w={signal:x.map(A=>{const{test:E,...k}=A;return`${py(null,E)} ? ${a6(k)} : `}).join("")+a6(b)};c[p]=w}}else if(nt(m)){const y=E6[p];if(y){const{vgProp:b,part:x}=y;w_(c,x,b,m),delete c[p]}}It(["labelAlign","labelBaseline"],p)&&c[p]===null&&delete c[p]}if(t==="grid"){if(!c.grid)return;if(c.encode){const{grid:h}=c.encode;c.encode={...h?{grid:h}:{}},an(c.encode)&&delete c.encode}return{scale:o,orient:s,...c,domain:!1,labels:!1,aria:!1,maxExtent:0,minExtent:0,ticks:!1,zindex:qn(u,0)}}else{if(!r.header&&e.mainExtracted)return;if(a!==void 0){let p=a;(d=(f=c.encode)==null?void 0:f.labels)!=null&&d.update&&nt(c.encode.labels.update.text)&&(p=Jc(a,"datum.label",c.encode.labels.update.text.signal)),w_(c,"labels","text",{signal:p})}if(c.labelAlign===null&&delete c.labelAlign,c.encode){for(const p of fj)e.hasAxisPart(p)||delete c.encode[p];an(c.encode)&&delete c.encode}const h=Y2e(l,n);return{scale:o,orient:s,grid:!1,...h?{title:h}:{},...c,...n.aria===!1?{aria:!1}:{},zindex:qn(u,0)}}}}function MU(e){const{axes:t}=e.component,n=[];for(const r of _l)if(t[r]){for(const i of t[r])if(!i.get("disable")&&!i.get("gridScale")){const s=r==="x"?"height":"width",o=e.getSizeSignalRef(s).signal;s!==o&&n.push({name:s,update:o})}}return n}function V2e(e,t){const{x:n=[],y:r=[]}=e;return[...n.map(i=>zp(i,"grid",t)),...r.map(i=>zp(i,"grid",t)),...n.map(i=>zp(i,"main",t)),...r.map(i=>zp(i,"main",t))].filter(i=>i)}function r8(e,t,n,r){return Object.assign.apply(null,[{},...e.map(i=>{if(i==="axisOrient"){const s=n==="x"?"bottom":"left",o=t[n==="x"?"axisBottom":"axisLeft"]||{},a=t[n==="x"?"axisTop":"axisRight"]||{},l=new Set([...Ee(o),...Ee(a)]),u={};for(const c of l.values())u[c]={signal:`${r.signal} === "${s}" ? ${uo(o[c])} : ${uo(a[c])}`};return u}return t[i]})])}function X2e(e,t,n,r){const i=t==="band"?["axisDiscrete","axisBand"]:t==="point"?["axisDiscrete","axisPoint"]:Pz(t)?["axisQuantitative"]:t==="time"||t==="utc"?["axisTemporal"]:[],s=e==="x"?"axisX":"axisY",o=nt(n)?"axisOrient":`axis${N0(n)}`,a=[...i,...i.map(u=>s+u.substr(4))],l=["axis",o,s];return{vlOnlyAxisConfig:r8(a,r,e,n),vgAxisConfig:r8(l,r,e,n),axisConfigStyle:K2e([...l,...a],r)}}function K2e(e,t){var r;const n=[{}];for(const i of e){let s=(r=t[i])==null?void 0:r.style;if(s){s=Be(s);for(const o of s)n.push(t.style[o])}}return Object.assign.apply(null,n)}function _A(e,t,n,r={}){var s;const i=dz(e,n,t);if(i!==void 0)return{configFrom:"style",configValue:i};for(const o of["vlOnlyAxisConfig","vgAxisConfig","axisConfigStyle"])if(((s=r[o])==null?void 0:s[e])!==void 0)return{configFrom:o,configValue:r[o][e]};return{}}const i8={scale:({model:e,channel:t})=>e.scaleName(t),format:({format:e})=>e,formatType:({formatType:e})=>e,grid:({fieldOrDatumDef:e,axis:t,scaleType:n})=>t.grid??Z2e(n,e),gridScale:({model:e,channel:t})=>J2e(e,t),labelAlign:({axis:e,labelAngle:t,orient:n,channel:r})=>e.labelAlign||RU(t,n,r),labelAngle:({labelAngle:e})=>e,labelBaseline:({axis:e,labelAngle:t,orient:n,channel:r})=>e.labelBaseline||TU(t,n,r),labelFlush:({axis:e,fieldOrDatumDef:t,channel:n})=>e.labelFlush??exe(t.type,n),labelOverlap:({axis:e,fieldOrDatumDef:t,scaleType:n})=>e.labelOverlap??txe(t.type,n,Ce(t)&&!!t.timeUnit,Ce(t)?t.sort:void 0),orient:({orient:e})=>e,tickCount:({channel:e,model:t,axis:n,fieldOrDatumDef:r,scaleType:i})=>{const s=e==="x"?"width":e==="y"?"height":void 0,o=s?t.getSizeSignalRef(s):void 0;return n.tickCount??rxe({fieldOrDatumDef:r,scaleType:i,size:o,values:n.values})},tickMinStep:ixe,title:({axis:e,model:t,channel:n})=>{if(e.title!==void 0)return e.title;const r=NU(t,n);if(r!==void 0)return r;const i=t.typedFieldDef(n),s=n==="x"?"x2":"y2",o=t.fieldDef(s);return pz(i?[_6(i)]:[],Ce(o)?[_6(o)]:[])},values:({axis:e,fieldOrDatumDef:t})=>sxe(e,t),zindex:({axis:e,fieldOrDatumDef:t,mark:n})=>e.zindex??oxe(n,t)};function Z2e(e,t){return!yr(e)&&Ce(t)&&!dn(t==null?void 0:t.bin)&&!Sr(t==null?void 0:t.bin)}function J2e(e,t){const n=t==="x"?"y":"x";if(e.getScaleComponent(n))return e.scaleName(n)}function Q2e(e,t,n,r,i){const s=t==null?void 0:t.labelAngle;if(s!==void 0)return nt(s)?s:Lg(s);{const{configValue:o}=_A("labelAngle",r,t==null?void 0:t.style,i);return o!==void 0?Lg(o):n===wn&&It([D$,F$],e.type)&&!(Ce(e)&&e.timeUnit)?270:void 0}}function wA(e){return`(((${e.signal} % 360) + 360) % 360)`}function TU(e,t,n,r){if(e!==void 0)if(n==="x"){if(nt(e)){const i=wA(e),s=nt(t)?`(${t.signal} === "top")`:t==="top";return{signal:`(45 < ${i} && ${i} < 135) || (225 < ${i} && ${i} < 315) ? "middle" :(${i} <= 45 || 315 <= ${i}) === ${s} ? "bottom" : "top"`}}if(45{if(Sf(r)&&ej(r.sort)){const{field:s,timeUnit:o}=r,a=r.sort,l=a.map((u,c)=>`${Nz({field:s,timeUnit:o,equal:u})} ? ${c} : `).join("")+a.length;t=new ah(t,{calculate:l,as:lh(r,i,{forAs:!0})})}}),t}producedFields(){return new Set([this.transform.as])}dependentFields(){return this._dependentFields}assemble(){return{type:"formula",expr:this.transform.calculate,as:this.transform.as}}hash(){return`Calculate ${Ut(this.transform)}`}}function lh(e,t,n){return Re(e,{prefix:t,suffix:"sort_index",...n})}function w2(e,t){return It(["top","bottom"],t)?"column":It(["left","right"],t)||e==="row"?"row":"column"}function uh(e,t,n,r){const i=r==="row"?n.headerRow:r==="column"?n.headerColumn:n.headerFacet;return qn((t||{})[e],i[e],n.header[e])}function E2(e,t,n,r){const i={};for(const s of e){const o=uh(s,t||{},n,r);o!==void 0&&(i[s]=o)}return i}const fF=["row","column"],dF=["header","footer"];function axe(e,t){const n=e.component.layoutHeaders[t].title,r=e.config?e.config:void 0,i=e.component.layoutHeaders[t].facetFieldDef?e.component.layoutHeaders[t].facetFieldDef:void 0,{titleAnchor:s,titleAngle:o,titleOrient:a}=E2(["titleAnchor","titleAngle","titleOrient"],i.header,r,t),l=w2(t,a),u=Lg(o);return{name:`${t}-title`,type:"group",role:`${l}-title`,title:{text:n,...t==="row"?{orient:"left"}:{},style:"guide-title",...LU(u,l),...OU(l,u,s),...IU(r,i,t,Pve,Fj)}}}function OU(e,t,n="middle"){switch(n){case"start":return{align:"left"};case"end":return{align:"right"}}const r=RU(t,e==="row"?"left":"top",e==="row"?"y":"x");return r?{align:r}:{}}function LU(e,t){const n=TU(e,t==="row"?"left":"top",t==="row"?"y":"x",!0);return n?{baseline:n}:{}}function lxe(e,t){const n=e.component.layoutHeaders[t],r=[];for(const i of dF)if(n[i])for(const s of n[i]){const o=cxe(e,t,i,n,s);o!=null&&r.push(o)}return r}function uxe(e,t){const{sort:n}=e;return il(n)?{field:Re(n,{expr:"datum"}),order:n.order??"ascending"}:de(n)?{field:lh(e,t,{expr:"datum"}),order:"ascending"}:{field:Re(e,{expr:"datum"}),order:n??"ascending"}}function EA(e,t,n){const{format:r,formatType:i,labelAngle:s,labelAnchor:o,labelOrient:a,labelExpr:l}=E2(["format","formatType","labelAngle","labelAnchor","labelOrient","labelExpr"],e.header,n,t),u=P$({fieldOrDatumDef:e,format:r,formatType:i,expr:"parent",config:n}).signal,c=w2(t,a);return{text:{signal:l?Jc(Jc(l,"datum.label",u),"datum.value",Re(e,{expr:"parent"})):u},...t==="row"?{orient:"left"}:{},style:"guide-label",frame:"group",...LU(s,c),...OU(c,s,o),...IU(n,e,t,Bve,Dj)}}function cxe(e,t,n,r,i){if(i){let s=null;const{facetFieldDef:o}=r,a=e.config?e.config:void 0;if(o&&i.labels){const{labelOrient:f}=E2(["labelOrient"],o.header,a,t);(t==="row"&&!It(["top","bottom"],f)||t==="column"&&!It(["left","right"],f))&&(s=EA(o,t,a))}const l=fs(e)&&!j0(e.facet),u=i.axes,c=(u==null?void 0:u.length)>0;if(s||c){const f=t==="row"?"height":"width";return{name:e.getName(`${t}_${n}`),type:"group",role:`${t}-${n}`,...r.facetFieldDef?{from:{data:e.getName(`${t}_domain`)},sort:uxe(o,t)}:{},...c&&l?{from:{data:e.getName(`facet_domain_${t}`)}}:{},...s?{title:s}:{},...i.sizeSignal?{encode:{update:{[f]:i.sizeSignal}}}:{},...c?{axes:u}:{}}}}return null}const fxe={column:{start:0,end:1},row:{start:1,end:0}};function dxe(e,t){return fxe[t][e]}function hxe(e,t){const n={};for(const r of Fs){const i=e[r];if(i!=null&&i.facetFieldDef){const{titleAnchor:s,titleOrient:o}=E2(["titleAnchor","titleOrient"],i.facetFieldDef.header,t,r),a=w2(r,o),l=dxe(s,a);l!==void 0&&(n[a]=l)}}return an(n)?void 0:n}function IU(e,t,n,r,i){const s={};for(const o of r){if(!i[o])continue;const a=uh(o,t==null?void 0:t.header,e,n);a!==void 0&&(s[i[o]]=a)}return s}function hF(e){return[...Om(e,"width"),...Om(e,"height"),...Om(e,"childWidth"),...Om(e,"childHeight")]}function Om(e,t){const n=t==="width"?"x":"y",r=e.component.layoutSize.get(t);if(!r||r==="merged")return[];const i=e.getSizeSignalRef(t).signal;if(r==="step"){const s=e.getScaleComponent(n);if(s){const o=s.get("type"),a=s.get("range");if(yr(o)&&Ef(a)){const l=e.scaleName(n);return fs(e.parent)&&e.parent.component.resolve.scale[n]==="independent"?[s8(l,a)]:[s8(l,a),{name:i,update:PU(l,s,`domain('${l}').length`)}]}}throw new Error("layout size is step although width/height is not step.")}else if(r=="container"){const s=i.endsWith("width"),o=s?"containerSize()[0]":"containerSize()[1]",a=cA(e.config.view,s?"width":"height"),l=`isFinite(${o}) ? ${o} : ${a}`;return[{name:i,init:l,on:[{update:l,events:"window:resize"}]}]}else return[{name:i,value:r}]}function s8(e,t){const n=`${e}_step`;return nt(t.step)?{name:n,update:t.step.signal}:{name:n,value:t.step}}function PU(e,t,n){const r=t.get("type"),i=t.get("padding"),s=qn(t.get("paddingOuter"),i);let o=t.get("paddingInner");return o=r==="band"?o!==void 0?o:i:1,`bandspace(${n}, ${uo(o)}, ${uo(s)}) * ${e}_step`}function BU(e){return e==="childWidth"?"width":e==="childHeight"?"height":e}function zU(e,t){return Ee(e).reduce((n,r)=>({...n,...Lh({model:t,channelDef:e[r],vgChannel:r,mainRefFn:i=>vn(i.value),invalidValueRef:void 0})}),{})}function jU(e,t){if(fs(t))return e==="theta"?"independent":"shared";if(zh(t))return"shared";if(xF(t))return Wn(e)||e==="theta"||e==="radius"?"independent":"shared";throw new Error("invalid model type for resolve")}function pF(e,t){const n=e.scale[t],r=Wn(t)?"axis":"legend";return n==="independent"?(e[r][t]==="shared"&&Se(Rme(t)),"independent"):e[r][t]||"shared"}const pxe={...Uve,disable:1,labelExpr:1,selections:1,opacity:1,shape:1,stroke:1,fill:1,size:1,strokeWidth:1,strokeDash:1,encode:1},UU=Ee(pxe);class gxe extends El{}const o8={symbols:mxe,gradient:vxe,labels:yxe,entries:bxe};function mxe(e,{fieldOrDatumDef:t,model:n,channel:r,legendCmpt:i,legendType:s}){if(s!=="symbol")return;const{markDef:o,encoding:a,config:l,mark:u}=n,c=o.filled&&u!=="trail";let f={...j0e({},n,I1e),...lU(n,{filled:c})};const d=i.get("symbolOpacity")??l.legend.symbolOpacity,h=i.get("symbolFillColor")??l.legend.symbolFillColor,p=i.get("symbolStrokeColor")??l.legend.symbolStrokeColor,g=d===void 0?qU(a.opacity)??o.opacity:void 0;if(f.fill){if(r==="fill"||c&&r===Wi)delete f.fill;else if(Ae(f.fill,"field"))h?delete f.fill:(f.fill=vn(l.legend.symbolBaseFillColor??"black"),f.fillOpacity=vn(g??1));else if(de(f.fill)){const m=AA(a.fill??a.color)??o.fill??(c&&o.color);m&&(f.fill=vn(m))}}if(f.stroke){if(r==="stroke"||!c&&r===Wi)delete f.stroke;else if(Ae(f.stroke,"field")||p)delete f.stroke;else if(de(f.stroke)){const m=qn(AA(a.stroke||a.color),o.stroke,c?o.color:void 0);m&&(f.stroke={value:m})}}if(r!==xl){const m=Ce(t)&&HU(n,i,t);m?f.opacity=[{test:m,...vn(g??1)},vn(l.legend.unselectedOpacity)]:g&&(f.opacity=vn(g))}return f={...f,...e},an(f)?void 0:f}function vxe(e,{model:t,legendType:n,legendCmpt:r}){if(n!=="gradient")return;const{config:i,markDef:s,encoding:o}=t;let a={};const u=(r.get("gradientOpacity")??i.legend.gradientOpacity)===void 0?qU(o.opacity)||s.opacity:void 0;return u&&(a.opacity=vn(u)),a={...a,...e},an(a)?void 0:a}function yxe(e,{fieldOrDatumDef:t,model:n,channel:r,legendCmpt:i}){const s=n.legend(r)||{},o=n.config,a=Ce(t)?HU(n,i,t):void 0,l=a?[{test:a,value:1},{value:o.legend.unselectedOpacity}]:void 0,{format:u,formatType:c}=s;let f;sf(c)?f=co({fieldOrDatumDef:t,field:"datum.value",format:u,formatType:c,config:o}):u===void 0&&c===void 0&&o.customFormatTypes&&(t.type==="quantitative"&&o.numberFormatType?f=co({fieldOrDatumDef:t,field:"datum.value",format:o.numberFormat,formatType:o.numberFormatType,config:o}):t.type==="temporal"&&o.timeFormatType&&Ce(t)&&t.timeUnit===void 0&&(f=co({fieldOrDatumDef:t,field:"datum.value",format:o.timeFormat,formatType:o.timeFormatType,config:o})));const d={...l?{opacity:l}:{},...f?{text:f}:{},...e};return an(d)?void 0:d}function bxe(e,{legendCmpt:t}){const n=t.get("selections");return n!=null&&n.length?{...e,fill:{value:"transparent"}}:e}function qU(e){return WU(e,(t,n)=>Math.max(t,n.value))}function AA(e){return WU(e,(t,n)=>qn(t,n.value))}function WU(e,t){if(ive(e))return Be(e.condition).reduce(t,e.value);if(xo(e))return e.value}function HU(e,t,n){const r=t.get("selections");if(!(r!=null&&r.length))return;const i=$e(n.field);return r.map(s=>`(!length(data(${$e(_n(s)+af)})) || (${s}[${i}] && indexof(${s}[${i}], datum.value) >= 0))`).join(" || ")}const a8={direction:({direction:e})=>e,format:({fieldOrDatumDef:e,legend:t,config:n})=>{const{format:r,formatType:i}=t;return Zz(e,e.type,r,i,n,!1)},formatType:({legend:e,fieldOrDatumDef:t,scaleType:n})=>{const{formatType:r}=e;return Jz(r,t,n)},gradientLength:e=>{const{legend:t,legendConfig:n}=e;return t.gradientLength??n.gradientLength??Sxe(e)},labelOverlap:({legend:e,legendConfig:t,scaleType:n})=>e.labelOverlap??t.labelOverlap??Cxe(n),symbolType:({legend:e,markDef:t,channel:n,encoding:r})=>e.symbolType??_xe(t.type,n,r.shape,t.shape),title:({fieldOrDatumDef:e,config:t})=>dd(e,t,{allowDisabling:!0}),type:({legendType:e,scaleType:t,channel:n})=>{if(fd(n)&&Qo(t)){if(e==="gradient")return}else if(e==="symbol")return;return e},values:({fieldOrDatumDef:e,legend:t})=>xxe(t,e)};function xxe(e,t){const n=e.values;if(de(n))return cj(t,n);if(nt(n))return n}function _xe(e,t,n,r){if(t!=="shape"){const i=AA(n)??r;if(i)return i}switch(e){case"bar":case"rect":case"image":case"square":return"square";case"line":case"trail":case"rule":return"stroke";case"arc":case"point":case"circle":case"tick":case"geoshape":case"area":case"text":return"circle"}}function wxe(e){const{legend:t}=e;return qn(t.type,Exe(e))}function Exe({channel:e,timeUnit:t,scaleType:n}){if(fd(e)){if(It(["quarter","month","day"],t))return"symbol";if(Qo(n))return"gradient"}return"symbol"}function Axe({legendConfig:e,legendType:t,orient:n,legend:r}){return r.direction??e[t?"gradientDirection":"symbolDirection"]??kxe(n,t)}function kxe(e,t){switch(e){case"top":case"bottom":return"horizontal";case"left":case"right":case"none":case void 0:return;default:return t==="gradient"?"horizontal":void 0}}function Sxe({legendConfig:e,model:t,direction:n,orient:r,scaleType:i}){const{gradientHorizontalMaxLength:s,gradientHorizontalMinLength:o,gradientVerticalMaxLength:a,gradientVerticalMinLength:l}=e;if(Qo(i))return n==="horizontal"?r==="top"||r==="bottom"?l8(t,"width",o,s):o:l8(t,"height",l,a)}function l8(e,t,n,r){return{signal:`clamp(${e.getSizeSignalRef(t).signal}, ${n}, ${r})`}}function Cxe(e){if(It(["quantile","threshold","log","symlog"],e))return"greedy"}function GU(e){const t=$n(e)?$xe(e):Txe(e);return e.component.legends=t,t}function $xe(e){const{encoding:t}=e,n={};for(const r of[Wi,...Tj]){const i=tr(t[r]);!i||!e.getScaleComponent(r)||r===Hi&&Ce(i)&&i.type===Oh||(n[r]=Mxe(e,r))}return n}function Fxe(e,t){const n=e.scaleName(t);if(e.mark==="trail"){if(t==="color")return{stroke:n};if(t==="size")return{strokeWidth:n}}return t==="color"?e.markDef.filled?{fill:n}:{stroke:n}:{[t]:n}}function Dxe(e,t,n,r){switch(t){case"disable":return n!==void 0;case"values":return!!(n!=null&&n.values);case"title":if(t==="title"&&e===(r==null?void 0:r.title))return!0}return e===(n||{})[t]}function Mxe(e,t){var _;let n=e.legend(t);const{markDef:r,encoding:i,config:s}=e,o=s.legend,a=new gxe({},Fxe(e,t));Mbe(e,t,a);const l=n!==void 0?!n:o.disable;if(a.set("disable",l,n!==void 0),l)return a;n=n||{};const u=e.getScaleComponent(t).get("type"),c=tr(i[t]),f=Ce(c)?(_=mr(c.timeUnit))==null?void 0:_.unit:void 0,d=n.orient||s.legend.orient||"right",h=wxe({legend:n,channel:t,timeUnit:f,scaleType:u}),p=Axe({legend:n,legendType:h,orient:d,legendConfig:o}),g={legend:n,channel:t,model:e,markDef:r,encoding:i,fieldOrDatumDef:c,legendConfig:o,config:s,scaleType:u,orient:d,legendType:h,direction:p};for(const w of UU){if(h==="gradient"&&w.startsWith("symbol")||h==="symbol"&&w.startsWith("gradient"))continue;const A=w in a8?a8[w](g):n[w];if(A!==void 0){const E=Dxe(A,w,n,e.fieldDef(t));(E||s.legend[w]===void 0)&&a.set(w,A,E)}}const m=(n==null?void 0:n.encoding)??{},y=a.get("selections"),b={},x={fieldOrDatumDef:c,model:e,channel:t,legendCmpt:a,legendType:h};for(const w of["labels","legend","title","symbols","gradient","entries"]){const A=zU(m[w]??{},e),E=w in o8?o8[w](A,x):A;E!==void 0&&!an(E)&&(b[w]={...y!=null&&y.length&&Ce(c)?{name:`${_n(c.field)}_legend_${w}`}:{},...y!=null&&y.length?{interactive:!!y}:{},update:E})}return an(b)||a.set("encode",b,!!(n!=null&&n.encoding)),a}function Txe(e){const{legends:t,resolve:n}=e.component;for(const r of e.children){GU(r);for(const i of Ee(r.component.legends))n.legend[i]=pF(e.component.resolve,i),n.legend[i]==="shared"&&(t[i]=YU(t[i],r.component.legends[i]),t[i]||(n.legend[i]="independent",delete t[i]))}for(const r of Ee(t))for(const i of e.children)i.component.legends[r]&&n.legend[r]==="shared"&&delete i.component.legends[r];return t}function YU(e,t){var s,o,a,l;if(!e)return t.clone();const n=e.getWithExplicit("orient"),r=t.getWithExplicit("orient");if(n.explicit&&r.explicit&&n.value!==r.value)return;let i=!1;for(const u of UU){const c=vu(e.getWithExplicit(u),t.getWithExplicit(u),u,"legend",(f,d)=>{switch(u){case"symbolType":return Rxe(f,d);case"title":return mz(f,d);case"type":return i=!0,Zi("symbol")}return h2(f,d,u,"legend")});e.setWithExplicit(u,c)}return i&&((o=(s=e.implicit)==null?void 0:s.encode)!=null&&o.gradient&&ty(e.implicit,["encode","gradient"]),(l=(a=e.explicit)==null?void 0:a.encode)!=null&&l.gradient&&ty(e.explicit,["encode","gradient"])),e}function Rxe(e,t){return t.value==="circle"?t:e}function Nxe(e,t,n,r){var i,s;e.encode??(e.encode={}),(i=e.encode)[t]??(i[t]={}),(s=e.encode[t]).update??(s.update={}),e.encode[t].update[n]=r}function VU(e){const t=e.component.legends,n={};for(const i of Ee(t)){const s=e.getScaleComponent(i),o=ln(s.get("domains"));if(n[o])for(const a of n[o])YU(a,t[i])||n[o].push(t[i]);else n[o]=[t[i].clone()]}return Or(n).flat().map(i=>Oxe(i,e.config)).filter(i=>i!==void 0)}function Oxe(e,t){var o,a,l;const{disable:n,labelExpr:r,selections:i,...s}=e.combine();if(!n){if(t.aria===!1&&s.aria==null&&(s.aria=!1),(o=s.encode)!=null&&o.symbols){const u=s.encode.symbols.update;u.fill&&u.fill.value!=="transparent"&&!u.stroke&&!s.stroke&&(u.stroke={value:"transparent"});for(const c of Tj)s[c]&&delete u[c]}if(s.title||delete s.title,r!==void 0){let u=r;(l=(a=s.encode)==null?void 0:a.labels)!=null&&l.update&&nt(s.encode.labels.update.text)&&(u=Jc(r,"datum.label",s.encode.labels.update.text.signal)),Nxe(s,"labels","text",{signal:u})}return s}}function Lxe(e){return zh(e)||xF(e)?Ixe(e):XU(e)}function Ixe(e){return e.children.reduce((t,n)=>t.concat(n.assembleProjections()),XU(e))}function XU(e){const t=e.component.projection;if(!t||t.merged)return[];const n=t.combine(),{name:r}=n;if(t.data){const i={signal:`[${t.size.map(o=>o.signal).join(", ")}]`},s=t.data.reduce((o,a)=>{const l=nt(a)?a.signal:`data('${e.lookupDataSource(a)}')`;return It(o,l)||o.push(l),o},[]);if(s.length<=0)throw new Error("Projection's fit didn't find any data sources");return[{name:r,size:i,fit:{signal:s.length>1?`[${s.join(", ")}]`:s[0]},...n}]}else return[{name:r,translate:{signal:"[width / 2, height / 2]"},...n}]}const Pxe=["type","clipAngle","clipExtent","center","rotate","precision","reflectX","reflectY","coefficient","distance","fraction","lobes","parallel","radius","ratio","spacing","tilt"];class KU extends El{constructor(t,n,r,i){super({...n},{name:t}),this.specifiedProjection=n,this.size=r,this.data=i,this.merged=!1}get isFit(){return!!this.data}}function ZU(e){e.component.projection=$n(e)?Bxe(e):Uxe(e)}function Bxe(e){if(e.hasProjection){const t=$r(e.specifiedProjection),n=!(t&&(t.scale!=null||t.translate!=null)),r=n?[e.getSizeSignalRef("width"),e.getSizeSignalRef("height")]:void 0,i=n?zxe(e):void 0,s=new KU(e.projectionName(!0),{...$r(e.config.projection),...t},r,i);return s.get("type")||s.set("type","equalEarth",!1),s}}function zxe(e){const t=[],{encoding:n}=e;for(const r of[[Fo,$o],[js,Do]])(tr(n[r[0]])||tr(n[r[1]]))&&t.push({signal:e.getName(`geojson_${t.length}`)});return e.channelHasField(Hi)&&e.typedFieldDef(Hi).type===Oh&&t.push({signal:e.getName(`geojson_${t.length}`)}),t.length===0&&t.push(e.requestDataName(Fn.Main)),t}function jxe(e,t){const n=n$(Pxe,i=>!!(!Ue(e.explicit,i)&&!Ue(t.explicit,i)||Ue(e.explicit,i)&&Ue(t.explicit,i)&&os(e.get(i),t.get(i))));if(os(e.size,t.size)){if(n)return e;if(os(e.explicit,{}))return t;if(os(t.explicit,{}))return e}return null}function Uxe(e){if(e.children.length===0)return;let t;for(const r of e.children)ZU(r);const n=n$(e.children,r=>{const i=r.component.projection;if(i)if(t){const s=jxe(t,i);return s&&(t=s),!!s}else return t=i,!0;else return!0});if(t&&n){const r=e.projectionName(!0),i=new KU(r,t.specifiedProjection,t.size,_t(t.data));for(const s of e.children){const o=s.component.projection;o&&(o.isFit&&i.data.push(...s.component.projection.data),s.renameProjection(o.get("name"),r),o.merged=!0)}return i}}function qxe(e,t,n,r){if(W0(t,n)){const i=$n(e)?e.axis(n)??e.legend(n)??{}:{},s=Re(t,{expr:"datum"}),o=Re(t,{expr:"datum",binSuffix:"end"});return{formulaAs:Re(t,{binSuffix:"range",forAs:!0}),formula:z0(s,o,i.format,i.formatType,r)}}return{}}function JU(e,t){return`${lz(e)}_${t}`}function Wxe(e,t){return{signal:e.getName(`${t}_bins`),extentSignal:e.getName(`${t}_extent`)}}function gF(e,t,n){const r=a2(n,void 0)??{},i=JU(r,t);return e.getName(`${i}_bins`)}function Hxe(e){return"as"in e}function u8(e,t,n){let r,i;Hxe(e)?r=Ie(e.as)?[e.as,`${e.as}_end`]:[e.as[0],e.as[1]]:r=[Re(e,{forAs:!0}),Re(e,{binSuffix:"end",forAs:!0})];const s={...a2(t,void 0)},o=JU(s,e.field),{signal:a,extentSignal:l}=Wxe(n,o);if(Kb(s.extent)){const c=s.extent;i=DU(n,c.param,c),delete s.extent}const u={bin:s,field:e.field,as:[r],...a?{signal:a}:{},...l?{extentSignal:l}:{},...i?{span:i}:{}};return{key:o,binComponent:u}}class sa extends sn{clone(){return new sa(null,_t(this.bins))}constructor(t,n){super(t),this.bins=n}static makeFromEncoding(t,n){const r=n.reduceFieldDef((i,s,o)=>{if(wi(s)&&dn(s.bin)){const{key:a,binComponent:l}=u8(s,s.bin,n);i[a]={...l,...i[a],...qxe(n,s,o,n.config)}}return i},{});return an(r)?null:new sa(t,r)}static makeFromTransform(t,n,r){const{key:i,binComponent:s}=u8(n,n.bin,r);return new sa(t,{[i]:s})}merge(t,n){for(const r of Ee(t.bins))r in this.bins?(n(t.bins[r].signal,this.bins[r].signal),this.bins[r].as=Jo([...this.bins[r].as,...t.bins[r].as],Ut)):this.bins[r]=t.bins[r];for(const r of t.children)t.removeChild(r),r.parent=this;t.remove()}producedFields(){return new Set(Or(this.bins).map(t=>t.as).flat(2))}dependentFields(){return new Set(Or(this.bins).map(t=>t.field))}hash(){return`Bin ${Ut(this.bins)}`}assemble(){return Or(this.bins).flatMap(t=>{const n=[],[r,...i]=t.as,{extent:s,...o}=t.bin,a={type:"bin",field:zs(t.field),as:r,signal:t.signal,...Kb(s)?{extent:null}:{extent:s},...t.span?{span:{signal:`span(${t.span})`}}:{},...o};!s&&t.extentSignal&&(n.push({type:"extent",field:zs(t.field),signal:t.extentSignal}),a.extent={signal:t.extentSignal}),n.push(a);for(const l of i)for(let u=0;u<2;u++)n.push({type:"formula",expr:Re({field:r[u]},{expr:"datum"}),as:l[u]});return t.formula&&n.push({type:"formula",expr:t.formula,as:t.formulaAs}),n})}}function Gxe(e,t,n,r){var s;const i=$n(r)?r.encoding[Ca(t)]:void 0;if(wi(n)&&$n(r)&&nj(n,i,r.markDef,r.config)){e.add(Re(n,{})),e.add(Re(n,{suffix:"end"}));const{mark:o,markDef:a,config:l}=r,u=mu({fieldDef:n,markDef:a,config:l});Ig(o)&&u!==.5&&Wn(t)&&(e.add(Re(n,{suffix:p2})),e.add(Re(n,{suffix:g2}))),n.bin&&W0(n,t)&&e.add(Re(n,{binSuffix:"range"}))}else if(QB(t)){const o=JB(t);e.add(r.getName(o))}else e.add(Re(n));return Sf(n)&&A1e((s=n.scale)==null?void 0:s.range)&&e.add(n.scale.range.field),e}function Yxe(e,t){for(const n of Ee(t)){const r=t[n];for(const i of Ee(r))n in e?e[n][i]=new Set([...e[n][i]??[],...r[i]]):e[n]={[i]:r[i]}}}class ho extends sn{clone(){return new ho(null,new Set(this.dimensions),_t(this.measures))}constructor(t,n,r){super(t),this.dimensions=n,this.measures=r}get groupBy(){return this.dimensions}static makeFromEncoding(t,n){let r=!1;n.forEachFieldDef(o=>{o.aggregate&&(r=!0)});const i={},s=new Set;return!r||(n.forEachFieldDef((o,a)=>{const{aggregate:l,field:u}=o;if(l)if(l==="count")i["*"]??(i["*"]={}),i["*"].count=new Set([Re(o,{forAs:!0})]);else{if(dl(l)||Lu(l)){const c=dl(l)?"argmin":"argmax",f=l[c];i[f]??(i[f]={}),i[f][c]=new Set([Re({op:c,field:f},{forAs:!0})])}else i[u]??(i[u]={}),i[u][l]=new Set([Re(o,{forAs:!0})]);$a(a)&&n.scaleDomain(a)==="unaggregated"&&(i[u]??(i[u]={}),i[u].min=new Set([Re({field:u,aggregate:"min"},{forAs:!0})]),i[u].max=new Set([Re({field:u,aggregate:"max"},{forAs:!0})]))}else Gxe(s,a,o,n)}),s.size+Ee(i).length===0)?null:new ho(t,s,i)}static makeFromTransform(t,n){var r;const i=new Set,s={};for(const o of n.aggregate){const{op:a,field:l,as:u}=o;a&&(a==="count"?(s["*"]??(s["*"]={}),s["*"].count=new Set([u||Re(o,{forAs:!0})])):(s[l]??(s[l]={}),(r=s[l])[a]??(r[a]=new Set),s[l][a].add(u||Re(o,{forAs:!0}))))}for(const o of n.groupby??[])i.add(o);return i.size+Ee(s).length===0?null:new ho(t,i,s)}merge(t){return WB(this.dimensions,t.dimensions)?(Yxe(this.measures,t.measures),!0):(Xme("different dimensions, cannot merge"),!1)}addDimensions(t){t.forEach(this.dimensions.add,this.dimensions)}dependentFields(){return new Set([...this.dimensions,...Ee(this.measures)])}producedFields(){const t=new Set;for(const n of Ee(this.measures))for(const r of Ee(this.measures[n])){const i=this.measures[n][r];i.size===0?t.add(`${r}_${n}`):i.forEach(t.add,t)}return t}hash(){return`Aggregate ${Ut({dimensions:this.dimensions,measures:this.measures})}`}assemble(){const t=[],n=[],r=[];for(const s of Ee(this.measures))for(const o of Ee(this.measures[s]))for(const a of this.measures[s][o])r.push(a),t.push(o),n.push(s==="*"?null:zs(s));return{type:"aggregate",groupby:[...this.dimensions].map(zs),ops:t,fields:n,as:r}}}class Ph extends sn{constructor(t,n,r,i){super(t),this.model=n,this.name=r,this.data=i;for(const s of Fs){const o=n.facet[s];if(o){const{bin:a,sort:l}=o;this[s]={name:n.getName(`${s}_domain`),fields:[Re(o),...dn(a)?[Re(o,{binSuffix:"end"})]:[]],...il(l)?{sortField:l}:de(l)?{sortIndexField:lh(o,s)}:{}}}}this.childModel=n.child}hash(){let t="Facet";for(const n of Fs)this[n]&&(t+=` ${n.charAt(0)}:${Ut(this[n])}`);return t}get fields(){var n;const t=[];for(const r of Fs)(n=this[r])!=null&&n.fields&&t.push(...this[r].fields);return t}dependentFields(){const t=new Set(this.fields);for(const n of Fs)this[n]&&(this[n].sortField&&t.add(this[n].sortField.field),this[n].sortIndexField&&t.add(this[n].sortIndexField));return t}producedFields(){return new Set}getSource(){return this.name}getChildIndependentFieldsWithStep(){const t={};for(const n of _l){const r=this.childModel.component.scales[n];if(r&&!r.merged){const i=r.get("type"),s=r.get("range");if(yr(i)&&Ef(s)){const o=A2(this.childModel,n),a=bF(o);a?t[n]=a:Se(m$(n))}}}return t}assembleRowColumnHeaderData(t,n,r){const i={row:"y",column:"x",facet:void 0}[t],s=[],o=[],a=[];i&&r&&r[i]&&(n?(s.push(`distinct_${r[i]}`),o.push("max")):(s.push(r[i]),o.push("distinct")),a.push(`distinct_${r[i]}`));const{sortField:l,sortIndexField:u}=this[t];if(l){const{op:c=i2,field:f}=l;s.push(f),o.push(c),a.push(Re(l,{forAs:!0}))}else u&&(s.push(u),o.push("max"),a.push(u));return{name:this[t].name,source:n??this.data,transform:[{type:"aggregate",groupby:this[t].fields,...s.length?{fields:s,ops:o,as:a}:{}}]}}assembleFacetHeaderData(t){var l;const{columns:n}=this.model.layout,{layoutHeaders:r}=this.model.component,i=[],s={};for(const u of fF){for(const c of dF){const f=(r[u]&&r[u][c])??[];for(const d of f)if(((l=d.axes)==null?void 0:l.length)>0){s[u]=!0;break}}if(s[u]){const c=`length(data("${this.facet.name}"))`,f=u==="row"?n?{signal:`ceil(${c} / ${n})`}:1:n?{signal:`min(${c}, ${n})`}:{signal:c};i.push({name:`${this.facet.name}_${u}`,transform:[{type:"sequence",start:0,stop:f}]})}}const{row:o,column:a}=s;return(o||a)&&i.unshift(this.assembleRowColumnHeaderData("facet",null,t)),i}assemble(){const t=[];let n=null;const r=this.getChildIndependentFieldsWithStep(),{column:i,row:s,facet:o}=this;if(i&&s&&(r.x||r.y)){n=`cross_${this.column.name}_${this.row.name}`;const a=[].concat(r.x??[],r.y??[]),l=a.map(()=>"distinct");t.push({name:n,source:this.data,transform:[{type:"aggregate",groupby:this.fields,fields:a,ops:l}]})}for(const a of[rl,nl])this[a]&&t.push(this.assembleRowColumnHeaderData(a,n,r));if(o){const a=this.assembleFacetHeaderData(r);a&&t.push(...a)}return t}}function c8(e){return e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e}function Vxe(e,t){const n=s$(e);if(t==="number")return`toNumber(${n})`;if(t==="boolean")return`toBoolean(${n})`;if(t==="string")return`toString(${n})`;if(t==="date")return`toDate(${n})`;if(t==="flatten")return n;if(t.startsWith("date:")){const r=c8(t.slice(5,t.length));return`timeParse(${n},'${r}')`}else if(t.startsWith("utc:")){const r=c8(t.slice(4,t.length));return`utcParse(${n},'${r}')`}else return Se(ime(t)),null}function Xxe(e){const t={};return $1(e.filter,n=>{if(Rz(n)){let r=null;w$(n)?r=rs(n.equal):A$(n)?r=rs(n.lte):E$(n)?r=rs(n.lt):k$(n)?r=rs(n.gt):S$(n)?r=rs(n.gte):C$(n)?r=n.range[0]:$$(n)&&(r=(n.oneOf??n.in)[0]),r&&(Af(r)?t[n.field]="date":Vt(r)?t[n.field]="number":Ie(r)&&(t[n.field]="string")),n.timeUnit&&(t[n.field]="date")}}),t}function Kxe(e){const t={};function n(r){ih(r)?t[r.field]="date":r.type==="quantitative"&&T0e(r.aggregate)?t[r.field]="number":Jd(r.field)>1?r.field in t||(t[r.field]="flatten"):Sf(r)&&il(r.sort)&&Jd(r.sort.field)>1&&(r.sort.field in t||(t[r.sort.field]="flatten"))}if(($n(e)||fs(e))&&e.forEachFieldDef((r,i)=>{if(wi(r))n(r);else{const s=_f(i),o=e.fieldDef(s);n({...r,type:o.type})}}),$n(e)){const{mark:r,markDef:i,encoding:s}=e;if(Iu(r)&&!e.encoding.order){const o=i.orient==="horizontal"?"y":"x",a=s[o];Ce(a)&&a.type==="quantitative"&&!(a.field in t)&&(t[a.field]="number")}}return t}function Zxe(e){const t={};if($n(e)&&e.component.selection)for(const n of Ee(e.component.selection)){const r=e.component.selection[n];for(const i of r.project.items)!i.channel&&Jd(i.field)>1&&(t[i.field]="flatten")}return t}class Xr extends sn{clone(){return new Xr(null,_t(this._parse))}constructor(t,n){super(t),this._parse=n}hash(){return`Parse ${Ut(this._parse)}`}static makeExplicit(t,n,r){var o;let i={};const s=n.data;return!nu(s)&&((o=s==null?void 0:s.format)!=null&&o.parse)&&(i=s.format.parse),this.makeWithAncestors(t,i,{},r)}static makeWithAncestors(t,n,r,i){for(const a of Ee(r)){const l=i.getWithExplicit(a);l.value!==void 0&&(l.explicit||l.value===r[a]||l.value==="derived"||r[a]==="flatten"?delete r[a]:Se(h6(a,r[a],l.value)))}for(const a of Ee(n)){const l=i.get(a);l!==void 0&&(l===n[a]?delete n[a]:Se(h6(a,n[a],l)))}const s=new El(n,r);i.copyAll(s);const o={};for(const a of Ee(s.combine())){const l=s.get(a);l!==null&&(o[a]=l)}return Ee(o).length===0||i.parseNothing?null:new Xr(t,o)}get parse(){return this._parse}merge(t){this._parse={...this._parse,...t.parse},t.remove()}assembleFormatParse(){const t={};for(const n of Ee(this._parse)){const r=this._parse[n];Jd(n)===1&&(t[n]=r)}return t}producedFields(){return new Set(Ee(this._parse))}dependentFields(){return new Set(Ee(this._parse))}assembleTransforms(t=!1){return Ee(this._parse).filter(n=>t?Jd(n)>1:!0).map(n=>{const r=Vxe(n,this._parse[n]);return r?{type:"formula",expr:r,as:Rh(n)}:null}).filter(n=>n!==null)}}class yu extends sn{clone(){return new yu(null)}constructor(t){super(t)}dependentFields(){return new Set}producedFields(){return new Set([wo])}hash(){return"Identifier"}assemble(){return{type:"identifier",as:wo}}}class K0 extends sn{clone(){return new K0(null,this.params)}constructor(t,n){super(t),this.params=n}dependentFields(){return new Set}producedFields(){}hash(){return`Graticule ${Ut(this.params)}`}assemble(){return{type:"graticule",...this.params===!0?{}:this.params}}}class Z0 extends sn{clone(){return new Z0(null,this.params)}constructor(t,n){super(t),this.params=n}dependentFields(){return new Set}producedFields(){return new Set([this.params.as??"data"])}hash(){return`Hash ${Ut(this.params)}`}assemble(){return{type:"sequence",...this.params}}}class cf extends sn{constructor(t){super(null),t??(t={name:"source"});let n;if(nu(t)||(n=t.format?{...Bi(t.format,["parse"])}:{}),Pg(t))this._data={values:t.values};else if(sh(t)){if(this._data={url:t.url},!n.type){let r=/(?:\.([^.]+))?$/.exec(t.url)[1];It(["json","csv","tsv","dsv","topojson"],r)||(r="json"),n.type=r}}else Kj(t)?this._data={values:[{type:"Sphere"}]}:(Vj(t)||nu(t))&&(this._data={});this._generator=nu(t),t.name&&(this._name=t.name),n&&!an(n)&&(this._data.format=n)}dependentFields(){return new Set}producedFields(){}get data(){return this._data}hasName(){return!!this._name}get isGenerator(){return this._generator}get dataName(){return this._name}set dataName(t){this._name=t}set parent(t){throw new Error("Source nodes have to be roots.")}remove(){throw new Error("Source nodes are roots and cannot be removed.")}hash(){throw new Error("Cannot hash sources")}assemble(){return{name:this._name,...this._data,transform:[]}}}var f8=function(e,t,n,r,i){if(r==="m")throw new TypeError("Private method is not writable");if(r==="a"&&!i)throw new TypeError("Private accessor was defined without a setter");if(typeof t=="function"?e!==t||!i:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return r==="a"?i.call(e,n):i?i.value=n:t.set(e,n),n},Jxe=function(e,t,n,r){if(n==="a"&&!r)throw new TypeError("Private accessor was defined without a getter");if(typeof t=="function"?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?r:n==="a"?r.call(e):r?r.value:t.get(e)},jp;function mF(e){return e instanceof cf||e instanceof K0||e instanceof Z0}class vF{constructor(){jp.set(this,void 0),f8(this,jp,!1,"f")}setModified(){f8(this,jp,!0,"f")}get modifiedFlag(){return Jxe(this,jp,"f")}}jp=new WeakMap;class $f extends vF{getNodeDepths(t,n,r){r.set(t,n);for(const i of t.children)this.getNodeDepths(i,n+1,r);return r}optimize(t){const r=[...this.getNodeDepths(t,0,new Map).entries()].sort((i,s)=>s[1]-i[1]);for(const i of r)this.run(i[0]);return this.modifiedFlag}}class yF extends vF{optimize(t){this.run(t);for(const n of t.children)this.optimize(n);return this.modifiedFlag}}class Qxe extends yF{mergeNodes(t,n){const r=n.shift();for(const i of n)t.removeChild(i),i.parent=r,i.remove()}run(t){const n=t.children.map(i=>i.hash()),r={};for(let i=0;i1&&(this.setModified(),this.mergeNodes(t,r[i]))}}class e_e extends yF{constructor(t){super(),this.requiresSelectionId=t&&aF(t)}run(t){t instanceof yu&&(this.requiresSelectionId&&(mF(t.parent)||t.parent instanceof ho||t.parent instanceof Xr)||(this.setModified(),t.remove()))}}class t_e extends vF{optimize(t){return this.run(t,new Set),this.modifiedFlag}run(t,n){let r=new Set;t instanceof ra&&(r=t.producedFields(),r$(r,n)&&(this.setModified(),t.removeFormulas(n),t.producedFields.length===0&&t.remove()));for(const i of t.children)this.run(i,new Set([...n,...r]))}}class n_e extends yF{constructor(){super()}run(t){t instanceof zi&&!t.isRequired()&&(this.setModified(),t.remove())}}class r_e extends $f{run(t){if(!mF(t)&&!(t.numChildren()>1)){for(const n of t.children)if(n instanceof Xr)if(t instanceof Xr)this.setModified(),t.merge(n);else{if(i$(t.producedFields(),n.dependentFields()))continue;this.setModified(),n.swapWithParent()}}}}class i_e extends $f{run(t){const n=[...t.children],r=t.children.filter(i=>i instanceof Xr);if(t.numChildren()>1&&r.length>=1){const i={},s=new Set;for(const o of r){const a=o.parse;for(const l of Ee(a))l in i?i[l]!==a[l]&&s.add(l):i[l]=a[l]}for(const o of s)delete i[o];if(!an(i)){this.setModified();const o=new Xr(t,i);for(const a of n){if(a instanceof Xr)for(const l of Ee(i))delete a.parse[l];t.removeChild(a),a.parent=o,a instanceof Xr&&Ee(a.parse).length===0&&a.remove()}}}}}class s_e extends $f{run(t){t instanceof zi||t.numChildren()>0||t instanceof Ph||t instanceof cf||(this.setModified(),t.remove())}}class o_e extends $f{run(t){const n=t.children.filter(i=>i instanceof ra),r=n.pop();for(const i of n)this.setModified(),r.merge(i)}}class a_e extends $f{run(t){const n=t.children.filter(i=>i instanceof ho),r={};for(const i of n){const s=Ut(i.groupBy);s in r||(r[s]=[]),r[s].push(i)}for(const i of Ee(r)){const s=r[i];if(s.length>1){const o=s.pop();for(const a of s)o.merge(a)&&(t.removeChild(a),a.parent=o,a.remove(),this.setModified())}}}}class l_e extends $f{constructor(t){super(),this.model=t}run(t){const n=!(mF(t)||t instanceof Ih||t instanceof Xr||t instanceof yu),r=[],i=[];for(const s of t.children)s instanceof sa&&(n&&!i$(t.producedFields(),s.dependentFields())?r.push(s):i.push(s));if(r.length>0){const s=r.pop();for(const o of r)s.merge(o,this.model.renameSignal.bind(this.model));this.setModified(),t instanceof sa?t.merge(s,this.model.renameSignal.bind(this.model)):s.swapWithParent()}if(i.length>1){const s=i.pop();for(const o of i)s.merge(o,this.model.renameSignal.bind(this.model));this.setModified()}}}class u_e extends $f{run(t){const n=[...t.children];if(!Zd(n,o=>o instanceof zi)||t.numChildren()<=1)return;const i=[];let s;for(const o of n)if(o instanceof zi){let a=o;for(;a.numChildren()===1;){const[l]=a.children;if(l instanceof zi)a=l;else break}i.push(...a.children),s?(t.removeChild(o),o.parent=s.parent,s.parent.removeChild(s),s.parent=a,this.setModified()):s=a}else i.push(o);if(i.length){this.setModified();for(const o of i)o.parent.removeChild(o),o.parent=s}}}class Ff extends sn{clone(){return new Ff(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n}addDimensions(t){this.transform.groupby=Jo(this.transform.groupby.concat(t),n=>n)}dependentFields(){const t=new Set;return this.transform.groupby&&this.transform.groupby.forEach(t.add,t),this.transform.joinaggregate.map(n=>n.field).filter(n=>n!==void 0).forEach(t.add,t),t}producedFields(){return new Set(this.transform.joinaggregate.map(this.getDefaultName))}getDefaultName(t){return t.as??Re(t)}hash(){return`JoinAggregateTransform ${Ut(this.transform)}`}assemble(){const t=[],n=[],r=[];for(const s of this.transform.joinaggregate)n.push(s.op),r.push(this.getDefaultName(s)),t.push(s.field===void 0?null:s.field);const i=this.transform.groupby;return{type:"joinaggregate",as:r,ops:n,fields:t,...i!==void 0?{groupby:i}:{}}}}class ch extends sn{clone(){return new ch(null,{...this.filter})}constructor(t,n){super(t),this.filter=n}static make(t,n,r){const{config:i,markDef:s}=n,{marks:o,scales:a}=r;if(o==="include-invalid-values"&&a==="include-invalid-values")return null;const l=n.reduceFieldDef((u,c,f)=>{const d=$a(f)&&n.getScaleComponent(f);if(d){const h=d.get("type"),{aggregate:p}=c,g=O$({scaleChannel:f,markDef:s,config:i,scaleType:h,isCountAggregate:Xb(p)});g!=="show"&&g!=="always-valid"&&(u[c.field]=c)}return u},{});return Ee(l).length?new ch(t,l):null}dependentFields(){return new Set(Ee(this.filter))}producedFields(){return new Set}hash(){return`FilterInvalid ${Ut(this.filter)}`}assemble(){const t=Ee(this.filter).reduce((n,r)=>{const i=this.filter[r],s=Re(i,{expr:"datum"});return i!==null&&(i.type==="temporal"?n.push(`(isDate(${s}) || (${kA(s)}))`):i.type==="quantitative"&&n.push(kA(s))),n},[]);return t.length>0?{type:"filter",expr:t.join(" && ")}:null}}function kA(e){return`isValid(${e}) && isFinite(+${e})`}function c_e(e){return e.stack.stackBy.reduce((t,n)=>{const r=n.fieldDef,i=Re(r);return i&&t.push(i),t},[])}function f_e(e){return de(e)&&e.every(t=>Ie(t))&&e.length>1}class ol extends sn{clone(){return new ol(null,_t(this._stack))}constructor(t,n){super(t),this._stack=n}static makeFromTransform(t,n){const{stack:r,groupby:i,as:s,offset:o="zero"}=n,a=[],l=[];if(n.sort!==void 0)for(const f of n.sort)a.push(f.field),l.push(qn(f.order,"ascending"));const u={field:a,order:l};let c;return f_e(s)?c=s:Ie(s)?c=[s,`${s}_end`]:c=[`${n.stack}_start`,`${n.stack}_end`],new ol(t,{dimensionFieldDefs:[],stackField:r,groupby:i,offset:o,sort:u,facetby:[],as:c})}static makeFromEncoding(t,n){const r=n.stack,{encoding:i}=n;if(!r)return null;const{groupbyChannels:s,fieldChannel:o,offset:a,impute:l}=r,u=s.map(h=>{const p=i[h];return _o(p)}).filter(h=>!!h),c=c_e(n),f=n.encoding.order;let d;if(de(f)||Ce(f))d=hz(f);else{const h=rj(f)?f.sort:o==="y"?"descending":"ascending";d=c.reduce((p,g)=>(p.field.includes(g)||(p.field.push(g),p.order.push(h)),p),{field:[],order:[]})}return new ol(t,{dimensionFieldDefs:u,stackField:n.vgField(o),facetby:[],stackby:c,sort:d,offset:a,impute:l,as:[n.vgField(o,{suffix:"start",forAs:!0}),n.vgField(o,{suffix:"end",forAs:!0})]})}get stack(){return this._stack}addDimensions(t){this._stack.facetby.push(...t)}dependentFields(){const t=new Set;return t.add(this._stack.stackField),this.getGroupbyFields().forEach(t.add,t),this._stack.facetby.forEach(t.add,t),this._stack.sort.field.forEach(t.add,t),t}producedFields(){return new Set(this._stack.as)}hash(){return`Stack ${Ut(this._stack)}`}getGroupbyFields(){const{dimensionFieldDefs:t,impute:n,groupby:r}=this._stack;return t.length>0?t.map(i=>i.bin?n?[Re(i,{binSuffix:"mid"})]:[Re(i,{}),Re(i,{binSuffix:"end"})]:[Re(i)]).flat():r??[]}assemble(){const t=[],{facetby:n,dimensionFieldDefs:r,stackField:i,stackby:s,sort:o,offset:a,impute:l,as:u}=this._stack;if(l)for(const c of r){const{bandPosition:f=.5,bin:d}=c;if(d){const h=Re(c,{expr:"datum"}),p=Re(c,{expr:"datum",binSuffix:"end"});t.push({type:"formula",expr:`${kA(h)} ? ${f}*${h}+${1-f}*${p} : ${h}`,as:Re(c,{binSuffix:"mid",forAs:!0})})}t.push({type:"impute",field:i,groupby:[...s,...n],key:Re(c,{binSuffix:"mid"}),method:"value",value:0})}return t.push({type:"stack",groupby:[...this.getGroupbyFields(),...n],field:i,sort:o,as:u,offset:a}),t}}class Bh extends sn{clone(){return new Bh(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n}addDimensions(t){this.transform.groupby=Jo(this.transform.groupby.concat(t),n=>n)}dependentFields(){const t=new Set;return(this.transform.groupby??[]).forEach(t.add,t),(this.transform.sort??[]).forEach(n=>t.add(n.field)),this.transform.window.map(n=>n.field).filter(n=>n!==void 0).forEach(t.add,t),t}producedFields(){return new Set(this.transform.window.map(this.getDefaultName))}getDefaultName(t){return t.as??Re(t)}hash(){return`WindowTransform ${Ut(this.transform)}`}assemble(){const t=[],n=[],r=[],i=[];for(const f of this.transform.window)n.push(f.op),r.push(this.getDefaultName(f)),i.push(f.param===void 0?null:f.param),t.push(f.field===void 0?null:f.field);const s=this.transform.frame,o=this.transform.groupby;if(s&&s[0]===null&&s[1]===null&&n.every(f=>p$(f)))return{type:"joinaggregate",as:r,ops:n,fields:t,...o!==void 0?{groupby:o}:{}};const a=[],l=[];if(this.transform.sort!==void 0)for(const f of this.transform.sort)a.push(f.field),l.push(f.order??"ascending");const u={field:a,order:l},c=this.transform.ignorePeers;return{type:"window",params:i,as:r,ops:n,fields:t,sort:u,...c!==void 0?{ignorePeers:c}:{},...o!==void 0?{groupby:o}:{},...s!==void 0?{frame:s}:{}}}}function d_e(e){function t(n){if(!(n instanceof Ph)){const r=n.clone();if(r instanceof zi){const i=CA+r.getSource();r.setSource(i),e.model.component.data.outputNodes[i]=r}else(r instanceof ho||r instanceof ol||r instanceof Bh||r instanceof Ff)&&r.addDimensions(e.fields);for(const i of n.children.flatMap(t))i.parent=r;return[r]}return n.children.flatMap(t)}return t}function SA(e){if(e instanceof Ph)if(e.numChildren()===1&&!(e.children[0]instanceof zi)){const t=e.children[0];(t instanceof ho||t instanceof ol||t instanceof Bh||t instanceof Ff)&&t.addDimensions(e.fields),t.swapWithParent(),SA(e)}else{const t=e.model.component.data.main;QU(t);const n=d_e(e),r=e.children.map(n).flat();for(const i of r)i.parent=t}else e.children.map(SA)}function QU(e){if(e instanceof zi&&e.type===Fn.Main&&e.numChildren()===1){const t=e.children[0];t instanceof Ph||(t.swapWithParent(),QU(e))}}const CA="scale_",Lm=5;function $A(e){for(const t of e){for(const n of t.children)if(n.parent!==t)return!1;if(!$A(t.children))return!1}return!0}function Vs(e,t){let n=!1;for(const r of t)n=e.optimize(r)||n;return n}function d8(e,t,n){let r=e.sources,i=!1;return i=Vs(new n_e,r)||i,i=Vs(new e_e(t),r)||i,r=r.filter(s=>s.numChildren()>0),i=Vs(new s_e,r)||i,r=r.filter(s=>s.numChildren()>0),n||(i=Vs(new r_e,r)||i,i=Vs(new l_e(t),r)||i,i=Vs(new t_e,r)||i,i=Vs(new i_e,r)||i,i=Vs(new a_e,r)||i,i=Vs(new o_e,r)||i,i=Vs(new Qxe,r)||i,i=Vs(new u_e,r)||i),e.sources=r,i}function h_e(e,t){$A(e.sources);let n=0,r=0;for(let i=0;it(n))}}function eq(e){$n(e)?p_e(e):g_e(e)}function p_e(e){const t=e.component.scales;for(const n of Ee(t)){const r=v_e(e,n);if(t[n].setWithExplicit("domains",r),b_e(e,n),e.component.data.isFaceted){let s=e;for(;!fs(s)&&s.parent;)s=s.parent;if(s.component.resolve.scale[n]==="shared")for(const a of r.value)Ka(a)&&(a.data=CA+a.data.replace(CA,""))}}}function g_e(e){for(const n of e.children)eq(n);const t=e.component.scales;for(const n of Ee(t)){let r,i=null;for(const s of e.children){const o=s.component.scales[n];if(o){r===void 0?r=o.getWithExplicit("domains"):r=vu(r,o.getWithExplicit("domains"),"domains","scale",FA);const a=o.get("selectionExtent");i&&a&&i.param!==a.param&&Se(Z0e),i=a}}t[n].setWithExplicit("domains",r),i&&t[n].set("selectionExtent",i,!0)}}function m_e(e,t,n,r){if(e==="unaggregated"){const{valid:i,reason:s}=h8(t,n);if(!i){Se(s);return}}else if(e===void 0&&r.useUnaggregatedDomain){const{valid:i}=h8(t,n);if(i)return"unaggregated"}return e}function v_e(e,t){const n=e.getScaleComponent(t).get("type"),{encoding:r}=e,i=m_e(e.scaleDomain(t),e.typedFieldDef(t),n,e.config.scale);return i!==e.scaleDomain(t)&&(e.specifiedScales[t]={...e.specifiedScales[t],domain:i}),t==="x"&&tr(r.x2)?tr(r.x)?vu(Fl(n,i,e,"x"),Fl(n,i,e,"x2"),"domain","scale",FA):Fl(n,i,e,"x2"):t==="y"&&tr(r.y2)?tr(r.y)?vu(Fl(n,i,e,"y"),Fl(n,i,e,"y2"),"domain","scale",FA):Fl(n,i,e,"y2"):Fl(n,i,e,t)}function y_e(e,t,n){return e.map(r=>({signal:`{data: ${l2(r,{timeUnit:n,type:t})}}`}))}function E_(e,t,n){var i;const r=(i=mr(n))==null?void 0:i.unit;return t==="temporal"||r?y_e(e,t,r):[e]}function Fl(e,t,n,r){const{encoding:i,markDef:s,mark:o,config:a,stack:l}=n,u=tr(i[r]),{type:c}=u,f=u.timeUnit,d=tbe({invalid:ha("invalid",s,a),isPath:Iu(o)});if(E1e(t)){const g=Fl(e,void 0,n,r),m=E_(t.unionWith,c,f);return jo([...m,...g.value])}else{if(nt(t))return jo([t]);if(t&&t!=="unaggregated"&&!zz(t))return jo(E_(t,c,f))}if(l&&r===l.fieldChannel){if(l.offset==="normalize")return Zi([[0,1]]);const g=n.requestDataName(d);return Zi([{data:g,field:n.vgField(r,{suffix:"start"})},{data:g,field:n.vgField(r,{suffix:"end"})}])}const h=$a(r)&&Ce(u)?x_e(n,r,e):void 0;if(Fa(u)){const g=E_([u.datum],c,f);return Zi(g)}const p=u;if(t==="unaggregated"){const{field:g}=u;return Zi([{data:n.requestDataName(d),field:Re({field:g,aggregate:"min"})},{data:n.requestDataName(d),field:Re({field:g,aggregate:"max"})}])}else if(dn(p.bin)){if(yr(e))return Zi(e==="bin-ordinal"?[]:[{data:Og(h)?n.requestDataName(d):n.requestDataName(Fn.Raw),field:n.vgField(r,W0(p,r)?{binSuffix:"range"}:{}),sort:h===!0||!Le(h)?{field:n.vgField(r,{}),op:"min"}:h}]);{const{bin:g}=p;if(dn(g)){const m=gF(n,p.field,g);return Zi([new lr(()=>{const y=n.getSignalName(m);return`[${y}.start, ${y}.stop]`})])}else return Zi([{data:n.requestDataName(d),field:n.vgField(r,{})}])}}else if(p.timeUnit&&It(["time","utc"],e)){const g=i[Ca(r)];if(nj(p,g,s,a)){const m=n.requestDataName(d),y=mu({fieldDef:p,fieldDef2:g,markDef:s,config:a}),b=Ig(o)&&y!==.5&&Wn(r);return Zi([{data:m,field:n.vgField(r,b?{suffix:p2}:{})},{data:m,field:n.vgField(r,{suffix:b?g2:"end"})}])}}return Zi(h?[{data:Og(h)?n.requestDataName(d):n.requestDataName(Fn.Raw),field:n.vgField(r),sort:h}]:[{data:n.requestDataName(d),field:n.vgField(r)}])}function A_(e,t){const{op:n,field:r,order:i}=e;return{op:n??(t?"sum":i2),...r?{field:zs(r)}:{},...i?{order:i}:{}}}function b_e(e,t){var a;const n=e.component.scales[t],r=e.specifiedScales[t].domain,i=(a=e.fieldDef(t))==null?void 0:a.bin,s=zz(r)?r:void 0,o=wf(i)&&Kb(i.extent)?i.extent:void 0;(s||o)&&n.set("selectionExtent",s??o,!0)}function x_e(e,t,n){if(!yr(n))return;const r=e.fieldDef(t),i=r.sort;if(ej(i))return{op:"min",field:lh(r,t),order:"ascending"};const{stack:s}=e,o=s?new Set([...s.groupbyFields,...s.stackBy.map(a=>a.fieldDef.field)]):void 0;if(il(i)){const a=s&&!o.has(i.field);return A_(i,a)}else if(tve(i)){const{encoding:a,order:l}=i,u=e.fieldDef(a),{aggregate:c,field:f}=u,d=s&&!o.has(f);if(dl(c)||Lu(c))return A_({field:Re(u),order:l},d);if(p$(c)||!c)return A_({op:c,field:f,order:l},d)}else{if(i==="descending")return{op:"min",field:e.vgField(t),order:"descending"};if(It(["ascending",void 0],i))return!0}}function h8(e,t){const{aggregate:n,type:r}=e;return n?Ie(n)&&!N0e.has(n)?{valid:!1,reason:Sme(n)}:r==="quantitative"&&t==="log"?{valid:!1,reason:Cme(e)}:{valid:!0}:{valid:!1,reason:kme(e)}}function FA(e,t,n,r){return e.explicit&&t.explicit&&Se(Tme(n,r,e.value,t.value)),{explicit:e.explicit,value:[...e.value,...t.value]}}function __e(e){const t=Jo(e.map(o=>{if(Ka(o)){const{sort:a,...l}=o;return l}return o}),Ut),n=Jo(e.map(o=>{if(Ka(o)){const a=o.sort;return a!==void 0&&!Og(a)&&("op"in a&&a.op==="count"&&delete a.field,a.order==="ascending"&&delete a.order),a}}).filter(o=>o!==void 0),Ut);if(t.length===0)return;if(t.length===1){const o=e[0];if(Ka(o)&&n.length>0){let a=n[0];if(n.length>1){Se(g6);const l=n.filter(u=>Le(u)&&"op"in u&&u.op!=="min");n.every(u=>Le(u)&&"op"in u)&&l.length===1?a=l[0]:a=!0}else if(Le(a)&&"field"in a){const l=a.field;o.field===l&&(a=a.order?{order:a.order}:!0)}return{...o,sort:a}}return o}const r=Jo(n.map(o=>Og(o)||!("op"in o)||Ie(o.op)&&Ue(D0e,o.op)?o:(Se(Nme(o)),!0)),Ut);let i;r.length===1?i=r[0]:r.length>1&&(Se(g6),i=!0);const s=Jo(e.map(o=>Ka(o)?o.data:null),o=>o);return s.length===1&&s[0]!==null?{data:s[0],fields:t.map(a=>a.field),...i?{sort:i}:{}}:{fields:t,...i?{sort:i}:{}}}function bF(e){if(Ka(e)&&Ie(e.field))return e.field;if(O0e(e)){let t;for(const n of e.fields)if(Ka(n)&&Ie(n.field)){if(!t)t=n.field;else if(t!==n.field)return Se(Ome),t}return Se(Lme),t}else if(L0e(e)){Se(Ime);const t=e.fields[0];return Ie(t)?t:void 0}}function A2(e,t){const r=e.component.scales[t].get("domains").map(i=>(Ka(i)&&(i.data=e.lookupDataSource(i.data)),i));return __e(r)}function tq(e){return zh(e)||xF(e)?e.children.reduce((t,n)=>t.concat(tq(n)),p8(e)):p8(e)}function p8(e){return Ee(e.component.scales).reduce((t,n)=>{const r=e.component.scales[n];if(r.merged)return t;const i=r.combine(),{name:s,type:o,selectionExtent:a,domains:l,range:u,reverse:c,...f}=i,d=w_e(i.range,s,n,e),h=A2(e,n),p=a?dbe(e,a,r,h):null;return t.push({name:s,type:o,...h?{domain:h}:{},...p?{domainRaw:p}:{},range:d,...c!==void 0?{reverse:c}:{},...f}),t},[])}function w_e(e,t,n,r){if(Wn(n)){if(Ef(e))return{step:{signal:`${t}_step`}}}else if(Le(e)&&Ka(e))return{...e,data:r.lookupDataSource(e.data)};return e}class nq extends El{constructor(t,n){super({},{name:t}),this.merged=!1,this.setWithExplicit("type",n)}domainHasZero(){const t=this.get("type");if(It([Fr.LOG,Fr.TIME,Fr.UTC],t))return"definitely-not";const n=this.get("zero");if(n===!0||n===void 0&&It([Fr.LINEAR,Fr.SQRT,Fr.POW],t))return"definitely";const r=this.get("domains");if(r.length>0){let i=!1,s=!1,o=!1;for(const a of r){if(de(a)){const l=a[0],u=a[a.length-1];if(Vt(l)&&Vt(u))if(l<=0&&u>=0){i=!0;continue}else{s=!0;continue}}o=!0}if(i)return"definitely";if(s&&!o)return"definitely-not"}return"maybe"}}const E_e=["range","scheme"];function A_e(e){const t=e.component.scales;for(const n of h$){const r=t[n];if(!r)continue;const i=k_e(n,e);r.setWithExplicit("range",i)}}function g8(e,t){const n=e.fieldDef(t);if(n!=null&&n.bin){const{bin:r,field:i}=n,s=Gi(t),o=e.getName(s);if(Le(r)&&r.binned&&r.step!==void 0)return new lr(()=>{const a=e.scaleName(t),l=`(domain("${a}")[1] - domain("${a}")[0]) / ${r.step}`;return`${e.getSignalName(o)} / (${l})`});if(dn(r)){const a=gF(e,i,r);return new lr(()=>{const l=e.getSignalName(a),u=`(${l}.stop - ${l}.start) / ${l}.step`;return`${e.getSignalName(o)} / (${u})`})}}}function k_e(e,t){const n=t.specifiedScales[e],{size:r}=t,s=t.getScaleComponent(e).get("type");for(const f of E_e)if(n[f]!==void 0){const d=aA(s,f),h=jz(e,f);if(!d)Se(xz(s,f,e));else if(h)Se(h);else switch(f){case"range":{const p=n.range;if(de(p)){if(Wn(e))return jo(p.map(g=>{if(g==="width"||g==="height"){const m=t.getName(g),y=t.getSignalName.bind(t);return lr.fromName(y,m)}return g}))}else if(Le(p))return jo({data:t.requestDataName(Fn.Main),field:p.field,sort:{op:"min",field:t.vgField(e)}});return jo(p)}case"scheme":return jo(S_e(n[f]))}}const o=e===wn||e==="xOffset"?"width":"height",a=r[o];if(ga(a)){if(Wn(e))if(yr(s)){const f=iq(a,t,e);if(f)return jo({step:f})}else Se(_z(o));else if(I0(e)){const f=e===Du?"x":"y";if(t.getScaleComponent(f).get("type")==="band"){const p=sq(a,s);if(p)return jo(p)}}}const{rangeMin:l,rangeMax:u}=n,c=C_e(e,t);return(l!==void 0||u!==void 0)&&aA(s,"rangeMin")&&de(c)&&c.length===2?jo([l??c[0],u??c[1]]):Zi(c)}function S_e(e){return w1e(e)?{scheme:e.name,...Bi(e,["name"])}:{scheme:e}}function rq(e,t,n,{center:r}={}){const i=Gi(e),s=t.getName(i),o=t.getSignalName.bind(t);return e===xr&&bo(n)?r?[lr.fromName(a=>`${o(a)}/2`,s),lr.fromName(a=>`-${o(a)}/2`,s)]:[lr.fromName(o,s),0]:r?[lr.fromName(a=>`-${o(a)}/2`,s),lr.fromName(a=>`${o(a)}/2`,s)]:[0,lr.fromName(o,s)]}function C_e(e,t){const{size:n,config:r,mark:i,encoding:s}=t,{type:o}=tr(s[e]),l=t.getScaleComponent(e).get("type"),{domain:u,domainMid:c}=t.specifiedScales[e];switch(e){case wn:case xr:{if(It(["point","band"],l)){const f=oq(e,n,r.view);if(ga(f))return{step:iq(f,t,e)}}return rq(e,t,l)}case Du:case Nh:return $_e(e,t,l);case bl:{const f=M_e(i,r),d=T_e(i,n,t,r);return th(l)?D_e(f,d,F_e(l,r,u,e)):[f,d]}case Ws:return[0,Math.PI*2];case xf:return[0,360];case Co:return[0,new lr(()=>{const f=t.getSignalName(fs(t.parent)?"child_width":"width"),d=t.getSignalName(fs(t.parent)?"child_height":"height");return`min(${f},${d})/2`})];case Mu:return{step:1e3/r.scale.framesPerSecond};case Nu:return[r.scale.minStrokeWidth,r.scale.maxStrokeWidth];case Ou:return[[1,0],[4,2],[2,1],[1,1],[1,2,4,2]];case Hi:return"symbol";case Wi:case ka:case Sa:return l==="ordinal"?o==="nominal"?"category":"ordinal":c!==void 0?"diverging":i==="rect"||i==="geoshape"?"heatmap":"ramp";case xl:case Tu:case Ru:return[r.scale.minOpacity,r.scale.maxOpacity]}}function iq(e,t,n){const{encoding:r}=t,i=t.getScaleComponent(n),s=u$(n),o=r[s];if(Nj({step:e,offsetIsDiscrete:kt(o)&&Oz(o.type)})==="offset"&&pj(r,s)){const l=t.getScaleComponent(s);let c=`domain('${t.scaleName(s)}').length`;if(l.get("type")==="band"){const d=l.get("paddingInner")??l.get("padding")??0,h=l.get("paddingOuter")??l.get("padding")??0;c=`bandspace(${c}, ${d}, ${h})`}const f=i.get("paddingInner")??i.get("padding");return{signal:`${e.step} * ${c} / (1-${z0e(f)})`}}else return e.step}function sq(e,t){if(Nj({step:e,offsetIsDiscrete:yr(t)})==="offset")return{step:e.step}}function $_e(e,t,n){const r=e===Du?"x":"y",i=t.getScaleComponent(r);if(!i)return rq(r,t,n,{center:!0});const s=i.get("type"),o=t.scaleName(r),{markDef:a,config:l}=t;if(s==="band"){const u=oq(r,t.size,t.config.view);if(ga(u)){const c=sq(u,n);if(c)return c}return[0,{signal:`bandwidth('${o}')`}]}else{const u=t.encoding[r];if(Ce(u)&&u.timeUnit){const c=Mz(u.timeUnit,p=>`scale('${o}', ${p})`),f=t.config.scale.bandWithNestedOffsetPaddingInner,d=mu({fieldDef:u,markDef:a,config:l})-.5,h=d!==0?` + ${d}`:"";if(f){const p=nt(f)?`${f.signal}/2`+h:`${f/2+d}`,g=nt(f)?`(1 - ${f.signal}/2)`+h:`${1-f/2+d}`;return[{signal:`${p} * (${c})`},{signal:`${g} * (${c})`}]}return[0,{signal:c}]}return UB(`Cannot use ${e} scale if ${r} scale is not discrete.`)}}function oq(e,t,n){const r=e===wn?"width":"height",i=t[r];return i||cy(n,r)}function F_e(e,t,n,r){switch(e){case"quantile":return t.scale.quantileCount;case"quantize":return t.scale.quantizeCount;case"threshold":return n!==void 0&&de(n)?n.length+1:(Se(Gme(r)),3)}}function D_e(e,t,n){const r=()=>{const i=uo(t),s=uo(e),o=`(${i} - ${s}) / (${n} - 1)`;return`sequence(${s}, ${i} + ${o}, ${o})`};return nt(t)?new lr(r):{signal:r()}}function M_e(e,t){switch(e){case"bar":case"tick":return t.scale.minBandSize;case"line":case"trail":case"rule":return t.scale.minStrokeWidth;case"text":return t.scale.minFontSize;case"point":case"square":case"circle":return t.scale.minSize}throw new Error(Zb("size",e))}const m8=.95;function T_e(e,t,n,r){const i={x:g8(n,"x"),y:g8(n,"y")};switch(e){case"bar":case"tick":{if(r.scale.maxBandSize!==void 0)return r.scale.maxBandSize;const s=v8(t,i,r.view);return Vt(s)?s-1:new lr(()=>`${s.signal} - 1`)}case"line":case"trail":case"rule":return r.scale.maxStrokeWidth;case"text":return r.scale.maxFontSize;case"point":case"square":case"circle":{if(r.scale.maxSize)return r.scale.maxSize;const s=v8(t,i,r.view);return Vt(s)?Math.pow(m8*s,2):new lr(()=>`pow(${m8} * ${s.signal}, 2)`)}}throw new Error(Zb("size",e))}function v8(e,t,n){const r=ga(e.width)?e.width.step:fA(n,"width"),i=ga(e.height)?e.height.step:fA(n,"height");return t.x||t.y?new lr(()=>`min(${[t.x?t.x.signal:r,t.y?t.y.signal:i].join(", ")})`):Math.min(r,i)}function aq(e,t){$n(e)?R_e(e,t):uq(e,t)}function R_e(e,t){const n=e.component.scales,{config:r,encoding:i,markDef:s,specifiedScales:o}=e;for(const a of Ee(n)){const l=o[a],u=n[a],c=e.getScaleComponent(a),f=tr(i[a]),d=l[t],h=c.get("type"),p=c.get("padding"),g=c.get("paddingInner"),m=aA(h,t),y=jz(a,t);if(d!==void 0&&(m?y&&Se(y):Se(xz(h,t,a))),m&&y===void 0)if(d!==void 0){const b=f.timeUnit,x=f.type;switch(t){case"domainMax":case"domainMin":Af(l[t])||x==="temporal"||b?u.set(t,{signal:l2(l[t],{type:x,timeUnit:b})},!0):u.set(t,l[t],!0);break;default:u.copyKeyFromObject(t,l)}}else{const b=Ae(y8,t)?y8[t]({model:e,channel:a,fieldOrDatumDef:f,scaleType:h,scalePadding:p,scalePaddingInner:g,domain:l.domain,domainMin:l.domainMin,domainMax:l.domainMax,markDef:s,config:r,hasNestedOffsetScale:gj(i,a),hasSecondaryRangeChannel:!!i[Ca(a)]}):r.scale[t];b!==void 0&&u.set(t,b,!1)}}}const y8={bins:({model:e,fieldOrDatumDef:t})=>Ce(t)?N_e(e,t):void 0,interpolate:({channel:e,fieldOrDatumDef:t})=>O_e(e,t.type),nice:({scaleType:e,channel:t,domain:n,domainMin:r,domainMax:i,fieldOrDatumDef:s})=>L_e(e,t,n,r,i,s),padding:({channel:e,scaleType:t,fieldOrDatumDef:n,markDef:r,config:i})=>I_e(e,t,i.scale,n,r,i.bar),paddingInner:({scalePadding:e,channel:t,markDef:n,scaleType:r,config:i,hasNestedOffsetScale:s})=>P_e(e,t,n.type,r,i.scale,s),paddingOuter:({scalePadding:e,channel:t,scaleType:n,scalePaddingInner:r,config:i,hasNestedOffsetScale:s})=>B_e(e,t,n,r,i.scale,s),reverse:({fieldOrDatumDef:e,scaleType:t,channel:n,config:r})=>{const i=Ce(e)?e.sort:void 0;return z_e(t,i,n,r.scale)},zero:({channel:e,fieldOrDatumDef:t,domain:n,markDef:r,scaleType:i,config:s,hasSecondaryRangeChannel:o})=>j_e(e,t,n,r,i,s.scale,o)};function lq(e){$n(e)?A_e(e):uq(e,"range")}function uq(e,t){const n=e.component.scales;for(const r of e.children)t==="range"?lq(r):aq(r,t);for(const r of Ee(n)){let i;for(const s of e.children){const o=s.component.scales[r];if(o){const a=o.getWithExplicit(t);i=vu(i,a,t,"scale",Yj((l,u)=>{switch(t){case"range":return l.step&&u.step?l.step-u.step:0}return 0}))}}n[r].setWithExplicit(t,i)}}function N_e(e,t){const n=t.bin;if(dn(n)){const r=gF(e,t.field,n);return new lr(()=>e.getSignalName(r))}else if(Sr(n)&&wf(n)&&n.step!==void 0)return{step:n.step}}function O_e(e,t){if(It([Wi,ka,Sa],e)&&t!=="nominal")return"hcl"}function L_e(e,t,n,r,i,s){var o;if(!((o=_o(s))!=null&&o.bin||de(n)||i!=null||r!=null||It([Fr.TIME,Fr.UTC],e)))return Wn(t)?!0:void 0}function I_e(e,t,n,r,i,s){if(Wn(e)){if(Qo(t)){if(n.continuousPadding!==void 0)return n.continuousPadding;const{type:o,orient:a}=i;if(o==="bar"&&!(Ce(r)&&(r.bin||r.timeUnit))&&(a==="vertical"&&e==="x"||a==="horizontal"&&e==="y"))return s.continuousBandSize}if(t===Fr.POINT)return n.pointPadding}}function P_e(e,t,n,r,i,s=!1){if(e===void 0){if(Wn(t)){const{bandPaddingInner:o,barBandPaddingInner:a,rectBandPaddingInner:l,tickBandPaddingInner:u,bandWithNestedOffsetPaddingInner:c}=i;return s?c:qn(o,n==="bar"?a:n==="tick"?u:l)}else if(I0(t)&&r===Fr.BAND)return i.offsetBandPaddingInner}}function B_e(e,t,n,r,i,s=!1){if(e===void 0){if(Wn(t)){const{bandPaddingOuter:o,bandWithNestedOffsetPaddingOuter:a}=i;if(s)return a;if(n===Fr.BAND)return qn(o,nt(r)?{signal:`${r.signal}/2`}:r/2)}else if(I0(t)){if(n===Fr.POINT)return .5;if(n===Fr.BAND)return i.offsetBandPaddingOuter}}}function z_e(e,t,n,r){if(n==="x"&&r.xReverse!==void 0)return bo(e)&&t==="descending"?nt(r.xReverse)?{signal:`!${r.xReverse.signal}`}:!r.xReverse:r.xReverse;if(bo(e)&&t==="descending")return!0}function j_e(e,t,n,r,i,s,o){if(!!n&&n!=="unaggregated"&&bo(i)){if(de(n)){const l=n[0],u=n[n.length-1];if(Vt(l)&&l<=0&&Vt(u)&&u>=0)return!0}return!1}if(e==="size"&&t.type==="quantitative"&&!th(i))return!0;if(!(Ce(t)&&t.bin)&&It([..._l,..._0e],e)){const{orient:l,type:u}=r;return It(["bar","area","line","trail"],u)&&(l==="horizontal"&&e==="y"||l==="vertical"&&e==="x")?!1:It(["bar","area"],u)&&!o?!0:s==null?void 0:s.zero}return!1}function U_e(e,t,n,r,i=!1){const s=q_e(t,n,r,i),{type:o}=e;return $a(t)?o!==void 0?F1e(t,o)?Ce(n)&&!$1e(o,n.type)?(Se(Dme(o,s)),s):o:(Se(Fme(t,o,s)),s):s:null}function q_e(e,t,n,r){var i;switch(t.type){case"nominal":case"ordinal":{if(fd(e)||u_(e)==="discrete")return e==="shape"&&t.type==="ordinal"&&Se(c_(e,"ordinal")),"ordinal";if(l_(e))return"band";if(Wn(e)||I0(e)){if(It(["rect","bar","image","rule","tick"],n.type)||r)return"band"}else if(n.type==="arc"&&e in d$)return"band";const s=n[Gi(e)];return rf(s)||rh(t)&&((i=t.axis)!=null&&i.tickBand)?"band":"point"}case"temporal":return fd(e)?"time":u_(e)==="discrete"?(Se(c_(e,"temporal")),"ordinal"):Ce(t)&&t.timeUnit&&mr(t.timeUnit).utc?"utc":l_(e)?"band":"time";case"quantitative":return fd(e)?Ce(t)&&dn(t.bin)?"bin-ordinal":"linear":u_(e)==="discrete"?(Se(c_(e,"quantitative")),"ordinal"):l_(e)?"band":"linear";case"geojson":return}throw new Error(yz(t.type))}function W_e(e,{ignoreRange:t}={}){cq(e),eq(e);for(const n of C1e)aq(e,n);t||lq(e)}function cq(e){$n(e)?e.component.scales=H_e(e):e.component.scales=Y_e(e)}function H_e(e){const{encoding:t,mark:n,markDef:r}=e,i={};for(const s of h$){const o=tr(t[s]);if(o&&n===Wz&&s===Hi&&o.type===Oh)continue;let a=o&&o.scale;if(o&&a!==null&&a!==!1){a??(a={});const l=gj(t,s),u=U_e(a,s,o,r,l);i[s]=new nq(e.scaleName(`${s}`,!0),{value:u,explicit:a.type===u})}}return i}const G_e=Yj((e,t)=>v6(e)-v6(t));function Y_e(e){var t;const n=e.component.scales={},r={},i=e.component.resolve;for(const s of e.children){cq(s);for(const o of Ee(s.component.scales))if((t=i.scale)[o]??(t[o]=jU(o,e)),i.scale[o]==="shared"){const a=r[o],l=s.component.scales[o].getWithExplicit("type");a?v1e(a.value,l.value)?r[o]=vu(a,l,"type","scale",G_e):(i.scale[o]="independent",delete r[o]):r[o]=l}}for(const s of Ee(r)){const o=e.scaleName(s,!0),a=r[s];n[s]=new nq(o,a);for(const l of e.children){const u=l.component.scales[s];u&&(l.renameScale(u.get("name"),o),u.merged=!0)}}return n}class k_{constructor(){this.nameMap={}}rename(t,n){this.nameMap[t]=n}has(t){return this.nameMap[t]!==void 0}get(t){for(;this.nameMap[t]&&t!==this.nameMap[t];)t=this.nameMap[t];return t}}function $n(e){return(e==null?void 0:e.type)==="unit"}function fs(e){return(e==null?void 0:e.type)==="facet"}function xF(e){return(e==null?void 0:e.type)==="concat"}function zh(e){return(e==null?void 0:e.type)==="layer"}class _F{constructor(t,n,r,i,s,o,a){this.type=n,this.parent=r,this.config=s,this.parent=r,this.config=s,this.view=$r(a),this.name=t.name??i,this.title=Nl(t.title)?{text:t.title}:t.title?$r(t.title):void 0,this.scaleNameMap=r?r.scaleNameMap:new k_,this.projectionNameMap=r?r.projectionNameMap:new k_,this.signalNameMap=r?r.signalNameMap:new k_,this.data=t.data,this.description=t.description,this.transforms=qye(t.transform??[]),this.layout=n==="layer"||n==="unit"?{}:Yve(t,n,s),this.component={data:{sources:r?r.component.data.sources:[],outputNodes:r?r.component.data.outputNodes:{},outputNodeRefCounts:r?r.component.data.outputNodeRefCounts:{},isFaceted:s2(t)||(r==null?void 0:r.component.data.isFaceted)&&t.data===void 0},layoutSize:new El,layoutHeaders:{row:{},column:{},facet:{}},mark:null,resolve:{scale:{},axis:{},legend:{},...o?_t(o):{}},selection:null,scales:null,projection:null,axes:{},legends:{}}}get width(){return this.getSizeSignalRef("width")}get height(){return this.getSizeSignalRef("height")}parse(){this.parseScale(),this.parseLayoutSize(),this.renameTopLevelLayoutSizeSignal(),this.parseSelections(),this.parseProjection(),this.parseData(),this.parseAxesAndHeaders(),this.parseLegends(),this.parseMarkGroup()}parseScale(){W_e(this)}parseProjection(){ZU(this)}renameTopLevelLayoutSizeSignal(){this.getName("width")!=="width"&&this.renameSignal(this.getName("width"),"width"),this.getName("height")!=="height"&&this.renameSignal(this.getName("height"),"height")}parseLegends(){GU(this)}assembleEncodeFromView(t){const{style:n,...r}=t,i={};for(const s of Ee(r)){const o=r[s];o!==void 0&&(i[s]=vn(o))}return i}assembleGroupEncodeEntry(t){let n={};return this.view&&(n=this.assembleEncodeFromView(this.view)),!t&&(this.description&&(n.description=vn(this.description)),this.type==="unit"||this.type==="layer")?{width:this.getSizeSignalRef("width"),height:this.getSizeSignalRef("height"),...n}:an(n)?void 0:n}assembleLayout(){if(!this.layout)return;const{spacing:t,...n}=this.layout,{component:r,config:i}=this,s=hxe(r.layoutHeaders,i);return{padding:t,...this.assembleDefaultLayout(),...n,...s?{titleBand:s}:{}}}assembleDefaultLayout(){return{}}assembleHeaderMarks(){const{layoutHeaders:t}=this.component;let n=[];for(const r of Fs)t[r].title&&n.push(axe(this,r));for(const r of fF)n=n.concat(lxe(this,r));return n}assembleAxes(){return V2e(this.component.axes,this.config)}assembleLegends(){return VU(this)}assembleProjections(){return Lxe(this)}assembleTitle(){const{encoding:t,...n}=this.title??{},r={...uz(this.config.title).nonMarkTitleProperties,...n,...t?{encode:{update:t}}:{}};if(r.text)return It(["unit","layer"],this.type)?It(["middle",void 0],r.anchor)&&(r.frame??(r.frame="group")):r.anchor??(r.anchor="start"),an(r)?void 0:r}assembleGroup(t=[]){const n={};t=t.concat(this.assembleSignals()),t.length>0&&(n.signals=t);const r=this.assembleLayout();r&&(n.layout=r),n.marks=[].concat(this.assembleHeaderMarks(),this.assembleMarks());const i=!this.parent||fs(this.parent)?tq(this):[];i.length>0&&(n.scales=i);const s=this.assembleAxes();s.length>0&&(n.axes=s);const o=this.assembleLegends();return o.length>0&&(n.legends=o),n}getName(t){return _n((this.name?`${this.name}_`:"")+t)}getDataName(t){return this.getName(Fn[t].toLowerCase())}requestDataName(t){const n=this.getDataName(t),r=this.component.data.outputNodeRefCounts;return r[n]=(r[n]||0)+1,n}getSizeSignalRef(t){if(fs(this.parent)){const n=BU(t),r=Vb(n),i=this.component.scales[r];if(i&&!i.merged){const s=i.get("type"),o=i.get("range");if(yr(s)&&Ef(o)){const a=i.get("name"),l=A2(this,r),u=bF(l);if(u){const c=Re({aggregate:"distinct",field:u},{expr:"datum"});return{signal:PU(a,i,c)}}else return Se(m$(r)),null}}}return{signal:this.signalNameMap.get(this.getName(t))}}lookupDataSource(t){const n=this.component.data.outputNodes[t];return n?n.getSource():t}getSignalName(t){return this.signalNameMap.get(t)}renameSignal(t,n){this.signalNameMap.rename(t,n)}renameScale(t,n){this.scaleNameMap.rename(t,n)}renameProjection(t,n){this.projectionNameMap.rename(t,n)}scaleName(t,n){if(n)return this.getName(t);if(tz(t)&&$a(t)&&this.component.scales[t]||this.scaleNameMap.has(this.getName(t)))return this.scaleNameMap.get(this.getName(t))}projectionName(t){if(t)return this.getName("projection");if(this.component.projection&&!this.component.projection.merged||this.projectionNameMap.has(this.getName("projection")))return this.projectionNameMap.get(this.getName("projection"))}getScaleComponent(t){if(!this.component.scales)throw new Error("getScaleComponent cannot be called before parseScale(). Make sure you have called parseScale or use parseUnitModelWithScale().");const n=this.component.scales[t];return n&&!n.merged?n:this.parent?this.parent.getScaleComponent(t):void 0}getScaleType(t){const n=this.getScaleComponent(t);return n?n.get("type"):void 0}getSelectionComponent(t,n){let r=this.component.selection[t];if(!r&&this.parent&&(r=this.parent.getSelectionComponent(t,n)),!r)throw new Error(H0e(n));return r}hasAxisOrientSignalRef(){var t,n;return((t=this.component.axes.x)==null?void 0:t.some(r=>r.hasOrientSignalRef()))||((n=this.component.axes.y)==null?void 0:n.some(r=>r.hasOrientSignalRef()))}}class fq extends _F{vgField(t,n={}){const r=this.fieldDef(t);if(r)return Re(r,n)}reduceFieldDef(t,n){return wve(this.getMapping(),(r,i,s)=>{const o=_o(i);return o?t(r,o,s):r},n)}forEachFieldDef(t,n){W$(this.getMapping(),(r,i)=>{const s=_o(r);s&&t(s,i)},n)}}class k2 extends sn{clone(){return new k2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=_t(n);const r=this.transform.as??[void 0,void 0];this.transform.as=[r[0]??"value",r[1]??"density"];const i=this.transform.resolve??"shared";this.transform.resolve=i}dependentFields(){return new Set([this.transform.density,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`DensityTransform ${Ut(this.transform)}`}assemble(){const{density:t,...n}=this.transform,r={type:"kde",field:t,...n};return r.resolve=this.transform.resolve,r}}class S2 extends sn{clone(){return new S2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=_t(n)}dependentFields(){return new Set([this.transform.extent])}producedFields(){return new Set([])}hash(){return`ExtentTransform ${Ut(this.transform)}`}assemble(){const{extent:t,param:n}=this.transform;return{type:"extent",field:t,signal:n}}}class C2 extends sn{clone(){return new C2(this.parent,_t(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=_t(n);const{flatten:r,as:i=[]}=this.transform;this.transform.as=r.map((s,o)=>i[o]??s)}dependentFields(){return new Set(this.transform.flatten)}producedFields(){return new Set(this.transform.as)}hash(){return`FlattenTransform ${Ut(this.transform)}`}assemble(){const{flatten:t,as:n}=this.transform;return{type:"flatten",fields:t,as:n}}}class $2 extends sn{clone(){return new $2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=_t(n);const r=this.transform.as??[void 0,void 0];this.transform.as=[r[0]??"key",r[1]??"value"]}dependentFields(){return new Set(this.transform.fold)}producedFields(){return new Set(this.transform.as)}hash(){return`FoldTransform ${Ut(this.transform)}`}assemble(){const{fold:t,as:n}=this.transform;return{type:"fold",fields:t,as:n}}}class pd extends sn{clone(){return new pd(null,_t(this.fields),this.geojson,this.signal)}static parseAll(t,n){if(n.component.projection&&!n.component.projection.isFit)return t;let r=0;for(const i of[[Fo,$o],[js,Do]]){const s=i.map(o=>{const a=tr(n.encoding[o]);return Ce(a)?a.field:Fa(a)?{expr:`${a.datum}`}:xo(a)?{expr:`${a.value}`}:void 0});(s[0]||s[1])&&(t=new pd(t,s,null,n.getName(`geojson_${r++}`)))}if(n.channelHasField(Hi)){const i=n.typedFieldDef(Hi);i.type===Oh&&(t=new pd(t,null,i.field,n.getName(`geojson_${r++}`)))}return t}constructor(t,n,r,i){super(t),this.fields=n,this.geojson=r,this.signal=i}dependentFields(){const t=(this.fields??[]).filter(Ie);return new Set([...this.geojson?[this.geojson]:[],...t])}producedFields(){return new Set}hash(){return`GeoJSON ${this.geojson} ${this.signal} ${Ut(this.fields)}`}assemble(){return[...this.geojson?[{type:"filter",expr:`isValid(datum["${this.geojson}"])`}]:[],{type:"geojson",...this.fields?{fields:this.fields}:{},...this.geojson?{geojson:this.geojson}:{},signal:this.signal}]}}class jg extends sn{clone(){return new jg(null,this.projection,_t(this.fields),_t(this.as))}constructor(t,n,r,i){super(t),this.projection=n,this.fields=r,this.as=i}static parseAll(t,n){if(!n.projectionName())return t;for(const r of[[Fo,$o],[js,Do]]){const i=r.map(o=>{const a=tr(n.encoding[o]);return Ce(a)?a.field:Fa(a)?{expr:`${a.datum}`}:xo(a)?{expr:`${a.value}`}:void 0}),s=r[0]===js?"2":"";(i[0]||i[1])&&(t=new jg(t,n.projectionName(),i,[n.getName(`x${s}`),n.getName(`y${s}`)]))}return t}dependentFields(){return new Set(this.fields.filter(Ie))}producedFields(){return new Set(this.as)}hash(){return`Geopoint ${this.projection} ${Ut(this.fields)} ${Ut(this.as)}`}assemble(){return{type:"geopoint",projection:this.projection,fields:this.fields,as:this.as}}}class Dc extends sn{clone(){return new Dc(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n}dependentFields(){return new Set([this.transform.impute,this.transform.key,...this.transform.groupby??[]])}producedFields(){return new Set([this.transform.impute])}processSequence(t){const{start:n=0,stop:r,step:i}=t;return{signal:`sequence(${[n,r,...i?[i]:[]].join(",")})`}}static makeFromTransform(t,n){return new Dc(t,n)}static makeFromEncoding(t,n){const r=n.encoding,i=r.x,s=r.y;if(Ce(i)&&Ce(s)){const o=i.impute?i:s.impute?s:void 0;if(o===void 0)return;const a=i.impute?s:s.impute?i:void 0,{method:l,value:u,frame:c,keyvals:f}=o.impute,d=yj(n.mark,r);return new Dc(t,{impute:o.field,key:a.field,...l?{method:l}:{},...u!==void 0?{value:u}:{},...c?{frame:c}:{},...f!==void 0?{keyvals:f}:{},...d.length?{groupby:d}:{}})}return null}hash(){return`Impute ${Ut(this.transform)}`}assemble(){const{impute:t,key:n,keyvals:r,method:i,groupby:s,value:o,frame:a=[null,null]}=this.transform,l={type:"impute",field:t,key:n,...r?{keyvals:Aye(r)?this.processSequence(r):r}:{},method:"value",...s?{groupby:s}:{},value:!i||i==="value"?o:null};if(i&&i!=="value"){const u={type:"window",as:[`imputed_${t}_value`],ops:[i],fields:[t],frame:a,ignorePeers:!1,...s?{groupby:s}:{}},c={type:"formula",expr:`datum.${t} === null ? datum.imputed_${t}_value : datum.${t}`,as:t};return[l,u,c]}else return[l]}}class F2 extends sn{clone(){return new F2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=_t(n);const r=this.transform.as??[void 0,void 0];this.transform.as=[r[0]??n.on,r[1]??n.loess]}dependentFields(){return new Set([this.transform.loess,this.transform.on,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`LoessTransform ${Ut(this.transform)}`}assemble(){const{loess:t,on:n,...r}=this.transform;return{type:"loess",x:n,y:t,...r}}}class Ug extends sn{clone(){return new Ug(null,_t(this.transform),this.secondary)}constructor(t,n,r){super(t),this.transform=n,this.secondary=r}static make(t,n,r,i){const s=n.component.data.sources,{from:o}=r;let a=null;if(kye(o)){let l=pq(o.data,s);l||(l=new cf(o.data),s.push(l));const u=n.getName(`lookup_${i}`);a=new zi(l,u,Fn.Lookup,n.component.data.outputNodeRefCounts),n.component.data.outputNodes[u]=a}else if(Sye(o)){const l=o.param;r={as:l,...r};let u;try{u=n.getSelectionComponent(_n(l),l)}catch{throw new Error(X0e(l))}if(a=u.materialized,!a)throw new Error(K0e(l))}return new Ug(t,r,a.getSource())}dependentFields(){return new Set([this.transform.lookup])}producedFields(){return new Set(this.transform.as?Be(this.transform.as):this.transform.from.fields)}hash(){return`Lookup ${Ut({transform:this.transform,secondary:this.secondary})}`}assemble(){let t;if(this.transform.from.fields)t={values:this.transform.from.fields,...this.transform.as?{as:Be(this.transform.as)}:{}};else{let n=this.transform.as;Ie(n)||(Se(ame),n="_lookup"),t={as:[n]}}return{type:"lookup",from:this.secondary,key:this.transform.from.key,fields:[this.transform.lookup],...t,...this.transform.default?{default:this.transform.default}:{}}}}class D2 extends sn{clone(){return new D2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=_t(n);const r=this.transform.as??[void 0,void 0];this.transform.as=[r[0]??"prob",r[1]??"value"]}dependentFields(){return new Set([this.transform.quantile,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`QuantileTransform ${Ut(this.transform)}`}assemble(){const{quantile:t,...n}=this.transform;return{type:"quantile",field:t,...n}}}class M2 extends sn{clone(){return new M2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n,this.transform=_t(n);const r=this.transform.as??[void 0,void 0];this.transform.as=[r[0]??n.on,r[1]??n.regression]}dependentFields(){return new Set([this.transform.regression,this.transform.on,...this.transform.groupby??[]])}producedFields(){return new Set(this.transform.as)}hash(){return`RegressionTransform ${Ut(this.transform)}`}assemble(){const{regression:t,on:n,...r}=this.transform;return{type:"regression",x:n,y:t,...r}}}class T2 extends sn{clone(){return new T2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n}addDimensions(t){this.transform.groupby=Jo((this.transform.groupby??[]).concat(t),n=>n)}producedFields(){}dependentFields(){return new Set([this.transform.pivot,this.transform.value,...this.transform.groupby??[]])}hash(){return`PivotTransform ${Ut(this.transform)}`}assemble(){const{pivot:t,value:n,groupby:r,limit:i,op:s}=this.transform;return{type:"pivot",field:t,value:n,...i!==void 0?{limit:i}:{},...s!==void 0?{op:s}:{},...r!==void 0?{groupby:r}:{}}}}class R2 extends sn{clone(){return new R2(null,_t(this.transform))}constructor(t,n){super(t),this.transform=n}dependentFields(){return new Set}producedFields(){return new Set}hash(){return`SampleTransform ${Ut(this.transform)}`}assemble(){return{type:"sample",size:this.transform.sample}}}function dq(e){let t=0;function n(r,i){if(r instanceof cf&&!r.isGenerator&&!sh(r.data)&&(e.push(i),i={name:null,source:i.name,transform:[]}),r instanceof Xr&&(r.parent instanceof cf&&!i.source?(i.format={...i.format,parse:r.assembleFormatParse()},i.transform.push(...r.assembleTransforms(!0))):i.transform.push(...r.assembleTransforms())),r instanceof Ph){i.name||(i.name=`data_${t++}`),!i.source||i.transform.length>0?(e.push(i),r.data=i.name):r.data=i.source,e.push(...r.assemble());return}switch((r instanceof K0||r instanceof Z0||r instanceof ch||r instanceof Ih||r instanceof ah||r instanceof jg||r instanceof ho||r instanceof Ug||r instanceof Bh||r instanceof Ff||r instanceof $2||r instanceof C2||r instanceof k2||r instanceof F2||r instanceof D2||r instanceof M2||r instanceof yu||r instanceof R2||r instanceof T2||r instanceof S2)&&i.transform.push(r.assemble()),(r instanceof sa||r instanceof ra||r instanceof Dc||r instanceof ol||r instanceof pd)&&i.transform.push(...r.assemble()),r instanceof zi&&(i.source&&i.transform.length===0?r.setSource(i.source):r.parent instanceof zi?r.setSource(i.name):(i.name||(i.name=`data_${t++}`),r.setSource(i.name),r.numChildren()===1&&(e.push(i),i={name:null,source:i.name,transform:[]}))),r.numChildren()){case 0:r instanceof zi&&(!i.source||i.transform.length>0)&&e.push(i);break;case 1:n(r.children[0],i);break;default:{i.name||(i.name=`data_${t++}`);let s=i.name;!i.source||i.transform.length>0?e.push(i):s=i.source;for(const o of r.children)n(o,{name:null,source:s,transform:[]});break}}}return n}function V_e(e){const t=[],n=dq(t);for(const r of e.children)n(r,{source:e.name,name:null,transform:[]});return t}function X_e(e,t){const n=[],r=dq(n);let i=0;for(const o of e.sources){o.hasName()||(o.dataName=`source_${i++}`);const a=o.assemble();r(o,a)}for(const o of n)o.transform.length===0&&delete o.transform;let s=0;for(const[o,a]of n.entries())(a.transform??[]).length===0&&!a.source&&n.splice(s++,0,n.splice(o,1)[0]);for(const o of n)for(const a of o.transform??[])a.type==="lookup"&&(a.from=e.outputNodes[a.from].getSource());for(const o of n)o.name in t&&(o.values=t[o.name]);return n}function K_e(e){return e==="top"||e==="left"||nt(e)?"header":"footer"}function Z_e(e){for(const t of Fs)J_e(e,t);b8(e,"x"),b8(e,"y")}function J_e(e,t){var o;const{facet:n,config:r,child:i,component:s}=e;if(e.channelHasField(t)){const a=n[t],l=uh("title",null,r,t);let u=dd(a,r,{allowDisabling:!0,includeDefault:l===void 0||!!l});i.component.layoutHeaders[t].title&&(u=de(u)?u.join(", "):u,u+=` / ${i.component.layoutHeaders[t].title}`,i.component.layoutHeaders[t].title=null);const c=uh("labelOrient",a.header,r,t),f=a.header!==null?qn((o=a.header)==null?void 0:o.labels,r.header.labels,!0):!1,d=It(["bottom","right"],c)?"footer":"header";s.layoutHeaders[t]={title:a.header!==null?u:null,facetFieldDef:a,[d]:t==="facet"?[]:[hq(e,t,f)]}}}function hq(e,t,n){const r=t==="row"?"height":"width";return{labels:n,sizeSignal:e.child.component.layoutSize.get(r)?e.child.getSizeSignalRef(r):void 0,axes:[]}}function b8(e,t){const{child:n}=e;if(n.component.axes[t]){const{layoutHeaders:r,resolve:i}=e.component;if(i.axis[t]=pF(i,t),i.axis[t]==="shared"){const s=t==="x"?"column":"row",o=r[s];for(const a of n.component.axes[t]){const l=K_e(a.get("orient"));o[l]??(o[l]=[hq(e,s,!1)]);const u=zp(a,"main",e.config,{header:!0});u&&o[l][0].axes.push(u),a.mainExtracted=!0}}}}function Q_e(e){wF(e),gy(e,"width"),gy(e,"height")}function ewe(e){wF(e);const t=e.layout.columns===1?"width":"childWidth",n=e.layout.columns===void 0?"height":"childHeight";gy(e,t),gy(e,n)}function wF(e){for(const t of e.children)t.parseLayoutSize()}function gy(e,t){const n=BU(t),r=Vb(n),i=e.component.resolve,s=e.component.layoutSize;let o;for(const a of e.children){const l=a.component.layoutSize.getWithExplicit(n),u=i.scale[r]??jU(r,e);if(u==="independent"&&l.value==="step"){o=void 0;break}if(o){if(u==="independent"&&o.value!==l.value){o=void 0;break}o=vu(o,l,n,"")}else o=l}if(o){for(const a of e.children)e.renameSignal(a.getName(n),e.getName(t)),a.component.layoutSize.set(n,"merged",!1);s.setWithExplicit(t,o)}else s.setWithExplicit(t,{explicit:!1,value:void 0})}function twe(e){const{size:t,component:n}=e;for(const r of _l){const i=Gi(r);if(t[i]){const s=t[i];n.layoutSize.set(i,ga(s)?"step":s,!0)}else{const s=nwe(e,i);n.layoutSize.set(i,s,!1)}}}function nwe(e,t){const n=t==="width"?"x":"y",r=e.config,i=e.getScaleComponent(n);if(i){const s=i.get("type"),o=i.get("range");if(yr(s)){const a=cy(r.view,t);return Ef(o)||ga(a)?"step":a}else return cA(r.view,t)}else{if(e.hasProjection||e.mark==="arc")return cA(r.view,t);{const s=cy(r.view,t);return ga(s)?s.step:s}}}function DA(e,t,n){return Re(t,{suffix:`by_${Re(e)}`,...n})}class lg extends fq{constructor(t,n,r,i){super(t,"facet",n,r,i,t.resolve),this.child=CF(t.spec,this,this.getName("child"),void 0,i),this.children=[this.child],this.facet=this.initFacet(t.facet)}initFacet(t){if(!j0(t))return{facet:this.initFacetFieldDef(t,"facet")};const n=Ee(t),r={};for(const i of n){if(![nl,rl].includes(i)){Se(Zb(i,"facet"));break}const s=t[i];if(s.field===void 0){Se(sA(s,i));break}r[i]=this.initFacetFieldDef(s,i)}return r}initFacetFieldDef(t,n){const r=q$(t,n);return r.header?r.header=$r(r.header):r.header===null&&(r.header=null),r}channelHasField(t){return Ae(this.facet,t)}fieldDef(t){return this.facet[t]}parseData(){this.component.data=N2(this),this.child.parseData()}parseLayoutSize(){wF(this)}parseSelections(){this.child.parseSelections(),this.component.selection=this.child.component.selection,Object.values(this.component.selection).some(t=>ia(t))&&y$(v$)}parseMarkGroup(){this.child.parseMarkGroup()}parseAxesAndHeaders(){this.child.parseAxesAndHeaders(),Z_e(this)}assembleSelectionTopLevelSignals(t){return this.child.assembleSelectionTopLevelSignals(t)}assembleSignals(){return this.child.assembleSignals(),[]}assembleSelectionData(t){return this.child.assembleSelectionData(t)}getHeaderLayoutMixins(){const t={};for(const n of Fs)for(const r of dF){const i=this.component.layoutHeaders[n],s=i[r],{facetFieldDef:o}=i;if(o){const a=uh("titleOrient",o.header,this.config,n);if(["right","bottom"].includes(a)){const l=w2(n,a);t.titleAnchor??(t.titleAnchor={}),t.titleAnchor[l]="end"}}if(s!=null&&s[0]){const a=n==="row"?"height":"width",l=r==="header"?"headerBand":"footerBand";n!=="facet"&&!this.child.component.layoutSize.get(a)&&(t[l]??(t[l]={}),t[l][n]=.5),i.title&&(t.offset??(t.offset={}),t.offset[n==="row"?"rowTitle":"columnTitle"]=10)}}return t}assembleDefaultLayout(){const{column:t,row:n}=this.facet,r=t?this.columnDistinctSignal():n?1:void 0;let i="all";return(!n&&this.component.resolve.scale.x==="independent"||!t&&this.component.resolve.scale.y==="independent")&&(i="none"),{...this.getHeaderLayoutMixins(),...r?{columns:r}:{},bounds:"full",align:i}}assembleLayoutSignals(){return this.child.assembleLayoutSignals()}columnDistinctSignal(){if(!(this.parent&&this.parent instanceof lg))return{signal:`length(data('${this.getName("column_domain")}'))`}}assembleGroupStyle(){}assembleGroup(t){return this.parent&&this.parent instanceof lg?{...this.channelHasField("column")?{encode:{update:{columns:{field:Re(this.facet.column,{prefix:"distinct"})}}}}:{},...super.assembleGroup(t)}:super.assembleGroup(t)}getCardinalityAggregateForChild(){const t=[],n=[],r=[];if(this.child instanceof lg){if(this.child.channelHasField("column")){const i=Re(this.child.facet.column);t.push(i),n.push("distinct"),r.push(`distinct_${i}`)}}else for(const i of _l){const s=this.child.component.scales[i];if(s&&!s.merged){const o=s.get("type"),a=s.get("range");if(yr(o)&&Ef(a)){const l=A2(this.child,i),u=bF(l);u?(t.push(u),n.push("distinct"),r.push(`distinct_${u}`)):Se(m$(i))}}}return{fields:t,ops:n,as:r}}assembleFacet(){const{name:t,data:n}=this.component.data.facetRoot,{row:r,column:i}=this.facet,{fields:s,ops:o,as:a}=this.getCardinalityAggregateForChild(),l=[];for(const c of Fs){const f=this.facet[c];if(f){l.push(Re(f));const{bin:d,sort:h}=f;if(dn(d)&&l.push(Re(f,{binSuffix:"end"})),il(h)){const{field:p,op:g=i2}=h,m=DA(f,h);r&&i?(s.push(m),o.push("max"),a.push(m)):(s.push(p),o.push(g),a.push(m))}else if(de(h)){const p=lh(f,c);s.push(p),o.push("max"),a.push(p)}}}const u=!!r&&!!i;return{name:t,data:n,groupby:l,...u||s.length>0?{aggregate:{...u?{cross:u}:{},...s.length?{fields:s,ops:o,as:a}:{}}}:{}}}facetSortFields(t){const{facet:n}=this,r=n[t];return r?il(r.sort)?[DA(r,r.sort,{expr:"datum"})]:de(r.sort)?[lh(r,t,{expr:"datum"})]:[Re(r,{expr:"datum"})]:[]}facetSortOrder(t){const{facet:n}=this,r=n[t];if(r){const{sort:i}=r;return[(il(i)?i.order:!de(i)&&i)||"ascending"]}return[]}assembleLabelTitle(){var i;const{facet:t,config:n}=this;if(t.facet)return EA(t.facet,"facet",n);const r={row:["top","bottom"],column:["left","right"]};for(const s of fF)if(t[s]){const o=uh("labelOrient",(i=t[s])==null?void 0:i.header,n,s);if(r[s].includes(o))return EA(t[s],s,n)}}assembleMarks(){const{child:t}=this,n=this.component.data.facetRoot,r=V_e(n),i=t.assembleGroupEncodeEntry(!1),s=this.assembleLabelTitle()||t.assembleTitle(),o=t.assembleGroupStyle();return[{name:this.getName("cell"),type:"group",...s?{title:s}:{},...o?{style:o}:{},from:{facet:this.assembleFacet()},sort:{field:Fs.map(l=>this.facetSortFields(l)).flat(),order:Fs.map(l=>this.facetSortOrder(l)).flat()},...r.length>0?{data:r}:{},...i?{encode:{update:i}}:{},...t.assembleGroup(lbe(this,[]))}]}getMapping(){return this.facet}}function rwe(e,t){const{row:n,column:r}=t;if(n&&r){let i=null;for(const s of[n,r])if(il(s.sort)){const{field:o,op:a=i2}=s.sort;e=i=new Ff(e,{joinaggregate:[{op:a,field:o,as:DA(s,s.sort,{forAs:!0})}],groupby:[Re(s)]})}return i}return null}function pq(e,t){var n,r,i,s;for(const o of t){const a=o.data;if(e.name&&o.hasName()&&e.name!==o.dataName)continue;const l=(n=e.format)==null?void 0:n.mesh,u=(r=a.format)==null?void 0:r.feature;if(l&&u)continue;const c=(i=e.format)==null?void 0:i.feature;if((c||u)&&c!==u)continue;const f=(s=a.format)==null?void 0:s.mesh;if(!((l||f)&&l!==f)){if(Pg(e)&&Pg(a)){if(os(e.values,a.values))return o}else if(sh(e)&&sh(a)){if(e.url===a.url)return o}else if(Vj(e)&&e.name===o.dataName)return o}}return null}function iwe(e,t){if(e.data||!e.parent){if(e.data===null){const r=new cf({values:[]});return t.push(r),r}const n=pq(e.data,t);if(n)return nu(e.data)||(n.data.format=qB({},e.data.format,n.data.format)),!n.hasName()&&e.data.name&&(n.dataName=e.data.name),n;{const r=new cf(e.data);return t.push(r),r}}else return e.parent.component.data.facetRoot?e.parent.component.data.facetRoot:e.parent.component.data.main}function swe(e,t,n){let r=0;for(const i of t.transforms){let s,o;if(Lye(i))o=e=new ah(e,i),s="derived";else if(tF(i)){const a=Xxe(i);o=e=Xr.makeWithAncestors(e,{},a,n)??e,e=new Ih(e,t,i.filter)}else if(qj(i))o=e=sa.makeFromTransform(e,i,t),s="number";else if(Pye(i))s="date",n.getWithExplicit(i.field).value===void 0&&(e=new Xr(e,{[i.field]:s}),n.set(i.field,s,!1)),o=e=ra.makeFromTransform(e,i);else if(Bye(i))o=e=ho.makeFromTransform(e,i),s="number",aF(t)&&(e=new yu(e));else if(Uj(i))o=e=Ug.make(e,t,i,r++),s="derived";else if(Rye(i))o=e=new Bh(e,i),s="number";else if(Nye(i))o=e=new Ff(e,i),s="number";else if(zye(i))o=e=ol.makeFromTransform(e,i),s="derived";else if(jye(i))o=e=new $2(e,i),s="derived";else if(Uye(i))o=e=new S2(e,i),s="derived";else if(Oye(i))o=e=new C2(e,i),s="derived";else if(Cye(i))o=e=new T2(e,i),s="derived";else if(Tye(i))e=new R2(e,i);else if(Iye(i))o=e=Dc.makeFromTransform(e,i),s="derived";else if($ye(i))o=e=new k2(e,i),s="derived";else if(Fye(i))o=e=new D2(e,i),s="derived";else if(Dye(i))o=e=new M2(e,i),s="derived";else if(Mye(i))o=e=new F2(e,i),s="derived";else{Se(ome(i));continue}if(o&&s!==void 0)for(const a of o.producedFields()??[])n.set(a,s,!1)}return e}function N2(e){var m;let t=iwe(e,e.component.data.sources);const{outputNodes:n,outputNodeRefCounts:r}=e.component.data,i=e.data,o=!(i&&(nu(i)||sh(i)||Pg(i)))&&e.parent?e.parent.component.data.ancestorParse.clone():new ebe;nu(i)?(Xj(i)?t=new Z0(t,i.sequence):nF(i)&&(t=new K0(t,i.graticule)),o.parseNothing=!0):((m=i==null?void 0:i.format)==null?void 0:m.parse)===null&&(o.parseNothing=!0),t=Xr.makeExplicit(t,e,o)??t,t=new yu(t);const a=e.parent&&zh(e.parent);($n(e)||fs(e))&&a&&(t=sa.makeFromEncoding(t,e)??t),e.transforms.length>0&&(t=swe(t,e,o));const l=Zxe(e),u=Kxe(e);t=Xr.makeWithAncestors(t,{},{...l,...u},o)??t,$n(e)&&(t=pd.parseAll(t,e),t=jg.parseAll(t,e)),($n(e)||fs(e))&&(a||(t=sa.makeFromEncoding(t,e)??t),t=ra.makeFromEncoding(t,e)??t,t=ah.parseAllForSortIndex(t,e));const c=t=Im(Fn.Raw,e,t);if($n(e)){const y=ho.makeFromEncoding(t,e);y&&(t=y,aF(e)&&(t=new yu(t))),t=Dc.makeFromEncoding(t,e)??t,t=ol.makeFromEncoding(t,e)??t}let f,d;if($n(e)){const{markDef:y,mark:b,config:x}=e,_=on("invalid",y,x),{marks:w,scales:A}=d=Zj({invalid:_,isPath:Iu(b)});w!==A&&A==="include-invalid-values"&&(f=t=Im(Fn.PreFilterInvalid,e,t)),w==="exclude-invalid-values"&&(t=ch.make(t,e,d)??t)}const h=t=Im(Fn.Main,e,t);let p;if($n(e)&&d){const{marks:y,scales:b}=d;y==="include-invalid-values"&&b==="exclude-invalid-values"&&(t=ch.make(t,e,d)??t,p=t=Im(Fn.PostFilterInvalid,e,t))}$n(e)&&G2e(e,h);let g=null;if(fs(e)){const y=e.getName("facet");t=rwe(t,e.facet)??t,g=new Ph(t,e,y,h.getSource()),n[y]=g}return{...e.component.data,outputNodes:n,outputNodeRefCounts:r,raw:c,main:h,facetRoot:g,ancestorParse:o,preFilterInvalid:f,postFilterInvalid:p}}function Im(e,t,n){const{outputNodes:r,outputNodeRefCounts:i}=t.component.data,s=t.getDataName(e),o=new zi(n,s,e,i);return r[s]=o,o}class owe extends _F{constructor(t,n,r,i){var s,o,a,l;super(t,"concat",n,r,i,t.resolve),(((o=(s=t.resolve)==null?void 0:s.axis)==null?void 0:o.x)==="shared"||((l=(a=t.resolve)==null?void 0:a.axis)==null?void 0:l.y)==="shared")&&Se(rme),this.children=this.getChildren(t).map((u,c)=>CF(u,this,this.getName(`concat_${c}`),void 0,i))}parseData(){this.component.data=N2(this);for(const t of this.children)t.parseData()}parseSelections(){this.component.selection={};for(const t of this.children){t.parseSelections();for(const n of Ee(t.component.selection))this.component.selection[n]=t.component.selection[n]}Object.values(this.component.selection).some(t=>ia(t))&&y$(v$)}parseMarkGroup(){for(const t of this.children)t.parseMarkGroup()}parseAxesAndHeaders(){for(const t of this.children)t.parseAxesAndHeaders()}getChildren(t){return f2(t)?t.vconcat:Q$(t)?t.hconcat:t.concat}parseLayoutSize(){ewe(this)}parseAxisGroup(){return null}assembleSelectionTopLevelSignals(t){return this.children.reduce((n,r)=>r.assembleSelectionTopLevelSignals(n),t)}assembleSignals(){return this.children.forEach(t=>t.assembleSignals()),[]}assembleLayoutSignals(){const t=hF(this);for(const n of this.children)t.push(...n.assembleLayoutSignals());return t}assembleSelectionData(t){return this.children.reduce((n,r)=>r.assembleSelectionData(n),t)}assembleMarks(){return this.children.map(t=>{const n=t.assembleTitle(),r=t.assembleGroupStyle(),i=t.assembleGroupEncodeEntry(!1);return{type:"group",name:t.getName("group"),...n?{title:n}:{},...r?{style:r}:{},...i?{encode:{update:i}}:{},...t.assembleGroup()}})}assembleGroupStyle(){}assembleDefaultLayout(){const t=this.layout.columns;return{...t!=null?{columns:t}:{},bounds:"full",align:"each"}}}function awe(e){return e===!1||e===null}const lwe={disable:1,gridScale:1,scale:1,...dj,labelExpr:1,encode:1},gq=Ee(lwe);class EF extends El{constructor(t={},n={},r=!1){super(),this.explicit=t,this.implicit=n,this.mainExtracted=r}clone(){return new EF(_t(this.explicit),_t(this.implicit),this.mainExtracted)}hasAxisPart(t){return t==="axis"?!0:t==="grid"||t==="title"?!!this.get(t):!awe(this.get(t))}hasOrientSignalRef(){return nt(this.explicit.orient)}}function uwe(e,t,n){const{encoding:r,config:i}=e,s=tr(r[t])??tr(r[Ca(t)]),o=e.axis(t)||{},{format:a,formatType:l}=o;if(sf(l))return{text:co({fieldOrDatumDef:s,field:"datum.value",format:a,formatType:l,config:i}),...n};if(a===void 0&&l===void 0&&i.customFormatTypes){if(nh(s)==="quantitative"){if(rh(s)&&s.stack==="normalize"&&i.normalizedNumberFormatType)return{text:co({fieldOrDatumDef:s,field:"datum.value",format:i.normalizedNumberFormat,formatType:i.normalizedNumberFormatType,config:i}),...n};if(i.numberFormatType)return{text:co({fieldOrDatumDef:s,field:"datum.value",format:i.numberFormat,formatType:i.numberFormatType,config:i}),...n}}if(nh(s)==="temporal"&&i.timeFormatType&&Ce(s)&&!s.timeUnit)return{text:co({fieldOrDatumDef:s,field:"datum.value",format:i.timeFormat,formatType:i.timeFormatType,config:i}),...n}}return n}function cwe(e){return _l.reduce((t,n)=>(e.component.scales[n]&&(t[n]=[vwe(n,e)]),t),{})}const fwe={bottom:"top",top:"bottom",left:"right",right:"left"};function dwe(e){const{axes:t,resolve:n}=e.component,r={top:0,bottom:0,right:0,left:0};for(const i of e.children){i.parseAxesAndHeaders();for(const s of Ee(i.component.axes))n.axis[s]=pF(e.component.resolve,s),n.axis[s]==="shared"&&(t[s]=hwe(t[s],i.component.axes[s]),t[s]||(n.axis[s]="independent",delete t[s]))}for(const i of _l){for(const s of e.children)if(s.component.axes[i]){if(n.axis[i]==="independent"){t[i]=(t[i]??[]).concat(s.component.axes[i]);for(const o of s.component.axes[i]){const{value:a,explicit:l}=o.getWithExplicit("orient");if(!nt(a)){if(r[a]>0&&!l){const u=fwe[a];r[a]>r[u]&&o.set("orient",u,!1)}r[a]++}}}delete s.component.axes[i]}if(n.axis[i]==="independent"&&t[i]&&t[i].length>1)for(const[s,o]of(t[i]||[]).entries())s>0&&o.get("grid")&&!o.explicit.grid&&(o.implicit.grid=!1)}}function hwe(e,t){if(e){if(e.length!==t.length)return;const n=e.length;for(let r=0;rn.clone());return e}function pwe(e,t){for(const n of gq){const r=vu(e.getWithExplicit(n),t.getWithExplicit(n),n,"axis",(i,s)=>{switch(n){case"title":return mz(i,s);case"gridScale":return{explicit:i.explicit,value:qn(i.value,s.value)}}return h2(i,s,n,"axis")});e.setWithExplicit(n,r)}return e}function gwe(e,t,n,r,i){if(t==="disable")return n!==void 0;switch(n=n||{},t){case"titleAngle":case"labelAngle":return e===(nt(n.labelAngle)?n.labelAngle:Lg(n.labelAngle));case"values":return!!n.values;case"encode":return!!n.encoding||!!n.labelAngle;case"title":if(e===NU(r,i))return!0}return e===n[t]}const mwe=new Set(["grid","translate","format","formatType","orient","labelExpr","tickCount","position","tickMinStep"]);function vwe(e,t){var y,b;let n=t.axis(e);const r=new EF,i=tr(t.encoding[e]),{mark:s,config:o}=t,a=(n==null?void 0:n.orient)||((y=o[e==="x"?"axisX":"axisY"])==null?void 0:y.orient)||((b=o.axis)==null?void 0:b.orient)||nxe(e),l=t.getScaleComponent(e).get("type"),u=X2e(e,l,a,t.config),c=n!==void 0?!n:_A("disable",o.style,n==null?void 0:n.style,u).configValue;if(r.set("disable",c,n!==void 0),c)return r;n=n||{};const f=Q2e(i,n,e,o.style,u),d=Jz(n.formatType,i,l),h=Zz(i,i.type,n.format,n.formatType,o,!0),p={fieldOrDatumDef:i,axis:n,channel:e,model:t,scaleType:l,orient:a,labelAngle:f,format:h,formatType:d,mark:s,config:o};for(const x of gq){const _=x in i8?i8[x](p):A6(x)?n[x]:void 0,w=_!==void 0,A=gwe(_,x,n,t,e);if(w&&A)r.set(x,_,A);else{const{configValue:E=void 0,configFrom:k=void 0}=A6(x)&&x!=="values"?_A(x,o.style,n.style,u):{},S=E!==void 0;w&&!S?r.set(x,_,A):(k!=="vgAxisConfig"||mwe.has(x)&&S||H0(E)||nt(E))&&r.set(x,E,!1)}}const g=n.encoding??{},m=fj.reduce((x,_)=>{if(!r.hasAxisPart(_))return x;const w=zU(g[_]??{},t),A=_==="labels"?uwe(t,e,w):w;return A!==void 0&&!an(A)&&(x[_]={update:A}),x},{});return an(m)||r.set("encode",m,!!n.encoding||n.labelAngle!==void 0),r}function ywe({encoding:e,size:t}){for(const n of _l){const r=Gi(n);ga(t[r])&&Yl(e[n])&&(delete t[r],Se(_z(r)))}return t}const bwe={vgMark:"arc",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"include",size:"ignore",orient:"ignore",theta:"ignore"}),...vi("x",e,{defaultPos:"mid"}),...vi("y",e,{defaultPos:"mid"}),...hl(e,"radius"),...hl(e,"theta")})},xwe={vgMark:"area",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"include",orient:"include",size:"ignore",theta:"ignore"}),...fy("x",e,{defaultPos:"zeroOrMin",defaultPos2:"zeroOrMin",range:e.markDef.orient==="horizontal"}),...fy("y",e,{defaultPos:"zeroOrMin",defaultPos2:"zeroOrMin",range:e.markDef.orient==="vertical"}),...oF(e)})},_we={vgMark:"rect",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...hl(e,"x"),...hl(e,"y")})},wwe={vgMark:"shape",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"include",size:"ignore",orient:"ignore",theta:"ignore"})}),postEncodingTransform:e=>{const{encoding:t}=e,n=t.shape;return[{type:"geoshape",projection:e.projectionName(),...n&&Ce(n)&&n.type===Oh?{field:Re(n,{expr:"datum"})}:{}}]}},Ewe={vgMark:"image",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"ignore",orient:"ignore",size:"ignore",theta:"ignore"}),...hl(e,"x"),...hl(e,"y"),...iF(e,"url")})},Awe={vgMark:"line",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"include",size:"ignore",orient:"ignore",theta:"ignore"}),...vi("x",e,{defaultPos:"mid"}),...vi("y",e,{defaultPos:"mid"}),...Dr("size",e,{vgChannel:"strokeWidth"}),...oF(e)})},kwe={vgMark:"trail",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"include",size:"include",orient:"ignore",theta:"ignore"}),...vi("x",e,{defaultPos:"mid"}),...vi("y",e,{defaultPos:"mid"}),...Dr("size",e),...oF(e)})};function AF(e,t){const{config:n}=e;return{...Hs(e,{align:"ignore",baseline:"ignore",color:"include",size:"include",orient:"ignore",theta:"ignore"}),...vi("x",e,{defaultPos:"mid"}),...vi("y",e,{defaultPos:"mid"}),...Dr("size",e),...Dr("angle",e),...Swe(e,n,t)}}function Swe(e,t,n){return n?{shape:{value:n}}:Dr("shape",e)}const Cwe={vgMark:"symbol",encodeEntry:e=>AF(e)},$we={vgMark:"symbol",encodeEntry:e=>AF(e,"circle")},Fwe={vgMark:"symbol",encodeEntry:e=>AF(e,"square")},Dwe={vgMark:"rect",encodeEntry:e=>({...Hs(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...hl(e,"x"),...hl(e,"y")})},Mwe={vgMark:"rule",encodeEntry:e=>{const{markDef:t}=e,n=t.orient;return!e.encoding.x&&!e.encoding.y&&!e.encoding.latitude&&!e.encoding.longitude?{}:{...Hs(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...fy("x",e,{defaultPos:n==="horizontal"?"zeroOrMax":"mid",defaultPos2:"zeroOrMin",range:n!=="vertical"}),...fy("y",e,{defaultPos:n==="vertical"?"zeroOrMax":"mid",defaultPos2:"zeroOrMin",range:n!=="horizontal"}),...Dr("size",e,{vgChannel:"strokeWidth"})}}},Twe={vgMark:"text",encodeEntry:e=>{const{config:t,encoding:n}=e;return{...Hs(e,{align:"include",baseline:"include",color:"include",size:"ignore",orient:"ignore",theta:"include"}),...vi("x",e,{defaultPos:"mid"}),...vi("y",e,{defaultPos:"mid"}),...iF(e),...Dr("size",e,{vgChannel:"fontSize"}),...Dr("angle",e),...Y6("align",Rwe(e.markDef,n,t)),...Y6("baseline",Nwe(e.markDef,n,t)),...vi("radius",e,{defaultPos:null}),...vi("theta",e,{defaultPos:null})}}};function Rwe(e,t,n){if(on("align",e,n)===void 0)return"center"}function Nwe(e,t,n){if(on("baseline",e,n)===void 0)return"middle"}const Owe={vgMark:"rect",encodeEntry:e=>{const{config:t,markDef:n}=e,r=n.orient,i=r==="horizontal"?"x":"y",s=r==="horizontal"?"y":"x",o=r==="horizontal"?"height":"width";return{...Hs(e,{align:"ignore",baseline:"ignore",color:"include",orient:"ignore",size:"ignore",theta:"ignore"}),...hl(e,i),...vi(s,e,{defaultPos:"mid",vgChannel:s==="y"?"yc":"xc"}),[o]:vn(on("thickness",n,t))}}},Pm={arc:bwe,area:xwe,bar:_we,circle:$we,geoshape:wwe,image:Ewe,line:Awe,point:Cwe,rect:Dwe,rule:Mwe,square:Fwe,text:Twe,tick:Owe,trail:kwe};function Lwe(e){if(It([n2,e2,R1e],e.mark)){const t=yj(e.mark,e.encoding);if(t.length>0)return Iwe(e,t)}else if(e.mark===t2){const t=rA.some(n=>on(n,e.markDef,e.config));if(e.stack&&!e.fieldDef("size")&&t)return Pwe(e)}return kF(e)}const x8="faceted_path_";function Iwe(e,t){return[{name:e.getName("pathgroup"),type:"group",from:{facet:{name:x8+e.requestDataName(Fn.Main),data:e.requestDataName(Fn.Main),groupby:t}},encode:{update:{width:{field:{group:"width"}},height:{field:{group:"height"}}}},marks:kF(e,{fromPrefix:x8})}]}const _8="stack_group_";function Pwe(e){var u;const[t]=kF(e,{fromPrefix:_8}),n=e.scaleName(e.stack.fieldChannel),r=(c={})=>e.vgField(e.stack.fieldChannel,c),i=(c,f)=>{const d=[r({prefix:"min",suffix:"start",expr:f}),r({prefix:"max",suffix:"start",expr:f}),r({prefix:"min",suffix:"end",expr:f}),r({prefix:"max",suffix:"end",expr:f})];return`${c}(${d.map(h=>`scale('${n}',${h})`).join(",")})`};let s,o;e.stack.fieldChannel==="x"?(s={...Kd(t.encode.update,["y","yc","y2","height",...rA]),x:{signal:i("min","datum")},x2:{signal:i("max","datum")},clip:{value:!0}},o={x:{field:{group:"x"},mult:-1},height:{field:{group:"height"}}},t.encode.update={...Bi(t.encode.update,["y","yc","y2"]),height:{field:{group:"height"}}}):(s={...Kd(t.encode.update,["x","xc","x2","width"]),y:{signal:i("min","datum")},y2:{signal:i("max","datum")},clip:{value:!0}},o={y:{field:{group:"y"},mult:-1},width:{field:{group:"width"}}},t.encode.update={...Bi(t.encode.update,["x","xc","x2"]),width:{field:{group:"width"}}});for(const c of rA){const f=ha(c,e.markDef,e.config);t.encode.update[c]?(s[c]=t.encode.update[c],delete t.encode.update[c]):f&&(s[c]=vn(f)),f&&(t.encode.update[c]={value:0})}const a=[];if(((u=e.stack.groupbyChannels)==null?void 0:u.length)>0)for(const c of e.stack.groupbyChannels){const f=e.fieldDef(c),d=Re(f);d&&a.push(d),(f!=null&&f.bin||f!=null&&f.timeUnit)&&a.push(Re(f,{binSuffix:"end"}))}return s=["stroke","strokeWidth","strokeJoin","strokeCap","strokeDash","strokeDashOffset","strokeMiterLimit","strokeOpacity"].reduce((c,f)=>{if(t.encode.update[f])return{...c,[f]:t.encode.update[f]};{const d=ha(f,e.markDef,e.config);return d!==void 0?{...c,[f]:vn(d)}:c}},s),s.stroke&&(s.strokeForeground={value:!0},s.strokeOffset={value:0}),[{type:"group",from:{facet:{data:e.requestDataName(Fn.Main),name:_8+e.requestDataName(Fn.Main),groupby:a,aggregate:{fields:[r({suffix:"start"}),r({suffix:"start"}),r({suffix:"end"}),r({suffix:"end"})],ops:["min","max","min","max"]}}},encode:{update:s},marks:[{type:"group",encode:{update:o},marks:[t]}]}]}function Bwe(e){const{encoding:t,stack:n,mark:r,markDef:i,config:s}=e,o=t.order;if(!(!de(o)&&xo(o)&&tA(o.value)||!o&&tA(on("order",i,s)))){if((de(o)||Ce(o))&&!n)return hz(o,{expr:"datum"});if(Iu(r)){const a=i.orient==="horizontal"?"y":"x",l=t[a];if(Ce(l))return{field:a}}}}function kF(e,t={fromPrefix:""}){const{mark:n,markDef:r,encoding:i,config:s}=e,o=qn(r.clip,zwe(e),jwe(e)),a=fz(r),l=i.key,u=Bwe(e),c=Uwe(e),f=on("aria",r,s),d=Pm[n].postEncodingTransform?Pm[n].postEncodingTransform(e):null;return[{name:e.getName("marks"),type:Pm[n].vgMark,...o?{clip:o}:{},...a?{style:a}:{},...l?{key:l.field}:{},...u?{sort:u}:{},...c||{},...f===!1?{aria:f}:{},from:{data:t.fromPrefix+e.requestDataName(Fn.Main)},encode:{update:Pm[n].encodeEntry(e)},...d?{transform:d}:{}}]}function zwe(e){const t=e.getScaleComponent("x"),n=e.getScaleComponent("y");return t!=null&&t.get("selectionExtent")||n!=null&&n.get("selectionExtent")?!0:void 0}function jwe(e){const t=e.component.projection;return t&&!t.isFit?!0:void 0}function Uwe(e){if(!e.component.selection)return null;const t=Ee(e.component.selection).length;let n=t,r=e.parent;for(;r&&n===0;)n=Ee(r.component.selection).length,r=r.parent;return n?{interactive:t>0||e.mark==="geoshape"||!!e.encoding.tooltip||!!e.markDef.tooltip}:null}class mq extends fq{constructor(t,n,r,i={},s){super(t,"unit",n,r,s,void 0,S6(t)?t.view:void 0),this.specifiedScales={},this.specifiedAxes={},this.specifiedLegends={},this.specifiedProjection={},this.selection=[],this.children=[],this.correctDataNames=u=>{var c,f,d;return(c=u.from)!=null&&c.data&&(u.from.data=this.lookupDataSource(u.from.data),"time"in this.encoding&&(u.from.data=u.from.data+Qj)),(d=(f=u.from)==null?void 0:f.facet)!=null&&d.data&&(u.from.facet.data=this.lookupDataSource(u.from.facet.data)),u};const o=pa(t.mark)?{...t.mark}:{type:t.mark},a=o.type;o.filled===void 0&&(o.filled=mye(o,s,{graticule:t.data&&nF(t.data)}));const l=this.encoding=xve(t.encoding||{},a,o.filled,s);this.markDef=Bj(o,l,s),this.size=ywe({encoding:l,size:S6(t)?{...i,...t.width?{width:t.width}:{},...t.height?{height:t.height}:{}}:i}),this.stack=Pj(this.markDef,l),this.specifiedScales=this.initScales(a,l),this.specifiedAxes=this.initAxes(l),this.specifiedLegends=this.initLegends(l),this.specifiedProjection=t.projection,this.selection=(t.params??[]).filter(u=>Z$(u))}get hasProjection(){const{encoding:t}=this,n=this.mark===Wz,r=t&&d0e.some(i=>kt(t[i]));return n||r}scaleDomain(t){const n=this.specifiedScales[t];return n?n.domain:void 0}axis(t){return this.specifiedAxes[t]}legend(t){return this.specifiedLegends[t]}initScales(t,n){return h$.reduce((r,i)=>{const s=tr(n[i]);return s&&(r[i]=this.initScale(s.scale??{})),r},{})}initScale(t){const{domain:n,range:r}=t,i=$r(t);return de(n)&&(i.domain=n.map(rs)),de(r)&&(i.range=r.map(rs)),i}initAxes(t){return _l.reduce((n,r)=>{const i=t[r];if(kt(i)||r===wn&&kt(t.x2)||r===xr&&kt(t.y2)){const s=kt(i)?i.axis:void 0;n[r]=s&&this.initAxis({...s})}return n},{})}initAxis(t){const n=Ee(t),r={};for(const i of n){const s=t[i];r[i]=H0(s)?cz(s):rs(s)}return r}initLegends(t){return E0e.reduce((n,r)=>{const i=tr(t[r]);if(i&&k0e(r)){const s=i.legend;n[r]=s&&$r(s)}return n},{})}parseData(){this.component.data=N2(this)}parseLayoutSize(){twe(this)}parseSelections(){this.component.selection=H2e(this,this.selection)}parseMarkGroup(){this.component.mark=Lwe(this)}parseAxesAndHeaders(){this.component.axes=cwe(this)}assembleSelectionTopLevelSignals(t){return ube(this,t)}assembleSignals(){return[...MU(this),...abe(this,[])]}assembleSelectionData(t){return cbe(this,t)}assembleLayout(){return null}assembleLayoutSignals(){return hF(this)}assembleMarks(){let t=this.component.mark??[];return(!this.parent||!zh(this.parent))&&(t=rU(this,t)),t.map(this.correctDataNames)}assembleGroupStyle(){const{style:t}=this.view||{};return t!==void 0?t:this.encoding.x||this.encoding.y?"cell":"view"}getMapping(){return this.encoding}get mark(){return this.markDef.type}channelHasField(t){return $c(this.encoding,t)}fieldDef(t){const n=this.encoding[t];return _o(n)}typedFieldDef(t){const n=this.fieldDef(t);return wi(n)?n:null}}class SF extends _F{constructor(t,n,r,i,s){super(t,"layer",n,r,s,t.resolve,t.view);const o={...i,...t.width?{width:t.width}:{},...t.height?{height:t.height}:{}};this.children=t.layer.map((a,l)=>{if(d2(a))return new SF(a,this,this.getName(`layer_${l}`),o,s);if(wl(a))return new mq(a,this,this.getName(`layer_${l}`),o,s);throw new Error(g$(a))})}parseData(){this.component.data=N2(this);for(const t of this.children)t.parseData()}parseLayoutSize(){Q_e(this)}parseSelections(){this.component.selection={};for(const t of this.children){t.parseSelections();for(const n of Ee(t.component.selection))this.component.selection[n]=t.component.selection[n]}Object.values(this.component.selection).some(t=>ia(t))&&y$(v$)}parseMarkGroup(){for(const t of this.children)t.parseMarkGroup()}parseAxesAndHeaders(){dwe(this)}assembleSelectionTopLevelSignals(t){return this.children.reduce((n,r)=>r.assembleSelectionTopLevelSignals(n),t)}assembleSignals(){return this.children.reduce((t,n)=>t.concat(n.assembleSignals()),MU(this))}assembleLayoutSignals(){return this.children.reduce((t,n)=>t.concat(n.assembleLayoutSignals()),hF(this))}assembleSelectionData(t){return this.children.reduce((n,r)=>r.assembleSelectionData(n),t)}assembleGroupStyle(){const t=new Set;for(const r of this.children)for(const i of Be(r.assembleGroupStyle()))t.add(i);const n=Array.from(t);return n.length>1?n:n.length===1?n[0]:void 0}assembleTitle(){let t=super.assembleTitle();if(t)return t;for(const n of this.children)if(t=n.assembleTitle(),t)return t}assembleLayout(){return null}assembleMarks(){return fbe(this,this.children.flatMap(t=>t.assembleMarks()))}assembleLegends(){return this.children.reduce((t,n)=>t.concat(n.assembleLegends()),VU(this))}}function CF(e,t,n,r,i){if(s2(e))return new lg(e,t,n,i);if(d2(e))return new SF(e,t,n,r,i);if(wl(e))return new mq(e,t,n,r,i);if(Wve(e))return new owe(e,t,n,i);throw new Error(g$(e))}function qwe(e,t={}){t.logger&&Yme(t.logger),t.fieldTitle&&lj(t.fieldTitle);try{const n=Ij(mh(t.config,e.config)),r=Gj(e,n),i=CF(r,null,"",void 0,n);return i.parse(),h_e(i.component.data,i),{spec:Hwe(i,Wwe(e,r.autosize,n,i),e.datasets,e.usermeta),normalized:r}}finally{t.logger&&Vme(),t.fieldTitle&&fve()}}function Wwe(e,t,n,r){const i=r.component.layoutSize.get("width"),s=r.component.layoutSize.get("height");if(t===void 0?(t={type:"pad"},r.hasAxisOrientSignalRef()&&(t.resize=!0)):Ie(t)&&(t={type:t}),i&&s&&Zye(t.type)){if(i==="step"&&s==="step")Se(c6()),t.type="pad";else if(i==="step"||s==="step"){const o=i==="step"?"width":"height";Se(c6(Vb(o)));const a=o==="width"?"height":"width";t.type=Jye(a)}}return{...Ee(t).length===1&&t.type?t.type==="pad"?{}:{autosize:t.type}:{autosize:t},...P6(n,!1),...P6(e,!0)}}function Hwe(e,t,n={},r){const i=e.config?iye(e.config):void 0,s=X_e(e.component.data,n),o=e.assembleSelectionData(s),a=e.assembleProjections(),l=e.assembleTitle(),u=e.assembleGroupStyle(),c=e.assembleGroupEncodeEntry(!0);let f=e.assembleLayoutSignals();f=f.filter(p=>(p.name==="width"||p.name==="height")&&p.value!==void 0?(t[p.name]=+p.value,!1):!0);const{params:d,...h}=t;return{$schema:"https://vega.github.io/schema/vega/v5.json",...e.description?{description:e.description}:{},...h,...l?{title:l}:{},...u?{style:u}:{},...c?{encode:{update:c}}:{},data:o,...a.length>0?{projections:a}:{},...e.assembleGroup([...f,...e.assembleSelectionTopLevelSignals([]),...Rj(d)]),...i?{config:i}:{},...r?{usermeta:r}:{}}}const Gwe=o0e.version,Ywe=Object.freeze(Object.defineProperty({__proto__:null,accessPathDepth:Jd,accessPathWithDatum:s$,accessWithDatumToUnescapedPath:en,compile:qwe,contains:It,deepEqual:os,deleteNestedProperty:ty,duplicate:_t,entries:pu,every:n$,fieldIntersection:i$,flatAccessWithDatum:HB,getFirstDefined:qn,hasIntersection:r$,hasProperty:Ae,hash:Ut,internalField:VB,isBoolean:Og,isEmpty:an,isEqual:l0e,isInternalField:XB,isNullOrFalse:tA,isNumeric:Ub,keys:Ee,logicalExpr:sg,mergeDeep:qB,never:UB,normalize:Gj,normalizeAngle:Lg,omit:Bi,pick:Kd,prefixGenerator:nA,removePathFromField:Rh,replaceAll:Jc,replacePathInField:zs,resetIdCounter:c0e,setEqual:WB,some:Zd,stringify:ln,titleCase:N0,unique:Jo,uniqueId:YB,vals:Or,varName:_n,version:Gwe},Symbol.toStringTag,{value:"Module"}));function vq(e){const[t,n]=/schema\/([\w-]+)\/([\w\.\-]+)\.json$/g.exec(e).slice(1,3);return{library:t,version:n}}var Vwe="2.15.0",Xwe={version:Vwe};const qf="#fff",w8="#888",Kwe={background:"#333",view:{stroke:w8},title:{color:qf,subtitleColor:qf},style:{"guide-label":{fill:qf},"guide-title":{fill:qf}},axis:{domainColor:qf,gridColor:w8,tickColor:qf}},Vu="#4572a7",Zwe={background:"#fff",arc:{fill:Vu},area:{fill:Vu},line:{stroke:Vu,strokeWidth:2},path:{stroke:Vu},rect:{fill:Vu},shape:{stroke:Vu},symbol:{fill:Vu,strokeWidth:1.5,size:50},axis:{bandPosition:.5,grid:!0,gridColor:"#000000",gridOpacity:1,gridWidth:.5,labelPadding:10,tickSize:5,tickWidth:.5},axisBand:{grid:!1,tickExtra:!0},legend:{labelBaseline:"middle",labelFontSize:11,symbolSize:50,symbolType:"square"},range:{category:["#4572a7","#aa4643","#8aa453","#71598e","#4598ae","#d98445","#94aace","#d09393","#b9cc98","#a99cbc"]}},Xu="#30a2da",S_="#cbcbcb",Jwe="#999",Qwe="#333",E8="#f0f0f0",A8="#333",eEe={arc:{fill:Xu},area:{fill:Xu},axis:{domainColor:S_,grid:!0,gridColor:S_,gridWidth:1,labelColor:Jwe,labelFontSize:10,titleColor:Qwe,tickColor:S_,tickSize:10,titleFontSize:14,titlePadding:10,labelPadding:4},axisBand:{grid:!1},background:E8,group:{fill:E8},legend:{labelColor:A8,labelFontSize:11,padding:1,symbolSize:30,symbolType:"square",titleColor:A8,titleFontSize:14,titlePadding:10},line:{stroke:Xu,strokeWidth:2},path:{stroke:Xu,strokeWidth:.5},rect:{fill:Xu},range:{category:["#30a2da","#fc4f30","#e5ae38","#6d904f","#8b8b8b","#b96db8","#ff9e27","#56cc60","#52d2ca","#52689e","#545454","#9fe4f8"],diverging:["#cc0020","#e77866","#f6e7e1","#d6e8ed","#91bfd9","#1d78b5"],heatmap:["#d6e8ed","#cee0e5","#91bfd9","#549cc6","#1d78b5"]},point:{filled:!0,shape:"circle"},shape:{stroke:Xu},bar:{binSpacing:2,fill:Xu,stroke:null},title:{anchor:"start",fontSize:24,fontWeight:600,offset:20}},Ku="#000",tEe={group:{fill:"#e5e5e5"},arc:{fill:Ku},area:{fill:Ku},line:{stroke:Ku},path:{stroke:Ku},rect:{fill:Ku},shape:{stroke:Ku},symbol:{fill:Ku,size:40},axis:{domain:!1,grid:!0,gridColor:"#FFFFFF",gridOpacity:1,labelColor:"#7F7F7F",labelPadding:4,tickColor:"#7F7F7F",tickSize:5.67,titleFontSize:16,titleFontWeight:"normal"},legend:{labelBaseline:"middle",labelFontSize:11,symbolSize:40},range:{category:["#000000","#7F7F7F","#1A1A1A","#999999","#333333","#B0B0B0","#4D4D4D","#C9C9C9","#666666","#DCDCDC"]}},nEe=22,rEe="normal",k8="Benton Gothic, sans-serif",S8=11.5,iEe="normal",Zu="#82c6df",C_="Benton Gothic Bold, sans-serif",C8="normal",$8=13,hp={"category-6":["#ec8431","#829eb1","#c89d29","#3580b1","#adc839","#ab7fb4"],"fire-7":["#fbf2c7","#f9e39c","#f8d36e","#f4bb6a","#e68a4f","#d15a40","#ab4232"],"fireandice-6":["#e68a4f","#f4bb6a","#f9e39c","#dadfe2","#a6b7c6","#849eae"]},sEe={background:"#ffffff",title:{anchor:"start",color:"#000000",font:C_,fontSize:nEe,fontWeight:rEe},arc:{fill:Zu},area:{fill:Zu},line:{stroke:Zu,strokeWidth:2},path:{stroke:Zu},rect:{fill:Zu},shape:{stroke:Zu},symbol:{fill:Zu,size:30},axis:{labelFont:k8,labelFontSize:S8,labelFontWeight:iEe,titleFont:C_,titleFontSize:$8,titleFontWeight:C8},axisX:{labelAngle:0,labelPadding:4,tickSize:3},axisY:{labelBaseline:"middle",maxExtent:45,minExtent:45,tickSize:2,titleAlign:"left",titleAngle:0,titleX:-45,titleY:-11},legend:{labelFont:k8,labelFontSize:S8,symbolType:"square",titleFont:C_,titleFontSize:$8,titleFontWeight:C8},range:{category:hp["category-6"],diverging:hp["fireandice-6"],heatmap:hp["fire-7"],ordinal:hp["fire-7"],ramp:hp["fire-7"]}},Ju="#ab5787",Bm="#979797",oEe={background:"#f9f9f9",arc:{fill:Ju},area:{fill:Ju},line:{stroke:Ju},path:{stroke:Ju},rect:{fill:Ju},shape:{stroke:Ju},symbol:{fill:Ju,size:30},axis:{domainColor:Bm,domainWidth:.5,gridWidth:.2,labelColor:Bm,tickColor:Bm,tickWidth:.2,titleColor:Bm},axisBand:{grid:!1},axisX:{grid:!0,tickSize:10},axisY:{domain:!1,grid:!0,tickSize:0},legend:{labelFontSize:11,padding:1,symbolSize:30,symbolType:"square"},range:{category:["#ab5787","#51b2e5","#703c5c","#168dd9","#d190b6","#00609f","#d365ba","#154866","#666666","#c4c4c4"]}},Qu="#3e5c69",aEe={background:"#fff",arc:{fill:Qu},area:{fill:Qu},line:{stroke:Qu},path:{stroke:Qu},rect:{fill:Qu},shape:{stroke:Qu},symbol:{fill:Qu},axis:{domainWidth:.5,grid:!0,labelPadding:2,tickSize:5,tickWidth:.5,titleFontWeight:"normal"},axisBand:{grid:!1},axisX:{gridWidth:.2},axisY:{gridDash:[3],gridWidth:.4},legend:{labelFontSize:11,padding:1,symbolType:"square"},range:{category:["#3e5c69","#6793a6","#182429","#0570b0","#3690c0","#74a9cf","#a6bddb","#e2ddf2"]}},bs="#1696d2",F8="#000000",lEe="#FFFFFF",zm="Lato",$_="Lato",uEe="Lato",cEe="#DEDDDD",fEe=18,pp={"shades-blue":["#CFE8F3","#A2D4EC","#73BFE2","#46ABDB","#1696D2","#12719E","#0A4C6A","#062635"],"six-groups-cat-1":["#1696d2","#ec008b","#fdbf11","#000000","#d2d2d2","#55b748"],"six-groups-seq":["#cfe8f3","#a2d4ec","#73bfe2","#46abdb","#1696d2","#12719e"],"diverging-colors":["#ca5800","#fdbf11","#fdd870","#fff2cf","#cfe8f3","#73bfe2","#1696d2","#0a4c6a"]},dEe={background:lEe,title:{anchor:"start",fontSize:fEe,font:zm},axisX:{domain:!0,domainColor:F8,domainWidth:1,grid:!1,labelFontSize:12,labelFont:$_,labelAngle:0,tickColor:F8,tickSize:5,titleFontSize:12,titlePadding:10,titleFont:zm},axisY:{domain:!1,domainWidth:1,grid:!0,gridColor:cEe,gridWidth:1,labelFontSize:12,labelFont:$_,labelPadding:8,ticks:!1,titleFontSize:12,titlePadding:10,titleFont:zm,titleAngle:0,titleY:-10,titleX:18},legend:{labelFontSize:12,labelFont:$_,symbolSize:100,titleFontSize:12,titlePadding:10,titleFont:zm,orient:"right",offset:10},view:{stroke:"transparent"},range:{category:pp["six-groups-cat-1"],diverging:pp["diverging-colors"],heatmap:pp["diverging-colors"],ordinal:pp["six-groups-seq"],ramp:pp["shades-blue"]},area:{fill:bs},rect:{fill:bs},line:{color:bs,stroke:bs,strokeWidth:5},trail:{color:bs,stroke:bs,strokeWidth:0,size:1},path:{stroke:bs,strokeWidth:.5},point:{filled:!0},text:{font:uEe,color:bs,fontSize:11,align:"center",fontWeight:400,size:11},style:{bar:{fill:bs,stroke:null}},arc:{fill:bs},shape:{stroke:bs},symbol:{fill:bs,size:30}},ec="#3366CC",D8="#ccc",jm="Arial, sans-serif",hEe={arc:{fill:ec},area:{fill:ec},path:{stroke:ec},rect:{fill:ec},shape:{stroke:ec},symbol:{stroke:ec},circle:{fill:ec},background:"#fff",padding:{top:10,right:10,bottom:10,left:10},style:{"guide-label":{font:jm,fontSize:12},"guide-title":{font:jm,fontSize:12},"group-title":{font:jm,fontSize:12}},title:{font:jm,fontSize:14,fontWeight:"bold",dy:-3,anchor:"start"},axis:{gridColor:D8,tickColor:D8,domain:!1,grid:!0},range:{category:["#4285F4","#DB4437","#F4B400","#0F9D58","#AB47BC","#00ACC1","#FF7043","#9E9D24","#5C6BC0","#F06292","#00796B","#C2185B"],heatmap:["#c6dafc","#5e97f6","#2a56c6"]}},$F=e=>e*(1/3+1),M8=$F(9),T8=$F(10),R8=$F(12),gp="Segoe UI",N8="wf_standard-font, helvetica, arial, sans-serif",O8="#252423",mp="#605E5C",L8="transparent",pEe="#C8C6C4",Ks="#118DFF",gEe="#12239E",mEe="#E66C37",vEe="#6B007B",yEe="#E044A7",bEe="#744EC2",xEe="#D9B300",_Ee="#D64550",yq=Ks,bq="#DEEFFF",I8=[bq,yq],wEe=[bq,"#c7e4ff","#b0d9ff","#9aceff","#83c3ff","#6cb9ff","#55aeff","#3fa3ff","#2898ff",yq],EEe={view:{stroke:L8},background:L8,font:gp,header:{titleFont:N8,titleFontSize:R8,titleColor:O8,labelFont:gp,labelFontSize:T8,labelColor:mp},axis:{ticks:!1,grid:!1,domain:!1,labelColor:mp,labelFontSize:M8,titleFont:N8,titleColor:O8,titleFontSize:R8,titleFontWeight:"normal"},axisQuantitative:{tickCount:3,grid:!0,gridColor:pEe,gridDash:[1,5],labelFlush:!1},axisBand:{tickExtra:!0},axisX:{labelPadding:5},axisY:{labelPadding:10},bar:{fill:Ks},line:{stroke:Ks,strokeWidth:3,strokeCap:"round",strokeJoin:"round"},text:{font:gp,fontSize:M8,fill:mp},arc:{fill:Ks},area:{fill:Ks,line:!0,opacity:.6},path:{stroke:Ks},rect:{fill:Ks},point:{fill:Ks,filled:!0,size:75},shape:{stroke:Ks},symbol:{fill:Ks,strokeWidth:1.5,size:50},legend:{titleFont:gp,titleFontWeight:"bold",titleColor:mp,labelFont:gp,labelFontSize:T8,labelColor:mp,symbolType:"circle",symbolSize:75},range:{category:[Ks,gEe,mEe,vEe,yEe,bEe,xEe,_Ee],diverging:I8,heatmap:I8,ordinal:wEe}},F_='IBM Plex Sans,system-ui,-apple-system,BlinkMacSystemFont,".sfnstext-regular",sans-serif',AEe='IBM Plex Sans Condensed, system-ui, -apple-system, BlinkMacSystemFont, ".SFNSText-Regular", sans-serif',D_=400,Um={textPrimary:{g90:"#f4f4f4",g100:"#f4f4f4",white:"#161616",g10:"#161616"},textSecondary:{g90:"#c6c6c6",g100:"#c6c6c6",white:"#525252",g10:"#525252"},layerAccent01:{white:"#e0e0e0",g10:"#e0e0e0",g90:"#525252",g100:"#393939"},gridBg:{white:"#ffffff",g10:"#ffffff",g90:"#161616",g100:"#161616"}},kEe=["#8a3ffc","#33b1ff","#007d79","#ff7eb6","#fa4d56","#fff1f1","#6fdc8c","#4589ff","#d12771","#d2a106","#08bdba","#bae6ff","#ba4e00","#d4bbff"],SEe=["#6929c4","#1192e8","#005d5d","#9f1853","#fa4d56","#570408","#198038","#002d9c","#ee538b","#b28600","#009d9a","#012749","#8a3800","#a56eff"];function O2({theme:e,background:t}){const n=["white","g10"].includes(e)?"light":"dark",r=Um.gridBg[e],i=Um.textPrimary[e],s=Um.textSecondary[e],o=n==="dark"?kEe:SEe,a=n==="dark"?"#d4bbff":"#6929c4";return{background:t,arc:{fill:a},area:{fill:a},path:{stroke:a},rect:{fill:a},shape:{stroke:a},symbol:{stroke:a},circle:{fill:a},view:{fill:r,stroke:r},group:{fill:r},title:{color:i,anchor:"start",dy:-15,fontSize:16,font:F_,fontWeight:600},axis:{labelColor:s,labelFontSize:12,labelFont:AEe,labelFontWeight:D_,titleColor:i,titleFontWeight:600,titleFontSize:12,grid:!0,gridColor:Um.layerAccent01[e],labelAngle:0},axisX:{titlePadding:10},axisY:{titlePadding:2.5},style:{"guide-label":{font:F_,fill:s,fontWeight:D_},"guide-title":{font:F_,fill:s,fontWeight:D_}},range:{category:o,diverging:["#750e13","#a2191f","#da1e28","#fa4d56","#ff8389","#ffb3b8","#ffd7d9","#fff1f1","#e5f6ff","#bae6ff","#82cfff","#33b1ff","#1192e8","#0072c3","#00539a","#003a6d"],heatmap:["#f6f2ff","#e8daff","#d4bbff","#be95ff","#a56eff","#8a3ffc","#6929c4","#491d8b","#31135e","#1c0f30"]}}}const CEe=O2({theme:"white",background:"#ffffff"}),$Ee=O2({theme:"g10",background:"#f4f4f4"}),FEe=O2({theme:"g90",background:"#262626"}),DEe=O2({theme:"g100",background:"#161616"}),MEe=Xwe.version,TEe=Object.freeze(Object.defineProperty({__proto__:null,carbong10:$Ee,carbong100:DEe,carbong90:FEe,carbonwhite:CEe,dark:Kwe,excel:Zwe,fivethirtyeight:eEe,ggplot2:tEe,googlecharts:hEe,latimes:sEe,powerbi:EEe,quartz:oEe,urbaninstitute:dEe,version:MEe,vox:aEe},Symbol.toStringTag,{value:"Module"}));function REe(e,t,n,r){if(de(e))return`[${e.map(i=>t(Ie(i)?i:P8(i,n))).join(", ")}]`;if(Le(e)){let i="";const{title:s,image:o,...a}=e;s&&(i+=`

      ${t(s)}

      `),o&&(i+=``);const l=Object.keys(a);if(l.length>0){i+="";for(const u of l){let c=a[u];c!==void 0&&(Le(c)&&(c=P8(c,n)),i+=``)}i+="
      ${t(u)}${t(c)}
      "}return i||"{}"}return t(e)}function NEe(e){const t=[];return function(n,r){if(typeof r!="object"||r===null)return r;const i=t.indexOf(this)+1;return t.length=i,t.length>e?"[Object]":t.indexOf(r)>=0?"[Circular]":(t.push(r),r)}}function P8(e,t){return JSON.stringify(e,NEe(t))}var OEe=`#vg-tooltip-element { + visibility: hidden; + padding: 8px; + position: fixed; + z-index: 1000; + font-family: sans-serif; + font-size: 11px; + border-radius: 3px; + box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); + /* The default theme is the light theme. */ + background-color: rgba(255, 255, 255, 0.95); + border: 1px solid #d9d9d9; + color: black; +} +#vg-tooltip-element.visible { + visibility: visible; +} +#vg-tooltip-element h2 { + margin-top: 0; + margin-bottom: 10px; + font-size: 13px; +} +#vg-tooltip-element table { + border-spacing: 0; +} +#vg-tooltip-element table tr { + border: none; +} +#vg-tooltip-element table tr td { + overflow: hidden; + text-overflow: ellipsis; + padding-top: 2px; + padding-bottom: 2px; +} +#vg-tooltip-element table tr td.key { + color: #808080; + max-width: 150px; + text-align: right; + padding-right: 4px; +} +#vg-tooltip-element table tr td.value { + display: block; + max-width: 300px; + max-height: 7em; + text-align: left; +} +#vg-tooltip-element.dark-theme { + background-color: rgba(32, 32, 32, 0.9); + border: 1px solid #f5f5f5; + color: white; +} +#vg-tooltip-element.dark-theme td.key { + color: #bfbfbf; +} +`;const xq="vg-tooltip-element",LEe={offsetX:10,offsetY:10,id:xq,styleId:"vega-tooltip-style",theme:"light",disableDefaultStyle:!1,sanitize:IEe,maxDepth:2,formatTooltip:REe,baseURL:"",anchor:"cursor",position:["top","bottom","left","right","top-left","top-right","bottom-left","bottom-right"]};function IEe(e){return String(e).replace(/&/g,"&").replace(/=0&&e.y>=0&&e.x+t.width<=window.innerWidth&&e.y+t.height<=window.innerHeight}function jEe(e,t,n){return e.clientX>=t.x&&e.clientX<=t.x+n.width&&e.clientY>=t.y&&e.clientY<=t.y+n.height}class UEe{constructor(t){this.options={...LEe,...t};const n=this.options.id;if(this.el=null,this.call=this.tooltipHandler.bind(this),!this.options.disableDefaultStyle&&!document.getElementById(this.options.styleId)){const r=document.createElement("style");r.setAttribute("id",this.options.styleId),r.innerHTML=PEe(n);const i=document.head;i.childNodes.length>0?i.insertBefore(r,i.childNodes[0]):i.appendChild(r)}}tooltipHandler(t,n,r,i){if(this.el=document.getElementById(this.options.id),this.el||(this.el=document.createElement("div"),this.el.setAttribute("id",this.options.id),this.el.classList.add("vg-tooltip"),(document.fullscreenElement??document.body).appendChild(this.el)),i==null||i===""){this.el.classList.remove("visible",`${this.options.theme}-theme`);return}this.el.innerHTML=this.options.formatTooltip(i,this.options.sanitize,this.options.maxDepth,this.options.baseURL),this.el.classList.add("visible",`${this.options.theme}-theme`);const{x:s,y:o}=this.options.anchor==="mark"?BEe(t,n,r,this.el.getBoundingClientRect(),this.options):_q(n,this.el.getBoundingClientRect(),this.options);this.el.style.top=`${o}px`,this.el.style.left=`${s}px`}}var M_={};/*! + * https://github.com/Starcounter-Jack/JSON-Patch + * (c) 2017-2022 Joachim Wester + * MIT licensed + */var qEe=(function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(r,i){r.__proto__=i}||function(r,i){for(var s in i)i.hasOwnProperty(s)&&(r[s]=i[s])},e(t,n)};return function(t,n){e(t,n);function r(){this.constructor=t}t.prototype=n===null?Object.create(n):(r.prototype=n.prototype,new r)}})(),WEe=Object.prototype.hasOwnProperty;function MA(e,t){return WEe.call(e,t)}function TA(e){if(Array.isArray(e)){for(var t=new Array(e.length),n=0;n=48&&r<=57){t++;continue}return!1}return!0}function rc(e){return e.indexOf("/")===-1&&e.indexOf("~")===-1?e:e.replace(/~/g,"~0").replace(/\//g,"~1")}function Aq(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")}function NA(e){if(e===void 0)return!0;if(e){if(Array.isArray(e)){for(var t=0,n=e.length;t0&&l[c-1]=="constructor"))throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");if(n&&d===void 0&&(u[h]===void 0?d=l.slice(0,c).join("/"):c==f-1&&(d=t.path),d!==void 0&&p(t,0,e,d)),c++,Array.isArray(u)){if(h==="-")h=u.length;else{if(n&&!RA(h))throw new Rn("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index","OPERATION_PATH_ILLEGAL_ARRAY_INDEX",s,t,e);RA(h)&&(h=~~h)}if(c>=f){if(n&&t.op==="add"&&h>u.length)throw new Rn("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",s,t,e);var o=GEe[t.op].call(t,u,h,e);if(o.test===!1)throw new Rn("Test operation failed","TEST_OPERATION_FAILED",s,t,e);return o}}else if(c>=f){var o=rd[t.op].call(t,u,h,e);if(o.test===!1)throw new Rn("Test operation failed","TEST_OPERATION_FAILED",s,t,e);return o}if(u=u[h],n&&c0)throw new Rn('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",t,e,n);if((e.op==="move"||e.op==="copy")&&typeof e.from!="string")throw new Rn("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",t,e,n);if((e.op==="add"||e.op==="replace"||e.op==="test")&&e.value===void 0)throw new Rn("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",t,e,n);if((e.op==="add"||e.op==="replace"||e.op==="test")&&NA(e.value))throw new Rn("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",t,e,n);if(n){if(e.op=="add"){var i=e.path.split("/").length,s=r.split("/").length;if(i!==s+1&&i!==s)throw new Rn("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",t,e,n)}else if(e.op==="replace"||e.op==="remove"||e.op==="_get"){if(e.path!==r)throw new Rn("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",t,e,n)}else if(e.op==="move"||e.op==="copy"){var o={op:"_get",path:e.from,value:void 0},a=Sq([o],n);if(a&&a.name==="OPERATION_PATH_UNRESOLVABLE")throw new Rn("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",t,e,n)}}}else throw new Rn("Operation `op` property is not one of operations defined in RFC-6902","OPERATION_OP_INVALID",t,e,n)}function Sq(e,t,n){try{if(!Array.isArray(e))throw new Rn("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(t)L2(as(t),as(e),n||!0);else{n=n||vy;for(var r=0;r0&&(e.patches=[],e.callback&&e.callback(r)),r}function DF(e,t,n,r,i){if(t!==e){typeof t.toJSON=="function"&&(t=t.toJSON());for(var s=TA(t),o=TA(e),a=!1,l=o.length-1;l>=0;l--){var u=o[l],c=e[u];if(MA(t,u)&&!(t[u]===void 0&&c!==void 0&&Array.isArray(t)===!1)){var f=t[u];typeof c=="object"&&c!=null&&typeof f=="object"&&f!=null&&Array.isArray(c)===Array.isArray(f)?DF(c,f,n,r+"/"+rc(u),i):c!==f&&(i&&n.push({op:"test",path:r+"/"+rc(u),value:as(c)}),n.push({op:"replace",path:r+"/"+rc(u),value:as(f)}))}else Array.isArray(e)===Array.isArray(t)?(i&&n.push({op:"test",path:r+"/"+rc(u),value:as(c)}),n.push({op:"remove",path:r+"/"+rc(u)}),a=!0):(i&&n.push({op:"test",path:r,value:e}),n.push({op:"replace",path:r,value:t}))}if(!(!a&&s.length==o.length))for(var l=0;l=this.max){const s=this.map.keys().next().value;this.delete(s)}this.map.set(n,r)}return this}}return T_=e,T_}var R_,j8;function MF(){if(j8)return R_;j8=1;const e=Object.freeze({loose:!0}),t=Object.freeze({});return R_=r=>r?typeof r!="object"?e:r:t,R_}var qm={exports:{}},N_,U8;function TF(){if(U8)return N_;U8=1;const e="2.0.0",t=256,n=Number.MAX_SAFE_INTEGER||9007199254740991,r=16,i=t-6;return N_={MAX_LENGTH:t,MAX_SAFE_COMPONENT_LENGTH:r,MAX_SAFE_BUILD_LENGTH:i,MAX_SAFE_INTEGER:n,RELEASE_TYPES:["major","premajor","minor","preminor","patch","prepatch","prerelease"],SEMVER_SPEC_VERSION:e,FLAG_INCLUDE_PRERELEASE:1,FLAG_LOOSE:2},N_}var O_,q8;function I2(){return q8||(q8=1,O_=typeof process=="object"&&M_&&M_.NODE_DEBUG&&/\bsemver\b/i.test(M_.NODE_DEBUG)?(...t)=>console.error("SEMVER",...t):()=>{}),O_}var W8;function RF(){return W8||(W8=1,(function(e,t){const{MAX_SAFE_COMPONENT_LENGTH:n,MAX_SAFE_BUILD_LENGTH:r,MAX_LENGTH:i}=TF(),s=I2();t=e.exports={};const o=t.re=[],a=t.safeRe=[],l=t.src=[],u=t.t={};let c=0;const f="[a-zA-Z0-9-]",d=[["\\s",1],["\\d",i],[f,r]],h=g=>{for(const[m,y]of d)g=g.split(`${m}*`).join(`${m}{0,${y}}`).split(`${m}+`).join(`${m}{1,${y}}`);return g},p=(g,m,y)=>{const b=h(m),x=c++;s(g,x,m),u[g]=x,l[x]=m,o[x]=new RegExp(m,y?"g":void 0),a[x]=new RegExp(b,y?"g":void 0)};p("NUMERICIDENTIFIER","0|[1-9]\\d*"),p("NUMERICIDENTIFIERLOOSE","\\d+"),p("NONNUMERICIDENTIFIER",`\\d*[a-zA-Z-]${f}*`),p("MAINVERSION",`(${l[u.NUMERICIDENTIFIER]})\\.(${l[u.NUMERICIDENTIFIER]})\\.(${l[u.NUMERICIDENTIFIER]})`),p("MAINVERSIONLOOSE",`(${l[u.NUMERICIDENTIFIERLOOSE]})\\.(${l[u.NUMERICIDENTIFIERLOOSE]})\\.(${l[u.NUMERICIDENTIFIERLOOSE]})`),p("PRERELEASEIDENTIFIER",`(?:${l[u.NUMERICIDENTIFIER]}|${l[u.NONNUMERICIDENTIFIER]})`),p("PRERELEASEIDENTIFIERLOOSE",`(?:${l[u.NUMERICIDENTIFIERLOOSE]}|${l[u.NONNUMERICIDENTIFIER]})`),p("PRERELEASE",`(?:-(${l[u.PRERELEASEIDENTIFIER]}(?:\\.${l[u.PRERELEASEIDENTIFIER]})*))`),p("PRERELEASELOOSE",`(?:-?(${l[u.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${l[u.PRERELEASEIDENTIFIERLOOSE]})*))`),p("BUILDIDENTIFIER",`${f}+`),p("BUILD",`(?:\\+(${l[u.BUILDIDENTIFIER]}(?:\\.${l[u.BUILDIDENTIFIER]})*))`),p("FULLPLAIN",`v?${l[u.MAINVERSION]}${l[u.PRERELEASE]}?${l[u.BUILD]}?`),p("FULL",`^${l[u.FULLPLAIN]}$`),p("LOOSEPLAIN",`[v=\\s]*${l[u.MAINVERSIONLOOSE]}${l[u.PRERELEASELOOSE]}?${l[u.BUILD]}?`),p("LOOSE",`^${l[u.LOOSEPLAIN]}$`),p("GTLT","((?:<|>)?=?)"),p("XRANGEIDENTIFIERLOOSE",`${l[u.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`),p("XRANGEIDENTIFIER",`${l[u.NUMERICIDENTIFIER]}|x|X|\\*`),p("XRANGEPLAIN",`[v=\\s]*(${l[u.XRANGEIDENTIFIER]})(?:\\.(${l[u.XRANGEIDENTIFIER]})(?:\\.(${l[u.XRANGEIDENTIFIER]})(?:${l[u.PRERELEASE]})?${l[u.BUILD]}?)?)?`),p("XRANGEPLAINLOOSE",`[v=\\s]*(${l[u.XRANGEIDENTIFIERLOOSE]})(?:\\.(${l[u.XRANGEIDENTIFIERLOOSE]})(?:\\.(${l[u.XRANGEIDENTIFIERLOOSE]})(?:${l[u.PRERELEASELOOSE]})?${l[u.BUILD]}?)?)?`),p("XRANGE",`^${l[u.GTLT]}\\s*${l[u.XRANGEPLAIN]}$`),p("XRANGELOOSE",`^${l[u.GTLT]}\\s*${l[u.XRANGEPLAINLOOSE]}$`),p("COERCEPLAIN",`(^|[^\\d])(\\d{1,${n}})(?:\\.(\\d{1,${n}}))?(?:\\.(\\d{1,${n}}))?`),p("COERCE",`${l[u.COERCEPLAIN]}(?:$|[^\\d])`),p("COERCEFULL",l[u.COERCEPLAIN]+`(?:${l[u.PRERELEASE]})?(?:${l[u.BUILD]})?(?:$|[^\\d])`),p("COERCERTL",l[u.COERCE],!0),p("COERCERTLFULL",l[u.COERCEFULL],!0),p("LONETILDE","(?:~>?)"),p("TILDETRIM",`(\\s*)${l[u.LONETILDE]}\\s+`,!0),t.tildeTrimReplace="$1~",p("TILDE",`^${l[u.LONETILDE]}${l[u.XRANGEPLAIN]}$`),p("TILDELOOSE",`^${l[u.LONETILDE]}${l[u.XRANGEPLAINLOOSE]}$`),p("LONECARET","(?:\\^)"),p("CARETTRIM",`(\\s*)${l[u.LONECARET]}\\s+`,!0),t.caretTrimReplace="$1^",p("CARET",`^${l[u.LONECARET]}${l[u.XRANGEPLAIN]}$`),p("CARETLOOSE",`^${l[u.LONECARET]}${l[u.XRANGEPLAINLOOSE]}$`),p("COMPARATORLOOSE",`^${l[u.GTLT]}\\s*(${l[u.LOOSEPLAIN]})$|^$`),p("COMPARATOR",`^${l[u.GTLT]}\\s*(${l[u.FULLPLAIN]})$|^$`),p("COMPARATORTRIM",`(\\s*)${l[u.GTLT]}\\s*(${l[u.LOOSEPLAIN]}|${l[u.XRANGEPLAIN]})`,!0),t.comparatorTrimReplace="$1$2$3",p("HYPHENRANGE",`^\\s*(${l[u.XRANGEPLAIN]})\\s+-\\s+(${l[u.XRANGEPLAIN]})\\s*$`),p("HYPHENRANGELOOSE",`^\\s*(${l[u.XRANGEPLAINLOOSE]})\\s+-\\s+(${l[u.XRANGEPLAINLOOSE]})\\s*$`),p("STAR","(<|>)?=?\\s*\\*"),p("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$"),p("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$")})(qm,qm.exports)),qm.exports}var L_,H8;function oAe(){if(H8)return L_;H8=1;const e=/^[0-9]+$/,t=(r,i)=>{const s=e.test(r),o=e.test(i);return s&&o&&(r=+r,i=+i),r===i?0:s&&!o?-1:o&&!s?1:rt(i,r)},L_}var I_,G8;function NF(){if(G8)return I_;G8=1;const e=I2(),{MAX_LENGTH:t,MAX_SAFE_INTEGER:n}=TF(),{safeRe:r,t:i}=RF(),s=MF(),{compareIdentifiers:o}=oAe();class a{constructor(u,c){if(c=s(c),u instanceof a){if(u.loose===!!c.loose&&u.includePrerelease===!!c.includePrerelease)return u;u=u.version}else if(typeof u!="string")throw new TypeError(`Invalid version. Must be a string. Got type "${typeof u}".`);if(u.length>t)throw new TypeError(`version is longer than ${t} characters`);e("SemVer",u,c),this.options=c,this.loose=!!c.loose,this.includePrerelease=!!c.includePrerelease;const f=u.trim().match(c.loose?r[i.LOOSE]:r[i.FULL]);if(!f)throw new TypeError(`Invalid Version: ${u}`);if(this.raw=u,this.major=+f[1],this.minor=+f[2],this.patch=+f[3],this.major>n||this.major<0)throw new TypeError("Invalid major version");if(this.minor>n||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>n||this.patch<0)throw new TypeError("Invalid patch version");f[4]?this.prerelease=f[4].split(".").map(d=>{if(/^[0-9]+$/.test(d)){const h=+d;if(h>=0&&h=0;)typeof this.prerelease[h]=="number"&&(this.prerelease[h]++,h=-2);if(h===-1){if(c===this.prerelease.join(".")&&f===!1)throw new Error("invalid increment argument: identifier already exists");this.prerelease.push(d)}}if(c){let h=[c,d];f===!1&&(h=[c]),o(this.prerelease[0],c)===0?isNaN(this.prerelease[1])&&(this.prerelease=h):this.prerelease=h}break}default:throw new Error(`invalid increment argument: ${u}`)}return this.raw=this.format(),this.build.length&&(this.raw+=`+${this.build.join(".")}`),this}}return I_=a,I_}var P_,Y8;function jh(){if(Y8)return P_;Y8=1;const e=NF();return P_=(n,r,i)=>new e(n,i).compare(new e(r,i)),P_}var B_,V8;function aAe(){if(V8)return B_;V8=1;const e=jh();return B_=(n,r,i)=>e(n,r,i)===0,B_}var z_,X8;function lAe(){if(X8)return z_;X8=1;const e=jh();return z_=(n,r,i)=>e(n,r,i)!==0,z_}var j_,K8;function uAe(){if(K8)return j_;K8=1;const e=jh();return j_=(n,r,i)=>e(n,r,i)>0,j_}var U_,Z8;function cAe(){if(Z8)return U_;Z8=1;const e=jh();return U_=(n,r,i)=>e(n,r,i)>=0,U_}var q_,J8;function fAe(){if(J8)return q_;J8=1;const e=jh();return q_=(n,r,i)=>e(n,r,i)<0,q_}var W_,Q8;function dAe(){if(Q8)return W_;Q8=1;const e=jh();return W_=(n,r,i)=>e(n,r,i)<=0,W_}var H_,eT;function hAe(){if(eT)return H_;eT=1;const e=aAe(),t=lAe(),n=uAe(),r=cAe(),i=fAe(),s=dAe();return H_=(a,l,u,c)=>{switch(l){case"===":return typeof a=="object"&&(a=a.version),typeof u=="object"&&(u=u.version),a===u;case"!==":return typeof a=="object"&&(a=a.version),typeof u=="object"&&(u=u.version),a!==u;case"":case"=":case"==":return e(a,u,c);case"!=":return t(a,u,c);case">":return n(a,u,c);case">=":return r(a,u,c);case"<":return i(a,u,c);case"<=":return s(a,u,c);default:throw new TypeError(`Invalid operator: ${l}`)}},H_}var G_,tT;function pAe(){if(tT)return G_;tT=1;const e=Symbol("SemVer ANY");class t{static get ANY(){return e}constructor(c,f){if(f=n(f),c instanceof t){if(c.loose===!!f.loose)return c;c=c.value}c=c.trim().split(/\s+/).join(" "),o("comparator",c,f),this.options=f,this.loose=!!f.loose,this.parse(c),this.semver===e?this.value="":this.value=this.operator+this.semver.version,o("comp",this)}parse(c){const f=this.options.loose?r[i.COMPARATORLOOSE]:r[i.COMPARATOR],d=c.match(f);if(!d)throw new TypeError(`Invalid comparator: ${c}`);this.operator=d[1]!==void 0?d[1]:"",this.operator==="="&&(this.operator=""),d[2]?this.semver=new a(d[2],this.options.loose):this.semver=e}toString(){return this.value}test(c){if(o("Comparator.test",c,this.options.loose),this.semver===e||c===e)return!0;if(typeof c=="string")try{c=new a(c,this.options)}catch{return!1}return s(c,this.operator,this.semver,this.options)}intersects(c,f){if(!(c instanceof t))throw new TypeError("a Comparator is required");return this.operator===""?this.value===""?!0:new l(c.value,f).test(this.value):c.operator===""?c.value===""?!0:new l(this.value,f).test(c.semver):(f=n(f),f.includePrerelease&&(this.value==="<0.0.0-0"||c.value==="<0.0.0-0")||!f.includePrerelease&&(this.value.startsWith("<0.0.0")||c.value.startsWith("<0.0.0"))?!1:!!(this.operator.startsWith(">")&&c.operator.startsWith(">")||this.operator.startsWith("<")&&c.operator.startsWith("<")||this.semver.version===c.semver.version&&this.operator.includes("=")&&c.operator.includes("=")||s(this.semver,"<",c.semver,f)&&this.operator.startsWith(">")&&c.operator.startsWith("<")||s(this.semver,">",c.semver,f)&&this.operator.startsWith("<")&&c.operator.startsWith(">")))}}G_=t;const n=MF(),{safeRe:r,t:i}=RF(),s=hAe(),o=I2(),a=NF(),l=Cq();return G_}var Y_,nT;function Cq(){if(nT)return Y_;nT=1;const e=/\s+/g;class t{constructor(F,N){if(N=i(N),F instanceof t)return F.loose===!!N.loose&&F.includePrerelease===!!N.includePrerelease?F:new t(F.raw,N);if(F instanceof s)return this.raw=F.value,this.set=[[F]],this.formatted=void 0,this;if(this.options=N,this.loose=!!N.loose,this.includePrerelease=!!N.includePrerelease,this.raw=F.trim().replace(e," "),this.set=this.raw.split("||").map(U=>this.parseRange(U.trim())).filter(U=>U.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${this.raw}`);if(this.set.length>1){const U=this.set[0];if(this.set=this.set.filter(j=>!g(j[0])),this.set.length===0)this.set=[U];else if(this.set.length>1){for(const j of this.set)if(j.length===1&&m(j[0])){this.set=[j];break}}}this.formatted=void 0}get range(){if(this.formatted===void 0){this.formatted="";for(let F=0;F0&&(this.formatted+="||");const N=this.set[F];for(let U=0;U0&&(this.formatted+=" "),this.formatted+=N[U].toString().trim()}}return this.formatted}format(){return this.range}toString(){return this.range}parseRange(F){const U=((this.options.includePrerelease&&h)|(this.options.loose&&p))+":"+F,j=r.get(U);if(j)return j;const W=this.options.loose,Z=W?l[u.HYPHENRANGELOOSE]:l[u.HYPHENRANGE];F=F.replace(Z,O(this.options.includePrerelease)),o("hyphen replace",F),F=F.replace(l[u.COMPARATORTRIM],c),o("comparator trim",F),F=F.replace(l[u.TILDETRIM],f),o("tilde trim",F),F=F.replace(l[u.CARETTRIM],d),o("caret trim",F);let Y=F.split(" ").map(Fe=>b(Fe,this.options)).join(" ").split(/\s+/).map(Fe=>M(Fe,this.options));W&&(Y=Y.filter(Fe=>(o("loose invalid filter",Fe,this.options),!!Fe.match(l[u.COMPARATORLOOSE])))),o("range list",Y);const J=new Map,ve=Y.map(Fe=>new s(Fe,this.options));for(const Fe of ve){if(g(Fe))return[Fe];J.set(Fe.value,Fe)}J.size>1&&J.has("")&&J.delete("");const Te=[...J.values()];return r.set(U,Te),Te}intersects(F,N){if(!(F instanceof t))throw new TypeError("a Range is required");return this.set.some(U=>y(U,N)&&F.set.some(j=>y(j,N)&&U.every(W=>j.every(Z=>W.intersects(Z,N)))))}test(F){if(!F)return!1;if(typeof F=="string")try{F=new a(F,this.options)}catch{return!1}for(let N=0;NT.value==="<0.0.0-0",m=T=>T.value==="",y=(T,F)=>{let N=!0;const U=T.slice();let j=U.pop();for(;N&&U.length;)N=U.every(W=>j.intersects(W,F)),j=U.pop();return N},b=(T,F)=>(o("comp",T,F),T=A(T,F),o("caret",T),T=_(T,F),o("tildes",T),T=k(T,F),o("xrange",T),T=$(T,F),o("stars",T),T),x=T=>!T||T.toLowerCase()==="x"||T==="*",_=(T,F)=>T.trim().split(/\s+/).map(N=>w(N,F)).join(" "),w=(T,F)=>{const N=F.loose?l[u.TILDELOOSE]:l[u.TILDE];return T.replace(N,(U,j,W,Z,Y)=>{o("tilde",T,U,j,W,Z,Y);let J;return x(j)?J="":x(W)?J=`>=${j}.0.0 <${+j+1}.0.0-0`:x(Z)?J=`>=${j}.${W}.0 <${j}.${+W+1}.0-0`:Y?(o("replaceTilde pr",Y),J=`>=${j}.${W}.${Z}-${Y} <${j}.${+W+1}.0-0`):J=`>=${j}.${W}.${Z} <${j}.${+W+1}.0-0`,o("tilde return",J),J})},A=(T,F)=>T.trim().split(/\s+/).map(N=>E(N,F)).join(" "),E=(T,F)=>{o("caret",T,F);const N=F.loose?l[u.CARETLOOSE]:l[u.CARET],U=F.includePrerelease?"-0":"";return T.replace(N,(j,W,Z,Y,J)=>{o("caret",T,j,W,Z,Y,J);let ve;return x(W)?ve="":x(Z)?ve=`>=${W}.0.0${U} <${+W+1}.0.0-0`:x(Y)?W==="0"?ve=`>=${W}.${Z}.0${U} <${W}.${+Z+1}.0-0`:ve=`>=${W}.${Z}.0${U} <${+W+1}.0.0-0`:J?(o("replaceCaret pr",J),W==="0"?Z==="0"?ve=`>=${W}.${Z}.${Y}-${J} <${W}.${Z}.${+Y+1}-0`:ve=`>=${W}.${Z}.${Y}-${J} <${W}.${+Z+1}.0-0`:ve=`>=${W}.${Z}.${Y}-${J} <${+W+1}.0.0-0`):(o("no pr"),W==="0"?Z==="0"?ve=`>=${W}.${Z}.${Y}${U} <${W}.${Z}.${+Y+1}-0`:ve=`>=${W}.${Z}.${Y}${U} <${W}.${+Z+1}.0-0`:ve=`>=${W}.${Z}.${Y} <${+W+1}.0.0-0`),o("caret return",ve),ve})},k=(T,F)=>(o("replaceXRanges",T,F),T.split(/\s+/).map(N=>S(N,F)).join(" ")),S=(T,F)=>{T=T.trim();const N=F.loose?l[u.XRANGELOOSE]:l[u.XRANGE];return T.replace(N,(U,j,W,Z,Y,J)=>{o("xRange",T,U,j,W,Z,Y,J);const ve=x(W),Te=ve||x(Z),Fe=Te||x(Y),He=Fe;return j==="="&&He&&(j=""),J=F.includePrerelease?"-0":"",ve?j===">"||j==="<"?U="<0.0.0-0":U="*":j&&He?(Te&&(Z=0),Y=0,j===">"?(j=">=",Te?(W=+W+1,Z=0,Y=0):(Z=+Z+1,Y=0)):j==="<="&&(j="<",Te?W=+W+1:Z=+Z+1),j==="<"&&(J="-0"),U=`${j+W}.${Z}.${Y}${J}`):Te?U=`>=${W}.0.0${J} <${+W+1}.0.0-0`:Fe&&(U=`>=${W}.${Z}.0${J} <${W}.${+Z+1}.0-0`),o("xRange return",U),U})},$=(T,F)=>(o("replaceStars",T,F),T.trim().replace(l[u.STAR],"")),M=(T,F)=>(o("replaceGTE0",T,F),T.trim().replace(l[F.includePrerelease?u.GTE0PRE:u.GTE0],"")),O=T=>(F,N,U,j,W,Z,Y,J,ve,Te,Fe,He)=>(x(U)?N="":x(j)?N=`>=${U}.0.0${T?"-0":""}`:x(W)?N=`>=${U}.${j}.0${T?"-0":""}`:Z?N=`>=${N}`:N=`>=${N}${T?"-0":""}`,x(ve)?J="":x(Te)?J=`<${+ve+1}.0.0-0`:x(Fe)?J=`<${ve}.${+Te+1}.0-0`:He?J=`<=${ve}.${Te}.${Fe}-${He}`:T?J=`<${ve}.${Te}.${+Fe+1}-0`:J=`<=${J}`,`${N} ${J}`.trim()),P=(T,F,N)=>{for(let U=0;U0){const j=T[U].semver;if(j.major===F.major&&j.minor===F.minor&&j.patch===F.patch)return!0}return!1}return!0};return Y_}var V_,rT;function gAe(){if(rT)return V_;rT=1;const e=Cq();return V_=(n,r,i)=>{try{r=new e(r,i)}catch{return!1}return r.test(n)},V_}var mAe=gAe(),$q=iAe(mAe);function vAe(e,t,n){const r=e.open(t),i=250,{origin:s}=new URL(t);let o=40;function a(u){u.source===r&&(o=0,e.removeEventListener("message",a,!1))}e.addEventListener("message",a,!1);function l(){o<=0||(r.postMessage(n,s),setTimeout(l,i),o-=1)}setTimeout(l,i)}var yAe=`.vega-embed { + position: relative; + display: inline-block; + box-sizing: border-box; +} +.vega-embed.has-actions { + padding-right: 38px; +} +.vega-embed details:not([open]) > :not(summary) { + display: none !important; +} +.vega-embed summary { + list-style: none; + position: absolute; + top: 0; + right: 0; + padding: 6px; + z-index: 1000; + background: white; + box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1); + color: #1b1e23; + border: 1px solid #aaa; + border-radius: 999px; + opacity: 0.2; + transition: opacity 0.4s ease-in; + cursor: pointer; + line-height: 0px; +} +.vega-embed summary::-webkit-details-marker { + display: none; +} +.vega-embed summary:active { + box-shadow: #aaa 0px 0px 0px 1px inset; +} +.vega-embed summary svg { + width: 14px; + height: 14px; +} +.vega-embed details[open] summary { + opacity: 0.7; +} +.vega-embed:hover summary, .vega-embed:focus-within summary { + opacity: 1 !important; + transition: opacity 0.2s ease; +} +.vega-embed .vega-actions { + position: absolute; + z-index: 1001; + top: 35px; + right: -9px; + display: flex; + flex-direction: column; + padding-bottom: 8px; + padding-top: 8px; + border-radius: 4px; + box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2); + border: 1px solid #d9d9d9; + background: white; + animation-duration: 0.15s; + animation-name: scale-in; + animation-timing-function: cubic-bezier(0.2, 0, 0.13, 1.5); + text-align: left; +} +.vega-embed .vega-actions a { + padding: 8px 16px; + font-family: sans-serif; + font-size: 14px; + font-weight: 600; + white-space: nowrap; + color: #434a56; + text-decoration: none; +} +.vega-embed .vega-actions a:hover, .vega-embed .vega-actions a:focus { + background-color: #f7f7f9; + color: black; +} +.vega-embed .vega-actions::before, .vega-embed .vega-actions::after { + content: ""; + display: inline-block; + position: absolute; +} +.vega-embed .vega-actions::before { + left: auto; + right: 14px; + top: -16px; + border: 8px solid rgba(0, 0, 0, 0); + border-bottom-color: #d9d9d9; +} +.vega-embed .vega-actions::after { + left: auto; + right: 15px; + top: -14px; + border: 7px solid rgba(0, 0, 0, 0); + border-bottom-color: #fff; +} +.vega-embed .chart-wrapper.fit-x { + width: 100%; +} +.vega-embed .chart-wrapper.fit-y { + height: 100%; +} + +.vega-embed-wrapper { + max-width: 100%; + overflow: auto; + padding-right: 14px; +} + +@keyframes scale-in { + from { + opacity: 0; + transform: scale(0.6); + } + to { + opacity: 1; + transform: scale(1); + } +} +`;function Fq(e,...t){for(const n of t)bAe(e,n);return e}function bAe(e,t){for(const n of Object.keys(t))vh(e,n,t[n],!0)}const Po=Vge;let Wg=Ywe;const Wm=typeof window<"u"?window:void 0;var TT;Wg===void 0&&((TT=Wm==null?void 0:Wm.vl)!=null&&TT.compile)&&(Wg=Wm.vl);const xAe={export:{svg:!0,png:!0},source:!0,compiled:!0,editor:!0},_Ae={CLICK_TO_VIEW_ACTIONS:"Click to view actions",COMPILED_ACTION:"View Compiled Vega",EDITOR_ACTION:"Open in Vega Editor",PNG_ACTION:"Save as PNG",SOURCE_ACTION:"View Source",SVG_ACTION:"Save as SVG"},Up={vega:"Vega","vega-lite":"Vega-Lite"},yy={vega:Po.version,"vega-lite":Wg?Wg.version:"not available"},wAe={vega:e=>e,"vega-lite":(e,t)=>Wg.compile(e,{config:t}).spec},EAe=` + + + + +`,AAe="chart-wrapper";function kAe(e){return typeof e=="function"}function iT(e,t,n,r){const i=`${t}
      `,s=`
      ${n}`,o=window.open("");o.document.write(i+e+s),o.document.title=`${Up[r]} JSON Source`}function SAe(e,t){if(e.$schema){const n=vq(e.$schema);t&&t!==n.library&&console.warn(`The given visualization spec is written in ${Up[n.library]}, but mode argument sets ${Up[t]??t}.`);const r=n.library;return $q(yy[r],`^${n.version.slice(1)}`)||console.warn(`The input spec uses ${Up[r]} ${n.version}, but the current version of ${Up[r]} is v${yy[r]}.`),r}return"mark"in e||"encoding"in e||"layer"in e||"hconcat"in e||"vconcat"in e||"facet"in e||"repeat"in e?"vega-lite":"marks"in e||"signals"in e||"scales"in e||"axes"in e?"vega":t??"vega"}function Dq(e){return!!(e&&"load"in e)}function sT(e){return Dq(e)?e:Po.loader(e)}function CAe(e){var n;const t=((n=e.usermeta)==null?void 0:n.embedOptions)??{};return Ie(t.defaultStyle)&&(t.defaultStyle=!1),t}async function Mq(e,t,n={}){let r,i;Ie(t)?(i=sT(n.loader),r=JSON.parse(await i.load(t))):r=t;const s=CAe(r),o=s.loader;(!i||o)&&(i=sT(n.loader??o));const a=await oT(s,i),l=await oT(n,i),u={...Fq(l,a),config:mh(l.config??{},a.config??{})};return await FAe(e,r,u,i)}async function oT(e,t){const n=Ie(e.config)?JSON.parse(await t.load(e.config)):e.config??{},r=Ie(e.patch)?JSON.parse(await t.load(e.patch)):e.patch;return{...e,...r?{patch:r}:{},...n?{config:n}:{}}}function $Ae(e){const t=e.getRootNode?e.getRootNode():document;return t instanceof ShadowRoot?{root:t,rootContainer:t}:{root:document,rootContainer:document.head??document.body}}async function FAe(e,t,n={},r){const i=n.theme?mh(TEe[n.theme],n.config??{}):n.config,s=wu(n.actions)?n.actions:Fq({},xAe,n.actions??{}),o={..._Ae,...n.i18n},a=n.renderer??"canvas",l=n.logLevel??Po.Warn,u=n.downloadFileName??"visualization",c=typeof e=="string"?document.querySelector(e):e;if(!c)throw new Error(`${e} does not exist`);if(n.defaultStyle!==!1){const w="vega-embed-style",{root:A,rootContainer:E}=$Ae(c);if(!A.getElementById(w)){const k=document.createElement("style");k.id=w,k.innerHTML=n.defaultStyle===void 0||n.defaultStyle===!0?yAe.toString():n.defaultStyle,E.appendChild(k)}}const f=SAe(t,n.mode);let d=wAe[f](t,i);if(f==="vega-lite"&&d.$schema){const w=vq(d.$schema);$q(yy.vega,`^${w.version.slice(1)}`)||console.warn(`The compiled spec uses Vega ${w.version}, but current version is v${yy.vega}.`)}c.classList.add("vega-embed"),s&&c.classList.add("has-actions"),c.innerHTML="";let h=c;if(s){const w=document.createElement("div");w.classList.add(AAe),c.appendChild(w),h=w}const p=n.patch;if(p&&(d=p instanceof Function?p(d):L2(d,p,!0,!1).newDocument),n.formatLocale&&Po.formatLocale(n.formatLocale),n.timeFormatLocale&&Po.timeFormatLocale(n.timeFormatLocale),n.expressionFunctions)for(const w in n.expressionFunctions){const A=n.expressionFunctions[w];"fn"in A?Po.expressionFunction(w,A.fn,A.visitor):A instanceof Function&&Po.expressionFunction(w,A)}const{ast:g}=n,m=Po.parse(d,f==="vega-lite"?{}:i,{ast:g}),y=new(n.viewClass||Po.View)(m,{loader:r,logLevel:l,renderer:a,...g?{expr:Po.expressionInterpreter??n.expr??i0e}:{}});if(y.addSignalListener("autosize",(w,A)=>{const{type:E}=A;E=="fit-x"?(h.classList.add("fit-x"),h.classList.remove("fit-y")):E=="fit-y"?(h.classList.remove("fit-x"),h.classList.add("fit-y")):E=="fit"?h.classList.add("fit-x","fit-y"):h.classList.remove("fit-x","fit-y")}),n.tooltip!==!1){const{loader:w,tooltip:A}=n,E=w&&!Dq(w)?w==null?void 0:w.baseURL:void 0,k=kAe(A)?A:new UEe({baseURL:E,...A===!0?{}:A}).call;y.tooltip(k)}let{hover:b}=n;if(b===void 0&&(b=f==="vega"),b){const{hoverSet:w,updateSet:A}=typeof b=="boolean"?{}:b;y.hover(w,A)}n&&(n.width!=null&&y.width(n.width),n.height!=null&&y.height(n.height),n.padding!=null&&y.padding(n.padding)),await y.initialize(h,n.bind).runAsync();let x;if(s!==!1){let w=c;if(n.defaultStyle!==!1||n.forceActionsMenu){const E=document.createElement("details");E.title=o.CLICK_TO_VIEW_ACTIONS,c.append(E),w=E;const k=document.createElement("summary");k.innerHTML=EAe,E.append(k),x=S=>{E.contains(S.target)||E.removeAttribute("open")},document.addEventListener("click",x)}const A=document.createElement("div");if(w.append(A),A.classList.add("vega-actions"),s===!0||s.export!==!1){for(const E of["svg","png"])if(s===!0||s.export===!0||s.export[E]){const k=o[`${E.toUpperCase()}_ACTION`],S=document.createElement("a"),$=Le(n.scaleFactor)?n.scaleFactor[E]:n.scaleFactor;S.text=k,S.href="#",S.target="_blank",S.download=`${u}.${E}`,S.addEventListener("mousedown",async function(M){M.preventDefault();const O=await y.toImageURL(E,$);this.href=O}),A.append(S)}}if(s===!0||s.source!==!1){const E=document.createElement("a");E.text=o.SOURCE_ACTION,E.href="#",E.addEventListener("click",function(k){iT(nx(t),n.sourceHeader??"",n.sourceFooter??"",f),k.preventDefault()}),A.append(E)}if(f==="vega-lite"&&(s===!0||s.compiled!==!1)){const E=document.createElement("a");E.text=o.COMPILED_ACTION,E.href="#",E.addEventListener("click",function(k){iT(nx(d),n.sourceHeader??"",n.sourceFooter??"","vega"),k.preventDefault()}),A.append(E)}if(s===!0||s.editor!==!1){const E=n.editorUrl??"https://vega.github.io/editor/",k=document.createElement("a");k.text=o.EDITOR_ACTION,k.href="#",k.addEventListener("click",function(S){vAe(window,E,{config:i,mode:p?"vega":f,renderer:a,spec:nx(p?d:t)}),S.preventDefault()}),A.append(k)}}function _(){x&&document.removeEventListener("click",x),y.finalize()}return{view:y,spec:t,vgSpec:d,finalize:_,embedOptions:n}}function aT(e,t,n){return!e||e.length===0?[]:t||e.length<=n?e:e.slice(0,n)}var DAe=q('
      '),MAe=q('
      '),TAe=q(''),RAe=q(' '),NAe=q(''),OAe=q('
      '),LAe=q(' '),IAe=q('
      '),PAe=q('
      ',1),BAe=q('
      '),zAe=q(''),jAe=q(' '),UAe=q(''),qAe=q('
      '),WAe=q(' '),HAe=q('
      '),GAe=q('
      '),YAe=q('
      ',1);function by(e,t){En(t,!0);let n=ae(t,"data",19,()=>[]),r=ae(t,"x",3,"step"),i=ae(t,"y",3,""),s=ae(t,"colorField",3,"run"),o=ae(t,"colorDisplayField",3,""),a=ae(t,"colorLabel",3,""),l=ae(t,"dashField",3,""),u=ae(t,"dashLabel",3,""),c=ae(t,"yLabel",3,""),f=ae(t,"colorMap",19,()=>({})),d=ae(t,"title",3,""),h=ae(t,"xLim",3,null),p=ae(t,"yExtent",3,void 0),g=ae(t,"onSelect",3,null),m=ae(t,"onResetZoom",3,null),y=ae(t,"draggable",3,!1),b=ae(t,"ondragstart",3,null),x=ae(t,"ondragover",3,null),_=ae(t,"ondrop",3,null),w=re(null),A=re(null),E=re(null),k=re(null),S=re(!1),$=null,M=!1,O=we(()=>a()||s()),P=we(()=>u()||l()),T=we(()=>c()||(i().includes("/")?i().split("/").pop():i())),F=we(()=>{if(!s()||!n()||n().length===0)return[];const Q=new Set,pe=[];for(const Ye of n()){const gt=Ye[s()];gt&&!Q.has(gt)&&(Q.add(gt),pe.push({key:gt,name:Ye[o()]||gt,color:f()[gt]||"#999"}))}return pe}),N=we(()=>MR(n(),s(),f()));const U=6;let j=re(!1),W=re(!1),Z=we(()=>aT(v(F),v(j),U)),Y=we(()=>aT(v(F),v(W),U)),J=we(()=>{if(!l()||!n()||n().length===0)return[];const Q=new Set,pe=[],Ye=[[1,0],[12,4],[3,2],[10,3,2,3],[2,2],[14,4,2,4],[6,4,1,4],[16,5],[4,2,1,2],[2,1]];for(const gt of n()){const Ke=gt[l()];Ke&&!Q.has(Ke)&&(Q.add(Ke),pe.push({name:Ke,pattern:Ye[pe.length%Ye.length]}))}return pe}),ve=we(()=>{if(!l()||!n()||n().length===0)return"";const Q=v(J).map(pe=>`${pe.name}:${pe.pattern.join(",")}`);return Q.sort(),Q.join("|")});function Te(Q,pe){return getComputedStyle(document.documentElement).getPropertyValue(Q).trim()||pe}function Fe(){const Q=n().filter(Ye=>Ye.data_type==="original"||!Ye.data_type),pe=n().filter(Ye=>Ye.data_type==="smoothed");return{originalData:Q,smoothedData:pe,hasSmoothed:pe.length>0}}function He(Q){const pe=Q.map(Ye=>Ye[r()]).filter(Ye=>Ye!=null);if(h())return[h()[0],h()[1]];if(pe.length>0)return[Math.min(...pe),Math.max(...pe)]}function ut(){const Q=s()&&n().length>0&&Object.hasOwn(n()[0],s()),pe=l()&&n().length>0&&Object.hasOwn(n()[0],l()),Ye=Q?[...new Set(n().map(vt=>vt[s()]))]:[],gt=[...new Set(Ye)],Ke=gt,Ze=gt.map(vt=>f()[vt]||"#999"),{originalData:We,smoothedData:it,hasSmoothed:bt}=Fe();M=bt;const Et=He(We),Ge={field:r(),type:"quantitative",scale:{zero:!1,...Et?{domain:Et}:{}}},dt={field:i(),type:"quantitative",...p()?{scale:{domain:p()}}:{}},mt=Q?{color:{field:s(),type:"nominal",scale:{domain:Ke,range:Ze},legend:null}}:{},se=pe?{strokeDash:{field:l(),type:"nominal",scale:{domain:v(J).map(vt=>vt.name),range:v(J).map(vt=>vt.pattern)},legend:null}}:{},ke=[],At=(vt={})=>({type:"line",clip:!0,strokeWidth:2.25,...vt}),Ft=v(T),Pe=[];Q&&Pe.push({field:o()||s(),type:"nominal",title:v(O)}),pe&&Pe.push({field:l(),type:"nominal",title:v(P)}),Pe.push({field:r(),type:"quantitative",title:r()},{field:i(),type:"quantitative",title:Ft});const Je=[{name:"hover",select:{type:"point",on:"pointerover",nearest:!0,clear:"pointerout"}}],Qe=(vt,kn)=>({...vt,mark:{type:"circle",clip:!0,size:60,opacity:0},encoding:{x:Ge,y:dt,...mt,tooltip:Pe,opacity:{condition:{param:"hover",empty:!1,value:1},value:0}},params:Je,name:kn});return bt?(ke.push({data:{name:"data_original",values:We},mark:At({strokeWidth:1,opacity:.3}),encoding:{x:Ge,y:dt,...mt,...se},name:"original"}),ke.push({data:{name:"data_smoothed",values:it},mark:At(),encoding:{x:Ge,y:dt,...mt,...se},name:"plot"}),ke.push(Qe({data:{name:"data_smoothed",values:it}},"hover_points"))):(ke.push({data:{name:"data_plot",values:n()},mark:At(),encoding:{x:Ge,y:dt,...mt,...se},name:"plot"}),ke.push(Qe({data:{name:"data_plot",values:n()}},"hover_points"))),{$schema:"https://vega.github.io/schema/vega-lite/v5.json",width:"container",height:v(S)?"container":250,autosize:{type:"fit",contains:"padding"},layer:ke,...g()?{params:[{name:"brush",select:{type:"interval",encodings:["x"],mark:{fill:"gray",fillOpacity:.3,stroke:"none"}},views:["plot"]}]}:{},config:{background:"transparent",axis:{labelColor:Te("--body-text-color-subdued","#6b7280"),titleColor:Te("--body-text-color","#374151"),gridColor:Te("--border-color-primary","#f3f4f6")},view:{stroke:"transparent"},mark:{cursor:g()?"crosshair":void 0}},encoding:{y:{title:Ft}}}}function wt(){const{originalData:Q}=Fe(),pe=He(Q),Ye=pe?`${pe[0]},${pe[1]}`:"auto",gt=p()?`${p()[0]},${p()[1]}`:"auto";return`${i()}\0${r()}\0${v(N)}\0${v(ve)}\0${d()}\0${v(S)}\0${!!g()}\0${Ye}\0${gt}`}function xe(Q,pe,Ye){const gt=Eu().remove(ds).insert(Ye);Q.change(pe,gt)}function je(){if(!v(k))return!1;const{originalData:Q,smoothedData:pe,hasSmoothed:Ye}=Fe();if(Ye!==M)return!1;try{return Ye?(xe(v(k),"data_original",Q),xe(v(k),"data_smoothed",pe)):xe(v(k),"data_plot",n()),v(k).run(),M=Ye,!0}catch{return!1}}async function fe(){if(await ns(),!v(w)||!n()||n().length===0||!i())return;const Q=ut();try{v(k)&&(v(k).finalize(),D(k,null));const pe=await Mq(v(w),Q,{actions:!1,renderer:"canvas"});if(D(k,pe.view,!0),$=wt(),requestAnimationFrame(()=>{pe.view.resize()}),g()){let Ye=0,gt=null;pe.view.addSignalListener("brush",(Ke,Ze)=>{if(Date.now()-Ye<1e3||!Ze||Object.keys(Ze).length===0)return;clearTimeout(gt);const We=Ze[Object.keys(Ze)[0]];!We||We.length!==2||(gt=setTimeout(()=>{Ye=Date.now(),g()(We)},250))})}}catch(pe){console.error("Vega render error:",pe)}}async function V(){if(!v(w)||!n()||n().length===0||!i())return;const Q=wt();v(k)&&Q===$&&je()||await fe()}function B(){if(!n()||n().length===0)return;const Q=n().filter(bt=>bt.data_type==="original"||!bt.data_type);if(Q.length===0)return;const pe=Object.keys(Q[0]).filter(bt=>bt!=="data_type"),Ye=pe.map(bt=>/[,"]/.test(bt)?`"${bt.replace(/"/g,'""')}"`:bt).join(","),gt=Q.map(bt=>pe.map(Et=>{const Ge=bt[Et];return Ge==null?"":typeof Ge=="string"&&(Ge.includes(",")||Ge.includes('"'))?`"${Ge.replace(/"/g,'""')}"`:Ge}).join(",")),Ke=[Ye,...gt].join(` +`),Ze=new Blob([Ke],{type:"text/csv"}),We=URL.createObjectURL(Ze),it=document.createElement("a");it.href=We,it.download=`${(i()||"data").replace(/\//g,"_")}.csv`,document.body.appendChild(it),it.click(),document.body.removeChild(it),URL.revokeObjectURL(We)}async function L(){if(v(k))try{const Q=await v(k).toImageURL("png",4),pe=document.createElement("a");pe.href=Q,pe.download=`${(i()||"chart").replace(/\//g,"_")}.png`,document.body.appendChild(pe),pe.click(),document.body.removeChild(pe)}catch(Q){console.error("Failed to export image:",Q)}}function X(Q){if(!Q)return Promise.reject(new Error("no element"));const pe=Q.requestFullscreen||Q.webkitRequestFullscreen||Q.mozRequestFullScreen||Q.msRequestFullscreen;return pe?pe.call(Q):Promise.reject(new Error("no fullscreen"))}function G(){const Q=document.exitFullscreen||document.webkitExitFullscreen||document.mozCancelFullScreen||document.msExitFullscreen;return Q?Q.call(document):Promise.resolve()}function z(Q){const pe=document.getElementById("vg-tooltip-element");pe&&Q&&pe.parentElement!==Q&&Q.appendChild(pe)}async function te(){var Q;D(S,!0),document.body.style.overflow="hidden",await ns(),await ns();try{await X(v(E)),await ns(),z(v(E)),(Q=v(k))==null||Q.resize()}catch{document.body.style.overflow="",D(S,!1)}}async function Ne(){try{await G()}catch{}document.body.style.overflow="",D(S,!1),z(document.body)}async function H(){v(S)?await Ne():await te()}function ee(){const Q=document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement;!Q&&v(S)&&(document.body.style.overflow="",D(S,!1),z(document.body)),Q&&v(S)&&ns().then(()=>{var pe;return(pe=v(k))==null?void 0:pe.resize()})}function ne(Q){Q.key==="Escape"&&v(S)&&Ne()}zt(()=>{n(),i(),r(),v(N),v(ve),h(),p(),d(),v(S),v(w),V()}),zt(()=>{if(!v(w))return;const Q=new ResizeObserver(()=>{queueMicrotask(()=>{var pe;(pe=v(k))==null||pe.resize()})});return Q.observe(v(w)),()=>Q.disconnect()}),hh(()=>(document.addEventListener("fullscreenchange",ee),document.addEventListener("webkitfullscreenchange",ee),document.addEventListener("mozfullscreenchange",ee),document.addEventListener("MSFullscreenChange",ee),()=>{document.removeEventListener("fullscreenchange",ee),document.removeEventListener("webkitfullscreenchange",ee),document.removeEventListener("mozfullscreenchange",ee),document.removeEventListener("MSFullscreenChange",ee),v(k)&&v(k).finalize(),document.body.style.overflow=""}));function be(Q){b()&&b()(Q)}var K=YAe();fn("keydown",$d,ne);var ge=Bt(K);let _e;var De=C(ge),ct=C(De),ze=R(ct,2),Xe=R(ze,2),lt=R(De,2);{var yt=Q=>{var pe=DAe();I(Q,pe)};he(lt,Q=>{y()&&Q(yt)})}var pt=R(lt,2);{var rt=Q=>{var pe=PAe(),Ye=Bt(pe);{var gt=mt=>{var se=MAe(),ke=C(se);ye(()=>me(ke,d())),I(mt,se)};he(Ye,mt=>{d()&&mt(gt)})}var Ke=R(Ye,2),Ze=C(Ke);is(Ze,mt=>D(w,mt),()=>v(w));var We=R(Ze,2);{var it=mt=>{var se=TAe();Oe("click",se,ke=>{ke.stopPropagation(),m()()}),I(mt,se)};he(We,mt=>{h()&&m()&&mt(it)})}var bt=R(Ke,2);{var Et=mt=>{var se=OAe(),ke=C(se);$t(ke,17,()=>v(Z),Dt,(Pe,Je)=>{var Qe=RAe(),vt=C(Qe),kn=R(vt,2),In=C(kn);ye(()=>{ll(vt,`background: ${v(Je).color??""}`),me(In,v(Je).name)}),I(Pe,Qe)});var At=R(ke,2);{var Ft=Pe=>{var Je=NAe(),Qe=C(Je);ye(()=>me(Qe,v(j)?"Show less":`+${v(F).length-U} more`)),Oe("click",Je,vt=>{vt.stopPropagation(),D(j,!v(j))}),I(Pe,Je)};he(At,Pe=>{v(F).length>U&&Pe(Ft)})}I(mt,se)};he(bt,mt=>{v(F).length>0&&mt(Et)})}var Ge=R(bt,2);{var dt=mt=>{var se=IAe(),ke=C(se),At=C(ke),Ft=R(ke,2);$t(Ft,17,()=>v(J),Dt,(Pe,Je)=>{var Qe=LAe(),vt=C(Qe),kn=C(vt),In=R(vt,2),Gn=C(In);ye(or=>{St(kn,"stroke-dasharray",or),me(Gn,v(Je).name)},[()=>v(Je).pattern.join(" ")]),I(Pe,Qe)}),ye(()=>me(At,v(P))),I(mt,se)};he(Ge,mt=>{v(J).length>0&&mt(dt)})}I(Q,pe)};he(pt,Q=>{v(S)||Q(rt)})}is(ge,Q=>D(A,Q),()=>v(A));var Ve=R(ge,2);{var qe=Q=>{var pe=GAe(),Ye=C(pe),gt=C(Ye),Ke=R(gt,2),Ze=R(Ke,2),We=R(Ye,2);{var it=Pe=>{var Je=BAe(),Qe=C(Je);ye(()=>me(Qe,d())),I(Pe,Je)};he(We,Pe=>{d()&&Pe(it)})}var bt=R(We,2),Et=C(bt),Ge=C(Et);is(Ge,Pe=>D(w,Pe),()=>v(w));var dt=R(Ge,2);{var mt=Pe=>{var Je=zAe();Oe("click",Je,Qe=>{Qe.stopPropagation(),m()()}),I(Pe,Je)};he(dt,Pe=>{h()&&m()&&Pe(mt)})}var se=R(bt,2);{var ke=Pe=>{var Je=qAe(),Qe=C(Je);$t(Qe,17,()=>v(Y),Dt,(In,Gn)=>{var or=jAe(),Xi=C(or),Jt=R(Xi,2),Dn=C(Jt);ye(()=>{ll(Xi,`background: ${v(Gn).color??""}`),me(Dn,v(Gn).name)}),I(In,or)});var vt=R(Qe,2);{var kn=In=>{var Gn=UAe(),or=C(Gn);ye(()=>me(or,v(W)?"Show less":`+${v(F).length-U} more`)),Oe("click",Gn,Xi=>{Xi.stopPropagation(),D(W,!v(W))}),I(In,Gn)};he(vt,In=>{v(F).length>U&&In(kn)})}I(Pe,Je)};he(se,Pe=>{v(F).length>0&&Pe(ke)})}var At=R(se,2);{var Ft=Pe=>{var Je=HAe(),Qe=C(Je),vt=C(Qe),kn=R(Qe,2);$t(kn,17,()=>v(J),Dt,(In,Gn)=>{var or=WAe(),Xi=C(or),Jt=C(Xi),Dn=R(Xi,2),Br=C(Dn);ye(hn=>{St(Jt,"stroke-dasharray",hn),me(Br,v(Gn).name)},[()=>v(Gn).pattern.join(" ")]),I(In,or)}),ye(()=>me(vt,v(P))),I(Pe,Je)};he(At,Pe=>{v(J).length>0&&Pe(Ft)})}is(pe,Pe=>D(E,Pe),()=>v(E)),Oe("click",gt,B),Oe("click",Ke,L),Oe("click",Ze,()=>Ne()),I(Q,pe)};he(Ve,Q=>{v(S)&&Q(qe)})}ye(()=>{_e=tn(ge,1,"plot-container svelte-9thu1j",null,_e,{"hidden-plot":v(S)}),St(ge,"draggable",y()?"true":void 0)}),fn("dragstart",ge,function(...Q){var pe;(pe=y()?be:void 0)==null||pe.apply(this,Q)}),fn("dragover",ge,function(...Q){var pe;(pe=y()?x():void 0)==null||pe.apply(this,Q)}),fn("drop",ge,function(...Q){var pe;(pe=y()?_():void 0)==null||pe.apply(this,Q)}),Oe("click",ct,B),Oe("click",ze,L),Oe("click",Xe,H),I(e,K),An()}si(["click"]);var VAe=q('
      '),XAe=q('
      '),KAe=q(' '),ZAe=q(''),JAe=q('
      '),QAe=q('
      ',1),eke=q('
      '),tke=q(' '),nke=q(''),rke=q('
      '),ike=q(`
      `),ske=q(`
      `,1);function lT(e,t){En(t,!0);let n=ae(t,"data",19,()=>[]),r=ae(t,"y",3,""),i=ae(t,"colorField",3,"run"),s=ae(t,"colorDisplayField",3,""),o=ae(t,"colorMap",19,()=>({})),a=ae(t,"title",3,""),l=ae(t,"draggable",3,!1),u=ae(t,"ondragstart",3,null),c=ae(t,"ondragover",3,null),f=ae(t,"ondrop",3,null),d=re(null),h=re(null),p=re(null),g=re(null),m=re(!1),y=we(()=>{if(!i()||!n()||n().length===0)return[];const G=new Set,z=[];for(const te of n()){const Ne=te[i()];Ne&&!G.has(Ne)&&(G.add(Ne),z.push({key:Ne,name:te[s()]||Ne,color:o()[Ne]||"#999"}))}return z}),b=we(()=>MR(n(),i(),o()));const x=6;let _=re(!1),w=re(!1),A=we(()=>v(_)||v(y).length<=x?v(y):v(y).slice(0,x)),E=we(()=>v(w)||v(y).length<=x?v(y):v(y).slice(0,x));function k(){const G=new Map;for(const z of n()){if(z.data_type==="smoothed")continue;const te=z[i()];te&&z[r()]!=null&&G.set(te,{run:te,label:z[s()]||te,value:z[r()]})}return Array.from(G.values())}function S(G,z){return getComputedStyle(document.documentElement).getPropertyValue(G).trim()||z}function $(G){const z=G.map(H=>H.run),te=z.map(H=>o()[H]||"#999"),Ne=r().includes("/")?r().split("/").pop():r();return{$schema:"https://vega.github.io/schema/vega-lite/v5.json",width:"container",height:v(m)?"container":250,autosize:{type:"fit",contains:"padding"},data:{values:G},mark:{type:"bar",cornerRadiusTopLeft:3,cornerRadiusTopRight:3},encoding:{x:{field:"run",type:"nominal",sort:z,axis:{labelExpr:"datum.label",labelAngle:z.length>4?-45:0,labelLimit:120},title:null},y:{field:"value",type:"quantitative",title:Ne,scale:{zero:!0}},color:{field:"run",type:"nominal",scale:{domain:z,range:te},legend:null},tooltip:[{field:s()||"label",type:"nominal",title:"Run"},{field:"value",type:"quantitative",title:Ne}]},config:{background:"transparent",axis:{labelColor:S("--body-text-color-subdued","#6b7280"),titleColor:S("--body-text-color","#374151"),gridColor:S("--border-color-primary","#f3f4f6")},view:{stroke:"transparent"}}}}async function M(){if(await ns(),!v(d)||!n()||n().length===0||!r())return;const G=k();if(G.length===0)return;const z=$(G);try{v(g)&&(v(g).finalize(),D(g,null));const te=await Mq(v(d),z,{actions:!1,renderer:"canvas"});D(g,te.view,!0),requestAnimationFrame(()=>{te.view.resize()})}catch(te){console.error("Vega render error:",te)}}function O(){const G=k();if(G.length===0)return;const te="run,"+(/[,"]/.test(r())?`"${r().replace(/"/g,'""')}"`:r()),Ne=G.map(K=>`${typeof K.label=="string"&&(K.label.includes(",")||K.label.includes('"'))?`"${K.label.replace(/"/g,'""')}"`:K.label},${K.value}`),H=[te,...Ne].join(` +`),ee=new Blob([H],{type:"text/csv"}),ne=URL.createObjectURL(ee),be=document.createElement("a");be.href=ne,be.download=`${(r()||"data").replace(/\//g,"_")}.csv`,document.body.appendChild(be),be.click(),document.body.removeChild(be),URL.revokeObjectURL(ne)}async function P(){if(v(g))try{const G=await v(g).toImageURL("png",4),z=document.createElement("a");z.href=G,z.download=`${(r()||"chart").replace(/\//g,"_")}.png`,document.body.appendChild(z),z.click(),document.body.removeChild(z)}catch(G){console.error("Failed to export image:",G)}}function T(G){if(!G)return Promise.reject(new Error("no element"));const z=G.requestFullscreen||G.webkitRequestFullscreen||G.mozRequestFullScreen||G.msRequestFullscreen;return z?z.call(G):Promise.reject(new Error("no fullscreen"))}function F(){const G=document.exitFullscreen||document.webkitExitFullscreen||document.mozCancelFullScreen||document.msExitFullscreen;return G?G.call(document):Promise.resolve()}function N(G){const z=document.getElementById("vg-tooltip-element");z&&G&&z.parentElement!==G&&G.appendChild(z)}async function U(){var G;D(m,!0),document.body.style.overflow="hidden",await ns(),await ns();try{await T(v(p)),await ns(),N(v(p)),(G=v(g))==null||G.resize()}catch{document.body.style.overflow="",D(m,!1)}}async function j(){try{await F()}catch{}document.body.style.overflow="",D(m,!1),N(document.body)}async function W(){v(m)?await j():await U()}function Z(){const G=document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement;!G&&v(m)&&(document.body.style.overflow="",D(m,!1),N(document.body)),G&&v(m)&&ns().then(()=>{var z;return(z=v(g))==null?void 0:z.resize()})}function Y(G){G.key==="Escape"&&v(m)&&j()}zt(()=>{n(),r(),v(b),a(),v(m),v(d),M()}),zt(()=>{if(!v(d))return;const G=new ResizeObserver(()=>{queueMicrotask(()=>{var z;(z=v(g))==null||z.resize()})});return G.observe(v(d)),()=>G.disconnect()}),hh(()=>(document.addEventListener("fullscreenchange",Z),document.addEventListener("webkitfullscreenchange",Z),document.addEventListener("mozfullscreenchange",Z),document.addEventListener("MSFullscreenChange",Z),()=>{document.removeEventListener("fullscreenchange",Z),document.removeEventListener("webkitfullscreenchange",Z),document.removeEventListener("mozfullscreenchange",Z),document.removeEventListener("MSFullscreenChange",Z),v(g)&&v(g).finalize(),document.body.style.overflow=""}));function J(G){u()&&u()(G)}var ve=ske();fn("keydown",$d,Y);var Te=Bt(ve);let Fe;var He=C(Te),ut=C(He),wt=R(ut,2),xe=R(wt,2),je=R(He,2);{var fe=G=>{var z=VAe();I(G,z)};he(je,G=>{l()&&G(fe)})}var V=R(je,2);{var B=G=>{var z=QAe(),te=Bt(z);{var Ne=K=>{var ge=XAe(),_e=C(ge);ye(()=>me(_e,a())),I(K,ge)};he(te,K=>{a()&&K(Ne)})}var H=R(te,2),ee=C(H);is(ee,K=>D(d,K),()=>v(d));var ne=R(H,2);{var be=K=>{var ge=JAe(),_e=C(ge);$t(_e,17,()=>v(A),Dt,(ze,Xe)=>{var lt=KAe(),yt=C(lt),pt=R(yt,2),rt=C(pt);ye(()=>{ll(yt,`background: ${v(Xe).color??""}`),me(rt,v(Xe).name)}),I(ze,lt)});var De=R(_e,2);{var ct=ze=>{var Xe=ZAe(),lt=C(Xe);ye(()=>me(lt,v(_)?"Show less":`+${v(y).length-x} more`)),Oe("click",Xe,yt=>{yt.stopPropagation(),D(_,!v(_))}),I(ze,Xe)};he(De,ze=>{v(y).length>x&&ze(ct)})}I(K,ge)};he(ne,K=>{v(y).length>0&&K(be)})}I(G,z)};he(V,G=>{v(m)||G(B)})}is(Te,G=>D(h,G),()=>v(h));var L=R(Te,2);{var X=G=>{var z=ike(),te=C(z),Ne=C(te),H=R(Ne,2),ee=R(H,2),ne=R(te,2);{var be=ze=>{var Xe=eke(),lt=C(Xe);ye(()=>me(lt,a())),I(ze,Xe)};he(ne,ze=>{a()&&ze(be)})}var K=R(ne,2),ge=C(K),_e=C(ge);is(_e,ze=>D(d,ze),()=>v(d));var De=R(K,2);{var ct=ze=>{var Xe=rke(),lt=C(Xe);$t(lt,17,()=>v(E),Dt,(rt,Ve)=>{var qe=tke(),Q=C(qe),pe=R(Q,2),Ye=C(pe);ye(()=>{ll(Q,`background: ${v(Ve).color??""}`),me(Ye,v(Ve).name)}),I(rt,qe)});var yt=R(lt,2);{var pt=rt=>{var Ve=nke(),qe=C(Ve);ye(()=>me(qe,v(w)?"Show less":`+${v(y).length-x} more`)),Oe("click",Ve,Q=>{Q.stopPropagation(),D(w,!v(w))}),I(rt,Ve)};he(yt,rt=>{v(y).length>x&&rt(pt)})}I(ze,Xe)};he(De,ze=>{v(y).length>0&&ze(ct)})}is(z,ze=>D(p,ze),()=>v(p)),Oe("click",Ne,O),Oe("click",H,P),Oe("click",ee,()=>j()),I(G,z)};he(L,G=>{v(m)&&G(X)})}ye(()=>{Fe=tn(Te,1,"plot-container bar-plot svelte-1swghqy",null,Fe,{"hidden-plot":v(m)}),St(Te,"draggable",l()?"true":void 0)}),fn("dragstart",Te,function(...G){var z;(z=l()?J:void 0)==null||z.apply(this,G)}),fn("dragover",Te,function(...G){var z;(z=l()?c():void 0)==null||z.apply(this,G)}),fn("drop",Te,function(...G){var z;(z=l()?f():void 0)==null||z.apply(this,G)}),Oe("click",ut,O),Oe("click",wt,P),Oe("click",xe,W),I(e,ve),An()}si(["click"]);var oke=q('
      '),ake=q('
      '),lke=q('
      ');function LA(e,t){En(t,!0);let n=ae(t,"label",3,""),r=ae(t,"open",15,!0),i=ae(t,"hidden",3,!1);function s(){r(!r())}var o=Ni(),a=Bt(o);{var l=c=>{var f=oke(),d=C(f);{var h=p=>{var g=Ni(),m=Bt(g);s5(m,()=>t.children),I(p,g)};he(d,p=>{t.children&&p(h)})}I(c,f)},u=c=>{var f=lke(),d=C(f),h=C(d);let p;var g=R(h,2),m=C(g),y=R(d,2);{var b=x=>{var _=ake(),w=C(_);{var A=E=>{var k=Ni(),S=Bt(k);s5(S,()=>t.children),I(E,k)};he(w,E=>{t.children&&E(A)})}I(x,_)};he(y,x=>{r()&&x(b)})}ye(()=>{p=tn(h,1,"arrow svelte-1jep0a",null,p,{rotated:r()}),me(m,n())}),Oe("click",d,s),I(c,f)};he(a,c=>{i()?c(l):c(u,-1)})}I(e,o),An()}si(["click"]);oH();const Tq="trackio_theme_preference";let M1=[];function uke(e){return M1.push(e),()=>{M1=M1.filter(t=>t!==e)}}function cke(){const e=OF();M1.forEach(t=>t(e))}const uT={"--neutral-50":"#fafafa","--neutral-100":"#f4f4f5","--neutral-200":"#e4e4e7","--neutral-300":"#d4d4d8","--neutral-400":"#bbbbc2","--neutral-500":"#71717a","--neutral-600":"#52525b","--neutral-700":"#3f3f46","--neutral-800":"#27272a","--neutral-900":"#18181b","--neutral-950":"#0f0f11","--background-fill-primary":"#0f0f11","--background-fill-secondary":"#18181b","--body-text-color":"#f4f4f5","--body-text-color-subdued":"#bbbbc2","--border-color-primary":"#3f3f46","--color-accent":"#f97316","--color-accent-soft":"#3f3f46","--input-background-fill":"#27272a","--input-background-fill-focus":"#f97316","--input-border-color":"#3f3f46","--input-border-color-focus":"#3f3f46","--input-placeholder-color":"#71717a","--input-shadow":"none","--input-shadow-focus":"none","--checkbox-background-color":"#27272a","--checkbox-background-color-focus":"#27272a","--checkbox-background-color-hover":"#27272a","--checkbox-background-color-selected":"#f97316","--checkbox-border-color":"#3f3f46","--checkbox-border-color-focus":"#f97316","--checkbox-border-color-hover":"#52525b","--checkbox-border-color-selected":"#f97316","--table-even-background-fill":"#0f0f11","--table-odd-background-fill":"#18181b","--slider-color":"#f97316","--shadow-drop":"rgba(0,0,0,0.15) 0px 1px 2px 0px","--shadow-drop-lg":"0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.2)","--shadow-inset":"rgba(0,0,0,0.15) 0px 2px 4px 0px inset","--block-title-text-color":"#bbbbc2","--block-info-text-color":"#71717a","--primary-50":"#3f3f46"};function ug(e){const t=document.documentElement;e==="dark"?(t.dataset.theme="dark",Object.entries(uT).forEach(([n,r])=>{t.style.setProperty(n,r)})):(delete t.dataset.theme,Object.keys(uT).forEach(n=>{t.style.removeProperty(n)})),cke()}function OF(){return document.documentElement.dataset.theme==="dark"}function LF(){return window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"default"}function IF(){return localStorage.getItem(Tq)||"system"}function fke(e){localStorage.setItem(Tq,e),Rq(e),Nq(e==="system")}function Rq(e){ug(e==="system"?LF():e==="dark"?"dark":"default")}let Hm=!1;function cT(){IF()==="system"&&ug(LF())}function Nq(e){const t=window.matchMedia("(prefers-color-scheme: dark)");e&&!Hm?(t.addEventListener("change",cT),Hm=!0):!e&&Hm&&(t.removeEventListener("change",cT),Hm=!1)}function dke(){const e=new URLSearchParams(window.location.search).get("__theme");if(e){ug(e);return}const t=IF();Rq(t),Nq(t==="system")}var hke=q('
      Loading
      ');function Bu(e,t){En(t,!1);const r=OF()||new URLSearchParams(window.location.search).get("__theme")==="dark"||LF()==="dark"?"/static/trackio/trackio_logo_dark.png":"/static/trackio/trackio_logo_light.png";oG();var i=hke(),s=C(i),o=C(s),a=C(o),l=R(o,2),u=C(l);ye(()=>{St(a,"src",r),St(u,"src",r)}),I(e,i),An()}const fT=["BOOLEAN","INT32","INT64","INT96","FLOAT","DOUBLE","BYTE_ARRAY","FIXED_LEN_BYTE_ARRAY"],uc=["PLAIN","GROUP_VAR_INT","PLAIN_DICTIONARY","RLE","BIT_PACKED","DELTA_BINARY_PACKED","DELTA_LENGTH_BYTE_ARRAY","DELTA_BYTE_ARRAY","RLE_DICTIONARY","BYTE_STREAM_SPLIT"],pke=["REQUIRED","OPTIONAL","REPEATED"],gke=["UTF8","MAP","MAP_KEY_VALUE","LIST","ENUM","DECIMAL","DATE","TIME_MILLIS","TIME_MICROS","TIMESTAMP_MILLIS","TIMESTAMP_MICROS","UINT_8","UINT_16","UINT_32","UINT_64","INT_8","INT_16","INT_32","INT_64","JSON","BSON","INTERVAL"],mke=["UNCOMPRESSED","SNAPPY","GZIP","LZO","BROTLI","LZ4","ZSTD","LZ4_RAW"],Oq=["DATA_PAGE","INDEX_PAGE","DICTIONARY_PAGE","DATA_PAGE_V2"],vke=["SPHERICAL","VINCENTY","THOMAS","ANDOYER","KARNEY"];function IA(e){const t=Gm(e);if(t.type===1)return{type:"Point",coordinates:PA(e,t)};if(t.type===2)return{type:"LineString",coordinates:BA(e,t)};if(t.type===3)return{type:"Polygon",coordinates:dT(e,t)};if(t.type===4){const n=[];for(let r=0;r1&&i<=7&&(o=t.getUint32(e.offset,n),e.offset+=4);let a=2;return s&&a++,s===3&&a++,{littleEndian:n,type:i,dim:a,count:o}}function PA(e,t){const n=[];for(let r=0;r{var d;return((d=f.element.logical_type)==null?void 0:d.type)==="VARIANT"}))&&o==="BYTE_ARRAY"&&a!=="UTF8"&&(l==null?void 0:l.type)!=="STRING")return e;if(a==="DECIMAL"){const d=10**-(n.scale||0),h=new Array(e.length);for(let p=0;pr.timestampFromNanoseconds(yke(f)));if(a==="DATE")return Array.from(e).map(f=>r.dateFromDays(f));if(a==="TIMESTAMP_MILLIS")return Array.from(e).map(f=>r.timestampFromMilliseconds(f));if(a==="TIMESTAMP_MICROS")return Array.from(e).map(f=>r.timestampFromMicroseconds(f));if(a==="JSON")return e.map(f=>JSON.parse(Lq.decode(f)));if(a==="BSON")throw new Error("parquet bson not supported");if(a==="INTERVAL")throw new Error("parquet interval not supported");if((l==null?void 0:l.type)==="GEOMETRY")return e.map(f=>r.geometryFromBytes(f));if((l==null?void 0:l.type)==="GEOGRAPHY")return e.map(f=>r.geographyFromBytes(f));if(a==="UTF8"||(l==null?void 0:l.type)==="STRING"||i&&o==="BYTE_ARRAY")return e.map(f=>r.stringFromBytes(f));if(a==="UINT_64"||(l==null?void 0:l.type)==="INTEGER"&&l.bitWidth===64&&!l.isSigned){if(e instanceof BigInt64Array)return new BigUint64Array(e.buffer,e.byteOffset,e.length);const f=u?new Array(e.length):new BigUint64Array(e.length);for(let d=0;d=2n**BigInt(n-1)&&(t-=2n**BigInt(n)),Number(t)}function yke(e){const t=(e>>64n)-2440588n,n=e&0xffffffffffffffffn;return t*86400000000000n+n}function Bq(e){if(!e)return;const t=e[1]<<8|e[0],n=t>>15?-1:1,r=t>>10&31,i=t&1023;return r===0?n*2**-14*(i/1024):r===31?i?NaN:n*(1/0):n*2**(r-15)*(1+i/1024)}function zq(e,t,n){const r=e[t],i=[];let s=1;if(r.num_children)for(;i.lengtho.element.name===i);if(!s)throw new Error(`parquet schema element not found: ${t}`);r.push(s),n=s}return r}function bke(e){const t=[];function n(r){if(r.children.length)for(const i of r.children)n(i);else t.push(r.path.join("."))}return n(e),t}function Uq(e){let t=0;for(const{element:n}of e)n.repetition_type==="REPEATED"&&t++;return t}function PF(e){let t=0;for(const{element:n}of e.slice(1))n.repetition_type!=="REQUIRED"&&t++;return t}function xke(e){if(!e||e.element.converted_type!=="LIST"||e.children.length>1)return!1;const t=e.children[0];return!(t.children.length>1||t.element.repetition_type!=="REPEATED")}function _ke(e){if(!e||e.element.converted_type!=="MAP"||e.children.length>1)return!1;const t=e.children[0];if(t.children.length!==2||t.element.repetition_type!=="REPEATED")return!1;const n=t.children.find(i=>i.element.name==="key");if((n==null?void 0:n.element.repetition_type)==="REPEATED")return!1;const r=t.children.find(i=>i.element.name==="value");return(r==null?void 0:r.element.repetition_type)!=="REPEATED"}function qq(e){if(e.length!==2)return!1;const[,t]=e;return!(t.element.repetition_type==="REPEATED"||t.children.length)}const wke=0,pT=1,gT=2,mT=3,Eke=4,Ake=5,kke=6,Ske=7,Cke=8,$ke=9,Fke=12;function B2(e){const t={};let n=0;for(;e.offset>4;n=s?n+s:Wq(e),t[`field_${n}`]=zA(e,i)}return t}function zA(e,t){switch(t){case pT:return!0;case gT:return!1;case mT:return e.view.getInt8(e.offset++);case Eke:case Ake:return Wq(e);case kke:return jA(e);case Ske:{const n=e.view.getFloat64(e.offset,!0);return e.offset+=8,n}case Cke:{const n=Tc(e),r=new Uint8Array(e.view.buffer,e.view.byteOffset+e.offset,n);return e.offset+=n,r}case $ke:{const n=e.view.getUint8(e.offset++),r=n&15;let i=n>>4;i===15&&(i=Tc(e));const s=r===pT||r===gT,o=new Array(i);for(let a=0;a>>1^-(t&1)}function jA(e){const t=Dke(e);return t>>1n^-(t&1n)}function Mke(e,t){var s,o,a,l,u;const n=new Map,r=(s=t==null?void 0:t.find(({key:c})=>c==="geo"))==null?void 0:s.value,i=(r&&((o=JSON.parse(r))==null?void 0:o.columns))??{};for(const[c,f]of Object.entries(i)){if(f.encoding!=="WKB")continue;const d=f.edges==="spherical"?"GEOGRAPHY":"GEOMETRY",h=((a=f.crs)==null?void 0:a.id)??((u=(l=f.crs)==null?void 0:l.ids)==null?void 0:u[0]),p=h?`${h.authority}:${h.code.toString()}`:void 0;n.set(c,{type:d,crs:p})}for(let c=1;c=0))throw new Error("parquet expected AsyncBuffer");const i=Math.max(0,e.byteLength-n),s=await e.slice(i,e.byteLength),o=new DataView(s);if(o.getUint32(s.byteLength-4,!0)!==827474256)throw new Error("parquet file invalid (footer != PAR1)");const a=o.getUint32(s.byteLength-8,!0);if(a>e.byteLength-8)throw new Error(`parquet metadata length ${a} exceeds available buffer ${e.byteLength-8}`);if(a+8>n){const l=e.byteLength-a-8,u=await e.slice(l,i),c=new ArrayBuffer(a+8),f=new Uint8Array(c);return f.set(new Uint8Array(u)),f.set(new Uint8Array(s),i-l),vT(c,{parsers:t,geoparquet:r})}else return vT(s,{parsers:t,geoparquet:r})}function vT(e,{parsers:t,geoparquet:n=!0}={}){var m;if(!(e instanceof ArrayBuffer))throw new Error("parquet expected ArrayBuffer");const r=new DataView(e);if(t={...P2,...t},r.byteLength<8)throw new Error("parquet file is too short");if(r.getUint32(r.byteLength-4,!0)!==827474256)throw new Error("parquet file invalid (footer != PAR1)");const i=r.byteLength-8,s=r.getUint32(i,!0);if(s>r.byteLength-8)throw new Error(`parquet metadata length ${s} exceeds available buffer ${r.byteLength-8}`);const o=i-s,l=B2({view:r,offset:o}),u=l.field_1,c=l.field_2.map(y=>({type:fT[y.field_1],type_length:y.field_2,repetition_type:pke[y.field_3],name:Bo(y.field_4),num_children:y.field_5,converted_type:gke[y.field_6],scale:y.field_7,precision:y.field_8,field_id:y.field_9,logical_type:Oke(y.field_10)})),f=c.filter(y=>y.type),d=l.field_3,h=l.field_4.map(y=>{var b;return{columns:y.field_1.map((x,_)=>{var w,A,E;return{file_path:Bo(x.field_1),file_offset:x.field_2,meta_data:x.field_3&&{type:fT[x.field_3.field_1],encodings:(w=x.field_3.field_2)==null?void 0:w.map(k=>uc[k]),path_in_schema:x.field_3.field_3.map(Bo),codec:mke[x.field_3.field_4],num_values:x.field_3.field_5,total_uncompressed_size:x.field_3.field_6,total_compressed_size:x.field_3.field_7,key_value_metadata:(A=x.field_3.field_8)==null?void 0:A.map(k=>({key:Bo(k.field_1),value:Bo(k.field_2)})),data_page_offset:x.field_3.field_9,index_page_offset:x.field_3.field_10,dictionary_page_offset:x.field_3.field_11,statistics:Lke(x.field_3.field_12,f[_],t),encoding_stats:(E=x.field_3.field_13)==null?void 0:E.map(k=>({page_type:Oq[k.field_1],encoding:uc[k.field_2],count:k.field_3})),bloom_filter_offset:x.field_3.field_14,bloom_filter_length:x.field_3.field_15,size_statistics:x.field_3.field_16&&{unencoded_byte_array_data_bytes:x.field_3.field_16.field_1,repetition_level_histogram:x.field_3.field_16.field_2,definition_level_histogram:x.field_3.field_16.field_3},geospatial_statistics:x.field_3.field_17&&{bbox:x.field_3.field_17.field_1&&{xmin:x.field_3.field_17.field_1.field_1,xmax:x.field_3.field_17.field_1.field_2,ymin:x.field_3.field_17.field_1.field_3,ymax:x.field_3.field_17.field_1.field_4,zmin:x.field_3.field_17.field_1.field_5,zmax:x.field_3.field_17.field_1.field_6,mmin:x.field_3.field_17.field_1.field_7,mmax:x.field_3.field_17.field_1.field_8},geospatial_types:x.field_3.field_17.field_2}},offset_index_offset:x.field_4,offset_index_length:x.field_5,column_index_offset:x.field_6,column_index_length:x.field_7,crypto_metadata:x.field_8,encrypted_column_metadata:x.field_9}}),total_byte_size:y.field_2,num_rows:y.field_3,sorting_columns:(b=y.field_4)==null?void 0:b.map(x=>({column_idx:x.field_1,descending:x.field_2,nulls_first:x.field_3})),file_offset:y.field_5,total_compressed_size:y.field_6,ordinal:y.field_7}}),p=(m=l.field_5)==null?void 0:m.map(y=>({key:Bo(y.field_1),value:Bo(y.field_2)})),g=Bo(l.field_6);return n&&Mke(c,p),{version:u,schema:c,num_rows:d,row_groups:h,key_value_metadata:p,created_by:g,metadata_length:s}}function UA({schema:e}){return jq(e,[])[0]}function Oke(e){return e!=null&&e.field_1?{type:"STRING"}:e!=null&&e.field_2?{type:"MAP"}:e!=null&&e.field_3?{type:"LIST"}:e!=null&&e.field_4?{type:"ENUM"}:e!=null&&e.field_5?{type:"DECIMAL",scale:e.field_5.field_1,precision:e.field_5.field_2}:e!=null&&e.field_6?{type:"DATE"}:e!=null&&e.field_7?{type:"TIME",isAdjustedToUTC:e.field_7.field_1,unit:yT(e.field_7.field_2)}:e!=null&&e.field_8?{type:"TIMESTAMP",isAdjustedToUTC:e.field_8.field_1,unit:yT(e.field_8.field_2)}:e!=null&&e.field_10?{type:"INTEGER",bitWidth:e.field_10.field_1,isSigned:e.field_10.field_2}:e!=null&&e.field_11?{type:"NULL"}:e!=null&&e.field_12?{type:"JSON"}:e!=null&&e.field_13?{type:"BSON"}:e!=null&&e.field_14?{type:"UUID"}:e!=null&&e.field_15?{type:"FLOAT16"}:e!=null&&e.field_16?{type:"VARIANT",specification_version:e.field_16.field_1}:e!=null&&e.field_17?{type:"GEOMETRY",crs:Bo(e.field_17.field_1)}:e!=null&&e.field_18?{type:"GEOGRAPHY",crs:Bo(e.field_18.field_1),algorithm:vke[e.field_18.field_2]}:e}function yT(e){if(e.field_1)return"MILLIS";if(e.field_2)return"MICROS";if(e.field_3)return"NANOS";throw new Error("parquet time unit required")}function Lke(e,t,n){return e&&{max:Ym(e.field_1,t,n),min:Ym(e.field_2,t,n),null_count:e.field_3,distinct_count:e.field_4,max_value:Ym(e.field_5,t,n),min_value:Ym(e.field_6,t,n),is_max_value_exact:e.field_7,is_min_value_exact:e.field_8}}function Ym(e,t,n){const{type:r,converted_type:i,logical_type:s}=t;if(e===void 0)return e;if(r==="BOOLEAN")return e[0]===1;if(r==="BYTE_ARRAY")return n.stringFromBytes(e);const o=new DataView(e.buffer,e.byteOffset,e.byteLength);return r==="FLOAT"&&o.byteLength===4?o.getFloat32(0,!0):r==="DOUBLE"&&o.byteLength===8?o.getFloat64(0,!0):r==="INT32"&&i==="DATE"?n.dateFromDays(o.getInt32(0,!0)):r==="INT64"&&i==="TIMESTAMP_MILLIS"?n.timestampFromMilliseconds(o.getBigInt64(0,!0)):r==="INT64"&&i==="TIMESTAMP_MICROS"?n.timestampFromMicroseconds(o.getBigInt64(0,!0)):r==="INT64"&&(s==null?void 0:s.type)==="TIMESTAMP"&&(s==null?void 0:s.unit)==="NANOS"?n.timestampFromNanoseconds(o.getBigInt64(0,!0)):r==="INT64"&&(s==null?void 0:s.type)==="TIMESTAMP"&&(s==null?void 0:s.unit)==="MICROS"?n.timestampFromMicroseconds(o.getBigInt64(0,!0)):r==="INT64"&&(s==null?void 0:s.type)==="TIMESTAMP"?n.timestampFromMilliseconds(o.getBigInt64(0,!0)):r==="INT32"&&o.byteLength===4?o.getInt32(0,!0):r==="INT64"&&o.byteLength===8?o.getBigInt64(0,!0):i==="DECIMAL"?Pq(e)*10**-(t.scale||0):(s==null?void 0:s.type)==="FLOAT16"?Bq(e):e}function Ike(e){const t=B2(e);return{page_locations:t.field_1.map(Pke),unencoded_byte_array_data_bytes:t.field_2}}function Pke(e){return{offset:e.field_1,compressed_page_size:e.field_2,first_row_index:e.field_3}}function Hq(e,t){for(let r=0;rn.split(".")[0])),[...new Set(t)]}function qp(e,t,n=!0){return"$and"in t&&Array.isArray(t.$and)?t.$and.every(r=>qp(e,r,n)):"$or"in t&&Array.isArray(t.$or)?t.$or.some(r=>qp(e,r,n)):"$nor"in t&&Array.isArray(t.$nor)?!t.$nor.some(r=>qp(e,r,n)):Object.entries(t).every(([r,i])=>{const s=Bke(e,r);return typeof i!="object"||i===null||Array.isArray(i)?al(s,i,n):Object.entries(i||{}).every(([o,a])=>o==="$gt"?s>a:o==="$gte"?s>=a:o==="$lt"?sqA({rowGroup:e,physicalColumns:t,filter:s,strict:r}));if("$or"in n&&Array.isArray(n.$or))return n.$or.every(s=>qA({rowGroup:e,physicalColumns:t,filter:s,strict:r}));if("$nor"in n&&Array.isArray(n.$nor))return!1;for(const[s,o]of Object.entries(n)){const a=t.indexOf(s);if(a===-1)continue;const l=(i=e.columns[a].meta_data)==null?void 0:i.statistics;if(!l)continue;const{min:u,max:c,min_value:f,max_value:d}=l,h=f!==void 0?f:u,p=d!==void 0?d:c;if(!(h===void 0||p===void 0)){for(const[g,m]of Object.entries(o||{}))if(g==="$gt"&&p<=m||g==="$gte"&&p=m||g==="$lte"&&h>m||g==="$eq"&&(mp)||g==="$ne"&&al(h,p,r)&&al(h,m,r)||g==="$in"&&Array.isArray(m)&&m.every(y=>yp)||g==="$nin"&&Array.isArray(m)&&al(h,p,r)&&m.includes(h))return!0}}return!1}function Bke(e,t){let n=e;for(const r of t.split("."))n=n==null?void 0:n[r];return n}const zke=1<<21;function jke({metadata:e,rowStart:t=0,rowEnd:n=1/0,columns:r,filter:i,filterStrict:s=!0,useOffsetIndex:o=!1}){if(!e)throw new Error("parquetPlan requires metadata");const a=[],l=[],u=[],c=bke(UA(e));let f=0;for(const d of e.row_groups){const h=Number(d.num_rows),p=f+h;if(h>0&&p>t&&fe.slice(r,i));return{byteLength:e.byteLength,slice(r,i=e.byteLength){const s=t.findIndex(({startByte:o,endByte:a})=>o<=r&&i<=a);if(s<0)return e.slice(r,i);if(t[s].startByte!==r||t[s].endByte!==i){const o=r-t[s].startByte,a=i-t[s].startByte;return n[s]instanceof Promise?n[s].then(l=>l.slice(o,a)):n[s].slice(o,a)}else return n[s]}}}const BF=new TextDecoder,bT=new WeakMap;function Yq(e,t=P2){if(Array.isArray(e))return e.map(n=>Yq(n,t));if(typeof e!="object")return e;if("metadata"in e){const n=qke(e.metadata),r=e.typed_value&&R1(e.typed_value,n,t),i=e.value&&Hg(xy(e.value),n,t);return r&&i?{...i,...r}:r??i}return e}function R1(e,t,n){if(e&&typeof e=="object"&&!Array.isArray(e)&&!(e instanceof Uint8Array)){if("typed_value"in e)return R1(e.typed_value,t,n);if("value"in e&&e.value instanceof Uint8Array)return Hg(xy(e.value),t,n);const r={};for(const[i,s]of Object.entries(e))r[i]=R1(s,t,n);return r}return e instanceof Uint8Array?Hg(xy(e),t,n):Array.isArray(e)?e.map(r=>R1(r,t,n)):e}function xy(e){return{view:new DataView(e.buffer,e.byteOffset,e.byteLength),offset:0}}function qke(e){let t=bT.get(e.buffer);t||(t=new Map,bT.set(e.buffer,t));const n=`${e.byteOffset}:${e.byteLength}`,r=t.get(n);if(r)return r;const i=xy(e),s=i.view.getUint8(i.offset++),o=s&15;if(o!==1)throw new Error(`parquet unsupported variant metadata version: ${o}`);const a=(s>>4&1)===1,l=(s>>6&3)+1,u=Rc(i,l),c=new Array(u+1);for(let p=0;p>2;if(i===0)return Wke(e,s,n);if(i===2)return Hke(e,s,t,n);if(i===3)return Gke(e,s,t,n);const o=new Uint8Array(e.view.buffer,e.view.byteOffset+e.offset,s);return e.offset+=s,BF.decode(o)}function Wke(e,t,n){switch(t){case 0:return null;case 1:return!0;case 2:return!1;case 3:{const r=e.view.getInt8(e.offset);return e.offset+=1,r}case 4:{const r=e.view.getInt16(e.offset,!0);return e.offset+=2,r}case 5:{const r=e.view.getInt32(e.offset,!0);return e.offset+=4,r}case 6:{const r=e.view.getBigInt64(e.offset,!0);return e.offset+=8,r}case 7:{const r=e.view.getFloat64(e.offset,!0);return e.offset+=8,r}case 8:return X_(e,4);case 9:return X_(e,8);case 10:return X_(e,16);case 11:{const r=e.view.getInt32(e.offset,!0);return e.offset+=4,n.dateFromDays(r)}case 12:case 13:{const r=e.view.getBigInt64(e.offset,!0);return e.offset+=8,n.timestampFromMicroseconds(r)}case 14:{const r=e.view.getFloat32(e.offset,!0);return e.offset+=4,r}case 15:return xT(e);case 16:{const r=xT(e);return BF.decode(r)}case 17:{const r=e.view.getBigInt64(e.offset,!0);return e.offset+=8,r}case 18:case 19:{const r=e.view.getBigInt64(e.offset,!0);return e.offset+=8,n.timestampFromNanoseconds(r)}case 20:{const r=new Uint8Array(e.view.buffer,e.view.byteOffset+e.offset,16);e.offset+=16;const i=Array.from(r,s=>s.toString(16).padStart(2,"0")).join("");return`${i.slice(0,8)}-${i.slice(8,12)}-${i.slice(12,16)}-${i.slice(16,20)}-${i.slice(20)}`}default:throw new Error(`parquet unsupported variant primitive type: ${t}`)}}function Hke(e,t,n,r){const i=(t&3)+1,s=(t>>2&3)+1,a=t>>4&1?Rc(e,4):e.view.getUint8(e.offset++),l=new Array(a);for(let f=0;f>2&1,o=i+1,a=Rc(e,s?4:1),l=new Array(a+1);for(let f=0;fp.repetition_type);let l=0;const u=[e];let c=e,f=0,d=0,h=0;if(n[0])for(;f>h&g;for(h+=d;h>=8;)h-=8n,e.offset++,h&&(m|=BigInt(e.view.getUint8(e.offset))<>>1;Vke(e,a,t,n,s),s+=a}}e.offset=i+r}function Vke(e,t,n,r,i){const s=n+7>>3;let o=0;for(let a=0;a>1<<3;const o=(1<8?(u-=8,l-=8,a>>>=8):l-u>u&o),s--,u+=n);return i}function Zq(e,t,n,r){const i=Kke(n,r),s=new Uint8Array(t*i);for(let o=0;o=n)throw new Error("invalid snappy length header");for(;i=n)throw new Error("missing eof marker");if((o&3)===0){let l=(o>>>2)+1;if(l>60){if(i+3>=n)throw new Error("snappy error literal pos + 3 >= inputLength");const u=l-60;l=e[i]+(e[i+1]<<8)+(e[i+2]<<16)+(e[i+3]<<24),l=(l&sSe[u])+1,i+=u}if(i+l>n)throw new Error("snappy error literal exceeds input length");wT(e,i,t,s,l),i+=l,s+=l}else{let l=0;switch(o&3){case 1:a=(o>>>2&7)+4,l=e[i]+(o>>>5<<8),i++;break;case 2:if(n<=i+1)throw new Error("snappy error end of input");a=(o>>>2)+1,l=e[i]+(e[i+1]<<8),i+=2;break;case 3:if(n<=i+3)throw new Error("snappy error end of input");a=(o>>>2)+1,l=e[i]+(e[i+1]<<8)+(e[i+2]<<16)+(e[i+3]<<24),i+=4;break}if(l===0||isNaN(l))throw new Error(`invalid offset ${l} pos ${i} inputLength ${n}`);if(l>s)throw new Error("cannot copy from before start of buffer");wT(t,s-l,t,s,a),s+=a}}if(s!==r)throw new Error("premature end of input")}function aSe(e,t,{type:n,element:r,schemaPath:i}){const s=new DataView(e.buffer,e.byteOffset,e.byteLength),o={view:s,offset:0};let a;const l=lSe(o,t,i),{definitionLevels:u,numNulls:c}=uSe(o,t,i),f=t.num_values-c;if(t.encoding==="PLAIN")a=zF(o,n,f,r.type_length);else if(t.encoding==="PLAIN_DICTIONARY"||t.encoding==="RLE_DICTIONARY"||t.encoding==="RLE"){const d=n==="BOOLEAN"?1:s.getUint8(o.offset++);d?(a=new Array(f),n==="BOOLEAN"?(bu(o,d,a),a=a.map(h=>!!h)):bu(o,d,a,s.byteLength-o.offset)):a=new Uint8Array(f)}else if(t.encoding==="BYTE_STREAM_SPLIT")a=Zq(o,f,n,r.type_length);else if(t.encoding==="DELTA_BINARY_PACKED")a=n==="INT32"?new Int32Array(f):new BigInt64Array(f),Gg(o,f,a);else if(t.encoding==="DELTA_LENGTH_BYTE_ARRAY")a=new Array(f),Kq(o,f,a);else throw new Error(`parquet unsupported encoding: ${t.encoding}`);return{definitionLevels:u,repetitionLevels:l,dataPage:a}}function lSe(e,t,n){if(n.length>1){const r=Uq(n);if(r){const i=new Array(t.num_values);return bu(e,z2(r),i),i}}return[]}function uSe(e,t,n){const r=PF(n);if(!r)return{definitionLevels:[],numNulls:0};const i=new Array(t.num_values);bu(e,z2(r),i);let s=t.num_values;for(const o of i)o===r&&s--;return s===0&&(i.length=0),{definitionLevels:i,numNulls:s}}function WA(e,t,n,r){let i;const s=r==null?void 0:r[n];if(n==="UNCOMPRESSED")i=e;else if(s)i=s(e,t);else if(n==="SNAPPY")i=new Uint8Array(t),oSe(e,i);else throw new Error(`parquet unsupported compression codec: ${n}`);if((i==null?void 0:i.length)!==t)throw new Error(`parquet decompressed page length ${i==null?void 0:i.length} does not match header ${t}`);return i}function cSe(e,t,n){const i={view:new DataView(e.buffer,e.byteOffset,e.byteLength),offset:0},{type:s,element:o,schemaPath:a,codec:l,compressors:u}=n,c=t.data_page_header_v2;if(!c)throw new Error("parquet data page header v2 is undefined");const f=fSe(i,c,a);i.offset=c.repetition_levels_byte_length;const d=dSe(i,c,a),h=t.uncompressed_page_size-c.definition_levels_byte_length-c.repetition_levels_byte_length;let p=e.subarray(i.offset);c.is_compressed!==!1&&(p=WA(p,h,l,u));const g=new DataView(p.buffer,p.byteOffset,p.byteLength),m={view:g,offset:0};let y;const b=c.num_values-c.num_nulls;if(c.encoding==="PLAIN")y=zF(m,s,b,o.type_length);else if(c.encoding==="RLE")y=new Array(b),bu(m,1,y),y=y.map(x=>!!x);else if(c.encoding==="PLAIN_DICTIONARY"||c.encoding==="RLE_DICTIONARY"){const x=g.getUint8(m.offset++);y=new Array(b),bu(m,x,y,h-1)}else if(c.encoding==="DELTA_BINARY_PACKED")y=s==="INT32"?new Int32Array(b):new BigInt64Array(b),Gg(m,b,y);else if(c.encoding==="DELTA_LENGTH_BYTE_ARRAY")y=new Array(b),Kq(m,b,y);else if(c.encoding==="DELTA_BYTE_ARRAY")y=new Array(b),Yke(m,b,y);else if(c.encoding==="BYTE_STREAM_SPLIT")y=Zq(m,b,s,o.type_length);else throw new Error(`parquet unsupported encoding: ${c.encoding}`);return{definitionLevels:d,repetitionLevels:f,dataPage:y}}function fSe(e,t,n){const r=Uq(n);if(!r)return[];const i=new Array(t.num_values);return bu(e,z2(r),i,t.repetition_levels_byte_length),i}function dSe(e,t,n){const r=PF(n);if(r){const i=new Array(t.num_values);return bu(e,z2(r),i,t.definition_levels_byte_length),i}}function ET(e,{groupStart:t,selectStart:n,selectEnd:r},i,s){const{pathInSchema:o,schemaPath:a}=i,l=qq(a),u=[];let c,f,d=0,h=0;const p=s&&(()=>{f&&s({pathInSchema:o,columnData:f,rowStart:t+d-f.length,rowEnd:t+d})});for(;(l?d=e.view.byteLength-1);){const g=hSe(e);if(g.type==="DICTIONARY_PAGE"){const{data:m}=AT(e,g,i,c,void 0,0);m&&(c=Iq(m,i))}else{const m=(f==null?void 0:f.length)||0,y=AT(e,g,i,c,f,n-d);y.skipped?(u.length||(h+=y.skipped),d+=y.skipped):y.data&&f===y.data?d+=y.data.length-m:y.data&&y.data.length&&(p==null||p(),u.push(y.data),d+=y.data.length,f=y.data)}}return p==null||p(),{data:u,skipped:h}}function AT(e,t,n,r,i,s){const{type:o,element:a,schemaPath:l,codec:u,compressors:c}=n,f=new Uint8Array(e.view.buffer,e.view.byteOffset+e.offset,t.compressed_page_size);if(e.offset+=t.compressed_page_size,t.type==="DATA_PAGE"){const d=t.data_page_header;if(!d)throw new Error("parquet data page header is undefined");if(s>d.num_values&&qq(l))return{skipped:d.num_values};const h=WA(f,Number(t.uncompressed_page_size),u,c),{definitionLevels:p,repetitionLevels:g,dataPage:m}=aSe(h,d,n),y=hT(m,r,d.encoding,n),b=Array.isArray(i)?i:[];return{skipped:0,data:_T(b,p,g,y,l)}}else if(t.type==="DATA_PAGE_V2"){const d=t.data_page_header_v2;if(!d)throw new Error("parquet data page header v2 is undefined");if(s>d.num_rows)return{skipped:d.num_values};const{definitionLevels:h,repetitionLevels:p,dataPage:g}=cSe(f,t,n),m=hT(g,r,d.encoding,n),y=Array.isArray(i)?i:[];return{skipped:0,data:_T(y,h,p,m,l)}}else if(t.type==="DICTIONARY_PAGE"){const d=t.dictionary_page_header;if(!d)throw new Error("parquet dictionary page header is undefined");const h=WA(f,Number(t.uncompressed_page_size),u,c),p={view:new DataView(h.buffer,h.byteOffset,h.byteLength),offset:0};return{skipped:0,data:zF(p,o,d.num_values,a.type_length)}}else throw new Error(`parquet unsupported page type: ${t.type}`)}function hSe(e){const t=B2(e),n=Oq[t.field_1],r=t.field_2,i=t.field_3,s=t.field_4,o=t.field_5&&{num_values:t.field_5.field_1,encoding:uc[t.field_5.field_2],definition_level_encoding:uc[t.field_5.field_3],repetition_level_encoding:uc[t.field_5.field_4],statistics:t.field_5.field_5&&{max:t.field_5.field_5.field_1,min:t.field_5.field_5.field_2,null_count:t.field_5.field_5.field_3,distinct_count:t.field_5.field_5.field_4,max_value:t.field_5.field_5.field_5,min_value:t.field_5.field_5.field_6}},a=t.field_6,l=t.field_7&&{num_values:t.field_7.field_1,encoding:uc[t.field_7.field_2],is_sorted:t.field_7.field_3},u=t.field_8&&{num_values:t.field_8.field_1,num_nulls:t.field_8.field_2,num_rows:t.field_8.field_3,encoding:uc[t.field_8.field_4],definition_levels_byte_length:t.field_8.field_5,repetition_levels_byte_length:t.field_8.field_6,is_compressed:t.field_8.field_7===void 0?!0:t.field_8.field_7,statistics:t.field_8.field_8};return{type:n,uncompressed_page_size:r,compressed_page_size:i,crc:s,data_page_header:o,index_page_header:a,dictionary_page_header:l,data_page_header_v2:u}}function pSe(e,{metadata:t},n){const{file:r,compressors:i,utf8:s}=e,o=[],a={...P2,...e.parsers};for(const l of n.chunks){const{columnMetadata:u}=l,c=jq(t.schema,u.path_in_schema),f={pathInSchema:u.path_in_schema,type:u.type,element:c[c.length-1].element,schemaPath:c,codec:u.codec,parsers:a,compressors:i,utf8:s};if(!("offsetIndex"in l)){o.push({pathInSchema:u.path_in_schema,data:Promise.resolve(r.slice(l.range.startByte,l.range.endByte)).then(d=>{const h={view:new DataView(d),offset:0};return ET(h,n,f,e.onPage)})});continue}o.push({pathInSchema:u.path_in_schema,data:Promise.resolve(r.slice(l.offsetIndex.startByte,l.offsetIndex.endByte)).then(async d=>{const h=Ike({view:new DataView(d),offset:0}),{selectStart:p,selectEnd:g}=n,m=h.page_locations;let y=NaN,b=NaN,x=0;for(let S=0;Sp&&(Number.isNaN(y)&&(y=Number($.offset),x=M),b=Number($.offset)+$.compressed_page_size)}const _=await r.slice(y,b),w={view:new DataView(_),offset:0},A=x?{...n,groupStart:n.groupStart+x,selectStart:n.selectStart-x,selectEnd:n.selectEnd-x}:n,{data:E,skipped:k}=ET(w,A,f,e.onPage);return{data:E,skipped:x+k}})})}return{groupStart:n.groupStart,groupRows:n.groupRows,asyncColumns:o}}async function kT({asyncColumns:e},t,n,r,i){const s=await Promise.all(e.map(async({data:f})=>{const d=await f;return{...d,data:Gq(d.data)}})),o=e.map(f=>f.pathInSchema[0]).filter(f=>!r||r.includes(f)),a=r??o,l=a.map(f=>e.findIndex(d=>d.pathInSchema[0]===f)),u=n-t;if(i==="object"){const f=Array(u);for(let d=0;d=0){const{data:m,skipped:y}=s[g];h[p]=m[d-y]}}c[f]=h}return c}function gSe(e,t,n){const{asyncColumns:r}=e;n={...P2,...n};const i=[];for(const s of t.children)if(s.children.length){const o=r.filter(u=>u.pathInSchema[0]===s.element.name);if(!o.length)continue;const a=new Map,l=Promise.all(o.map(u=>u.data.then(({data:c})=>{a.set(u.pathInSchema.join("."),Gq(c))}))).then(()=>{Wp(a,s,n);const u=a.get(s.path.join("."));if(!u)throw new Error("parquet column data not assembled");return{data:[u],skipped:0}});i.push({pathInSchema:s.path,data:l})}else{const o=r.find(a=>a.pathInSchema[0]===s.element.name);o&&i.push(o)}return{...e,asyncColumns:i}}async function mSe(e){e.metadata??(e.metadata=await Nke(e.file,e));const{rowStart:t=0,rowEnd:n,columns:r,onChunk:i,onComplete:s,rowFormat:o,filter:a,filterStrict:l=!0}=e;if(a&&o!=="object")throw new Error('parquet filter requires rowFormat: "object"');const u=T1(a);if(u.length){const m=UA(e.metadata).children.map(b=>b.element.name),y=u.filter(b=>!m.includes(b));if(y.length)throw new Error(`parquet filter columns not found: ${y.join(", ")}`)}let c=r,f=!1;if(r&&a){const m=u.filter(y=>!r.includes(y));m.length&&(c=[...r,...m],f=!0)}const d=c!==r?{...e,columns:c}:e,h=vSe(d);if(!s&&!i){for(const{asyncColumns:m}of h)for(const{data:y}of m)await y;return}const p=UA(e.metadata),g=h.map(m=>gSe(m,p,e.parsers));if(i)for(const m of g)for(const y of m.asyncColumns)y.data.then(({data:b,skipped:x})=>{let _=m.groupStart+x;for(const w of b)i({columnName:y.pathInSchema[0],columnData:w,rowStart:_,rowEnd:_+w.length}),_+=w.length});if(s){const m=[];for(const y of g){const b=Math.max(t-y.groupStart,0),x=Math.min((n??1/0)-y.groupStart,y.groupRows),_=o==="object"?await kT(y,b,x,c,"object"):await kT(y,b,x,r,"array");if(a){for(const w of _)if(qp(w,a,l)){if(f&&r)for(const A of u)r.includes(A)||delete w[A];m.push(w)}}else Hq(m,_)}s(m)}else for(const{asyncColumns:m}of g)for(const{data:y}of m)await y}function vSe(e){if(!e.metadata)throw new Error("parquet requires metadata");const t=jke(e);return e.file=Uke(e.file,t),t.groups.map(n=>pSe(e,t,n))}const Vm=new Map;function ySe(e){const t={};for(const n in e){const r=e[n];t[n]=typeof r=="bigint"?Number(r):r}return t}async function U2(e,t={}){if(Vm.has(e))return Vm.get(e);const n=await fetch(e,{headers:t});if(!n.ok){if(n.status===404)return Vm.set(e,[]),[];throw new Error(`Failed to fetch ${e}: ${n.status}`)}const r=await n.arrayBuffer();let i=[];return await mSe({file:r,rowFormat:"object",onComplete:s=>{i=s.map(ySe)}}),Vm.set(e,i),i}let jn=null,Xm=null,Km=null,Zm=null,Jm=null,Wf=null,Hf=null,Lo=null;function Df(e){return jn.bucket_id?`https://huggingface.co/buckets/${jn.bucket_id}/resolve/${e}`:`https://huggingface.co/datasets/${jn.dataset_id}/resolve/main/${e}`}async function bSe(e){jn=e}function xSe(){return!jn||jn.mode!=="static"?null:jn.bucket_id?{url:`https://huggingface.co/buckets/${jn.bucket_id}`}:jn.dataset_id?{url:`https://huggingface.co/datasets/${jn.dataset_id}`}:null}async function jF(){return Xm||(Xm=await U2(Df("metrics.parquet")),Xm)}async function Jq(){return Km||(Km=await U2(Df("aux/system_metrics.parquet")),Km)}async function Qq(){return Zm||(Zm=await U2(Df("aux/configs.parquet")),Zm)}async function UF(){return Jm||(Jm=await U2(Df("aux/traces.parquet")),Jm)}async function qF(){if(Wf)return Wf;const e=await fetch(Df("runs.json"));return e.ok?(Wf=await e.json(),Wf):(Wf=[],Wf)}async function _Se(){if(Hf)return Hf;const e=await fetch(Df("settings.json"));return e.ok?(Hf=await e.json(),Hf):(Hf={},Hf)}const J0=new Set(["id","run_id","run_name","timestamp","step","log_id","space_id","created_at"]);function Q0(e){return!e||e.length===0?{rows:[],columns:[]}:{rows:e,columns:Object.keys(e[0])}}function WF(e){return e==null?{name:null,id:null}:typeof e=="string"?{name:e,id:null}:{name:e.name??null,id:e.id??null}}function em(e,t){const n=WF(t);return n.id!=null&&e.run_id!=null?e.run_id===n.id:n.name==null?!0:e.run_name===n.name}async function wSe(){return[jn.project]}async function ESe(){return(await qF()).map(t=>({id:t.id??t.run_id??t.name,name:t.name,created_at:t.created_at??null,last_step:t.last_step??null,log_count:t.log_count??0}))}async function ASe(e,t){const n=await jF(),{rows:r,columns:i}=Q0(n),s=i.filter(l=>!J0.has(l)),o=r.filter(l=>em(l,t)),a=new Set;for(const l of o)for(const u of s)l[u]!==null&&l[u]!==void 0&&a.add(u);return[...a]}function eW(e){return typeof e=="number"&&Number.isFinite(e)}async function tW(e,t,n={}){const r=await jF(),{rows:i}=Q0(r),s=i.filter(a=>em(a,t)),o=n.scalar_only===!0;return s.map(a=>{const l={};for(const[u,c]of Object.entries(a))if(!J0.has(u)&&c!=null){if(o){eW(c)&&(l[u]=c);continue}if(typeof c=="string"&&c.startsWith("{")&&c.includes("_type"))try{l[u]=JSON.parse(c)}catch{l[u]=c}else l[u]=c}return l.timestamp=a.timestamp,l.step=a.step,l})}function kSe(e){const t=[];function n(r){if(r!=null){if(Array.isArray(r)){r.forEach(n);return}if(typeof r=="object"){Object.values(r).forEach(n);return}t.push(String(r))}}return n(e.messages||[]),n(e.metadata||{}),t.join(" ").toLowerCase()}function SSe(e,t){switch(t){case"step_asc":return[...e].sort((n,r)=>(n.step??0)-(r.step??0));case"step_desc":return[...e].sort((n,r)=>(r.step??0)-(n.step??0));case"request_time_asc":return[...e].sort((n,r)=>String(n.timestamp||"").localeCompare(String(r.timestamp||"")));case"request_time_desc":default:return[...e].sort((n,r)=>String(r.timestamp||"").localeCompare(String(n.timestamp||"")))}}function ST(e,t){if(e==null)return t;if(typeof e=="string"){if(!e)return t;try{return JSON.parse(e)}catch{return t}}if(typeof e=="object"&&!ArrayBuffer.isView(e)&&!(e instanceof ArrayBuffer))return e;let n;try{const r=e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer||e);n=new TextDecoder("utf-8").decode(r)}catch{return t}if(!n)return t;try{return JSON.parse(n)}catch{return t}}async function CSe(e,t){const n=await UF(),r=new Map;for(const o of n){if(!em(o,t))continue;const a=o.step;r.set(a,(r.get(a)||0)+1)}const i=[...r.entries()].map(([o,a])=>({step:o,count:a})).sort((o,a)=>(o.step??0)-(a.step??0));return{total:i.reduce((o,a)=>o+a.count,0),steps:i}}async function $Se(e,t,n={}){const r=WF(t);let o=(await UF()).filter(a=>em(a,t)).map(a=>{const l={id:a.id,key:a.key,index:a.trace_index,run:a.run_name||r.name,run_id:a.run_id||r.id,step:a.step,timestamp:a.timestamp,messages:ST(a.messages,[]),metadata:ST(a.metadata,{})};return l._search_text=(a.search_text||`${l.id} ${l.key} ${kSe(l)}`).toLowerCase(),l});if(n.step!=null&&(o=o.filter(a=>a.step===n.step)),n.search&&n.search.trim()){const a=n.search.trim().toLowerCase();o=o.filter(l=>l._search_text.includes(a))}return o=SSe(o,n.sort||"request_time_desc"),n.offset&&(o=o.slice(n.offset)),n.limit!=null&&(o=o.slice(0,n.limit)),o.map(({_search_text:a,...l})=>l)}async function FSe(){const e=await qF(),t=e.map(n=>n.last_step||0);return{project:jn.project,num_runs:e.length,runs:e.map(n=>({id:n.id??n.run_id??n.name,name:n.name,created_at:n.created_at??null,last_step:n.last_step??null,log_count:n.log_count??0})),last_activity:t.length?Math.max(...t):null}}async function DSe(e,t){const n=await qF(),r=WF(t),i=n.find(c=>r.id!=null&&(c.id??c.run_id??c.name)!=null?(c.id??c.run_id??c.name)===r.id:c.name===r.name);if(!i)return{project:jn.project,run:r.name,run_id:r.id,num_logs:0,metrics:[],config:null,last_step:null};const s=await ASe(jn.project,t);let o=null;const a=await Qq(),{rows:l}=Q0(a),u=l.find(c=>r.id!=null&&c.run_id!=null?c.run_id===r.id:c.run_name===r.name);if(u){o={};for(const[c,f]of Object.entries(u))c!=="id"&&c!=="run_name"&&c!=="created_at"&&(o[c]=f)}return{project:jn.project,run:i.name,run_id:i.id??i.run_id??i.name,num_logs:i.log_count||0,metrics:s,config:o,last_step:i.last_step}}async function MSe(){return[]}async function nW(e,t){const n=await Jq(),{rows:r}=Q0(n);return r.filter(s=>em(s,t)).map(s=>{const o={};for(const[a,l]of Object.entries(s))J0.has(a)||l!=null&&(o[a]=l);return o.timestamp=s.timestamp,o})}async function TSe(){const e=await _Se();return{logo_urls:{light:"/static/trackio/trackio_logo_type_light_transparent.png",dark:"/static/trackio/trackio_logo_type_dark_transparent.png"},color_palette:e.color_palette||[],plot_order:e.plot_order||[],table_truncate_length:250}}let Qm=null;const RSe=new Set(["trackio.image","trackio.video","trackio.audio","trackio.table"]),NSe=new Set(["trackio.markdown"]);function OSe(e){for(const[t,n]of Object.entries(e))if(!J0.has(t)&&n!=null&&eW(n))return!0;return!1}function CT(e,t){for(const[n,r]of Object.entries(e)){if(J0.has(n)||r==null)continue;let i=r;if(typeof i=="string"&&i.startsWith("{")&&i.includes("_type"))try{i=JSON.parse(i)}catch{continue}if(i&&typeof i=="object"&&t.has(i._type))return!0}return!1}async function LSe(){if(Qm)return Qm;const[e,t,n,r]=await Promise.all([jF().catch(()=>[]),Jq().catch(()=>[]),UF().catch(()=>[]),rW().catch(()=>[])]),i=e||[];let s=!1,o=!1,a=!1;for(const l of i)if(!s&&OSe(l)&&(s=!0),!o&&CT(l,RSe)&&(o=!0),!a&&CT(l,NSe)&&(a=!0),s&&o&&a)break;return Qm={metrics:s,media:o,reports:a,system:(t||[]).length>0,traces:(n||[]).length>0,files:(r||[]).length>0},Qm}async function rW(){if(Lo)return Lo;if(jn.bucket_id){const r=await fetch(`https://huggingface.co/api/buckets/${jn.bucket_id}/tree?prefix=media/files/&recursive=true`);if(!r.ok)return Lo=[],Lo;const i=await r.json();return Lo=(Array.isArray(i)?i:[]).filter(s=>s.type==="file").map(s=>({name:s.path.split("/").at(-1)??s.path,path:s.path.slice(6)})),Lo}const e=await fetch(`https://huggingface.co/api/datasets/${jn.dataset_id}`);if(!e.ok)return Lo=[],Lo;const t=await e.json();return Lo=(Array.isArray(t==null?void 0:t.siblings)?t.siblings:[]).map(r=>r==null?void 0:r.rfilename).filter(r=>typeof r=="string"&&r.startsWith("media/files/")).map(r=>({name:r.split("/").at(-1)??r,path:r.slice(6)})),Lo}async function ISe(){const e=new Set(["id","run_id","run_name","created_at"]),t=await Qq().catch(()=>null);if(!t)return{};const{rows:n}=Q0(t),r={};for(const i of n){const s=i.run_name;if(!s)continue;const o={};for(const[a,l]of Object.entries(i))e.has(a)||l!=null&&(o[a]=l);r[i.run_id??s]=o}return r}async function PSe(){return{allowed:!1}}async function BSe(){throw new Error("Not supported in static mode")}async function zSe(){throw new Error("Not supported in static mode")}function jSe(e){return jn.project&&e.startsWith(jn.project+"/")?e.slice(jn.project.length+1):e}function iW(e){const t=jSe(e);return Df(`media/${t}`)}let HA=0;function sW(){return typeof window>"u"?!1:(window.location.hostname||"").toLowerCase().endsWith(".hf.space")}function USe(){const e=Date.now()+12e3;HA=Math.max(HA,e)}function HF(){return Date.now()(cg=e,e))),K_)}function HSe(){const e=sessionStorage.getItem("trackio_oauth_session");return e?{"x-trackio-oauth-session":e}:{}}async function _r(e,t={}){const n=e.startsWith("/")?e.slice(1):e,r=`${q2}/api/${n}`,i=await fetch(r,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...HSe()},body:JSON.stringify(t)});if(i.status===429&&USe(),!i.ok)throw new Error(`API call ${e} failed: ${i.status}`);const s=await i.json();if(s.error)throw new Error(s.error);return s.data}async function GSe(){return await Xn()?wSe():await _r("/get_all_projects")}async function YSe(e){return await Xn()?ESe():await _r("/get_runs_for_project",{project:e})}async function VSe(e){return await Xn()?ISe():await _r("/get_run_configs",{project:e})}function Us(e){return e==null?{run:null,run_id:null}:typeof e=="string"?{run:e,run_id:null}:{run:e.name??null,run_id:e.id??null}}async function lW(e,t,n={}){const r={project:e,...Us(t),...n};return await Xn()?tW(e,t,n):await _r("/get_logs",r)}async function XSe(e,t,n={}){if(await Xn()){const i=[];for(const s of t){const o=await tW(e,s,n);i.push({...Us(s),logs:o})}return i}const r={project:e,runs:t.map(i=>Us(i)),...n};return await _r("/get_logs_batch",r)}async function KSe(e,t,n={}){const r={project:e,...Us(t),...n};return await Xn()?$Se(e,t,n):await _r("/get_traces",r)}async function ZSe(e,t){const n={project:e,...Us(t)};return await Xn()?CSe(e,t):await _r("/get_trace_steps",n)}async function JSe(e){return await Xn()?FSe():await _r("/get_project_summary",{project:e})}async function uW(e,t){const n={project:e,...Us(t)};return await Xn()?DSe(e,t):await _r("/get_run_summary",n)}async function cW(e,t,n,r){const i={project:e,...Us(t),level:n,since:r};return await Xn()?MSe():await _r("/get_alerts",i)}async function QSe(e,t){const n={project:e,...Us(t)};return await Xn()?nW(e,t):await _r("/get_system_logs",n)}async function $T(e,t){if(await Xn()){const n=[];for(const r of t){const i=await nW(e,r);n.push({...Us(r),logs:i})}return n}return await _r("/get_system_logs_batch",{project:e,runs:t.map(n=>Us(n))})}async function e3e(){return await Xn()?TSe():await _r("/get_settings")}async function t3e(e){return await Xn()?rW():await _r("/get_project_files",{project:e})}async function n3e(e){return await Xn()?LSe():await _r("/get_tab_availability",{project:e})}async function r3e(){return await Xn()?PSe():await _r("/get_run_mutation_status",{})}async function i3e(e,t){const n={project:e,...Us(t)};return await Xn()?BSe():await _r("/delete_run",n)}async function s3e(e,t,n){const r=Us(t);return await Xn()?zSe():await _r("/rename_run",{project:e,old_name:r.run,run_id:r.run_id,new_name:n})}function o3e(e){aW=e?e+"/":""}function fW(e){return cg?iW(e):`${q2}/file?path=${encodeURIComponent(`${aW}${e}`)}`}function Z_(e){return cg?iW(e):`${q2}/file?path=${encodeURIComponent(e)}`}async function a3e(){return await Xn()?xSe():null}var l3e=q('

      No projects

      Create a project by calling trackio.init(project="…") in your training script.

      '),u3e=q('

      No run selected

      Select one or more runs in the sidebar.

      '),c3e=q('

      Start logging with Trackio

      You can create a new project by calling trackio.init():

      Then call trackio.log() to log metrics:

      Finally, call trackio.finish() to finish the run:

      '),f3e=q('
      '),d3e=q('
      '),h3e=q('
      ',1),p3e=q('
      ');function g3e(e,t){En(t,!0);let n=ae(t,"project",3,null),r=ae(t,"selectedRuns",19,()=>[]),i=ae(t,"allRuns",19,()=>[]),s=ae(t,"smoothing",3,10),o=ae(t,"xAxis",3,"step"),a=ae(t,"logScaleX",3,!1),l=ae(t,"logScaleY",3,!1),u=ae(t,"metricFilter",3,""),c=ae(t,"showHeaders",3,!0),f=ae(t,"appBootstrapReady",3,!1),d=ae(t,"plotOrder",19,()=>[]),h=ae(t,"realtimeEnabled",3,!0),p=ae(t,"metricColumns",31,()=>xt([])),g=re(xt([])),m=re("step"),y=re(xt([])),b=re(xt(new Set)),x=re(null),_=re(!1),w=re(xt({})),A=re(xt({group:null,index:-1})),E=new Map,k=null;const S=64;let $=we(()=>n0(i())),M=we(()=>{let fe=u()?Cy(v(y),u()):v(y);return DR(fe,d())}),O=we(()=>Object.keys(v(M)));function P(fe){return vw(v(g),v(m),fe,v(x))}function T(fe,V){const B=v(w)[fe];if(!B)return V;const L=[];for(const X of B)V.includes(X)&&L.push(X);for(const X of V)L.includes(X)||L.push(X);return L}function F(fe,V,B){D(A,{group:fe,index:V},!0),B.dataTransfer.effectAllowed="move",B.dataTransfer.setData("text/plain","")}function N(fe,V,B){v(A).group===fe&&(B.preventDefault(),B.dataTransfer.dropEffect="move")}function U(fe,V,B,L){if(L.preventDefault(),v(A).group!==fe||v(A).index===V){D(A,{group:null,index:-1},!0);return}const X=[...B],[G]=X.splice(v(A).index,1);X.splice(V,0,G),D(w,{...v(w),[fe]:X},!0),D(A,{group:null,index:-1},!0)}function j(){if(!n()||r().length===0){D(g,[],!0),D(y,[],!0);return}const fe=[];for(const z of r()){const te=E.get(z.id??z.name);if(!te)continue;const Ne=FG(te,z,s(),o(),a(),l());Ne&&(fe.push(...Ne.rows),D(m,Ne.xColumn,!0))}D(g,fe,!0);const V=fe.filter(z=>z.data_type==="original"||!z.data_type),B=MG(V).filter(z=>z!=="run"&&z!=="data_type"&&z!=="x_axis"),L=B.filter(z=>z!==v(m));D(y,L,!0),p(B);const X=new Map;for(const z of V){const te=z.series_key;for(const Ne of L){if(z[Ne]==null)continue;const H=`${Ne}\0${te}`;X.set(H,(X.get(H)||0)+1)}}const G=new Set(L);for(const[z,te]of X)te>1&&G.delete(z.split("\0")[0]);D(b,G,!0)}async function W(fe){const V=[];for(let B=0;B{const L=B.id??B.name;return!E.has(L)});let V=!1;if(fe.length>0)try{const B=await W(fe);for(const L of B){const X=L.run_id??L.run;E.set(X,L.logs),V=!0}}catch(B){console.error("Failed to load metric logs:",B)}(V||!v(_))&&j(),D(_,!0)}async function Y(){if(h()&&!(!n()||r().length===0)&&!GF()&&!HF())try{const fe=await W(r());let V=!1;for(const B of fe){const L=B.run_id??B.run,X=B.logs,G=E.get(L);(!G||TR(G,X))&&(E.set(L,X),V=!0)}V&&j()}catch(fe){console.error("Failed to refresh metric logs:",fe)}}zt(()=>{n(),r(),f(),E=n()?E:new Map,Z()}),zt(()=>{s(),o(),a(),l(),v(_)&&j()}),hh(()=>{const fe=Hr("xmin"),V=Hr("xmax");if(fe!=null&&fe!==""&&V!=null&&V!==""){const B=parseFloat(fe),L=parseFloat(V);!Number.isNaN(B)&&!Number.isNaN(L)&&B{k&&clearInterval(k)}});function J(fe){fe&&fe.length===2&&D(x,fe,!0)}function ve(){D(x,null)}var Te=p3e(),Fe=C(Te);{var He=fe=>{Bu(fe,{})},ut=fe=>{var V=l3e();I(fe,V)},wt=fe=>{var V=u3e();I(fe,V)},xe=fe=>{var V=c3e(),B=R(C(V),4),L=C(B);L.textContent=`import trackio +trackio.init(project="my-project")`;var X=R(B,4),G=C(X);G.textContent=`for i in range(10): + trackio.log({"loss": 1/(i+1)})`;var z=R(X,4),te=C(z);te.textContent="trackio.finish()",I(fe,V)},je=fe=>{var V=Ni(),B=Bt(V);$t(B,17,()=>v(O),Dt,(L,X)=>{const G=we(()=>v(M)[v(X)]),z=we(()=>`${v(X)}:direct`),te=we(()=>T(v(z),v(G).direct)),Ne=we(()=>v(G).direct.length),H=we(()=>Object.values(v(G).subgroups).reduce((ne,be)=>ne+be.length,0)),ee=we(()=>v(Ne)+v(H));{let ne=we(()=>!c());LA(L,{get label(){return`${v(X)??""} (${v(ee)??""})`},open:!0,get hidden(){return v(ne)},children:(be,K)=>{var ge=h3e(),_e=Bt(ge);{var De=ze=>{var Xe=f3e();$t(Xe,21,()=>v(te),Dt,(lt,yt,pt)=>{const rt=we(()=>P(v(yt))),Ve=we(()=>v(rt).data),qe=we(()=>v(rt).yExtent),Q=we(()=>v(b).has(v(yt))),pe=we(()=>c()&&v(yt).split("/").slice(1).join("/")||v(yt));var Ye=Ni(),gt=Bt(Ye);{var Ke=Ze=>{var We=Ni(),it=Bt(We);{var bt=Ge=>{lT(Ge,{get data(){return v(Ve)},get y(){return v(yt)},get title(){return v(pe)},colorField:"series_key",colorDisplayField:"run",get colorMap(){return v($)},draggable:!0,ondragstart:dt=>F(v(z),pt,dt),ondragover:dt=>N(v(z),pt,dt),ondrop:dt=>U(v(z),pt,v(te),dt)})},Et=Ge=>{by(Ge,{get data(){return v(Ve)},get x(){return v(m)},get y(){return v(yt)},get title(){return v(pe)},colorField:"series_key",colorDisplayField:"run",get colorMap(){return v($)},get xLim(){return v(x)},get yExtent(){return v(qe)},onSelect:J,onResetZoom:ve,draggable:!0,ondragstart:dt=>F(v(z),pt,dt),ondragover:dt=>N(v(z),pt,dt),ondrop:dt=>U(v(z),pt,v(te),dt)})};he(it,Ge=>{v(Q)?Ge(bt):Ge(Et,-1)})}I(Ze,We)};he(gt,Ze=>{v(Ve).length>0&&Ze(Ke)})}I(lt,Ye)}),I(ze,Xe)};he(_e,ze=>{v(te).length>0&&ze(De)})}var ct=R(_e,2);$t(ct,21,()=>Object.entries(v(G).subgroups),Dt,(ze,Xe)=>{var lt=we(()=>XA(v(Xe),2));let yt=()=>v(lt)[0],pt=()=>v(lt)[1];const rt=we(()=>`${v(X)}:${yt()}`),Ve=we(()=>T(v(rt),pt()));{let qe=we(()=>!c());LA(ze,{get label(){return`${yt()??""} (${pt().length??""})`},open:!0,get hidden(){return v(qe)},children:(Q,pe)=>{var Ye=d3e();$t(Ye,21,()=>v(Ve),Dt,(gt,Ke,Ze)=>{const We=we(()=>P(v(Ke))),it=we(()=>v(We).data),bt=we(()=>v(We).yExtent),Et=we(()=>v(b).has(v(Ke))),Ge=we(()=>c()&&v(Ke).split("/").slice(2).join("/")||v(Ke));var dt=Ni(),mt=Bt(dt);{var se=ke=>{var At=Ni(),Ft=Bt(At);{var Pe=Qe=>{lT(Qe,{get data(){return v(it)},get y(){return v(Ke)},get title(){return v(Ge)},colorField:"series_key",colorDisplayField:"run",get colorMap(){return v($)},draggable:!0,ondragstart:vt=>F(v(rt),Ze,vt),ondragover:vt=>N(v(rt),Ze,vt),ondrop:vt=>U(v(rt),Ze,v(Ve),vt)})},Je=Qe=>{by(Qe,{get data(){return v(it)},get x(){return v(m)},get y(){return v(Ke)},get title(){return v(Ge)},colorField:"series_key",colorDisplayField:"run",get colorMap(){return v($)},get xLim(){return v(x)},get yExtent(){return v(bt)},onSelect:J,onResetZoom:ve,draggable:!0,ondragstart:vt=>F(v(rt),Ze,vt),ondragover:vt=>N(v(rt),Ze,vt),ondrop:vt=>U(v(rt),Ze,v(Ve),vt)})};he(Ft,Qe=>{v(Et)?Qe(Pe):Qe(Je,-1)})}I(ke,At)};he(mt,ke=>{v(it).length>0&&ke(se)})}I(gt,dt)}),I(Q,Ye)},$$slots:{default:!0}})}}),I(be,ge)},$$slots:{default:!0}})}}),I(fe,V)};he(Fe,fe=>{!f()||!v(_)?fe(He):n()?r().length===0?fe(wt,2):v(g).length===0?fe(xe,3):fe(je,-1):fe(ut,1)})}I(e,Te),An()}var m3e=q('

      Select a project

      Pick a project to browse trace logs.

      '),v3e=q('

      No runs selected

      Select one or more runs in the sidebar to browse traces.

      '),y3e=q(""),b3e=q('

      No traces match the current filters

      Try a different search query, step, or run selection.

      '),x3e=q(" "),_3e=q('tool calls'),w3e=q('function call'),E3e=q('
      Expand content
       
      '),A3e=q('
       
      '),k3e=q(''),S3e=q('
       
      '),C3e=q('
      '),$3e=q('
       
      '),F3e=q('
      '),D3e=q('
       
      '),M3e=q('
      '),T3e=q('
      '),R3e=q('
      ',1),N3e=q('
      Trace IDRequestRunStepRequest time
      ',1),O3e=q('
      ',1),L3e=q('
      ');function I3e(e,t){En(t,!0);let n=ae(t,"project",3,null),r=ae(t,"selectedRuns",19,()=>[]);const i=50;let s=re(!1),o=re(""),a=re("request_time_desc"),l=re("all"),u=re(0),c=re(null),f=re(xt([])),d=re(xt([])),h=re(0),p=0,g=0;function m(B){return B.map(L=>`${L.id||""}:${L.name||""}`).join("|")}function y(B){return typeof B=="string"?B:Array.isArray(B)?B.map(L=>typeof L=="string"?L:typeof(L==null?void 0:L.text)=="string"?L.text:typeof(L==null?void 0:L.content)=="string"?L.content:(L==null?void 0:L._type)==="trackio.image"||(L==null?void 0:L.type)==="image"?"[image]":"").filter(Boolean).join(" "):typeof(B==null?void 0:B.text)=="string"?B.text:""}function b(B,L){const X=Array.isArray(B.messages)?B.messages:[],G=X.find(te=>(te==null?void 0:te.role)==="user"),z=X.find(te=>(te==null?void 0:te.role)==="assistant");return{...B,run:B.run||L,request:y(G==null?void 0:G.content)||"(no user message)",preview:y(z==null?void 0:z.content)||"(no assistant response)"}}function x(B,L){return[...B].sort((X,G)=>{switch(L){case"step_asc":return(X.step??0)-(G.step??0);case"step_desc":return(G.step??0)-(X.step??0);case"request_time_asc":return String(X.timestamp||"").localeCompare(String(G.timestamp||""));case"request_time_desc":default:return String(G.timestamp||"").localeCompare(String(X.timestamp||""))}})}async function _(){const B=++g;if(!n()||r().length===0){D(d,[],!0),D(h,0);return}try{const L=await Promise.all(r().map(z=>ZSe(n(),z)));if(B!==g)return;const X=new Map;let G=0;for(const z of L){G+=(z==null?void 0:z.total)||0;for(const te of(z==null?void 0:z.steps)||[])X.set(te.step,(X.get(te.step)||0)+te.count)}D(d,[...X.entries()].map(([z,te])=>({step:z,count:te})).sort((z,te)=>(z.step??0)-(te.step??0)),!0),D(h,G,!0)}catch(L){if(B!==g)return;console.error("Failed to load trace summary:",L),D(d,[],!0),D(h,0)}}async function w(B,L,X,G){const z=++p;if(!n()||r().length===0){D(f,[],!0),D(c,null);return}D(s,!0);try{const te=X==="all"?null:Number(X),Ne=G*i,H=r().length===1,ee=H?i:Ne+i,ne=H?Ne:0,be=await Promise.all(r().map(async ge=>(await KSe(n(),ge,{search:B,sort:L,step:te,limit:ee,offset:ne})).map(De=>b(De,ge.name))));if(z!==p)return;let K=x(be.flat(),L);H||(K=K.slice(Ne,Ne+i)),D(f,K,!0),v(f).find(ge=>ge.id===v(c))||D(c,null)}catch(te){if(z!==p)return;console.error("Failed to load traces:",te),D(f,[],!0)}finally{z===p&&D(s,!1)}}let A="",E="",k="",S="all";zt(()=>{const B=`${n()||""}::${m(r())}`;B!==A&&(A=B,D(u,0),D(l,"all"),D(c,null),D(f,[],!0),_())}),zt(()=>{n(),m(r());const B=v(o).trim();(B!==E||v(a)!==k||v(l)!==S)&&((E!==""||B!==""||v(a)!==k||v(l)!==S)&&D(u,0),E=B,k=v(a),S=v(l));const L=setTimeout(()=>{w(B,v(a),v(l),v(u))},150);return()=>clearTimeout(L)});function $(B){D(c,v(c)===B?null:B,!0)}function M(B,L){(B.key==="Enter"||B.key===" ")&&(B.preventDefault(),$(L))}function O(B){if(!B)return"—";const L=new Date(B);if(Number.isNaN(L.getTime()))return B;const G=new Date().getTime()-L.getTime(),z=Math.max(0,Math.round(G/1e3));if(z<5)return"just now";if(z<60)return`${z} sec ago`;const te=Math.round(z/60);if(te<60)return`${te} min ago`;const Ne=Math.round(te/60);if(Ne<24)return`${Ne} hr ago`;const H=Math.round(Ne/24);if(H<7)return`${H} day${H===1?"":"s"} ago`;const ee=Math.round(H/7);if(ee<5)return`${ee} wk ago`;const ne=Math.round(H/30);return ne<12?`${ne} mo ago`:`${Math.round(H/365)} yr ago`}function P(B){const L=B==null?void 0:B.content;return typeof L=="string"||L==null?[]:Array.isArray(L)?L:[L]}function T(B){return P(B).length>0}function F(B){return(B==null?void 0:B._type)==="trackio.image"||(B==null?void 0:B.type)==="image"||(B==null?void 0:B.type)==="input_image"||(B==null?void 0:B.type)==="image_url"}function N(B){var L;return B!=null&&B.file_path?fW(B.file_path):(L=B==null?void 0:B.image_url)!=null&&L.url?B.image_url.url:typeof(B==null?void 0:B.url)=="string"?B.url:""}function U(B){return(B==null?void 0:B.caption)||(B==null?void 0:B.alt)||"Trace image"}function j(B){return typeof B=="string"&&B.length>500}function W(B){if(!B)return"";const L=String(B).split(":");if(L.length>=4){const X=L[1],G=L[L.length-1];return G!==""&&!Number.isNaN(Number(G))?`${X}:${G}`:X}return String(B)}function Z(B){if(!B)return"";const L=String(B).split(":"),X=L.length>=4?L[1]||L[0]:String(B);return X.replace(/[^a-zA-Z0-9]/g,"").slice(0,7)||X.slice(0,7)}function Y(B){if(!B)return null;const L=String(B).split(":");if(L.length>=4){const X=L[L.length-1];if(X!==""&&!Number.isNaN(Number(X)))return X}return null}function J(B){if(B==null)return"—";if(typeof B=="string")return B;if(typeof B=="number"||typeof B=="boolean")return String(B);try{return JSON.stringify(B)}catch{return String(B)}}function ve(B){return Object.entries(B.metadata||{})}let Te=we(()=>{if(v(l)==="all")return v(h);const B=Number(v(l)),L=v(d).find(X=>X.step===B);return L?L.count*Math.max(1,r().length):0}),Fe=we(()=>Math.max(1,Math.ceil(v(Te)/i)));function He(){v(u)>0&&D(u,v(u)-1)}function ut(){v(u){var L=m3e();I(B,L)},fe=B=>{var L=v3e();I(B,L)},V=B=>{var L=O3e(),X=Bt(L),G=C(X),z=C(G),te=R(G,2),Ne=R(C(te),2),H=C(Ne),ee=C(H);H.value=H.__value="all";var ne=R(H);$t(ne,17,()=>v(d),Dt,(Ve,qe)=>{var Q=y3e(),pe=C(Q),Ye={};ye(gt=>{me(pe,`Step ${v(qe).step??""} (${v(qe).count??""})`),Ye!==(Ye=gt)&&(Q.value=(Q.__value=gt)??"")},[()=>String(v(qe).step)]),I(Ve,Q)});var be=R(te,2),K=R(C(be),2),ge=C(K);ge.value=ge.__value="request_time_desc";var _e=R(ge);_e.value=_e.__value="request_time_asc";var De=R(_e);De.value=De.__value="step_desc";var ct=R(De);ct.value=ct.__value="step_asc";var ze=R(be,2),Xe=C(ze),lt=R(X,2);{var yt=Ve=>{Bu(Ve,{})},pt=Ve=>{var qe=b3e();I(Ve,qe)},rt=Ve=>{var qe=N3e(),Q=Bt(qe);let pe;var Ye=C(Q),gt=R(C(Ye),2);$t(gt,21,()=>v(f),Et=>Et.id,(Et,Ge)=>{var dt=R3e(),mt=Bt(dt),se=C(mt),ke=C(se),At=C(ke),Ft=R(se),Pe=C(Ft),Je=C(Pe),Qe=R(Pe,2),vt=C(Qe),kn=R(Ft),In=C(kn),Gn=R(kn),or=C(Gn),Xi=R(Gn),Jt=C(Xi),Dn=R(mt,2);{var Br=hn=>{var pn=T3e(),Si=C(pn),oi=C(Si),Kn=C(oi),Zn=C(Kn),vs=C(Zn),ar=R(Zn,2),Ci=C(ar),ai=R(ar,2),gn=C(ai),zu=R(ai,2);$t(zu,17,()=>ve(v(Ge)),Dt,(Er,bn)=>{var zr=we(()=>XA(v(bn),2));let Pn=()=>v(zr)[0],Sn=()=>v(zr)[1];var Ma=x3e(),Ar=C(Ma);ye(Gs=>me(Ar,`${Pn()??""}: ${Gs??""}`),[()=>J(Sn())]),I(Er,Ma)});var wr=R(Kn,2);$t(wr,21,()=>v(Ge).messages,Dt,(Er,bn)=>{var zr=M3e(),Pn=C(zr),Sn=C(Pn),Ma=R(Sn);{var Ar=Mn=>{var Bn=_3e();I(Mn,Bn)};he(Ma,Mn=>{var Bn;(Bn=v(bn).tool_calls)!=null&&Bn.length&&Mn(Ar)})}var Gs=R(Ma,2);{var dW=Mn=>{var Bn=w3e();I(Mn,Bn)};he(Gs,Mn=>{v(bn).function_call&&Mn(dW)})}var YF=R(Pn,2);{var hW=Mn=>{var Bn=Ni(),ju=Bt(Bn);{var To=Ro=>{var qu=E3e(),qh=R(C(qu),2),Al=C(qh);ye(()=>me(Al,v(bn).content)),I(Ro,qu)},Uu=we(()=>j(v(bn).content)),Uh=Ro=>{var qu=A3e(),qh=C(qu);ye(()=>me(qh,v(bn).content)),I(Ro,qu)};he(ju,Ro=>{v(Uu)?Ro(To):Ro(Uh,-1)})}I(Mn,Bn)},pW=Mn=>{var Bn=C3e();$t(Bn,21,()=>P(v(bn)),Dt,(ju,To)=>{var Uu=Ni(),Uh=Bt(Uu);{var Ro=Al=>{var Mf=k3e();ye((W2,H2)=>{St(Mf,"src",W2),St(Mf,"alt",H2)},[()=>N(v(To)),()=>U(v(To))]),I(Al,Mf)},qu=we(()=>F(v(To))),qh=Al=>{var Mf=S3e(),W2=C(Mf);ye(H2=>me(W2,H2),[()=>JSON.stringify(v(To),null,2)]),I(Al,Mf)};he(Uh,Al=>{v(qu)?Al(Ro):Al(qh,-1)})}I(ju,Uu)}),I(Mn,Bn)},gW=we(()=>T(v(bn)));he(YF,Mn=>{typeof v(bn).content=="string"?Mn(hW):v(gW)&&Mn(pW,1)})}var VF=R(YF,2);{var mW=Mn=>{var Bn=F3e();$t(Bn,21,()=>v(bn).tool_calls,Dt,(ju,To)=>{var Uu=$3e(),Uh=C(Uu);ye(Ro=>me(Uh,Ro),[()=>JSON.stringify(v(To),null,2)]),I(ju,Uu)}),I(Mn,Bn)};he(VF,Mn=>{var Bn;(Bn=v(bn).tool_calls)!=null&&Bn.length&&Mn(mW)})}var vW=R(VF,2);{var yW=Mn=>{var Bn=D3e(),ju=C(Bn);ye(To=>me(ju,To),[()=>JSON.stringify(v(bn).function_call,null,2)]),I(Mn,Bn)};he(vW,Mn=>{v(bn).function_call&&Mn(yW)})}ye(()=>{St(zr,"data-role",v(bn).role||"unknown"),me(Sn,`${(v(bn).role||"message")??""} `)}),I(Er,zr)}),ye(Er=>{me(vs,`Trace ID: ${Er??""}`),me(Ci,`Logged as: ${v(Ge).key??""}`),me(gn,`Timestamp: ${(v(Ge).timestamp||"—")??""}`)},[()=>W(v(Ge).id)]),I(hn,pn)};he(Dn,hn=>{v(c)===v(Ge).id&&hn(Br)})}ye((hn,pn,Si,oi)=>{St(mt,"aria-expanded",v(c)===v(Ge).id),St(ke,"title",hn),me(At,`${pn??""}${Si??""}`),me(Je,v(Ge).request),me(vt,v(Ge).preview),me(In,v(Ge).run||"—"),me(or,v(Ge).step??"—"),me(Jt,oi)},[()=>W(v(Ge).id),()=>Z(v(Ge).id),()=>Y(v(Ge).id)!==null?`:${Y(v(Ge).id)}`:"",()=>O(v(Ge).timestamp)]),Oe("click",mt,()=>$(v(Ge).id)),Oe("keydown",mt,hn=>M(hn,v(Ge).id)),I(Et,dt)});var Ke=R(Q,2),Ze=C(Ke),We=R(Ze,2),it=C(We),bt=R(We,2);ye(()=>{pe=tn(Q,1,"traces-table-wrap svelte-1s32ifo",null,pe,{dim:v(s)}),Ze.disabled=v(u)===0||v(s),me(it,`Page ${v(u)+1} of ${v(Fe)??""}`),bt.disabled=v(u)>=v(Fe)-1||v(s)}),Oe("click",Ze,He),Oe("click",bt,ut),I(Ve,qe)};he(lt,Ve=>{v(s)&&v(f).length===0?Ve(yt):v(f).length===0?Ve(pt,1):Ve(rt,-1)})}ye(()=>{me(ee,`All steps (${v(h)??""})`),me(Xe,`${v(Te)??""} trace${v(Te)===1?"":"s"}`)}),ph(z,()=>v(o),Ve=>D(o,Ve)),L1(Ne,()=>v(l),Ve=>D(l,Ve)),L1(K,()=>v(a),Ve=>D(a,Ve)),I(B,L)};he(xe,B=>{n()?r().length===0?B(fe,1):B(V,-1):B(je)})}I(e,wt),An()}si(["click","keydown"]);var P3e=q('

      Unable to load system metrics

      '),B3e=q('

      No projects

      Create a project by calling trackio.init(project="…") in your training script.

      '),z3e=q('

      No run selected

      Select one or more runs in the sidebar.

      '),j3e=q('

      No System Metrics Available

      System metrics will appear here once logged. To enable automatic logging:

      Setup:

      • CPU/system metrics: pip install trackio[cpu] (requires psutil)
      • NVIDIA GPU: pip install trackio[gpu] (requires nvidia-ml-py)
      • Apple Silicon: pip install trackio[apple-gpu] (requires psutil)
      '),U3e=q('
      '),q3e=q('
      '),W3e=q(" ",1),H3e=q('
      ');function G3e(e,t){En(t,!0);let n=ae(t,"project",3,null),r=ae(t,"selectedRuns",19,()=>[]),i=ae(t,"allRuns",19,()=>[]),s=ae(t,"smoothing",3,5),o=ae(t,"appBootstrapReady",3,!1),a=ae(t,"realtimeEnabled",3,!0),l=ae(t,"availableDevices",31,()=>xt([])),u=ae(t,"selectedDevices",31,()=>xt([])),c=re(xt([])),f=re(xt([])),d=re(null),h=re(!1),p=re(null),g=!0,m=re(xt({})),y=re(xt({group:null,index:-1}));const b=64;let x=new Map,_=null,w=we(()=>n0(i().length?i():r())),A=we(()=>DR(v(f))),E=we(()=>Object.keys(v(A))),k=we(()=>{const H=new Map,ee=v(d);for(const ne of Object.values(v(A))){for(const be of ne.direct)H.has(be)||H.set(be,vw(v(c),"time",be,ee));for(const be of Object.values(ne.subgroups))for(const K of be)H.has(K)||H.set(K,vw(v(c),"time",K,ee))}return H}),S=we(()=>{const H=[];for(const[ee,ne]of Object.entries(v(A)))for(const be of N(Object.keys(ne.subgroups)))H.push(wt(ee,be));return[...new Set(H)]}),$=we(()=>{const H=new Map;for(const[ee,ne]of Object.entries(v(A)))H.set(ee,je(ee,ne.subgroups));return H}),M=we(()=>{const H=new Map,ee=v(d);for(const[ne,be]of v($).entries())for(const[K,ge]of Object.entries(be)){const _e=`sys:${ne}:compare:${K}`;H.set(_e,fe(v(c),"time",ge,ee))}return H});function O(H,ee){const ne=v(m)[H];if(!ne)return ee;const be=[];for(const K of ne)ee.includes(K)&&be.push(K);for(const K of ee)be.includes(K)||be.push(K);return be}function P(H,ee,ne){D(y,{group:H,index:ee},!0),ne.dataTransfer.effectAllowed="move",ne.dataTransfer.setData("text/plain","")}function T(H,ee,ne){v(y).group===H&&(ne.preventDefault(),ne.dataTransfer.dropEffect="move")}function F(H,ee,ne,be){if(be.preventDefault(),v(y).group!==H||v(y).index===ee){D(y,{group:null,index:-1},!0);return}const K=[...ne],[ge]=K.splice(v(y).index,1);K.splice(ee,0,ge),D(m,{...v(m),[H]:K},!0),D(y,{group:null,index:-1},!0)}function N(H){return[...H].sort((ee,ne)=>{const be=Number(ee),K=Number(ne);return!Number.isNaN(be)&&!Number.isNaN(K)?be-K:ee.localeCompare(ne)})}function U(H,ee){return H.length!==ee.length?!1:H.every((ne,be)=>ne===ee[be])}function j(){if(!n()||r().length===0){D(c,[],!0),D(f,[],!0);return}const H=[],ee=new Set;for(const ne of r()){const be=ne.id??ne.name,K=x.get(be);if(!K||K.length===0)continue;const ge=new Date(K[0].timestamp).getTime();K.forEach(_e=>{const De=(new Date(_e.timestamp).getTime()-ge)/1e3;Object.keys(_e).forEach(ct=>{typeof _e[ct]=="number"&&ct!=="step"&&ct!=="time"&&ee.add(ct)}),H.push({..._e,time:De,run:ne.name,run_id:be,series_key:be,data_type:"original"})})}D(f,Array.from(ee).sort(),!0),D(c,H,!0)}function W(H){const ee=H&&H.message?String(H.message):"";return/\b(404|405|501)\b/.test(ee)}async function Z(H){if(g&&H.length<=b)try{return await $T(n(),H)}catch(ne){if(!W(ne))throw ne;g=!1}if(g){const ne=[];for(let be=0;be{const be=ne.id??ne.name;return!x.has(be)});let ee=!1;if(H.length>0)try{const ne=await Z(H);for(const be of ne){const K=be.run_id??be.run;x.set(K,be.logs),ee=!0}D(p,null)}catch(ne){if(console.error("Failed to load system metric logs:",ne),!v(h)){D(p,ne&&ne.message?ne.message:"Failed to load system metrics",!0);return}}(ee||!v(h))&&j(),D(p,null),D(h,!0)}async function J(){if(a()&&!(!n()||r().length===0)&&!GF()&&!HF())try{const H=await Z(r());let ee=!1;for(const ne of H){const be=ne.run_id??ne.run,K=ne.logs,ge=x.get(be);(!ge||TR(ge,K))&&(x.set(be,K),ee=!0)}ee&&j()}catch(H){console.error("Failed to refresh system metric logs:",H)}}zt(()=>{n(),r(),o(),x=n()?x:new Map,Y()}),zt(()=>{s(),v(h)&&j()}),zt(()=>{const H=l(),ee=v(S),ne=u().filter(be=>ee.includes(be));if(U(l(),ee)||l(ee),ee.length===0){u().length>0&&u([]);return}if(H.length===0&&u().length===0){U(u(),ee)||u([...ee]);return}if(u().length>0&&ne.length!==u().length){const be=ne.length>0?ne:[...ee];U(u(),be)||u(be)}}),hh(()=>(_=setInterval(J,oW()),()=>{_&&clearInterval(_)}));function ve(H){H&&H.length===2&&D(d,H,!0)}function Te(){D(d,null)}const Fe={utilization:"%",mean_utilization:"%",allocated_memory:"GiB",total_allocated_memory:"GiB",power:"W",total_power:"W",temp:"°C",max_temp:"°C"};function He(H){const ee=H.split("/").pop(),ne=Fe[ee];return ne?`${H} (${ne})`:H}function ut(H,ee=1){const ne=H.split("/").slice(ee).join("/")||H;return He(ne)}function wt(H,ee){return H==="gpu"?`GPU ${ee}`:`${H.toUpperCase()} ${ee}`}function xe(H,ee){return wt(H,ee)}function je(H,ee){const ne={},be=N(Object.keys(ee)).filter(ge=>{const _e=xe(H,ge);return u().length===0||u().includes(_e)});for(const ge of be)for(const _e of ee[ge]??[]){const De=_e.split("/").slice(2).join("/");De&&(ne[De]||(ne[De]=[]),ne[De].push(_e))}const K={};return Object.keys(ne).sort().forEach(ge=>{K[ge]=ne[ge]}),K}function fe(H,ee,ne,be){if(!ne||ne.length===0)return{data:[],yExtent:void 0};let K=[];for(const De of ne){const[ct,ze]=De.split("/");for(const Xe of H){const lt=Xe[De];lt!=null&&K.push({[ee]:Xe[ee],value:lt,seriesKey:`${Xe.series_key}\0${ct}\0${ze}`,run:Xe.run,series_key:Xe.series_key,device:xe(ct,ze),data_type:Xe.data_type})}}if(be){const De=new Map;for(const ze of K){const Xe=`${ze.seriesKey}\0${ze.data_type||"original"}`;De.has(Xe)||De.set(Xe,[]),De.get(Xe).push(ze)}const ct=[];for(const ze of De.values()){ze.sort((yt,pt)=>yt[ee]-pt[ee]);let Xe=0,lt=ze.length-1;for(;Xe=0&&ze[lt][ee]>be[1];)lt--;Xe=Math.max(0,Xe-1),lt=Math.min(ze.length-1,lt+1),ct.push(...ze.slice(Xe,lt+1))}K=ct}const ge=K.filter(De=>De.data_type==="original"||!De.data_type);let _e;if(ge.length>0){let De=1/0,ct=-1/0;for(const ze of ge)ze.valuect&&(ct=ze.value);De!==1/0&&(_e=[De,ct])}return{data:FR(K,ee,"value","seriesKey",be,["seriesKey","run","series_key","device"]).data,yExtent:_e}}var V=H3e(),B=C(V);{var L=H=>{Bu(H,{})},X=H=>{var ee=P3e(),ne=R(C(ee),2),be=C(ne);ye(()=>me(be,v(p))),I(H,ee)},G=H=>{var ee=B3e();I(H,ee)},z=H=>{var ee=z3e();I(H,ee)},te=H=>{var ee=j3e(),ne=R(C(ee),4),be=C(ne);be.textContent=`import trackio + +# CPU/system metrics auto-enable when psutil is installed: +run = trackio.init(project="my-project") + +# Or explicitly enable/disable them: +run = trackio.init(project="my-project", auto_log_cpu=True) + +# Manually log at any time: +trackio.log_cpu() +trackio.log_gpu()`,I(H,ee)},Ne=H=>{var ee=Ni(),ne=Bt(ee);$t(ne,17,()=>v(E),Dt,(be,K)=>{const ge=we(()=>v(A)[v(K)]),_e=we(()=>`sys:${v(K)}`),De=we(()=>`sys:${v(K)}:compare`),ct=we(()=>O(v(_e),v(ge).direct)),ze=we(()=>v($).get(v(K))??{}),Xe=we(()=>O(v(De),Object.keys(v(ze))));LA(be,{get label(){return v(K)},open:!0,children:(lt,yt)=>{var pt=W3e(),rt=Bt(pt);{var Ve=pe=>{var Ye=U3e();$t(Ye,21,()=>v(ct),Dt,(gt,Ke,Ze)=>{const We=we(()=>v(k).get(v(Ke))??{data:[],yExtent:void 0}),it=we(()=>v(We).data),bt=we(()=>v(We).yExtent);var Et=Ni(),Ge=Bt(Et);{var dt=mt=>{{let se=we(()=>ut(v(Ke),1));by(mt,{get data(){return v(it)},x:"time",get y(){return v(Ke)},get title(){return v(se)},get colorMap(){return v(w)},colorField:"series_key",colorDisplayField:"run",get xLim(){return v(d)},get yExtent(){return v(bt)},onSelect:ve,onResetZoom:Te,draggable:!0,ondragstart:ke=>P(v(_e),Ze,ke),ondragover:ke=>T(v(_e),Ze,ke),ondrop:ke=>F(v(_e),Ze,v(ct),ke)})}};he(Ge,mt=>{v(it).length>0&&mt(dt)})}I(gt,Et)}),I(pe,Ye)};he(rt,pe=>{v(ct).length>0&&pe(Ve)})}var qe=R(rt,2);{var Q=pe=>{var Ye=q3e(),gt=C(Ye);$t(gt,21,()=>v(Xe),Dt,(Ke,Ze,We)=>{const it=we(()=>`sys:${v(K)}:compare:${v(Ze)}`),bt=we(()=>v(M).get(v(it))??{data:[],yExtent:void 0}),Et=we(()=>v(bt).data),Ge=we(()=>v(bt).yExtent);var dt=Ni(),mt=Bt(dt);{var se=ke=>{{let At=we(()=>He(v(Ze))),Ft=we(()=>He(v(Ze)));by(ke,{get data(){return v(Et)},x:"time",y:"value",get yLabel(){return v(At)},get title(){return v(Ft)},colorField:"series_key",colorDisplayField:"run",colorLabel:"Run",get colorMap(){return v(w)},dashField:"device",dashLabel:"Device",get xLim(){return v(d)},get yExtent(){return v(Ge)},onSelect:ve,onResetZoom:Te,draggable:!0,ondragstart:Pe=>P(v(De),We,Pe),ondragover:Pe=>T(v(De),We,Pe),ondrop:Pe=>F(v(De),We,v(Xe),Pe)})}};he(mt,ke=>{v(Et).length>0&&ke(se)})}I(Ke,dt)}),I(pe,Ye)};he(qe,pe=>{v(Xe).length>0&&pe(Q)})}I(lt,pt)},$$slots:{default:!0}})}),I(H,ee)};he(B,H=>{!o()||!v(h)&&!v(p)?H(L):v(p)&&!v(h)?H(X,1):n()?r().length===0?H(z,3):v(c).length===0?H(te,4):H(Ne,-1):H(G,2)})}I(e,V),An()}var Y3e=Ei(''),V3e=Ei(''),X3e=q('
      ');function K3e(e,t){En(t,!0);let n=ae(t,"src",3,"");const r=72;let i,s,o=re(xt([])),a=re(0),l=re(0),u=re(!1),c=re(!1);function f(S){if(!Number.isFinite(S)||S<0)return"0:00";const $=Math.floor(S/60),M=Math.floor(S%60);return`${$}:${M.toString().padStart(2,"0")}`}async function d(){var S;if(n()){D(c,!1);try{const M=await(await fetch(n())).arrayBuffer(),O=window.AudioContext||window.webkitAudioContext,P=new O,T=await P.decodeAudioData(M);D(a,T.duration,!0);const F=T.getChannelData(0),N=Math.max(1,Math.floor(F.length/r)),U=new Array(r);for(let W=0;WW/j),!0),(S=P.close)==null||S.call(P)}catch{D(c,!0)}}}function h(){if(!i||v(o).length===0)return;const S=window.devicePixelRatio||1,$=i.getBoundingClientRect();if($.width===0)return;i.width=$.width*S,i.height=$.height*S;const M=i.getContext("2d");M.setTransform(S,0,0,S,0,0),M.clearRect(0,0,$.width,$.height);const O=getComputedStyle(i),P=(O.getPropertyValue("--wave-played")||"#f97316").trim(),T=(O.getPropertyValue("--wave-base")||"#9ca3af").trim(),F=v(a)>0?v(l)/v(a):0,N=$.width/v(o).length,U=$.height/2;for(let j=0;j{}):s.pause())}function g(S){if(!s||!v(a))return;const $=i.getBoundingClientRect(),M=S.clientX-$.left,O=Math.max(0,Math.min(v(a),M/$.width*v(a)));s.currentTime=O,D(l,O,!0)}zt(()=>{n(),D(o,[],!0),D(l,0),D(a,0),D(u,!1),d()}),zt(()=>{v(o),v(l),v(a),h()});var m=X3e();fn("resize",$d,h);var y=C(m),b=C(y);{var x=S=>{var $=Y3e();I(S,$)},_=S=>{var $=V3e();I(S,$)};he(b,S=>{v(u)?S(x):S(_,-1)})}var w=R(y,2);is(w,S=>i=S,()=>i);var A=R(w,2),E=C(A),k=R(A,2);is(k,S=>s=S,()=>s),ye((S,$)=>{St(y,"aria-label",v(u)?"Pause":"Play"),y.disabled=v(c),me(E,`${S??""} / ${$??""}`),St(k,"src",n())},[()=>f(v(l)),()=>f(v(a))]),Oe("click",y,p),Oe("click",w,g),fn("timeupdate",k,()=>D(l,s.currentTime,!0)),fn("loadedmetadata",k,()=>D(a,s.duration,!0)),fn("play",k,()=>D(u,!0)),fn("pause",k,()=>D(u,!1)),fn("ended",k,()=>{D(u,!1),D(l,0)}),I(e,m),An()}si(["click"]);var Z3e=q('

      Select a project

      Pick a project in the sidebar to browse media and tables for a run.

      ',1),J3e=q('

      No runs selected

      Select runs in the sidebar to browse media and tables.

      ',1),Q3e=q('

      No media or tables in this run

      Log images, video, audio, and tables by passing Trackio objects to trackio.log():

      Each type appears in its own section here once logged.

      ',1),eCe=q('
      '),tCe=q('
      '),nCe=q('
      '),rCe=q(''),iCe=q('
      No images match this filter.
      '),sCe=q('
      '),oCe=q('
      Sort
      '),aCe=q('',2),lCe=q('
      '),uCe=q('
      '),cCe=q(''),fCe=q('
      '),dCe=q('
      '),hCe=q(' '),pCe=q(''),gCe=q(''),mCe=q('
      '),vCe=q(''),yCe=q(''),bCe=q('
      '),xCe=q('
      '),_Ce=q('
      '),wCe=q(" ",1),ECe=q(''),ACe=q(''),kCe=q('
      '),SCe=q('
      '),CCe=q(' '),$Ce=q(''),FCe=q('
      ',1);function DCe(e,t){En(t,!0);let n=ae(t,"project",3,null),r=ae(t,"selectedRuns",19,()=>[]),i=ae(t,"allRuns",19,()=>[]),s=ae(t,"tableTruncateLength",3,250),o=we(()=>n0(i().length?i():r()));function a(L){return v(o)[L._runId]??v(o)[L._run]??"#9ca3af"}const l=48,u={images:[],videos:[],audios:[],tables:[]};let c=re(xt(u)),f=re("newest"),d=re(""),h=re(xt(b())),p=re(null),g=re(xt([])),m=re(null),y=re(!1);function b(){return{images:l,videos:l,audios:l,tables:l}}function x(){D(h,b(),!0)}function _(L,X){const G=Number.isFinite(L.step)?L.step:0,z=Number.isFinite(X.step)?X.step:0,te=v(f)==="newest"?z-G:G-z;if(te!==0)return te;const Ne=Number.isFinite(L._index)?L._index:0,H=Number.isFinite(X._index)?X._index:0;return v(f)==="newest"?H-Ne:Ne-H}function w(L){return[...L].sort(_)}function A(L){return Array.isArray(L._value)&&L._value.length>0}let E=we(()=>({images:w(v(c).images),videos:w(v(c).videos),audios:w(v(c).audios),tables:w(v(c).tables.filter(A))}));function k(L){return L.caption?`${L.key} ${L.caption}`:L.key}let S=we(()=>{if(!v(d).trim())return v(E).images;const L=new Set(Cy(v(E).images.map(X=>k(X)),v(d)));return v(E).images.filter(X=>L.has(k(X)))}),$=we(()=>({images:v(S).slice(0,v(h).images),videos:v(E).videos.slice(0,v(h).videos),audios:v(E).audios.slice(0,v(h).audios),tables:v(E).tables.slice(0,v(h).tables)})),M=we(()=>v(E).images.length>0||v(E).videos.length>0||v(E).audios.length>0||v(E).tables.length>0);function O(L){v(h)[L]+=l}zt(()=>{v(f),v(d),v(c),x()});async function P(){if(!n()||r().length===0){D(c,u,!0);return}D(y,!0);try{const L=r(),X=[];for(const ne of L){const be=await lW(n(),ne);be&&X.push(...be.map(K=>({...K,_run:ne.name,_runId:ne.id??ne.name})))}const G=X,z=[],te=[],Ne=[],H=[];let ee=0;G&&G.forEach((ne,be)=>{Object.entries(ne).forEach(([K,ge])=>{if(ge&&typeof ge=="object"&&ge._type){const _e={key:K,step:ne.step??be,_index:ee++,_run:ne._run,_runId:ne._runId,...ge};switch(ge._type){case"trackio.image":z.push(_e);break;case"trackio.video":te.push(_e);break;case"trackio.audio":Ne.push(_e);break;case"trackio.table":H.push(_e);break}}})}),D(c,{images:z,videos:te,audios:Ne,tables:H},!0)}catch(L){console.error("Failed to load media:",L)}finally{D(y,!1)}}zt(()=>{n(),r(),P()});function T(L){return L._resolvedUrl?L._resolvedUrl:L.file_path?fW(L.file_path):""}function F(L){return L&&typeof L=="object"&&!Array.isArray(L)&&L._type==="trackio.image"}function N(L){return Array.isArray(L)&&L.length>0&&L.every(X=>X&&typeof X=="object"&&X._type==="trackio.image")}function U(L){var X;(X=L.currentTarget.parentElement)==null||X.classList.add("image-loaded")}function j(L){var X;(X=L.currentTarget.parentElement)==null||X.classList.add("image-failed")}function W(L,X=null){return{...L,key:L.key??(X==null?void 0:X.key),step:L.step??(X==null?void 0:X.step),_run:L._run??(X==null?void 0:X._run),_runId:L._runId??(X==null?void 0:X._runId),caption:L.caption??(X==null?void 0:X.caption)}}function Z(L,X=null,G=[],z=null){D(p,W(L,X),!0),D(g,G,!0),D(m,z,!0)}function Y(){D(p,null),D(g,[],!0),D(m,null)}function J(L){L<0||L>=v(g).length||(D(p,W(v(g)[L]),!0),D(m,L,!0))}function ve(){v(m)===null||v(g).length<=1||J((v(m)-1+v(g).length)%v(g).length)}function Te(){v(m)===null||v(g).length<=1||J((v(m)+1)%v(g).length)}function Fe(L){v(p)&&(L.key==="Escape"&&Y(),L.key==="ArrowLeft"&&ve(),L.key==="ArrowRight"&&Te())}var He=FCe();fn("keydown",$d,Fe);var ut=Bt(He),wt=C(ut);{var xe=L=>{Bu(L,{})},je=L=>{var X=eCe(),G=C(X);{var z=H=>{var ee=Z3e();I(H,ee)},te=H=>{var ee=J3e(),ne=R(Bt(ee),4),be=C(ne);be.textContent=`import trackio +trackio.init(project="my-project") +trackio.log({"loss": 0.5}) +trackio.finish()`,I(H,ee)},Ne=H=>{var ee=Q3e(),ne=R(Bt(ee),4),be=C(ne);be.textContent=`import trackio + +trackio.init(project="my-project") +trackio.log({"plot": trackio.Image("figure.png")}) +trackio.log({"clip": trackio.Video("output.mp4")}) +trackio.log({"audio": trackio.Audio("speech.wav")}) + +import pandas as pd +df = pd.DataFrame({"epoch": [0, 1], "acc": [0.9, 0.95]}) +trackio.log({"samples": trackio.Table(dataframe=df)})`,I(H,ee)};he(G,H=>{n()?r().length===0?H(te,1):H(Ne,-1):H(z)})}I(L,X)},fe=L=>{const X=(ge,_e=LT)=>{var De=tCe(),ct=C(De);let ze;var Xe=R(ct,2),lt=C(Xe);ye(yt=>{ze=ll(ct,"",ze,yt),me(lt,`Run: ${_e()._run??""}, Step: ${_e().step??""}`)},[()=>({background:a(_e())})]),I(ge,De)};var G=wCe(),z=Bt(G);{var te=ge=>{var _e=oCe(),De=C(_e),ct=C(De),ze=R(C(ct),2),Xe=C(ze),lt=R(ct,2),yt=C(lt),pt=C(yt),rt=R(yt,2),Ve=R(C(rt),2),qe=C(Ve);qe.value=qe.__value="newest";var Q=R(qe);Q.value=Q.__value="oldest";var pe=R(De,2);$t(pe,21,()=>v($).images,Dt,(We,it,bt)=>{var Et=rCe(),Ge=C(Et),dt=C(Ge),mt=R(Ge,2),se=R(C(mt),2),ke=R(mt,2);{var At=Pe=>{var Je=nCe(),Qe=C(Je);ye(()=>me(Qe,v(it).caption)),I(Pe,Je)};he(ke,Pe=>{v(it).caption&&Pe(At)})}var Ft=R(ke,2);X(Ft,()=>v(it)),ye(Pe=>{me(dt,v(it).key),St(mt,"aria-label",`Open ${v(it).caption||v(it).key}`),St(se,"src",Pe),St(se,"alt",v(it).caption||v(it).key)},[()=>T(v(it))]),Oe("click",mt,()=>Z(v(it),null,v(S),bt)),fn("load",se,U),fn("error",se,j),I(We,Et)});var Ye=R(pe,2);{var gt=We=>{var it=iCe();I(We,it)};he(Ye,We=>{v(S).length===0&&We(gt)})}var Ke=R(Ye,2);{var Ze=We=>{var it=sCe(),bt=C(it),Et=C(bt),Ge=R(bt,2);ye(()=>me(Et,`Showing ${v($).images.length??""} of ${v(S).length??""}`)),Oe("click",Ge,()=>O("images")),I(We,it)};he(Ke,We=>{v(h).imagesme(Xe,`Images (${v(S).length??""})`)),Oe("click",pt,We=>We.stopPropagation()),Oe("keydown",pt,We=>We.stopPropagation()),ph(pt,()=>v(d),We=>D(d,We)),Oe("click",Ve,We=>We.stopPropagation()),Oe("keydown",Ve,We=>We.stopPropagation()),L1(Ve,()=>v(f),We=>D(f,We)),I(ge,_e)};he(z,ge=>{v(E).images.length>0&&ge(te)})}var Ne=R(z,2);{var H=ge=>{var _e=uCe(),De=C(_e),ct=R(C(De),2),ze=C(ct),Xe=R(De,2);$t(Xe,21,()=>v($).videos,Dt,(pt,rt)=>{var Ve=aCe(),qe=C(Ve),Q=C(qe),pe=R(qe,2),Ye=R(pe,2);X(Ye,()=>v(rt)),ye(gt=>{me(Q,v(rt).key),St(pe,"src",gt)},[()=>T(v(rt))]),I(pt,Ve)});var lt=R(Xe,2);{var yt=pt=>{var rt=lCe(),Ve=C(rt),qe=C(Ve),Q=R(Ve,2);ye(()=>me(qe,`Showing ${v($).videos.length??""} of ${v(E).videos.length??""}`)),Oe("click",Q,()=>O("videos")),I(pt,rt)};he(lt,pt=>{v(h).videosme(ze,`Videos (${v(E).videos.length??""})`)),I(ge,_e)};he(Ne,ge=>{v(E).videos.length>0&&ge(H)})}var ee=R(Ne,2);{var ne=ge=>{var _e=dCe(),De=C(_e),ct=R(C(De),2),ze=C(ct),Xe=R(De,2);$t(Xe,21,()=>v($).audios,Dt,(pt,rt)=>{var Ve=cCe(),qe=C(Ve),Q=C(qe),pe=R(qe,2);{let gt=we(()=>T(v(rt)));K3e(pe,{get src(){return v(gt)}})}var Ye=R(pe,2);X(Ye,()=>v(rt)),ye(()=>me(Q,v(rt).key)),I(pt,Ve)});var lt=R(Xe,2);{var yt=pt=>{var rt=fCe(),Ve=C(rt),qe=C(Ve),Q=R(Ve,2);ye(()=>me(qe,`Showing ${v($).audios.length??""} of ${v(E).audios.length??""}`)),Oe("click",Q,()=>O("audios")),I(pt,rt)};he(lt,pt=>{v(h).audiosme(ze,`Audio (${v(E).audios.length??""})`)),I(ge,_e)};he(ee,ge=>{v(E).audios.length>0&&ge(ne)})}var be=R(ee,2);{var K=ge=>{var _e=_Ce(),De=C(_e),ct=R(C(De),2),ze=C(ct),Xe=R(De,2);$t(Xe,17,()=>v($).tables,Dt,(pt,rt)=>{var Ve=bCe(),qe=C(Ve),Q=C(qe),pe=C(Q),Ye=R(Q,2);X(Ye,()=>v(rt));var gt=R(qe,2),Ke=C(gt),Ze=C(Ke);$t(Ze,21,()=>Object.keys(v(rt)._value[0]),Dt,(it,bt)=>{var Et=hCe(),Ge=C(Et);ye(()=>me(Ge,v(bt))),I(it,Et)});var We=R(Ke);$t(We,21,()=>v(rt)._value,Dt,(it,bt)=>{var Et=yCe();$t(Et,21,()=>Object.values(v(bt)),Dt,(Ge,dt)=>{var mt=vCe(),se=C(mt);{var ke=Qe=>{var vt=pCe(),kn=R(C(vt),2);ye(In=>{St(kn,"src",In),St(kn,"alt",v(dt).caption||"")},[()=>T(v(dt))]),Oe("click",vt,()=>Z(v(dt),v(rt))),fn("load",kn,U),fn("error",kn,j),I(Qe,vt)},At=we(()=>F(v(dt))),Ft=Qe=>{var vt=mCe();$t(vt,21,()=>v(dt),Dt,(kn,In)=>{var Gn=gCe(),or=R(C(Gn),2);ye(Xi=>{St(or,"src",Xi),St(or,"alt",v(In).caption||"")},[()=>T(v(In))]),Oe("click",Gn,()=>Z(v(In),v(rt))),fn("load",or,U),fn("error",or,j),I(kn,Gn)}),I(Qe,vt)},Pe=we(()=>N(v(dt))),Je=Qe=>{var vt=hw();ye(kn=>me(vt,kn),[()=>typeof v(dt)=="string"&&v(dt).length>s()?v(dt).slice(0,s())+"…":v(dt)??""]),I(Qe,vt)};he(se,Qe=>{v(At)?Qe(ke):v(Pe)?Qe(Ft,1):Qe(Je,-1)})}I(Ge,mt)}),I(it,Et)}),ye(()=>me(pe,v(rt).key)),I(pt,Ve)});var lt=R(Xe,2);{var yt=pt=>{var rt=xCe(),Ve=C(rt),qe=C(Ve),Q=R(Ve,2);ye(()=>me(qe,`Showing ${v($).tables.length??""} of ${v(E).tables.length??""}`)),Oe("click",Q,()=>O("tables")),I(pt,rt)};he(lt,pt=>{v(h).tablesme(ze,`Tables (${v(E).tables.length??""})`)),I(ge,_e)};he(be,ge=>{v(E).tables.length>0&&ge(K)})}I(L,G)};he(wt,L=>{v(y)?L(xe):v(M)?L(fe,-1):L(je,1)})}var V=R(ut,2);{var B=L=>{var X=$Ce(),G=C(X),z=C(G),te=R(z,2);{var Ne=qe=>{var Q=ECe();Oe("click",Q,ve),I(qe,Q)};he(te,qe=>{v(g).length>1&&qe(Ne)})}var H=R(te,2),ee=R(C(H),2),ne=R(H,2);{var be=qe=>{var Q=ACe();Oe("click",Q,Te),I(qe,Q)};he(ne,qe=>{v(g).length>1&&qe(be)})}var K=R(ne,2),ge=C(K);{var _e=qe=>{var Q=kCe(),pe=C(Q);ye(()=>me(pe,v(p).key)),I(qe,Q)};he(ge,qe=>{v(p).key&&qe(_e)})}var De=R(ge,2);{var ct=qe=>{var Q=SCe(),pe=C(Q);ye(()=>me(pe,v(p).caption)),I(qe,Q)};he(De,qe=>{v(p).caption&&qe(ct)})}var ze=R(De,2),Xe=C(ze);let lt;var yt=R(Xe,2),pt=C(yt),rt=R(yt,2);{var Ve=qe=>{var Q=CCe(),pe=C(Q);ye(()=>me(pe,`${v(m)+1} / ${v(g).length??""}`)),I(qe,Q)};he(rt,qe=>{v(m)!==null&&v(g).length>1&&qe(Ve)})}ye((qe,Q)=>{St(ee,"src",qe),St(ee,"alt",v(p).caption||v(p).key||"Image preview"),lt=ll(Xe,"",lt,Q),me(pt,`Run: ${v(p)._run??""}, Step: ${v(p).step??""}`)},[()=>T(v(p)),()=>({background:a(v(p))})]),Oe("click",X,Y),Oe("click",G,qe=>qe.stopPropagation()),Oe("keydown",G,qe=>qe.stopPropagation()),Oe("click",z,Y),fn("load",ee,U),fn("error",ee,j),I(L,X)};he(V,L=>{v(p)&&L(B)})}I(e,He),An()}si(["click","keydown"]);var MCe=q(`

      No alerts or reports yet

      Alerts are recorded when your training script calls trackio.alert(). + Reports are logged as Markdown via trackio.log().

      `),TCe=q('
      '),RCe=q('

      '),NCe=q('

      No alerts for this level.

      '),OCe=q(' '),LCe=q(' '),ICe=q(''),PCe=q('
      '),BCe=q('

      '),zCe=q(" ",1),jCe=q('
      ');function UCe(e,t){En(t,!0);let n=ae(t,"project",3,null),r=ae(t,"selectedRuns",19,()=>[]),i=re(xt([])),s=re(xt([])),o=re(null),a=re(!1);const l={info:"🔵",warn:"🟡",error:"🔴"};function u(_){if(!_)return"";let w=_.replace(/&/g,"&").replace(//g,">");return w=w.replace(/^### (.+)$/gm,"

      $1

      "),w=w.replace(/^## (.+)$/gm,"

      $1

      "),w=w.replace(/^# (.+)$/gm,"

      $1

      "),w=w.replace(/\*\*(.+?)\*\*/g,"$1"),w=w.replace(/`([^`]+)`/g,"$1"),w=w.replace(/^- (.+)$/gm,"
    • $1
    • "),w=w.replace(/(
    • .*<\/li>\n?)+/gs,A=>`
        ${A}
      `),w=w.replace(/\n{2,}/g,"

      "),w=`

      ${w}

      `,w=w.replace(/

      \s*()/g,"$1"),w=w.replace(/(<\/h[234]>)\s*<\/p>/g,"$1"),w=w.replace(/

      \s*(

        )/g,"$1"),w=w.replace(/(<\/ul>)\s*<\/p>/g,"$1"),w=w.replace(/

        \s*<\/p>/g,""),w}let c=we(()=>v(o)?v(i).filter(_=>_.level===v(o)):v(i));async function f(){if(!n()){D(i,[],!0),D(s,[],!0);return}D(a,!0);try{const _=await cW(n(),null,null,null),w=new Set(r().map(k=>k.name));D(i,(_||[]).filter(k=>!k.run||w.has(k.run)),!0);const A=r(),E=[];for(const k of A)try{const S=await lW(n(),k);if(S)for(const $ of S)for(const[M,O]of Object.entries($))O&&typeof O=="object"&&O._type==="trackio.markdown"&&E.push({key:M,run:k.name,step:$.step,content:O._value||""})}catch{}D(s,E,!0)}catch(_){console.error("Failed to load alerts:",_),D(i,[],!0)}finally{D(a,!1)}}zt(()=>{n(),r(),f()});function d(_){if(!_)return"";try{return new Date(_).toLocaleString()}catch{return _}}let h=["Level","Run","Title","Text","Step","Time"],p=we(()=>v(c).map(_=>[`${l[_.level]||""} ${_.level}`,_.run||"",_.title,_.text||"",_.step??"",d(_.timestamp)]));var g=jCe(),m=C(g);{var y=_=>{Bu(_,{})},b=_=>{var w=MCe(),A=R(C(w),4),E=C(A);E.textContent=`import trackio +from trackio import AlertLevel + +trackio.init(project="my-project") +trackio.alert("Low validation loss", text="Consider saving a checkpoint.", level=AlertLevel.INFO) +trackio.log({"reports/summary": trackio.Markdown("# My Report\\nResults look good.")})`,I(_,w)},x=_=>{var w=zCe(),A=Bt(w);{var E=$=>{var M=RCe(),O=C(M),P=C(O),T=R(O,2);$t(T,17,()=>v(s),Dt,(F,N)=>{var U=TCe(),j=C(U),W=C(j),Z=R(j,2);ZH(Z,()=>u(v(N).content),!0),ye(()=>me(W,`${v(N).key??""} · ${v(N).run??""} · step ${v(N).step??""}`)),I(F,U)}),ye(()=>me(P,`Reports (${v(s).length??""})`)),I($,M)};he(A,$=>{v(s).length>0&&$(E)})}var k=R(A,2);{var S=$=>{var M=BCe(),O=C(M),P=C(O),T=R(O,2),F=C(T),N=C(F),U=C(N);let j;var W=R(U,2);let Z;var Y=R(W,2);let J;var ve=R(Y,2);let Te;var Fe=R(T,2);{var He=wt=>{var xe=NCe();I(wt,xe)},ut=wt=>{var xe=PCe(),je=C(xe),fe=C(je);$t(fe,21,()=>h,Dt,(B,L)=>{var X=OCe(),G=C(X);ye(()=>me(G,v(L))),I(B,X)});var V=R(je);$t(V,21,()=>v(p),Dt,(B,L)=>{var X=ICe();$t(X,21,()=>v(L),Dt,(G,z)=>{var te=LCe(),Ne=C(te);ye(()=>me(Ne,v(z))),I(G,te)}),I(B,X)}),I(wt,xe)};he(Fe,wt=>{v(c).length===0?wt(He):wt(ut,-1)})}ye(()=>{me(P,`Alerts (${v(i).length??""})`),j=tn(U,1,"pill svelte-iufsej",null,j,{active:v(o)===null}),Z=tn(W,1,"pill svelte-iufsej",null,Z,{active:v(o)==="info"}),J=tn(Y,1,"pill svelte-iufsej",null,J,{active:v(o)==="warn"}),Te=tn(ve,1,"pill svelte-iufsej",null,Te,{active:v(o)==="error"})}),Oe("click",U,()=>D(o,null)),Oe("click",W,()=>D(o,"info")),Oe("click",Y,()=>D(o,"warn")),Oe("click",ve,()=>D(o,"error")),I($,M)};he(k,$=>{v(i).length>0&&$(S)})}I(_,w)};he(m,_=>{v(a)?_(y):v(i).length===0&&v(s).length===0?_(b,1):_(x,-1)})}I(e,g),An()}si(["click"]);var qCe=q('

        No runs in this project

        Runs are created when you call trackio.init() and log at least one step. Example:

        Refresh this page or wait for the dashboard to poll; new runs appear in the table with step counts.

        '),WCe=q('
        '),HCe=q(''),GCe=q('
        '),YCe=q('
        '),VCe=q('
        ActionsRun NameStepsLast Step
        ',1),XCe=q('
        ');function KCe(e,t){En(t,!0);let n=ae(t,"project",3,null),r=ae(t,"runs",19,()=>[]),i=ae(t,"filterText",3,""),s=ae(t,"onRunsChanged",3,null),o=ae(t,"runMutationAllowed",3,!0),a=we(o),l=we(()=>n0(r())),u=re(xt([])),c=re(!1),f=re(-1),d=re(""),h=re(null),p=we(()=>{if(!i()||!i().trim())return v(u);const S=new Set(Cy(v(u).map($=>$.name),i()));return v(u).filter($=>S.has($.name))});async function g(){if(!n()){D(u,[],!0);return}D(c,!0);try{const $=(await JSe(n())).runs||[],O=(await Promise.all($.map(P=>uW(n(),P)))).map((P,T)=>({id:$[T].id??$[T].name,name:$[T].name,numSteps:P.num_logs||0,lastStep:P.last_step||0}));D(u,O,!0)}catch(S){console.error("Failed to load runs:",S)}finally{D(c,!1)}}zt(()=>{n(),g()});async function m(S){if(v(a)&&confirm(`Delete run "${S.name}"? This cannot be undone.`))try{await i3e(n(),S),await g(),s()&&s()()}catch($){console.error("Failed to delete run:",$)}}async function y(S,$){var M,O;v(a)&&(D(f,S,!0),D(d,$,!0),await ns(),(M=v(h))==null||M.focus(),(O=v(h))==null||O.select())}async function b(S){if(!v(a))return;const $=v(d).trim();if(!$||$===S.name){D(f,-1);return}try{await s3e(n(),S,$),D(f,-1),await g(),s()&&s()()}catch(M){console.error("Failed to rename run:",M)}}function x(S,$){S.key==="Enter"&&b($),S.key==="Escape"&&D(f,-1)}var _=XCe(),w=C(_);{var A=S=>{Bu(S,{})},E=S=>{var $=qCe(),M=R(C($),4),O=C(M);O.textContent=`import trackio +trackio.init(project="my-project") +for i in range(10): + trackio.log({"loss": 1 / (i + 1)}) +trackio.finish()`,I(S,$)},k=S=>{var $=VCe(),M=Bt($);{var O=F=>{var N=WCe(),U=C(N),j=C(U);ye(()=>me(j,`${v(p).length??""} of ${v(u).length??""} runs`)),I(F,N)};he(M,F=>{i()&&F(O)})}var P=R(M,2),T=R(C(P));$t(T,21,()=>v(p),Dt,(F,N,U)=>{var j=YCe(),W=C(j),Z=C(W),Y=C(Z),J=R(Y,2),ve=R(W),Te=C(ve);{var Fe=fe=>{var V=HCe();is(V,B=>D(h,B),()=>v(h)),Oe("keydown",V,B=>x(B,v(N))),fn("blur",V,()=>b(v(N))),ph(V,()=>v(d),B=>D(d,B)),I(fe,V)},He=fe=>{var V=GCe(),B=C(V);let L;var X=R(B,2),G=C(X);ye(()=>{L=ll(B,"",L,{background:v(l)[v(N).id]??"#9ca3af"}),me(G,v(N).name)}),Oe("click",X,()=>{y5("selected_run_id",v(N).id),y5("selected_run",v(N).name),yw("run-detail")}),I(fe,V)};he(Te,fe=>{v(f)===U?fe(Fe):fe(He,-1)})}var ut=R(ve),wt=C(ut),xe=R(ut),je=C(xe);ye(()=>{St(Y,"title",v(a)?"Rename":"Sign in with Hugging Face (write access) to rename runs"),Y.disabled=!v(a),St(J,"title",v(a)?"Delete":"Sign in with Hugging Face (write access) to delete runs"),J.disabled=!v(a),me(wt,v(N).numSteps),me(je,v(N).lastStep)}),Oe("click",Y,()=>y(U,v(N).name)),Oe("click",J,()=>m(v(N))),I(F,j)}),I(S,$)};he(w,S=>{v(c)?S(A):v(u).length===0?S(E,1):S(k,-1)})}I(e,_),An()}si(["click","keydown"]);var ZCe=q(`

        Open a run

        Choose a run from the Runs page or follow a run name from the sidebar. This view shows the + project name, log count, last step, metric keys, and any logged config.

        Config passed to trackio.init() appears under Configuration when present.

        `),JCe=q('

        Configuration

         
        ',1),QCe=q('

        Project
        Total Logs
        Last Step
        Metrics
        '),e$e=q('
        ');function t$e(e,t){En(t,!0);let n=ae(t,"project",3,null),r=re(null),i=re(null),s=re(null),o=re(!1);zt(()=>{D(i,Hr("selected_run_id"),!0),D(r,Hr("selected_run"),!0)});async function a(){if(!n()||!v(r)&&!v(i)){D(s,null);return}D(o,!0);try{const h=await uW(n(),v(i)?{id:v(i),name:v(r)}:v(r));D(s,h,!0),h!=null&&h.run&&D(r,h.run,!0)}catch(h){console.error("Failed to load run detail:",h)}finally{D(o,!1)}}zt(()=>{n(),v(r),v(i),a()});var l=e$e(),u=C(l);{var c=h=>{Bu(h,{})},f=h=>{var p=ZCe(),g=R(C(p),4),m=C(g);m.textContent=`import trackio +trackio.init(project="my-project", config={"lr": 1e-3}) +trackio.log({"loss": 0.5}) +trackio.finish()`,I(h,p)},d=h=>{var p=QCe(),g=C(p),m=C(g),y=R(g,2),b=C(y),x=R(C(b),2),_=C(x),w=R(b,2),A=R(C(w),2),E=C(A),k=R(w,2),S=R(C(k),2),$=C(S),M=R(k,2),O=R(C(M),2),P=C(O),T=R(y,2);{var F=N=>{var U=JCe(),j=R(Bt(U),2),W=C(j);ye(Z=>me(W,Z),[()=>JSON.stringify(v(s).config,null,2)]),I(N,U)};he(T,N=>{v(s).config&&N(F)})}ye(N=>{me(m,v(s).run),me(_,v(s).project),me(E,v(s).num_logs),me($,v(s).last_step??"N/A"),me(P,N)},[()=>v(s).metrics?v(s).metrics.join(", "):"None"]),I(h,p)};he(u,h=>{v(o)?h(c):v(s)?h(d,-1):h(f,1)})}I(e,l),An()}var n$e=q('

        No project files yet

        Files are stored at the project level (not tied to a single run). After trackio.init(), copy artifacts into the project with trackio.save():

        Paths can be a single file or a glob. Saved files will list here for download.

        '),r$e=q(' '),i$e=q('
        Loading preview...
        '),s$e=q('
         
        '),o$e=q('
        Preview not available. Download the file instead.
        '),a$e=q('
        '),l$e=q('
        '),u$e=q('

        Files

        Showing files saved across all runs in this project.

        ',1),c$e=q('
        ');function f$e(e,t){En(t,!0);let n=ae(t,"project",3,null),r=re(xt([])),i=re(!1),s=re(null),o=re(null),a=re(!1);const l=new Set(["txt","md","json","yml","yaml","toml","ini","cfg","csv","tsv","xml","html","css","js","py","sh","log","conf","env","gitignore","dockerfile"]);function u(b){const x=b.split(".").pop().toLowerCase();return l.has(x)}function c(b){return b==null?"":b<1024?`${b} B`:b<1024*1024?`${(b/1024).toFixed(1)} KB`:`${(b/(1024*1024)).toFixed(1)} MB`}async function f(b){if(v(s)===b.name){D(s,null),D(o,null);return}if(D(s,b.name,!0),!u(b.name)){D(o,null);return}D(a,!0);try{const x=Z_(b.path),_=await fetch(x);if(!_.ok)throw new Error("fetch failed");const w=await _.text();D(o,w.length>5e4?w.slice(0,5e4)+` + +… (truncated)`:w,!0)}catch{D(o,null)}finally{D(a,!1)}}async function d(){if(!n()){D(r,[],!0);return}D(i,!0);try{D(r,await t3e(n()),!0)}catch{D(r,[],!0)}finally{D(i,!1)}}zt(()=>{n(),d()});var h=c$e(),p=C(h);{var g=b=>{Bu(b,{})},m=b=>{var x=n$e(),_=R(C(x),4),w=C(_);w.textContent=`import trackio + +trackio.init(project="my-project") +trackio.save("config.yaml") +trackio.save("checkpoints/*.pt")`,I(b,x)},y=b=>{var x=u$e(),_=R(Bt(x),4);$t(_,21,()=>v(r),Dt,(w,A)=>{var E=l$e();let k;var S=C(E),$=C(S),M=C($),O=C(M),P=R(M),T=R($,2),F=C(T);{var N=Z=>{var Y=r$e(),J=C(Y);ye(ve=>me(J,ve),[()=>c(v(A).size)]),I(Z,Y)};he(F,Z=>{v(A).size!=null&&Z(N)})}var U=R(F,2),j=R(S,2);{var W=Z=>{var Y=a$e(),J=C(Y);{var ve=He=>{var ut=i$e();I(He,ut)},Te=He=>{var ut=s$e(),wt=C(ut);ye(()=>me(wt,v(o))),I(He,ut)},Fe=He=>{var ut=o$e(),wt=R(C(ut));ye(xe=>St(wt,"href",xe),[()=>Z_(v(A).path)]),I(He,ut)};he(J,He=>{v(a)?He(ve):v(o)!=null?He(Te,1):He(Fe,-1)})}I(Z,Y)};he(j,Z=>{v(s)===v(A).name&&Z(W)})}ye((Z,Y)=>{k=tn(E,1,"file-item svelte-1xvfk9n",null,k,{expanded:v(s)===v(A).name}),me(O,Z),me(P,` ${v(A).name??""}`),St(U,"href",Y)},[()=>u(v(A).name)?"📄":"📦",()=>Z_(v(A).path)]),Oe("click",$,()=>f(v(A))),I(w,E)}),I(b,x)};he(p,b=>{v(i)?b(g):v(r).length===0?b(m,1):b(y,-1)})}I(e,h),An()}si(["click"]);var d$e=Ei(''),h$e=Ei(''),p$e=Ei(''),g$e=q(""),m$e=q('Connected to — remote commands include --space automatically.',1),v$e=q(""),y$e=q('
        '),b$e=Ei(''),x$e=Ei(''),_$e=q('
        '),w$e=q(""),E$e=Ei(''),A$e=Ei(''),k$e=Ei(''),S$e=Ei(''),C$e=q('

        Settings

        Appearance

        Choose how the dashboard looks to you.

        CLI Reference

        Common Trackio CLI commands.

        Agent Skills

        Install Trackio as a skill in your AI coding agent to query experiments with natural language.

        Run in Terminal to Install:
        Example prompt

        ');function $$e(e,t){En(t,!0);let n=ae(t,"spaceId",3,null),r=ae(t,"selectedProject",3,null),i=ae(t,"projects",19,()=>[]),s=re(xt(IF())),o=re(null),a=re(null),l=re("claude"),u=re(!1),c=re(!1);const f=[{id:"claude",label:"Claude Code",flag:"--claude"},{id:"codex",label:"Codex",flag:"--codex"},{id:"cursor",label:"Cursor",flag:"--cursor"},{id:"opencode",label:"OpenCode",flag:"--opencode"}];let d=we(()=>{var z;return`trackio skills add ${(z=f.find(te=>te.id===v(l)))==null?void 0:z.flag}`}),h=we(()=>{const z=v(a)||"";return{claude:`Use the trackio skill to look at the runs in project "${z}" and find at which step the loss started diverging. Summarize what happened.`,codex:`Use the trackio skill to pull the latest metrics for project "${z}" and tell me which run has the best final eval accuracy.`,cursor:`Use the trackio skill to compare the last two runs in project "${z}" and explain why the learning rate change affected convergence.`,opencode:`Use the trackio skill to get a summary of project "${z}" and flag any runs where the loss spiked unexpectedly.`}[v(l)]});zt(()=>{if(i(),r(),!(v(a)&&i().includes(v(a)))){if(r()&&i().includes(r())){D(a,r());return}D(a,i()[0]??r()??null,!0)}});function p(z){D(s,z,!0),fke(z)}function g(){return n()?` --space ${n()}`:""}let m=we(()=>{const z=g(),te=v(a)||"";return[{title:"Launch dashboard",cmd:"trackio show"},{title:"Launch dashboard (project)",cmd:`trackio show --project "${te}"`},{title:"List projects",cmd:`trackio${z} list projects`},{title:"List runs",cmd:`trackio${z} list runs --project "${te}"`},{title:"List metrics",cmd:`trackio${z} list metrics --project "${te}" --run `},{title:"Project summary",cmd:`trackio${z} get project --project "${te}"`},{title:"Run summary",cmd:`trackio${z} get run --project "${te}" --run `},{title:"Sync to HF Space",cmd:`trackio sync${z} --project "${te}"`},{title:"Check sync status",cmd:"trackio status"}]});async function y(z,te){try{await navigator.clipboard.writeText(z),D(o,te,!0),setTimeout(()=>{v(o)===te&&D(o,null)},1500)}catch{}}async function b(z,te){try{await navigator.clipboard.writeText(z),te==="agent"?(D(u,!0),setTimeout(()=>{D(u,!1)},1500)):(D(c,!0),setTimeout(()=>{D(c,!1)},1500))}catch{}}var x=C$e(),_=R(C(x),2),w=C(_),A=C(w),E=R(C(A),4);$t(E,20,()=>[{value:"system",label:"System"},{value:"light",label:"Light"},{value:"dark",label:"Dark"}],Dt,(z,te)=>{var Ne=g$e();let H;var ee=C(Ne);{var ne=_e=>{var De=d$e();I(_e,De)},be=_e=>{var De=h$e();I(_e,De)},K=_e=>{var De=p$e();I(_e,De)};he(ee,_e=>{te.value==="system"?_e(ne):te.value==="light"?_e(be,1):_e(K,-1)})}var ge=R(ee);ye(()=>{H=tn(Ne,1,"theme-option svelte-1ozf5k3",null,H,{selected:v(s)===te.value}),me(ge,` ${te.label??""}`)}),Oe("click",Ne,()=>p(te.value)),I(z,Ne)});var k=R(A,2),S=R(C(k),2),$=R(C(S));{var M=z=>{var te=m$e(),Ne=R(Bt(te)),H=C(Ne);ye(()=>me(H,n())),I(z,te)};he($,z=>{n()&&z(M)})}var O=R(S,2);{var P=z=>{var te=y$e(),Ne=R(C(te),2);$t(Ne,21,i,Dt,(H,ee)=>{var ne=v$e(),be=C(ne),K={};ye(()=>{me(be,v(ee)),K!==(K=v(ee))&&(ne.value=(ne.__value=v(ee))??"")}),I(H,ne)}),L1(Ne,()=>v(a),H=>D(a,H)),I(z,te)};he(O,z=>{i().length>0&&z(P)})}var T=R(O,2);$t(T,21,()=>v(m),Dt,(z,te,Ne)=>{var H=_$e(),ee=C(H),ne=C(ee),be=R(ee,2),K=C(be),ge=C(K),_e=R(K,2);let De;var ct=C(_e);{var ze=lt=>{var yt=b$e();I(lt,yt)},Xe=lt=>{var yt=x$e();I(lt,yt)};he(ct,lt=>{v(o)===Ne?lt(ze):lt(Xe,-1)})}ye(()=>{me(ne,v(te).title),me(ge,v(te).cmd),De=tn(_e,1,"copy-btn svelte-1ozf5k3",null,De,{copied:v(o)===Ne})}),Oe("click",_e,()=>y(v(te).cmd,Ne)),I(z,H)});var F=R(w,2),N=C(F),U=R(C(N),4);$t(U,21,()=>f,Dt,(z,te)=>{var Ne=w$e();let H;var ee=C(Ne);ye(()=>{H=tn(Ne,1,"agent-tab svelte-1ozf5k3",null,H,{active:v(l)===v(te).id}),me(ee,v(te).label)}),Oe("click",Ne,()=>{D(l,v(te).id,!0)}),I(z,Ne)});var j=R(U,2),W=C(j),Z=R(C(W),2),Y=C(Z),J=C(Y),ve=R(Y,2);let Te;var Fe=C(ve);{var He=z=>{var te=E$e();I(z,te)},ut=z=>{var te=A$e();I(z,te)};he(Fe,z=>{v(u)?z(He):z(ut,-1)})}var wt=R(W,2),xe=C(wt),je=R(C(xe),2);let fe;var V=C(je);{var B=z=>{var te=k$e();I(z,te)},L=z=>{var te=S$e();I(z,te)};he(V,z=>{v(c)?z(B):z(L,-1)})}var X=R(xe,2),G=C(X);ye(()=>{me(J,v(d)),Te=tn(ve,1,"copy-btn svelte-1ozf5k3",null,Te,{copied:v(u)}),fe=tn(je,1,"copy-btn svelte-1ozf5k3",null,fe,{copied:v(c)}),me(G,v(h))}),Oe("click",ve,()=>b(v(d),"agent")),Oe("click",je,()=>b(v(h),"example")),I(e,x),An()}si(["click"]);var F$e=q('
        ');function D$e(e,t){En(t,!0);function n(se){if(!se)return"";const ke=se.trim(),At=ke.split(",").map(Pe=>Pe.trim()).filter(Boolean);if(At.length===0)return"";const Ft=Pe=>/^[\w./-]+$/.test(Pe);return At.every(Ft)?At.map(Pe=>`^${Pe.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}$`).join("|"):ke}function r(){return Hr("x_axis")||Hr("x-axis")}dke();let i=re(xt(OF()));uke(se=>{D(i,se,!0)});let s=re("metrics"),o=re(xt([])),a=re(null),l=re(xt([])),u=re(xt([])),c=re(10),f=re("step"),d=re(!1),h=re(!1),p=re(""),g=re(!0),m=re(!0),y=re(""),b=re(xt([])),x=re(null),_=re(!1),w=re(!0),A=re(!1),E=re(!1),k=re(0),S=re(xt([])),$=re(null),M=re(xt({spaces:!1,allowed:!0,auth:"local"})),O=re(null),P=re(!1),T=re(xt({light:"/static/trackio/trackio_logo_type_light_transparent.png",dark:"/static/trackio/trackio_logo_type_dark_transparent.png"})),F=re(xt([])),N=re(250),U=re(null),j=re(null),W=re(xt([])),Z=re(xt([])),Y=re(xt({})),J=0,ve=0,Te=!1,Fe=!1;const He=15e3,ut=new Set(["system","traces","media","reports","files"]),wt=["metrics","system","traces","media","reports","runs","files"];let xe=re(xt({})),je=re(null);function fe(se){return(se==null?void 0:se.id)??(se==null?void 0:se.name)}function V(se){return se==="step"||se==="time"||v(b).includes(se)}let B=we(()=>v(l).filter(se=>v(u).includes(fe(se))));function L(se){Fe=!0,D(s,se,!0),yw(se)}function X(){return(window.location.pathname.replace(/\/+$/,"")||"/")==="/"}function G(){return Hr("project")||Hr("selected_project")}function z(){const se=G();se&&v(o).includes(se)&&D(a,se,!0)}async function te(){try{const se=await GSe();if(D(o,se||[],!0),v(o).length>0&&!v(a)){const ke=G();D(a,ke&&v(o).includes(ke)?ke:v(o)[0],!0)}z()}catch(se){console.error("Failed to load projects:",se)}}async function Ne(){await H(),await _e()}async function H(){const se=v(a);if(!se){D(l,[],!0),D(u,[],!0),D(W,[],!0),D(Z,[],!0),D(xe,{},!0),D(je,null);return}se!==v(je)&&D(xe,{},!0);try{const[ke,At]=await Promise.all([YSe(se),VSe(se).catch(()=>null)]);if(v(a)!==se)return;const Ft=[...ke||[]].reverse();if(JSON.stringify(v(l))!==JSON.stringify(Ft)){const Pe=v(u),Je=v(l).map(fe);D(l,Ft,!0),D(u,$G(Pe,Ft.map(fe),Je),!0)}At!=null&&(D(xe,At,!0),D(je,se,!0))}catch(ke){console.error("Failed to load runs:",ke)}}async function ee(){if(v(a))try{const se=await cW(v(a),null,null,null);D(S,(se||[]).slice(-20),!0)}catch{}}function ne(){return{metrics:!1,system:!1,traces:!1,media:!1,reports:!1,runs:!1,files:!1}}async function be({force:se=!1}={}){const ke=Date.now();if(!se&&ke-ve0};if(D(Y,Pe,!0),Te&&!Fe&&X()){const Je=wt.find(Qe=>Pe[Qe]);Je&&Je!==v(s)&&(D(s,Je,!0),yw(Je)),Fe=!0}}catch(Ft){if(At!==J)return;console.error("Failed to load tab availability:",Ft),D(Y,ne(),!0)}}function K(){v($)&&clearInterval(v($)),D($,setInterval(async()=>{v(g)&&(GF()||HF()||(await te(),await H(),await ee(),await be()))},qSe()),!0)}function ge(){const se=new URLSearchParams(window.location.search);let ke=!1;const At=se.get("write_token");At&&(document.cookie=`trackio_write_token=${encodeURIComponent(At)}; path=/; max-age=604800; SameSite=Lax`,se.delete("write_token"),ke=!0);const Ft=se.get("oauth_session");if(Ft&&(sessionStorage.setItem("trackio_oauth_session",Ft),se.delete("oauth_session"),ke=!0),ke){const Pe=se.toString(),Je=window.location.pathname+(Pe?`?${Pe}`:"");window.history.replaceState({},"",Je)}}async function _e(){try{const se=await r3e();D(M,{spaces:!!se.spaces,allowed:!!se.allowed,auth:se.auth??"none"},!0)}catch{D(M,{spaces:!1,allowed:!0,auth:"local"},!0)}}function De(){v(O)&&clearInterval(v(O)),D(O,setInterval(()=>{_e()},12e4),!0)}zt(()=>{v(a),D(W,[],!0),D(Z,[],!0),H()}),zt(()=>{v(k),D(E,Hr("navbar")==="hidden")}),hh(()=>{const se=Hr("sidebar");se==="hidden"?(D(A,!0),D(w,!1)):se==="collapsed"?(D(A,!1),D(w,!1)):D(A,!1);const ke=Hr("smoothing");if(ke){const Je=parseInt(ke,10);Number.isNaN(Je)||D(c,Je,!0)}const At=r();At&&At.trim()?(D(x,At.trim(),!0),D(f,v(x),!0)):D(_,!0);const Ft=Hr("metric_filter"),Pe=Hr("metrics");return Ft?D(p,Ft,!0):Pe&&D(p,n(Pe),!0),Hr("accordion")==="hidden"&&D(m,!1),Te=X(),D(s,v5(),!0),window.addEventListener("popstate",()=>{D(s,v5(),!0),tR(k),z()}),ge(),(async()=>{const Je=await Xn();Je?(D(g,!1),D(M,{spaces:!1,allowed:!1,auth:"static"},!0),D(U,await a3e(),!0)):(_e(),De(),window.addEventListener("focus",_e));try{try{const Qe=await e3e();Qe&&(Qe.logo_urls&&D(T,Qe.logo_urls,!0),Qe.color_palette&&CG(Qe.color_palette),Qe.plot_order&&D(F,Qe.plot_order,!0),Qe.table_truncate_length&&D(N,Qe.table_truncate_length,!0),Qe.media_dir&&o3e(Qe.media_dir),Qe.space_id&&D(j,Qe.space_id,!0))}catch{}await te(),await H(),await ee(),await be({force:!0})}catch(Qe){console.error("Failed to load projects:",Qe)}finally{D(P,!0)}Je||K()})(),()=>{v($)&&clearInterval(v($)),v(O)&&clearInterval(v(O)),window.removeEventListener("focus",_e)}});let ct=we(()=>{v(k);const se=G();return!!(se&&v(o).includes(se))});zt(()=>{v(o),v(k),v(ct)&&z()}),zt(()=>{v(a),v(l),v(P)&&be({force:!0})}),zt(()=>{v(_)||!v(x)||(V(v(x))?(D(f,v(x),!0),D(_,!0)):v(b).length>0&&(D(f,"step"),D(_,!0)))});let ze=re(!1);zt(()=>{if(v(ze)||!v(P)||!v(a))return;const se=Hr("run_ids"),ke=Hr("runs");if(!se&&!ke){D(ze,!0);return}if(!v(l).length){D(ze,!0);return}let At;if(se){const Ft=se.split(",").map(Je=>Je.trim()).filter(Boolean),Pe=new Set(v(l).map(Je=>fe(Je)));At=Ft.filter(Je=>Pe.has(Je))}else{const Ft=ke.split(",").map(Je=>Je.trim()).filter(Boolean),Pe=new Set(Ft);At=v(l).filter(Je=>Pe.has(Je.name)).map(Je=>fe(Je))}At.length&&D(u,At,!0),D(ze,!0)});let Xe=we(()=>v(s)==="metrics"||v(s)==="traces"||v(s)==="system"||v(s)==="media"||v(s)==="reports"||v(s)==="runs"||v(s)==="run-detail"||v(s)==="files"),lt=we(()=>v(s)==="runs"||v(s)==="files"?"compact":"full");var yt=F$e(),pt=C(yt);{var rt=se=>{cY(se,{get variant(){return v(lt)},get currentPage(){return v(s)},get spacesMode(){return v(M).spaces},get runMutationAllowed(){return v(M).allowed},get mutationAuth(){return v(M).auth},get readOnlySource(){return v(U)},get projects(){return v(o)},get projectLocked(){return v(ct)},get runs(){return v(l)},get runConfigs(){return v(xe)},get metricColumns(){return v(b)},get availableSystemDevices(){return v(W)},get spaceId(){return v(j)},get logoUrls(){return v(T)},get darkMode(){return v(i)},get open(){return v(w)},set open(ke){D(w,ke,!0)},get selectedProject(){return v(a)},set selectedProject(ke){D(a,ke,!0)},get selectedRuns(){return v(u)},set selectedRuns(ke){D(u,ke,!0)},get smoothing(){return v(c)},set smoothing(ke){D(c,ke,!0)},get xAxis(){return v(f)},set xAxis(ke){D(f,ke,!0)},get logScaleX(){return v(d)},set logScaleX(ke){D(d,ke,!0)},get logScaleY(){return v(h)},set logScaleY(ke){D(h,ke,!0)},get metricFilter(){return v(p)},set metricFilter(ke){D(p,ke,!0)},get realtimeEnabled(){return v(g)},set realtimeEnabled(ke){D(g,ke,!0)},get showHeaders(){return v(m)},set showHeaders(ke){D(m,ke,!0)},get filterText(){return v(y)},set filterText(ke){D(y,ke,!0)},get selectedSystemDevices(){return v(Z)},set selectedSystemDevices(ke){D(Z,ke,!0)}})};he(pt,se=>{v(Xe)&&!v(A)&&se(rt)})}var Ve=R(pt,2),qe=C(Ve);{var Q=se=>{uG(se,{get currentPage(){return v(s)},get tabAvailability(){return v(Y)},get optionalEmptyTabs(){return ut},onNavigate:L})};he(qe,se=>{v(E)||se(Q)})}var pe=R(qe,2),Ye=C(pe);{var gt=se=>{g3e(se,{get project(){return v(a)},get selectedRuns(){return v(B)},get allRuns(){return v(l)},get smoothing(){return v(c)},get xAxis(){return v(f)},get logScaleX(){return v(d)},get logScaleY(){return v(h)},get metricFilter(){return v(p)},get showHeaders(){return v(m)},get appBootstrapReady(){return v(P)},get plotOrder(){return v(F)},get realtimeEnabled(){return v(g)},get metricColumns(){return v(b)},set metricColumns(ke){D(b,ke,!0)}})},Ke=se=>{I3e(se,{get project(){return v(a)},get selectedRuns(){return v(B)}})},Ze=se=>{G3e(se,{get project(){return v(a)},get selectedRuns(){return v(B)},get allRuns(){return v(l)},get smoothing(){return v(c)},get appBootstrapReady(){return v(P)},get realtimeEnabled(){return v(g)},get availableDevices(){return v(W)},set availableDevices(ke){D(W,ke,!0)},get selectedDevices(){return v(Z)},set selectedDevices(ke){D(Z,ke,!0)}})},We=se=>{DCe(se,{get project(){return v(a)},get selectedRuns(){return v(B)},get allRuns(){return v(l)},get tableTruncateLength(){return v(N)}})},it=se=>{UCe(se,{get project(){return v(a)},get selectedRuns(){return v(B)}})},bt=se=>{KCe(se,{get project(){return v(a)},get runs(){return v(l)},get filterText(){return v(y)},onRunsChanged:Ne,get runMutationAllowed(){return v(M).allowed}})},Et=se=>{t$e(se,{get project(){return v(a)}})},Ge=se=>{f$e(se,{get project(){return v(a)}})},dt=se=>{$$e(se,{get spaceId(){return v(j)},get selectedProject(){return v(a)},get projects(){return v(o)}})};he(Ye,se=>{v(s)==="metrics"?se(gt):v(s)==="traces"?se(Ke,1):v(s)==="system"?se(Ze,2):v(s)==="media"?se(We,3):v(s)==="reports"?se(it,4):v(s)==="runs"?se(bt,5):v(s)==="run-detail"?se(Et,6):v(s)==="files"?se(Ge,7):v(s)==="settings"&&se(dt,8)})}var mt=R(Ve,2);mY(mt,{get alerts(){return v(S)}}),I(e,yt),An()}WH(D$e,{target:document.getElementById("app")}); diff --git a/trackio/frontend/dist/assets/index-DWKQjbgJ.css b/trackio/frontend/dist/assets/index-DWKQjbgJ.css new file mode 100644 index 0000000000000000000000000000000000000000..8eb59bc7872d5c9a065e1fae669cab29f2101958 --- /dev/null +++ b/trackio/frontend/dist/assets/index-DWKQjbgJ.css @@ -0,0 +1 @@ +:root{--primary-50: #fff7ed;--primary-100: #ffedd5;--primary-200: #fed7aa;--primary-300: #fdba74;--primary-400: #fb923c;--primary-500: #f97316;--primary-600: #ea580c;--primary-700: #c2410c;--primary-800: #9a3412;--primary-900: #7c2d12;--primary-950: #6c2e12;--secondary-50: #eff6ff;--secondary-100: #dbeafe;--secondary-200: #bfdbfe;--secondary-300: #93c5fd;--secondary-400: #60a5fa;--secondary-500: #3b82f6;--secondary-600: #2563eb;--secondary-700: #1d4ed8;--secondary-800: #1e40af;--secondary-900: #1e3a8a;--secondary-950: #1d3660;--neutral-50: #f9fafb;--neutral-100: #f3f4f6;--neutral-200: #e5e7eb;--neutral-300: #d1d5db;--neutral-400: #9ca3af;--neutral-500: #6b7280;--neutral-600: #4b5563;--neutral-700: #374151;--neutral-800: #1f2937;--neutral-900: #111827;--neutral-950: #0b0f19;--size-0-5: 2px;--size-1: 4px;--size-2: 8px;--size-3: 12px;--size-4: 16px;--size-5: 20px;--size-6: 24px;--size-8: 32px;--size-14: 56px;--size-16: 64px;--size-28: 112px;--size-full: 100%;--spacing-xxs: 1px;--spacing-xs: 2px;--spacing-sm: 4px;--spacing-md: 6px;--spacing-lg: 8px;--spacing-xl: 10px;--spacing-xxl: 16px;--radius-xxs: 1px;--radius-xs: 2px;--radius-sm: 3px;--radius-md: 4px;--radius-lg: 5px;--radius-xl: 8px;--radius-xxl: 12px;--text-xxs: 9px;--text-xs: 10px;--text-sm: 12px;--text-md: 14px;--text-lg: 16px;--text-xl: 22px;--text-xxl: 26px;--line-sm: 1.4;--background-fill-primary: white;--background-fill-secondary: var(--neutral-50);--body-text-color: var(--neutral-900);--body-text-color-subdued: var(--neutral-600);--border-color-primary: var(--neutral-200);--color-accent: var(--primary-500);--color-accent-soft: var(--primary-50);--shadow-drop: rgba(0, 0, 0, .05) 0px 1px 2px 0px;--shadow-drop-lg: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--shadow-inset: rgba(0, 0, 0, .05) 0px 2px 4px 0px inset;--shadow-spread: 3px;--block-title-text-color: var(--neutral-500);--block-title-text-size: var(--text-md);--block-title-text-weight: 400;--block-info-text-color: var(--body-text-color-subdued);--block-info-text-size: var(--text-sm);--input-background-fill: white;--input-background-fill-focus: var(--primary-500);--input-border-color: var(--border-color-primary);--input-border-color-focus: var(--primary-300);--input-border-width: 1px;--input-padding: var(--spacing-xl);--input-placeholder-color: var(--neutral-400);--input-radius: var(--radius-lg);--input-shadow: 0 0 0 var(--shadow-spread) transparent, var(--shadow-inset);--input-shadow-focus: 0 0 0 var(--shadow-spread) var(--primary-50), var(--shadow-inset);--input-text-size: var(--text-md);--checkbox-background-color: var(--background-fill-primary);--checkbox-background-color-focus: var(--checkbox-background-color);--checkbox-background-color-hover: var(--checkbox-background-color);--checkbox-background-color-selected: var(--primary-600);--checkbox-border-color: var(--neutral-300);--checkbox-border-color-focus: var(--primary-500);--checkbox-border-color-hover: var(--neutral-300);--checkbox-border-color-selected: var(--primary-600);--checkbox-border-radius: var(--radius-sm);--checkbox-border-width: var(--input-border-width);--checkbox-label-gap: var(--spacing-lg);--checkbox-label-padding: var(--spacing-md) calc(2 * var(--spacing-md));--checkbox-label-text-size: var(--text-md);--checkbox-shadow: var(--input-shadow);--checkbox-check: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");--slider-color: var(--primary-500);--container-radius: var(--radius-lg);--layer-top: 9999}.navbar.svelte-d8j1hi{display:flex;align-items:stretch;border-bottom:1px solid var(--border-color-primary, #e5e7eb);background:var(--background-fill-primary, white);padding:0;flex-shrink:0;min-height:44px}.nav-spacer.svelte-d8j1hi{flex:1 1 0;min-width:0}.nav-tabs.svelte-d8j1hi{display:flex;gap:0;flex-shrink:0;padding-right:8px}.nav-link.svelte-d8j1hi{padding:10px 16px;border:none;background:none;color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-md, 14px);cursor:pointer;white-space:nowrap;border-bottom:2px solid transparent;transition:color .15s;font-weight:400}.nav-link.empty.svelte-d8j1hi:not(.active){color:var(--body-text-color-subdued, #9ca3af);opacity:.48}.nav-link.svelte-d8j1hi:hover{color:var(--body-text-color, #1f2937);opacity:1}.nav-link.active.svelte-d8j1hi{color:var(--body-text-color, #1f2937);border-bottom-color:var(--body-text-color, #1f2937);font-weight:500}.settings-btn.svelte-d8j1hi{display:flex;align-items:center;gap:6px}.settings-btn.svelte-d8j1hi svg:where(.svelte-d8j1hi){flex-shrink:0}.checkbox-group.svelte-17gmtkf{display:flex;flex-direction:column}.checkbox-item.svelte-17gmtkf{display:flex;align-items:center;gap:8px;padding:3px 0;cursor:pointer;font-size:13px}.checkbox-item.svelte-17gmtkf input[type=checkbox]:where(.svelte-17gmtkf){-moz-appearance:none;appearance:none;-webkit-appearance:none;width:16px;height:16px;margin:0;border:1px solid var(--checkbox-border-color, #d1d5db);border-radius:var(--checkbox-border-radius, 4px);background-color:var(--checkbox-background-color, white);box-shadow:var(--checkbox-shadow);cursor:pointer;flex-shrink:0;transition:background-color .15s,border-color .15s}.checkbox-item.svelte-17gmtkf input[type=checkbox]:where(.svelte-17gmtkf):checked{background-image:var(--checkbox-check);background-color:var(--checkbox-background-color-selected, #f97316);border-color:var(--checkbox-border-color-selected, #f97316)}.checkbox-item.svelte-17gmtkf input[type=checkbox]:where(.svelte-17gmtkf):hover{border-color:var(--checkbox-border-color-hover, #d1d5db)}.color-dot.svelte-17gmtkf{width:10px;height:10px;border-radius:50%;flex-shrink:0}.run-name.svelte-17gmtkf{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--body-text-color, #1f2937)}.dropdown-container.svelte-kgylqb{width:100%;margin-bottom:4px}.label.svelte-kgylqb{display:block;font-size:13px;font-weight:500;color:var(--body-text-color-subdued, #6b7280);margin-bottom:6px}.info.svelte-kgylqb{display:block;font-size:12px;color:var(--body-text-color-subdued, #9ca3af);margin-bottom:4px}.wrap.svelte-kgylqb{position:relative;border-radius:var(--input-radius, 8px);background:var(--input-background-fill, white);border:1px solid var(--border-color-primary, #e5e7eb);transition:border-color .15s,box-shadow .15s}.wrap.focused.svelte-kgylqb{border-color:var(--input-border-color-focus, #fdba74);box-shadow:0 0 0 2px var(--primary-50, #fff7ed)}.wrap-inner.svelte-kgylqb{display:flex;position:relative;align-items:center;padding:0 10px}.secondary-wrap.svelte-kgylqb{display:flex;flex:1;align-items:center}input.svelte-kgylqb{margin:0;outline:none;border:none;background:inherit;width:100%;color:var(--body-text-color, #1f2937);font-size:13px;font-family:inherit;padding:7px 0}input.svelte-kgylqb::placeholder{color:var(--input-placeholder-color, #9ca3af)}input[readonly].svelte-kgylqb{cursor:pointer}.icon-wrap.svelte-kgylqb{color:var(--body-text-color-subdued, #9ca3af);width:16px;flex-shrink:0;pointer-events:none}.options.svelte-kgylqb{position:fixed;z-index:var(--layer-top, 9999);margin:0;padding:4px 0;box-shadow:0 4px 12px #0000001f;border-radius:var(--input-radius, 8px);border:1px solid var(--border-color-primary, #e5e7eb);background:var(--background-fill-primary, white);min-width:fit-content;overflow:auto;color:var(--body-text-color, #1f2937);list-style:none}.item.svelte-kgylqb{display:flex;cursor:pointer;padding:6px 10px;font-size:13px;word-break:break-word}.item.svelte-kgylqb:hover,.item.active.svelte-kgylqb{background:var(--background-fill-secondary, #f9fafb)}.item.selected.svelte-kgylqb{font-weight:500}.check-mark.svelte-kgylqb{padding-right:6px;min-width:16px;font-size:12px}.check-mark.hide.svelte-kgylqb{visibility:hidden}.checkbox-container.svelte-oj84db{display:flex;align-items:center;gap:8px;cursor:pointer;padding:3px 0}.label-text.svelte-oj84db{color:var(--body-text-color, #1f2937);font-size:13px;line-height:1.4}input[type=checkbox].svelte-oj84db{--ring-color: transparent;position:relative;-moz-appearance:none;appearance:none;-webkit-appearance:none;width:16px;height:16px;box-shadow:var(--checkbox-shadow);border:1px solid var(--checkbox-border-color, #d1d5db);border-radius:var(--checkbox-border-radius, 4px);background-color:var(--checkbox-background-color, white);flex-shrink:0;cursor:pointer;transition:background-color .15s,border-color .15s}input[type=checkbox].svelte-oj84db:checked,input[type=checkbox].svelte-oj84db:checked:hover,input[type=checkbox].svelte-oj84db:checked:focus{background-image:var(--checkbox-check);background-color:var(--checkbox-background-color-selected, #f97316);border-color:var(--checkbox-border-color-selected, #f97316)}input[type=checkbox].svelte-oj84db:hover{border-color:var(--checkbox-border-color-hover, #d1d5db);background-color:var(--checkbox-background-color-hover, white)}input[type=checkbox].svelte-oj84db:focus{border-color:var(--checkbox-border-color-focus, #f97316);background-color:var(--checkbox-background-color-focus, white);outline:none}.slider-wrap.svelte-wei6ev{display:flex;flex-direction:column;width:100%}.head.svelte-wei6ev{margin-bottom:4px;display:flex;justify-content:space-between;align-items:center;width:100%}.label.svelte-wei6ev{flex:1;font-size:13px;font-weight:500;color:var(--body-text-color-subdued, #6b7280)}.info.svelte-wei6ev{display:block;font-size:12px;color:var(--body-text-color-subdued, #9ca3af);margin-bottom:4px}.slider-input-container.svelte-wei6ev{display:flex;align-items:center;gap:6px}input[type=range].svelte-wei6ev{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;cursor:pointer;outline:none;border-radius:var(--radius-xl, 12px);min-width:var(--size-28, 112px);background:transparent}input[type=range].svelte-wei6ev::-webkit-slider-runnable-track{height:6px;border-radius:var(--radius-xl, 12px);background:linear-gradient(to right,var(--slider-color, #f97316) var(--range_progress, 50%),var(--neutral-200, #e5e7eb) var(--range_progress, 50%))}input[type=range].svelte-wei6ev::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:16px;width:16px;background-color:var(--slider-color, #f97316);border:2px solid var(--background-fill-primary, white);border-radius:50%;margin-top:-5px;box-shadow:0 0 0 1px var(--border-color-primary, rgba(0, 0, 0, .08)),0 1px 3px #0003}input[type=range].svelte-wei6ev::-moz-range-track{height:6px;background:var(--neutral-200, #e5e7eb);border-radius:var(--radius-xl, 12px)}input[type=range].svelte-wei6ev::-moz-range-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:16px;width:16px;background-color:var(--slider-color, #f97316);border:2px solid var(--background-fill-primary, white);border-radius:50%;box-shadow:0 0 0 1px var(--border-color-primary, rgba(0, 0, 0, .08)),0 1px 3px #0003}input[type=range].svelte-wei6ev::-moz-range-progress{height:6px;background-color:var(--slider-color, #f97316);border-radius:var(--radius-xl, 12px)}.bound.svelte-wei6ev{font-size:11px;color:var(--body-text-color-subdued, #9ca3af);min-width:12px;text-align:center}.textbox-container.svelte-6yncpg{width:100%}.label.svelte-6yncpg{display:block;font-size:13px;font-weight:500;color:var(--body-text-color-subdued, #6b7280);margin-bottom:6px}.info.svelte-6yncpg{display:block;font-size:12px;color:var(--body-text-color-subdued, #9ca3af);margin-bottom:4px}.input-wrap.svelte-6yncpg{border-radius:var(--input-radius, 8px);background:var(--input-background-fill, white);border:1px solid var(--border-color-primary, #e5e7eb);transition:border-color .15s,box-shadow .15s}.input-wrap.svelte-6yncpg:focus-within{border-color:var(--input-border-color-focus, #fdba74);box-shadow:0 0 0 2px var(--primary-50, #fff7ed)}input.svelte-6yncpg{width:100%;padding:7px 10px;outline:none;border:none;background:transparent;color:var(--body-text-color, #1f2937);font-size:13px;font-family:inherit;border-radius:var(--input-radius, 8px)}input.svelte-6yncpg::placeholder{color:var(--input-placeholder-color, #9ca3af)}.sidebar.svelte-181dlmc{width:290px;min-width:290px;background:var(--background-fill-primary, white);border-right:1px solid var(--border-color-primary, #e5e7eb);display:flex;flex-direction:column;position:relative;overflow:hidden;transition:width .2s,min-width .2s}.sidebar.collapsed.svelte-181dlmc{width:40px;min-width:40px}.toggle-btn.svelte-181dlmc{position:absolute;top:12px;right:8px;z-index:10;border:none;background:none;color:var(--body-text-color-subdued, #9ca3af);cursor:pointer;padding:4px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm, 4px);transition:color .15s,background-color .15s}.toggle-btn.svelte-181dlmc:hover{color:var(--body-text-color, #1f2937);background-color:var(--background-fill-secondary, #f9fafb)}.sidebar-content.svelte-181dlmc{padding:16px;flex:1;min-height:0;display:flex;flex-direction:column}.sidebar-scroll.svelte-181dlmc{overflow-y:auto;flex:1;min-height:0}.oauth-footer.svelte-181dlmc{flex-shrink:0;margin-top:12px;padding-top:12px;border-top:1px solid var(--border-color-primary, #e5e7eb)}.readonly-footer.svelte-181dlmc{flex-shrink:0;margin-top:12px;padding-top:12px;border-top:1px solid var(--border-color-primary, #e5e7eb);display:flex;align-items:center;gap:8px;flex-wrap:wrap}.readonly-badge.svelte-181dlmc{display:inline-flex;align-items:center;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:999px;padding:2px 8px;font-size:10px;letter-spacing:.06em;font-weight:600;color:var(--body-text-color-subdued, #6b7280);background:var(--background-fill-secondary, #f9fafb)}.readonly-link.svelte-181dlmc{font-size:12px;color:var(--body-text-color-subdued, #6b7280);text-decoration:none;max-width:100%;overflow-wrap:anywhere}.readonly-link.svelte-181dlmc:hover{color:var(--body-text-color, #1f2937);text-decoration:underline}.oauth-line.svelte-181dlmc{margin:0;font-size:12px;line-height:1.4;color:var(--body-text-color-subdued, #6b7280)}.oauth-warn.svelte-181dlmc{color:var(--body-text-color, #92400e)}.hf-login-btn.svelte-181dlmc{display:inline-flex;align-items:center;justify-content:center;gap:8px;width:100%;padding:8px 12px;font-size:13px;font-weight:600;color:#fff;background:#141c2e;border-radius:var(--radius-lg, 8px);text-decoration:none;border:none;cursor:pointer;box-sizing:border-box}.hf-login-btn.svelte-181dlmc:hover{background:#283042}.hf-logo.svelte-181dlmc{width:20px;height:20px;flex-shrink:0}.oauth-hint.svelte-181dlmc{margin:8px 0 0;font-size:11px;line-height:1.35;color:var(--body-text-color-subdued, #9ca3af)}.oauth-signed-in.svelte-181dlmc{margin:0;font-size:12px;color:var(--body-text-color-subdued, #6b7280)}.oauth-logout.svelte-181dlmc{font-size:12px;color:var(--body-text-color-subdued, #9ca3af);text-decoration:none;cursor:pointer}.oauth-logout.svelte-181dlmc:hover{text-decoration:underline;color:var(--body-text-color, #1f2937)}.logo-section.svelte-181dlmc{margin-bottom:20px}.logo.svelte-181dlmc{width:80%;max-width:200px}.section.svelte-181dlmc{margin-top:2px;margin-bottom:18px}.share-tabs.svelte-181dlmc{display:flex;gap:6px;margin-bottom:8px}.share-tab-btn.svelte-181dlmc{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);padding:4px 8px;font-size:12px;color:var(--body-text-color-subdued, #6b7280);background:var(--background-fill-primary, white);cursor:pointer}.share-tab-btn.active.svelte-181dlmc{color:var(--body-text-color, #1f2937);background:var(--background-fill-secondary, #f9fafb)}.share-field.svelte-181dlmc{display:flex;flex-direction:column;gap:6px}.share-input-row.svelte-181dlmc{display:flex;gap:6px;align-items:stretch}.share-input-row.svelte-181dlmc input:where(.svelte-181dlmc),.share-input-row.svelte-181dlmc textarea:where(.svelte-181dlmc){width:100%;min-width:0;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);padding:6px 8px;font-size:12px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;color:var(--body-text-color, #1f2937);background:var(--background-fill-secondary, #f9fafb);resize:vertical}.copy-btn.svelte-181dlmc{box-sizing:border-box;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);padding:6px 10px;min-width:3.25rem;display:inline-flex;align-items:center;justify-content:center;font-size:12px;line-height:1;color:var(--body-text-color, #1f2937);background:var(--background-fill-primary, white);cursor:pointer;flex-shrink:0}.copy-btn-check.svelte-181dlmc{display:block;color:var(--color-accent, #f97316)}.share-hint.svelte-181dlmc{margin:0;font-size:12px;line-height:1.4;color:var(--body-text-color-subdued, #9ca3af)}.section-label.svelte-181dlmc{font-size:13px;font-weight:500;color:var(--body-text-color-subdued, #6b7280)}.locked-project.svelte-181dlmc{margin-top:4px;font-size:13px;font-weight:500;color:var(--body-text-color, #1f2937);padding:8px 10px;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);background:var(--background-fill-secondary, #f9fafb)}.runs-header.svelte-181dlmc{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.select-all-label.svelte-181dlmc{display:flex;align-items:center;gap:6px;cursor:pointer}.select-all-cb.svelte-181dlmc{-moz-appearance:none;appearance:none;-webkit-appearance:none;width:16px;height:16px;border:1px solid var(--checkbox-border-color, #d1d5db);border-radius:var(--checkbox-border-radius, 4px);background-color:var(--checkbox-background-color, white);cursor:pointer;flex-shrink:0;position:relative;transition:background-color .15s,border-color .15s}.select-all-cb.svelte-181dlmc:checked{background-color:var(--checkbox-background-color-selected, var(--color-accent, #f97316));border-color:var(--checkbox-background-color-selected, var(--color-accent, #f97316));background-image:var(--checkbox-check)}.select-all-cb.svelte-181dlmc:indeterminate{background-color:var(--checkbox-background-color-selected, var(--color-accent, #f97316));border-color:var(--checkbox-background-color-selected, var(--color-accent, #f97316));background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='3' y='7' width='10' height='2' rx='1'/%3E%3C/svg%3E");background-size:12px;background-position:center;background-repeat:no-repeat}.latest-toggle.svelte-181dlmc{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--body-text-color-subdued, #6b7280);cursor:pointer}.latest-toggle.svelte-181dlmc input[type=checkbox]:where(.svelte-181dlmc){-moz-appearance:none;appearance:none;-webkit-appearance:none;width:16px;height:16px;margin:0;border:1px solid var(--checkbox-border-color, #d1d5db);border-radius:var(--checkbox-border-radius, 4px);background-color:var(--checkbox-background-color, white);box-shadow:var(--checkbox-shadow);cursor:pointer;flex-shrink:0;transition:background-color .15s,border-color .15s}.latest-toggle.svelte-181dlmc input[type=checkbox]:where(.svelte-181dlmc):checked{background-image:var(--checkbox-check);background-color:var(--checkbox-background-color-selected, #f97316);border-color:var(--checkbox-border-color-selected, #f97316)}.checkbox-list.svelte-181dlmc{max-height:300px;overflow-y:auto;margin-top:8px}.device-group.svelte-181dlmc{margin-top:14px;padding-top:12px;border-top:1px solid var(--border-color-primary, #e5e7eb)}.section-sublabel.svelte-181dlmc{font-size:12px;font-weight:600;color:var(--body-text-color-subdued, #6b7280)}.checkbox-group.svelte-181dlmc{display:flex;flex-direction:column;margin-top:8px}.checkbox-item.svelte-181dlmc{display:flex;align-items:center;gap:8px;padding:3px 0;cursor:pointer;font-size:13px}.checkbox-item.svelte-181dlmc input[type=checkbox]:where(.svelte-181dlmc){-moz-appearance:none;appearance:none;-webkit-appearance:none;width:16px;height:16px;margin:0;border:1px solid var(--checkbox-border-color, #d1d5db);border-radius:var(--checkbox-border-radius, 4px);background-color:var(--checkbox-background-color, white);box-shadow:var(--checkbox-shadow);cursor:pointer;flex-shrink:0;transition:background-color .15s,border-color .15s}.checkbox-item.svelte-181dlmc input[type=checkbox]:where(.svelte-181dlmc):checked{background-image:var(--checkbox-check);background-color:var(--checkbox-background-color-selected, #f97316);border-color:var(--checkbox-border-color-selected, #f97316)}.checkbox-item.svelte-181dlmc input[type=checkbox]:where(.svelte-181dlmc):hover{border-color:var(--checkbox-border-color-hover, #d1d5db)}.run-name.svelte-181dlmc{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--body-text-color, #1f2937)}.group-by-row.svelte-181dlmc{margin-top:8px}.grouped-runs.svelte-181dlmc{margin-top:8px;display:flex;flex-direction:column;gap:6px}.run-group-section.svelte-181dlmc{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);overflow:hidden}.run-group-header.svelte-181dlmc{display:flex;align-items:center;padding:6px 10px;background:var(--background-fill-secondary, #f9fafb);border-bottom:1px solid var(--border-color-primary, #e5e7eb)}.run-group-label.svelte-181dlmc{font-size:12px;font-weight:600;color:var(--body-text-color, #1f2937);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:160px}.run-group-count.svelte-181dlmc{font-size:11px;color:var(--body-text-color-subdued, #9ca3af);margin-left:4px;flex-shrink:0}.group-checkbox-list.svelte-181dlmc{padding:4px 10px;max-height:none}.alert-panel.svelte-x5aqew{position:fixed;bottom:16px;right:16px;width:380px;max-height:400px;background:var(--background-fill-primary, white);border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);box-shadow:var(--shadow-drop-lg);z-index:1000;overflow:hidden;display:flex;flex-direction:column}.alert-panel.collapsed.svelte-x5aqew{max-height:none}.alert-header.svelte-x5aqew{padding:10px 12px;border:none;border-bottom:1px solid var(--border-color-primary, #e5e7eb);background:none;width:100%;display:flex;align-items:center;justify-content:space-between;cursor:pointer;gap:8px}.alert-panel.collapsed.svelte-x5aqew .alert-header:where(.svelte-x5aqew){border-bottom:none}.collapse-icon.svelte-x5aqew{color:var(--body-text-color-subdued, #9ca3af);flex-shrink:0;transition:transform .15s}.collapse-icon.rotated.svelte-x5aqew{transform:rotate(-90deg)}.alert-title.svelte-x5aqew{font-size:13px;font-weight:600;color:var(--body-text-color, #1f2937)}.filter-pills.svelte-x5aqew{display:flex;gap:4px}.pill.svelte-x5aqew{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-xxl, 22px);padding:2px 8px;font-size:11px;background:var(--background-fill-secondary, #f9fafb);color:var(--body-text-color-subdued, #6b7280);cursor:pointer}.pill.active.svelte-x5aqew{background:var(--color-accent, #f97316);color:#fff;border-color:var(--color-accent, #f97316)}.alert-list.svelte-x5aqew{overflow-y:auto;flex:1}.alert-item.svelte-x5aqew{border-bottom:1px solid var(--neutral-100, #f3f4f6)}.alert-row.svelte-x5aqew{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:none;background:none;text-align:left;cursor:pointer;font-size:var(--text-sm, 12px)}.alert-row.svelte-x5aqew:hover{background:var(--background-fill-secondary, #f9fafb)}.alert-text.svelte-x5aqew{flex:1;color:var(--body-text-color, #1f2937)}.alert-meta.svelte-x5aqew{font-size:var(--text-xs, 10px);color:var(--body-text-color-subdued, #9ca3af);white-space:nowrap}.alert-detail.svelte-x5aqew{padding:4px 12px 8px 32px;font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280)}.plot-container.svelte-9thu1j{min-width:350px;flex:1;background:var(--background-fill-primary, white);border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);padding:12px;overflow:hidden;position:relative}.plot-container[draggable=true].svelte-9thu1j{cursor:grab}.plot-container[draggable=true].svelte-9thu1j:active{cursor:grabbing}.hidden-plot.svelte-9thu1j{visibility:hidden;height:0;padding:0;margin:0;border:none;overflow:hidden;pointer-events:none}.drag-handle.svelte-9thu1j{position:absolute;top:8px;left:8px;color:var(--body-text-color-subdued, #9ca3af);opacity:0;transition:opacity .15s;z-index:5}.plot-container.svelte-9thu1j:hover .drag-handle:where(.svelte-9thu1j){opacity:.5}.drag-handle.svelte-9thu1j:hover{opacity:1!important}.plot-toolbar.svelte-9thu1j{position:absolute;top:8px;right:8px;display:flex;gap:4px;z-index:5;opacity:0;transition:opacity .15s}.plot-container.svelte-9thu1j:hover .plot-toolbar:where(.svelte-9thu1j){opacity:1}.toolbar-btn.svelte-9thu1j{border:1px solid var(--border-color-primary, #e5e7eb);background:var(--background-fill-primary, white);color:var(--body-text-color-subdued, #6b7280);cursor:pointer;padding:4px 6px;border-radius:var(--radius-sm, 4px);display:flex;align-items:center;justify-content:center}.toolbar-btn.svelte-9thu1j:hover{background:var(--neutral-100, #f3f4f6);color:var(--body-text-color, #1f2937)}.plot-chart-wrap.svelte-9thu1j{position:relative;width:100%}.plot-chart-wrap--fs.svelte-9thu1j{flex:1;min-height:0;display:flex;flex-direction:column}.reset-zoom-btn.svelte-9thu1j{position:absolute;bottom:1px;right:1px;z-index:6;display:inline-flex;align-items:center;justify-content:center;margin:0;min-width:52px;padding:5px 12px 5px 10px;border:none;border-radius:4px;background:transparent;color:var(--body-text-color-subdued, #334155);cursor:pointer;opacity:.92;transform:translateY(6px);transition:opacity .15s ease,color .15s ease,background .15s ease;box-shadow:none}.reset-zoom-btn.svelte-9thu1j:hover{opacity:1;color:var(--body-text-color, #0f172a);background:var(--background-fill-secondary, rgba(226, 232, 240, .85));transform:translateY(6px)}.reset-zoom-btn.svelte-9thu1j svg:where(.svelte-9thu1j){display:block;flex-shrink:0;filter:drop-shadow(0 0 .5px rgba(255,255,255,.95))}.plot-title.svelte-9thu1j{font-size:13px;font-weight:600;color:var(--body-text-color, #374151);text-align:center;padding:0 0 6px;word-break:break-word}.plot-title--fs.svelte-9thu1j{flex-shrink:0}.plot.svelte-9thu1j{width:100%}.plot.svelte-9thu1j .vega-embed{width:100%!important}.plot.svelte-9thu1j .vega-embed summary{display:none}.fullscreen-host.svelte-9thu1j{position:fixed;top:0;right:0;bottom:0;left:0;z-index:10000;box-sizing:border-box;display:flex;flex-direction:column;background:var(--background-fill-primary, white);padding:12px;gap:8px;pointer-events:auto}.fullscreen-host.svelte-9thu1j:fullscreen{width:100%;height:100%}.fullscreen-host.svelte-9thu1j:-webkit-full-screen{width:100%;height:100%}.fullscreen-toolbar.svelte-9thu1j{flex-shrink:0;display:flex;justify-content:flex-end;gap:4px;z-index:5}.fullscreen-chart-wrap.svelte-9thu1j{flex:1;min-height:0;display:flex;flex-direction:column}.fullscreen-legend.svelte-9thu1j{flex-shrink:0}.fullscreen-plot.svelte-9thu1j{flex:1;min-height:0;width:100%;overflow:hidden}.fullscreen-plot.svelte-9thu1j .vega-embed{width:100%!important;height:100%!important;min-height:0;display:flex;flex-direction:column}.fullscreen-plot.svelte-9thu1j .vega-embed .vega-view{flex:1;min-height:0}.fullscreen-plot.svelte-9thu1j .vega-embed summary{display:none}.custom-legend.svelte-9thu1j{display:flex;align-items:center;justify-content:center;gap:12px;padding:6px 0 0;flex-wrap:wrap}.legend-title.svelte-9thu1j{font-size:11px;color:var(--body-text-color-subdued, #6b7280);font-weight:600}.legend-item.svelte-9thu1j{display:flex;align-items:center;gap:4px}.legend-dot.svelte-9thu1j{width:10px;height:10px;border-radius:50%;flex-shrink:0}.legend-line-swatch.svelte-9thu1j{width:24px;height:10px;flex-shrink:0;color:var(--body-text-color, #1f2937)}.legend-label.svelte-9thu1j{font-size:11px;color:var(--body-text-color-subdued, #6b7280)}.legend-toggle.svelte-9thu1j{font-size:11px;color:var(--body-text-color-subdued, #6b7280);background:none;border:none;padding:0 4px;cursor:pointer;text-decoration:underline}.legend-toggle.svelte-9thu1j:hover{color:var(--body-text-color, #1f2937)}.plot-container.svelte-1swghqy{min-width:350px;flex:1;background:var(--background-fill-primary, white);border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);padding:12px;overflow:hidden;position:relative}.plot-container[draggable=true].svelte-1swghqy{cursor:grab}.plot-container[draggable=true].svelte-1swghqy:active{cursor:grabbing}.hidden-plot.svelte-1swghqy{visibility:hidden;height:0;padding:0;margin:0;border:none;overflow:hidden;pointer-events:none}.drag-handle.svelte-1swghqy{position:absolute;top:8px;left:8px;color:var(--body-text-color-subdued, #9ca3af);opacity:0;transition:opacity .15s;z-index:5}.plot-container.svelte-1swghqy:hover .drag-handle:where(.svelte-1swghqy){opacity:.5}.drag-handle.svelte-1swghqy:hover{opacity:1!important}.plot-toolbar.svelte-1swghqy{position:absolute;top:8px;right:8px;display:flex;gap:4px;z-index:5;opacity:0;transition:opacity .15s}.plot-container.svelte-1swghqy:hover .plot-toolbar:where(.svelte-1swghqy){opacity:1}.toolbar-btn.svelte-1swghqy{border:1px solid var(--border-color-primary, #e5e7eb);background:var(--background-fill-primary, white);color:var(--body-text-color-subdued, #6b7280);cursor:pointer;padding:4px 6px;border-radius:var(--radius-sm, 4px);display:flex;align-items:center;justify-content:center}.toolbar-btn.svelte-1swghqy:hover{background:var(--neutral-100, #f3f4f6);color:var(--body-text-color, #1f2937)}.plot-chart-wrap.svelte-1swghqy{position:relative;width:100%}.plot-chart-wrap--fs.svelte-1swghqy{flex:1;min-height:0;display:flex;flex-direction:column}.plot-title.svelte-1swghqy{font-size:13px;font-weight:600;color:var(--body-text-color, #374151);text-align:center;padding:0 0 6px;word-break:break-word}.plot-title--fs.svelte-1swghqy{flex-shrink:0}.plot.svelte-1swghqy{width:100%}.plot.svelte-1swghqy .vega-embed{width:100%!important}.plot.svelte-1swghqy .vega-embed summary{display:none}.fullscreen-host.svelte-1swghqy{position:fixed;top:0;right:0;bottom:0;left:0;z-index:10000;box-sizing:border-box;display:flex;flex-direction:column;background:var(--background-fill-primary, white);padding:12px;gap:8px;pointer-events:auto}.fullscreen-host.svelte-1swghqy:fullscreen{width:100%;height:100%}.fullscreen-host.svelte-1swghqy:-webkit-full-screen{width:100%;height:100%}.fullscreen-toolbar.svelte-1swghqy{flex-shrink:0;display:flex;justify-content:flex-end;gap:4px;z-index:5}.fullscreen-chart-wrap.svelte-1swghqy{flex:1;min-height:0;display:flex;flex-direction:column}.fullscreen-legend.svelte-1swghqy{flex-shrink:0}.fullscreen-plot.svelte-1swghqy{flex:1;min-height:0;width:100%;overflow:hidden}.fullscreen-plot.svelte-1swghqy .vega-embed{width:100%!important;height:100%!important;min-height:0;display:flex;flex-direction:column}.fullscreen-plot.svelte-1swghqy .vega-embed .vega-view{flex:1;min-height:0}.fullscreen-plot.svelte-1swghqy .vega-embed summary{display:none}.custom-legend.svelte-1swghqy{display:flex;align-items:center;justify-content:center;gap:12px;padding:6px 0 0;flex-wrap:wrap}.legend-item.svelte-1swghqy{display:flex;align-items:center;gap:4px}.legend-dot.svelte-1swghqy{width:10px;height:10px;border-radius:50%;flex-shrink:0}.legend-label.svelte-1swghqy{font-size:11px;color:var(--body-text-color-subdued, #6b7280)}.legend-toggle.svelte-1swghqy{font-size:11px;color:var(--body-text-color-subdued, #6b7280);background:none;border:none;padding:0 4px;cursor:pointer;text-decoration:underline}.legend-toggle.svelte-1swghqy:hover{color:var(--body-text-color, #1f2937)}.accordion.svelte-1jep0a{margin-bottom:12px;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);background:var(--background-fill-primary, white);overflow:hidden}.accordion-hidden.svelte-1jep0a{margin-bottom:8px}.accordion-header.svelte-1jep0a{display:flex;align-items:center;gap:8px;width:100%;padding:10px 14px;border:none;background:var(--background-fill-primary, white);color:var(--body-text-color, #1f2937);font-size:var(--text-md, 14px);font-weight:600;cursor:pointer;text-align:left}.accordion-header.svelte-1jep0a:hover{background:var(--background-fill-secondary, #f9fafb)}.arrow.svelte-1jep0a{font-size:14px;transition:transform .15s;color:var(--body-text-color, #1f2937);display:inline-block}.arrow.svelte-1jep0a:not(.rotated){transform:rotate(-90deg)}.accordion-body.svelte-1jep0a{padding:0 14px 14px}.trackio-loading.svelte-1kc6b2l{display:flex;align-items:center;justify-content:center;width:100%;min-height:min(70vh,640px);padding:32px 24px;box-sizing:border-box;background:transparent}.logo-stack.svelte-1kc6b2l{position:relative;width:min(100%,200px);max-width:min(92vw,200px);line-height:0;background:transparent;isolation:isolate}.logo-base.svelte-1kc6b2l{display:block;background:transparent}.logo-img.svelte-1kc6b2l{width:100%;height:auto;display:block;background:transparent}.logo-overlay.svelte-1kc6b2l{position:absolute;left:0;top:0;width:100%;animation:svelte-1kc6b2l-trackio-logo-sweep 4s linear infinite;pointer-events:none;background:transparent}.logo-overlay.svelte-1kc6b2l .logo-img:where(.svelte-1kc6b2l){width:100%;height:auto;object-position:left center}.logo-img--gray.svelte-1kc6b2l{filter:grayscale(1)}@keyframes svelte-1kc6b2l-trackio-logo-sweep{0%{clip-path:inset(0 0 0 0)}50%{clip-path:inset(0 0 0 100%)}to{clip-path:inset(0 0 0 0)}}@media(prefers-reduced-motion:reduce){.logo-overlay.svelte-1kc6b2l{display:none}}.sr-only.svelte-1kc6b2l{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.metrics-page.svelte-2bul55{padding:20px 24px;overflow-y:auto;flex:1;min-height:0}.plot-grid.svelte-2bul55{display:flex;flex-wrap:wrap;gap:16px}.subgroup-list.svelte-2bul55{margin-top:16px}.empty-state.svelte-2bul55{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-2bul55 h2:where(.svelte-2bul55){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-2bul55 p:where(.svelte-2bul55){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.empty-state.svelte-2bul55 pre:where(.svelte-2bul55){background:var(--background-fill-secondary, #f9fafb);padding:16px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:13px;overflow-x:auto}.empty-state.svelte-2bul55 code:where(.svelte-2bul55){background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.empty-state.svelte-2bul55 pre:where(.svelte-2bul55) code:where(.svelte-2bul55){background:none;padding:0}.traces-page.svelte-1s32ifo{padding:20px 24px;overflow-y:auto;flex:1;background:var(--background-fill-primary, white)}.toolbar.svelte-1s32ifo{display:flex;align-items:center;gap:12px;margin-bottom:16px}.search-wrap.svelte-1s32ifo{flex:1}.search-wrap.svelte-1s32ifo input:where(.svelte-1s32ifo),.filter-wrap.svelte-1s32ifo select:where(.svelte-1s32ifo){width:100%;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);background:var(--background-fill-primary, white);color:var(--body-text-color, #1f2937);font-size:14px;padding:10px 12px;font-family:inherit}.filter-wrap.svelte-1s32ifo{display:flex;align-items:center;gap:8px;color:var(--body-text-color, #1f2937);font-size:14px;white-space:nowrap}.count.svelte-1s32ifo{margin-left:auto;color:var(--body-text-color-subdued, #6b7280);font-size:14px;white-space:nowrap}.traces-table-wrap.svelte-1s32ifo{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);overflow:hidden;transition:opacity .15s ease}.traces-table-wrap.dim.svelte-1s32ifo{opacity:.55}.traces-table.svelte-1s32ifo{width:100%;border-collapse:collapse;font-size:14px;table-layout:fixed}.trace-id-col.svelte-1s32ifo{width:140px}.request-col.svelte-1s32ifo{width:auto}.run-col.svelte-1s32ifo{width:180px}.step-col.svelte-1s32ifo{width:76px}.request-time-col.svelte-1s32ifo{width:150px}.traces-table.svelte-1s32ifo th:where(.svelte-1s32ifo){text-align:left;padding:10px 12px;border-bottom:1px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color-subdued, #6b7280);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.05em;background:var(--background-fill-primary, white)}.traces-table.svelte-1s32ifo td:where(.svelte-1s32ifo){padding:10px 12px;border-bottom:1px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color, #1f2937);vertical-align:top}.trace-row.svelte-1s32ifo{cursor:pointer}.trace-row.svelte-1s32ifo:hover{background:var(--background-fill-secondary, #f9fafb)}.trace-id-chip.svelte-1s32ifo{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;color:var(--body-text-color, #1f2937)}.request.svelte-1s32ifo{font-weight:500;margin-bottom:4px}.preview.svelte-1s32ifo{color:var(--body-text-color-subdued, #6b7280);font-size:13px;line-height:1.45;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.expanded-row.svelte-1s32ifo td:where(.svelte-1s32ifo){padding:0;background:var(--background-fill-secondary, #fafafa)}.trace-detail.svelte-1s32ifo{padding:16px 18px 18px}.detail-meta.svelte-1s32ifo{display:flex;gap:16px;flex-wrap:wrap;color:var(--body-text-color-subdued, #6b7280);font-size:13px;margin-bottom:14px}.conversation.svelte-1s32ifo{display:flex;flex-direction:column;gap:12px}.message.svelte-1s32ifo{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);background:var(--background-fill-primary, white);padding:12px}.message-role.svelte-1s32ifo{margin-bottom:8px;color:var(--body-text-color-subdued, #6b7280);font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;display:flex;align-items:center;gap:8px;flex-wrap:wrap}.message-tag.svelte-1s32ifo{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:999px;padding:2px 8px;font-size:11px;font-weight:500;text-transform:none;letter-spacing:0}.message-content.svelte-1s32ifo,.tool-block.svelte-1s32ifo{margin:0;white-space:pre-wrap;word-break:break-word;font-family:inherit;color:var(--body-text-color, #1f2937);line-height:1.5}.message-details.svelte-1s32ifo summary:where(.svelte-1s32ifo){cursor:pointer;margin-bottom:8px;color:var(--body-text-color-subdued, #6b7280)}.tool-blocks.svelte-1s32ifo{display:flex;flex-direction:column;gap:8px;margin-top:10px}.tool-block.svelte-1s32ifo{background:var(--background-fill-secondary, #f9fafb);border-radius:var(--radius-md, 6px);padding:10px;overflow-x:auto}.message-parts.svelte-1s32ifo{display:flex;flex-direction:column;gap:10px}.trace-image.svelte-1s32ifo{max-width:100%;max-height:360px;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px)}.empty-state.svelte-1s32ifo{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-1s32ifo h2:where(.svelte-1s32ifo){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-1s32ifo p:where(.svelte-1s32ifo){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.pagination.svelte-1s32ifo{display:flex;align-items:center;justify-content:center;gap:12px;padding:16px 0 4px}.pagination.svelte-1s32ifo button:where(.svelte-1s32ifo){border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 6px);background:var(--background-fill-primary, white);color:var(--body-text-color, #1f2937);font-size:14px;padding:8px 14px;cursor:pointer;font-family:inherit}.pagination.svelte-1s32ifo button:where(.svelte-1s32ifo):hover:not(:disabled){background:var(--background-fill-secondary, #f9fafb)}.pagination.svelte-1s32ifo button:where(.svelte-1s32ifo):disabled{opacity:.5;cursor:not-allowed}.page-info.svelte-1s32ifo{color:var(--body-text-color-subdued, #6b7280);font-size:14px;min-width:120px;text-align:center}@media(max-width:1100px){.toolbar.svelte-1s32ifo{flex-wrap:wrap}.count.svelte-1s32ifo{margin-left:0}}.system-page.svelte-nv5os4{padding:20px 24px;overflow-y:auto;flex:1;min-height:0}.plot-grid.svelte-nv5os4{display:flex;flex-wrap:wrap;gap:12px}.subgroup-list.svelte-nv5os4{margin-top:16px}.empty-state.svelte-nv5os4{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-nv5os4 h2:where(.svelte-nv5os4){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-nv5os4 p:where(.svelte-nv5os4){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.empty-state.svelte-nv5os4 pre:where(.svelte-nv5os4){background:var(--background-fill-secondary, #f9fafb);padding:16px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:13px;overflow-x:auto}.empty-state.svelte-nv5os4 ul:where(.svelte-nv5os4){list-style:disc;padding-left:20px;margin:4px 0 0}.empty-state.svelte-nv5os4 li:where(.svelte-nv5os4){margin:4px 0;color:var(--body-text-color, #1f2937)}.empty-state.svelte-nv5os4 code:where(.svelte-nv5os4){background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.empty-state.svelte-nv5os4 pre:where(.svelte-nv5os4) code:where(.svelte-nv5os4){background:none;padding:0}.wave-wrap.svelte-19wbodf{--wave-base: var(--body-text-color-subdued, #9ca3af);--wave-played: var(--color-accent, #f97316);display:flex;align-items:center;gap:8px;padding:8px 10px;background:var(--background-fill-secondary, #f9fafb);border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);color:var(--body-text-color, #1f2937)}.play-btn.svelte-19wbodf{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;background:var(--color-accent, #f97316);color:#fff;border:none;cursor:pointer;flex-shrink:0;padding:0}.play-btn.svelte-19wbodf:disabled{opacity:.4;cursor:not-allowed}.play-btn.svelte-19wbodf:hover:not(:disabled){filter:brightness(1.1)}.wave.svelte-19wbodf{flex:1;height:32px;min-width:0;cursor:pointer}.time.svelte-19wbodf{font-size:11px;color:var(--body-text-color-subdued, #6b7280);font-variant-numeric:tabular-nums;flex-shrink:0}audio.svelte-19wbodf{display:none}.media-page.svelte-outb32{padding:20px 24px;overflow-y:auto;flex:1}.section.svelte-outb32{margin:16px 0}.section-heading.svelte-outb32,.image-section-controls.svelte-outb32{display:flex;align-items:center;gap:8px}.image-section-summary.svelte-outb32{justify-content:space-between;gap:12px}.image-section-controls.svelte-outb32{flex:1;justify-content:flex-end}.media-control.svelte-outb32{display:flex;align-items:center;gap:8px;font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280)}.media-control.svelte-outb32 select:where(.svelte-outb32){height:30px;border:1px solid var(--border-color-primary, #d1d5db);border-radius:var(--radius-sm, 4px);background:var(--background-fill-primary, white);color:var(--body-text-color, #1f2937);font-size:var(--text-sm, 12px);padding:0 28px 0 8px}.section-summary.svelte-outb32{display:flex;align-items:center;gap:6px;cursor:pointer;list-style:none;-webkit-user-select:none;user-select:none;padding:4px 0;margin-bottom:8px}.section-summary.svelte-outb32::-webkit-details-marker{display:none}.chevron.svelte-outb32{color:var(--body-text-color-subdued, #6b7280);transform:rotate(-90deg);transition:transform .15s ease;flex-shrink:0}details[open].svelte-outb32>.section-summary:where(.svelte-outb32) .chevron:where(.svelte-outb32){transform:rotate(0)}.section-title.svelte-outb32{font-size:var(--text-lg, 16px);font-weight:600;color:var(--body-text-color, #1f2937)}.media-label.svelte-outb32{font-size:var(--text-sm, 12px);font-weight:500;color:var(--body-text-color, #1f2937);word-break:break-word}.meta.svelte-outb32{display:flex;align-items:center;gap:3px;font-size:var(--text-xs, 11px);color:var(--body-text-color-subdued, #9ca3af);font-variant-numeric:tabular-nums}.meta.svelte-outb32 .run-dot:where(.svelte-outb32){width:8px;height:8px;border-radius:50%;flex-shrink:0;margin:0 2px}.meta-text.svelte-outb32{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.table-header.svelte-outb32{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:6px}.runs-table.svelte-outb32{width:100%;border-collapse:collapse;font-size:var(--text-md, 14px)}.runs-table.svelte-outb32 th:where(.svelte-outb32){text-align:left;padding:8px 12px;border-bottom:2px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color-subdued, #6b7280);font-weight:600;font-size:var(--text-sm, 12px);text-transform:uppercase;letter-spacing:.05em}.runs-table.svelte-outb32 td:where(.svelte-outb32){padding:8px 12px;border-bottom:1px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color, #1f2937)}.runs-table.svelte-outb32 tbody:where(.svelte-outb32) tr:where(.svelte-outb32):nth-child(odd){background:var(--table-odd-background-fill, var(--background-fill-primary, white))}.runs-table.svelte-outb32 tbody:where(.svelte-outb32) tr:where(.svelte-outb32):nth-child(2n){background:var(--table-even-background-fill, var(--background-fill-secondary, #f9fafb))}.runs-table.svelte-outb32 tr:where(.svelte-outb32):hover{background:var(--background-fill-secondary, #f3f4f6)}.table-image-frame.svelte-outb32{position:relative;display:inline-flex;width:120px;height:80px;align-items:center;justify-content:center;overflow:hidden;border:0;border-radius:var(--radius-sm, 4px);background:var(--background-fill-secondary, #f3f4f6);color:var(--body-text-color-subdued, #6b7280);cursor:zoom-in;font:inherit;padding:0;text-decoration:none;vertical-align:top}.table-image-placeholder.svelte-outb32{position:absolute;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;font-size:var(--text-xs, 11px)}.table-image-frame.svelte-outb32.image-loaded .table-image-placeholder:where(.svelte-outb32){display:none}.table-image-frame.svelte-outb32.image-failed .table-image-placeholder:where(.svelte-outb32){color:var(--error-text-color, #b91c1c)}.table-image.svelte-outb32{position:relative;z-index:1;max-height:80px;max-width:120px;border-radius:var(--radius-sm, 4px);display:block;object-fit:contain}.table-image-list.svelte-outb32{display:flex;flex-wrap:wrap;gap:4px}.gallery.svelte-outb32{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}.gallery-item.svelte-outb32{display:flex;flex-direction:column;gap:6px;padding:8px;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);background:var(--background-fill-secondary, #f9fafb);overflow:hidden}.image-frame.svelte-outb32{position:relative;display:block;width:100%;aspect-ratio:4 / 3;overflow:hidden;border:0;border-radius:var(--radius-sm, 4px);background:var(--background-fill-primary, #f3f4f6);color:var(--body-text-color-subdued, #6b7280);cursor:zoom-in;font:inherit;padding:0;text-decoration:none}.image-placeholder.svelte-outb32{position:absolute;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;font-size:var(--text-sm, 12px)}.image-frame.svelte-outb32.image-loaded .image-placeholder:where(.svelte-outb32){display:none}.image-frame.svelte-outb32.image-failed .image-placeholder:where(.svelte-outb32){color:var(--error-text-color, #b91c1c)}.image-frame.svelte-outb32 img:where(.svelte-outb32){position:relative;z-index:1;width:100%;height:100%;display:block;object-fit:contain}.gallery-item.svelte-outb32 video:where(.svelte-outb32){width:100%;display:block;border-radius:var(--radius-sm, 4px)}.audio-gallery-item.svelte-outb32{justify-content:space-between}.caption.svelte-outb32{font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #9ca3af)}.image-filter.svelte-outb32{width:min(320px,100%)}.image-filter.svelte-outb32 input:where(.svelte-outb32){width:100%;padding:7px 10px;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--input-radius, 8px);background:var(--input-background-fill, white);color:var(--body-text-color, #1f2937);font-family:inherit;font-size:13px;outline:none;transition:border-color .15s,box-shadow .15s}.image-filter.svelte-outb32 input:where(.svelte-outb32):focus{border-color:var(--input-border-color-focus, #fdba74);box-shadow:0 0 0 2px var(--primary-50, #fff7ed)}.image-filter.svelte-outb32 input:where(.svelte-outb32)::placeholder{color:var(--input-placeholder-color, #9ca3af)}.empty-filter-state.svelte-outb32{padding:16px 0;color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-sm, 12px)}.image-modal-backdrop.svelte-outb32{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:32px;background:#000000bf}.image-modal.svelte-outb32{position:relative;display:flex;max-width:min(92vw,1200px);max-height:92vh;flex-direction:column;overflow:hidden;border-radius:var(--radius-lg, 8px);background:var(--background-fill-primary, white);box-shadow:0 20px 60px #00000059}.image-modal-close.svelte-outb32{position:absolute;top:8px;right:8px;z-index:2;width:32px;height:32px;border:0;border-radius:999px;background:#0000008c;color:#fff;cursor:pointer;font-size:24px;line-height:1}.image-modal-nav.svelte-outb32{position:absolute;top:50%;z-index:2;width:48px;height:48px;border:0;border-radius:999px;background:#00000059;color:#fff;cursor:pointer;font-size:40px;line-height:1;transform:translateY(-50%)}.image-modal-nav.svelte-outb32:hover{background:#0000008c}.image-modal-prev.svelte-outb32{left:12px}.image-modal-next.svelte-outb32{right:12px}.modal-image-frame.svelte-outb32{position:relative;display:grid;min-width:min(70vw,720px);min-height:min(65vh,520px);place-items:center;overflow:hidden;background:var(--background-fill-secondary, #f3f4f6);color:var(--body-text-color-subdued, #6b7280)}.modal-image-placeholder.svelte-outb32{position:absolute;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;font-size:var(--text-sm, 12px)}.modal-image-frame.svelte-outb32.image-loaded .modal-image-placeholder:where(.svelte-outb32){display:none}.modal-image-frame.svelte-outb32.image-failed .modal-image-placeholder:where(.svelte-outb32){color:var(--error-text-color, #b91c1c)}.modal-image-frame.svelte-outb32 img:where(.svelte-outb32){position:relative;z-index:1;max-width:100%;max-height:calc(92vh - 96px);object-fit:contain}.image-modal-info.svelte-outb32{display:flex;flex-direction:column;gap:4px;padding:10px 14px 12px;text-align:center}.image-modal-title.svelte-outb32{font-size:var(--text-md, 14px);font-weight:600;color:var(--body-text-color, #1f2937)}.image-modal-caption.svelte-outb32{font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280)}.image-modal-meta.svelte-outb32{justify-content:center}.image-modal-count.svelte-outb32{margin-left:8px}.table-section.svelte-outb32{margin-bottom:16px;overflow-x:auto}.pagination-row.svelte-outb32{display:flex;justify-content:center;align-items:center;gap:12px;margin-top:12px;font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280)}.load-more-button.svelte-outb32{height:30px;border:1px solid var(--border-color-primary, #d1d5db);border-radius:var(--radius-sm, 4px);background:var(--background-fill-primary, white);color:var(--body-text-color, #1f2937);font-size:var(--text-sm, 12px);font-weight:500;padding:0 10px;cursor:pointer}.load-more-button.svelte-outb32:hover{background:var(--background-fill-secondary, #f9fafb)}.empty-state.svelte-outb32{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-outb32 h2:where(.svelte-outb32){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-outb32 p:where(.svelte-outb32){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.empty-state.svelte-outb32 pre:where(.svelte-outb32){background:var(--background-fill-secondary, #f9fafb);padding:16px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:13px;overflow-x:auto}.empty-state.svelte-outb32 code:where(.svelte-outb32){background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.empty-state.svelte-outb32 pre:where(.svelte-outb32) code:where(.svelte-outb32){background:none;padding:0}.reports-page.svelte-iufsej{padding:20px 24px;overflow-y:auto;flex:1}.controls.svelte-iufsej{display:flex;gap:16px;margin-bottom:16px;flex-wrap:wrap;align-items:flex-end}.control.svelte-iufsej{min-width:200px}.filter-pills.svelte-iufsej{display:flex;gap:4px}.pill.svelte-iufsej{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-xxl, 22px);padding:4px 12px;font-size:var(--text-sm, 12px);background:var(--background-fill-secondary, #f9fafb);color:var(--body-text-color-subdued, #6b7280);cursor:pointer;transition:background-color .15s,color .15s}.pill.svelte-iufsej:hover{background:var(--neutral-100, #f3f4f6)}.pill.active.svelte-iufsej{background:var(--color-accent, #f97316);color:#fff;border-color:var(--color-accent, #f97316)}.empty-state.svelte-iufsej{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-iufsej h2:where(.svelte-iufsej){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-iufsej p:where(.svelte-iufsej){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.empty-state.svelte-iufsej pre:where(.svelte-iufsej){background:var(--background-fill-secondary, #f9fafb);padding:16px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:13px;overflow-x:auto}.empty-state.svelte-iufsej code:where(.svelte-iufsej){background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.empty-state.svelte-iufsej pre:where(.svelte-iufsej) code:where(.svelte-iufsej){background:none;padding:0}.alerts-table.svelte-iufsej{width:100%;border-collapse:collapse;font-size:var(--text-md, 14px)}.alerts-table.svelte-iufsej th:where(.svelte-iufsej){text-align:left;padding:8px 12px;border-bottom:2px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color-subdued, #6b7280);font-weight:600;font-size:var(--text-sm, 12px);text-transform:uppercase;letter-spacing:.05em}.alerts-table.svelte-iufsej td:where(.svelte-iufsej){padding:8px 12px;border-bottom:1px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color, #1f2937)}.alerts-table.svelte-iufsej tbody:where(.svelte-iufsej) tr:where(.svelte-iufsej):nth-child(odd){background:var(--table-odd-background-fill, var(--background-fill-primary, white))}.alerts-table.svelte-iufsej tbody:where(.svelte-iufsej) tr:where(.svelte-iufsej):nth-child(2n){background:var(--table-even-background-fill, var(--background-fill-secondary, #f9fafb))}.alerts-table.svelte-iufsej tr:where(.svelte-iufsej):hover{background:var(--background-fill-secondary, #f3f4f6)}.section-title.svelte-iufsej{font-size:16px;font-weight:700;margin:0 0 12px;color:var(--body-text-color, #1f2937)}.reports-section.svelte-iufsej,.alerts-section.svelte-iufsej{margin-bottom:32px}.report-card.svelte-iufsej{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);padding:16px 20px;margin-bottom:12px;background:var(--background-fill-primary, white)}.report-meta.svelte-iufsej{font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280);margin-bottom:8px}.report-content.svelte-iufsej{font-size:var(--text-md, 14px);color:var(--body-text-color, #1f2937);line-height:1.6}.report-content.svelte-iufsej h2{font-size:18px;font-weight:700;margin:0 0 8px}.report-content.svelte-iufsej h3{font-size:16px;font-weight:600;margin:12px 0 6px}.report-content.svelte-iufsej h4{font-size:14px;font-weight:600;margin:10px 0 4px}.report-content.svelte-iufsej code{background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.report-content.svelte-iufsej ul{margin:4px 0;padding-left:20px}.report-content.svelte-iufsej li{margin:2px 0}.report-content.svelte-iufsej p{margin:6px 0}.filter-empty.svelte-iufsej{color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-md, 14px)}.runs-page.svelte-1yb6d54{padding:20px 24px;overflow-y:auto;flex:1}.empty-state.svelte-1yb6d54{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-1yb6d54 h2:where(.svelte-1yb6d54){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-1yb6d54 p:where(.svelte-1yb6d54){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.empty-state.svelte-1yb6d54 pre:where(.svelte-1yb6d54){background:var(--background-fill-secondary, #f9fafb);padding:16px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:13px;overflow-x:auto}.empty-state.svelte-1yb6d54 code:where(.svelte-1yb6d54){background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.empty-state.svelte-1yb6d54 pre:where(.svelte-1yb6d54) code:where(.svelte-1yb6d54){background:none;padding:0}.filter-count-row.svelte-1yb6d54{margin-bottom:12px}.filter-count.svelte-1yb6d54{font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280)}.runs-table.svelte-1yb6d54{width:100%;border-collapse:collapse;font-size:var(--text-md, 14px)}.runs-table.svelte-1yb6d54 th:where(.svelte-1yb6d54){text-align:left;padding:8px 12px;border-bottom:2px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color-subdued, #6b7280);font-weight:600;font-size:var(--text-sm, 12px);text-transform:uppercase;letter-spacing:.05em}.runs-table.svelte-1yb6d54 td:where(.svelte-1yb6d54){padding:8px 12px;border-bottom:1px solid var(--border-color-primary, #e5e7eb);color:var(--body-text-color, #1f2937)}.runs-table.svelte-1yb6d54 tbody:where(.svelte-1yb6d54) tr:where(.svelte-1yb6d54):nth-child(odd){background:var(--table-odd-background-fill, var(--background-fill-primary, white))}.runs-table.svelte-1yb6d54 tbody:where(.svelte-1yb6d54) tr:where(.svelte-1yb6d54):nth-child(2n){background:var(--table-even-background-fill, var(--background-fill-secondary, #f9fafb))}.runs-table.svelte-1yb6d54 tr:where(.svelte-1yb6d54):hover{background:var(--background-fill-secondary, #f3f4f6)}.run-name-cell.svelte-1yb6d54{font-weight:500}.run-name-with-dot.svelte-1yb6d54{display:inline-flex;align-items:center;gap:8px;max-width:100%}.run-dot.svelte-1yb6d54{width:10px;height:10px;border-radius:50%;flex-shrink:0}.link-btn.svelte-1yb6d54{background:none;border:none;color:var(--color-accent, #f97316);cursor:pointer;font:inherit;font-weight:500;padding:0;text-align:left}.link-btn.svelte-1yb6d54:hover{text-decoration:underline}.rename-input.svelte-1yb6d54{font:inherit;padding:2px 6px;border:1px solid var(--color-accent, #f97316);border-radius:var(--radius-sm, 4px);outline:none;width:100%}.actions-wrap.svelte-1yb6d54{display:flex;gap:4px;align-items:center}.action-btn.svelte-1yb6d54{background:none;border:1px solid transparent;color:var(--body-text-color-subdued, #6b7280);cursor:pointer;padding:4px;border-radius:var(--radius-sm, 4px);display:flex;align-items:center}.action-btn.svelte-1yb6d54:hover{background:var(--background-fill-secondary, #f9fafb);border-color:var(--border-color-primary, #e5e7eb);color:var(--body-text-color, #1f2937)}.delete-btn.svelte-1yb6d54:hover{color:#dc2626;border-color:#fecaca;background:#fef2f2}.action-btn.svelte-1yb6d54:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.run-detail-page.svelte-1bpgsx2{padding:20px 24px;overflow-y:auto;flex:1}.detail-card.svelte-1bpgsx2{background:var(--background-fill-primary, white);border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);padding:24px;max-width:800px}.detail-card.svelte-1bpgsx2 h2:where(.svelte-1bpgsx2){color:var(--body-text-color, #1f2937);margin:0 0 16px;font-size:var(--text-xl, 22px)}.detail-card.svelte-1bpgsx2 h3:where(.svelte-1bpgsx2){color:var(--body-text-color, #1f2937);margin:20px 0 8px;font-size:var(--text-lg, 16px)}.detail-grid.svelte-1bpgsx2{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}.detail-item.svelte-1bpgsx2{display:flex;flex-direction:column;gap:2px}.detail-label.svelte-1bpgsx2{font-size:var(--text-xs, 10px);font-weight:600;color:var(--body-text-color-subdued, #9ca3af);text-transform:uppercase}.detail-value.svelte-1bpgsx2{font-size:var(--text-md, 14px);color:var(--body-text-color, #1f2937)}.config-block.svelte-1bpgsx2{background:var(--background-fill-secondary, #f9fafb);padding:12px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:var(--text-sm, 12px);color:var(--body-text-color, #1f2937);overflow-x:auto}.empty-state.svelte-1bpgsx2{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-1bpgsx2 h2:where(.svelte-1bpgsx2){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-1bpgsx2 p:where(.svelte-1bpgsx2){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.empty-state.svelte-1bpgsx2 pre:where(.svelte-1bpgsx2){background:var(--background-fill-secondary, #f9fafb);padding:16px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:13px;overflow-x:auto}.empty-state.svelte-1bpgsx2 code:where(.svelte-1bpgsx2){background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.empty-state.svelte-1bpgsx2 pre:where(.svelte-1bpgsx2) code:where(.svelte-1bpgsx2){background:none;padding:0}.files-page.svelte-1xvfk9n{padding:20px 24px;overflow-y:auto;flex:1}.page-title.svelte-1xvfk9n{color:var(--body-text-color, #1f2937);font-size:16px;font-weight:700;margin:0 0 4px}.page-subtitle.svelte-1xvfk9n{color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-sm, 12px);margin:0 0 16px}.file-list.svelte-1xvfk9n{display:flex;flex-direction:column;gap:4px}.file-item.svelte-1xvfk9n{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);background:var(--background-fill-primary, white);overflow:hidden}.file-item.expanded.svelte-1xvfk9n{border-color:var(--color-accent, #f97316)}.file-row.svelte-1xvfk9n{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;gap:12px}.file-name.svelte-1xvfk9n{display:flex;align-items:center;gap:8px;background:none;border:none;padding:0;font-size:var(--text-md, 14px);color:var(--body-text-color, #1f2937);cursor:pointer;text-align:left}.file-name.svelte-1xvfk9n:hover{color:var(--color-accent, #f97316)}.file-icon.svelte-1xvfk9n{font-size:14px;flex-shrink:0}.file-actions.svelte-1xvfk9n{display:flex;align-items:center;gap:12px;flex-shrink:0}.file-size.svelte-1xvfk9n{font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280);white-space:nowrap}.download-btn.svelte-1xvfk9n{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-md, 6px);color:var(--body-text-color-subdued, #6b7280);transition:background-color .15s,color .15s}.download-btn.svelte-1xvfk9n:hover{background:var(--background-fill-secondary, #f3f4f6);color:var(--body-text-color, #1f2937)}.file-preview.svelte-1xvfk9n{border-top:1px solid var(--border-color-primary, #e5e7eb);padding:12px 14px;background:var(--background-fill-secondary, #f9fafb)}.preview-code.svelte-1xvfk9n{margin:0;font-size:12px;line-height:1.5;max-height:400px;overflow:auto;white-space:pre-wrap;word-break:break-all;color:var(--body-text-color, #1f2937)}.preview-loading.svelte-1xvfk9n,.preview-unavailable.svelte-1xvfk9n{color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-sm, 12px);padding:8px 0}.preview-unavailable.svelte-1xvfk9n a:where(.svelte-1xvfk9n){color:var(--color-accent, #f97316);text-decoration:none}.preview-unavailable.svelte-1xvfk9n a:where(.svelte-1xvfk9n):hover{text-decoration:underline}.empty-state.svelte-1xvfk9n{max-width:640px;padding:40px 24px;color:var(--body-text-color, #1f2937)}.empty-state.svelte-1xvfk9n h2:where(.svelte-1xvfk9n){margin:0 0 8px;font-size:20px;font-weight:700}.empty-state.svelte-1xvfk9n p:where(.svelte-1xvfk9n){margin:12px 0 8px;color:var(--body-text-color-subdued, #6b7280)}.empty-state.svelte-1xvfk9n pre:where(.svelte-1xvfk9n){background:var(--background-fill-secondary, #f9fafb);padding:16px;border-radius:var(--radius-lg, 8px);border:1px solid var(--border-color-primary, #e5e7eb);font-size:13px;overflow-x:auto}.empty-state.svelte-1xvfk9n code:where(.svelte-1xvfk9n){background:var(--background-fill-secondary, #f0f0f0);padding:1px 5px;border-radius:var(--radius-sm, 4px);font-size:13px}.empty-state.svelte-1xvfk9n pre:where(.svelte-1xvfk9n) code:where(.svelte-1xvfk9n){background:none;padding:0}.settings-page.svelte-1ozf5k3{padding:24px 32px;overflow-y:auto;flex:1}.page-title.svelte-1ozf5k3{color:var(--body-text-color, #1f2937);font-size:18px;font-weight:700;margin:0 0 24px}.two-col.svelte-1ozf5k3{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:32px;align-items:start}@media(max-width:900px){.two-col.svelte-1ozf5k3{grid-template-columns:1fr}}.settings-section.svelte-1ozf5k3{margin-bottom:32px}.section-title.svelte-1ozf5k3{color:var(--body-text-color, #1f2937);font-size:15px;font-weight:600;margin:0 0 4px}.section-desc.svelte-1ozf5k3{color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-sm, 12px);margin:0 0 12px;line-height:1.5}.section-desc.svelte-1ozf5k3 code:where(.svelte-1ozf5k3){background:var(--background-fill-secondary, #f3f4f6);padding:1px 5px;border-radius:var(--radius-sm, 3px);font-size:11px}.section-desc.svelte-1ozf5k3 strong:where(.svelte-1ozf5k3){color:var(--color-accent, #f97316)}.theme-switcher.svelte-1ozf5k3{display:inline-flex;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);overflow:hidden}.theme-option.svelte-1ozf5k3{display:inline-flex;align-items:center;gap:6px;padding:8px 20px;border:none;background:var(--background-fill-primary, white);color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-md, 14px);cursor:pointer;transition:all .15s;border-right:1px solid var(--border-color-primary, #e5e7eb)}.theme-option.svelte-1ozf5k3:last-child{border-right:none}.theme-option.svelte-1ozf5k3:hover{color:var(--body-text-color, #1f2937);background:var(--background-fill-secondary, #f9fafb)}.theme-option.selected.svelte-1ozf5k3{background:var(--color-accent, #f97316);color:#fff;font-weight:500}.project-selector.svelte-1ozf5k3{display:flex;align-items:center;gap:10px;margin-bottom:12px}.selector-label.svelte-1ozf5k3{font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280);flex-shrink:0}.selector-select.svelte-1ozf5k3{padding:6px 10px;border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 4px);background:var(--background-fill-primary, white);color:var(--body-text-color, #1f2937);font-size:var(--text-sm, 12px);min-width:160px;cursor:pointer}.selector-select.svelte-1ozf5k3:focus{outline:none;border-color:var(--color-accent, #f97316)}.commands-table.svelte-1ozf5k3{border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-lg, 8px);overflow:hidden}.command-row.svelte-1ozf5k3{display:flex;align-items:center;gap:16px;padding:10px 14px;border-bottom:1px solid var(--border-color-primary, #e5e7eb)}.command-row.svelte-1ozf5k3:last-child{border-bottom:none}.command-label.svelte-1ozf5k3{width:180px;flex-shrink:0;font-size:var(--text-sm, 12px);color:var(--body-text-color-subdued, #6b7280)}.command-value.svelte-1ozf5k3{flex:1;display:flex;align-items:center;gap:8px;min-width:0}.command-value.svelte-1ozf5k3 code:where(.svelte-1ozf5k3){flex:1;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px;color:var(--body-text-color, #1f2937);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.copy-btn.svelte-1ozf5k3{display:flex;align-items:center;justify-content:center;width:26px;height:26px;flex-shrink:0;border:none;background:none;border-radius:var(--radius-md, 4px);color:var(--body-text-color-subdued, #6b7280);cursor:pointer;transition:background-color .15s,color .15s}.copy-btn.svelte-1ozf5k3:hover{background:var(--background-fill-secondary, #f3f4f6);color:var(--body-text-color, #1f2937)}.copy-btn.copied.svelte-1ozf5k3{color:var(--color-accent, #f97316)}.agent-tabs.svelte-1ozf5k3{display:flex;border-bottom:1px solid var(--border-color-primary, #e5e7eb);gap:0;margin-bottom:0}.agent-tab.svelte-1ozf5k3{padding:8px 16px;border:none;background:none;color:var(--body-text-color-subdued, #6b7280);font-size:var(--text-sm, 12px);cursor:pointer;border-bottom:2px solid transparent;transition:all .15s;white-space:nowrap}.agent-tab.svelte-1ozf5k3:hover{color:var(--body-text-color, #1f2937)}.agent-tab.active.svelte-1ozf5k3{color:var(--color-accent, #f97316);border-bottom-color:var(--color-accent, #f97316);font-weight:500}.agent-panel.svelte-1ozf5k3{border:1px solid var(--border-color-primary, #e5e7eb);border-top:none;border-radius:0 0 var(--radius-lg, 8px) var(--radius-lg, 8px);padding:16px}.install-block.svelte-1ozf5k3{margin-bottom:16px}.install-label.svelte-1ozf5k3{display:block;font-size:11px;font-weight:500;color:var(--body-text-color-subdued, #6b7280);text-transform:uppercase;letter-spacing:.04em;margin-bottom:6px}.install-cmd.svelte-1ozf5k3{display:flex;align-items:center;gap:8px;background:var(--background-fill-secondary, #f3f4f6);border-radius:var(--radius-md, 4px);padding:8px 10px}.install-cmd.svelte-1ozf5k3 code:where(.svelte-1ozf5k3){flex:1;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:12px;color:var(--body-text-color, #1f2937);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.example-block.svelte-1ozf5k3{background:var(--background-fill-secondary, #f9fafb);border:1px solid var(--border-color-primary, #e5e7eb);border-radius:var(--radius-md, 4px);padding:12px}.example-header.svelte-1ozf5k3{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.example-label.svelte-1ozf5k3{font-size:11px;font-weight:500;color:var(--body-text-color-subdued, #6b7280);text-transform:uppercase;letter-spacing:.04em}.example-text.svelte-1ozf5k3{margin:0;font-size:var(--text-sm, 12px);color:var(--body-text-color, #1f2937);line-height:1.6;font-style:italic}*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;background:var(--background-fill-primary, #fff);color:var(--body-text-color, #1f2937);font-size:var(--text-md, 14px);-webkit-font-smoothing:antialiased}.app.svelte-1n46o8q{display:flex;height:100vh;overflow:hidden}.main.svelte-1n46o8q{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0}.page-content.svelte-1n46o8q{flex:1;overflow:hidden;display:flex;background:var(--bg-primary)} diff --git a/trackio/frontend/dist/index.html b/trackio/frontend/dist/index.html new file mode 100644 index 0000000000000000000000000000000000000000..35d5e979a28bd3bafb8b6bc02f52c6ab33724587 --- /dev/null +++ b/trackio/frontend/dist/index.html @@ -0,0 +1,14 @@ + + + + + + Trackio Dashboard + + + + + +
        + + diff --git a/trackio/frontend/eslint.config.js b/trackio/frontend/eslint.config.js new file mode 100644 index 0000000000000000000000000000000000000000..c0bd968851d9ee35d98943b9c2b04b91af245322 --- /dev/null +++ b/trackio/frontend/eslint.config.js @@ -0,0 +1,42 @@ +import js from "@eslint/js"; +import svelte from "eslint-plugin-svelte"; +import svelteParser from "svelte-eslint-parser"; +import globals from "globals"; + +export default [ + { ignores: ["dist/**", "node_modules/**"] }, + { + files: ["**/*.js"], + languageOptions: { + globals: { + ...globals.browser, + ...globals.es2021, + $state: "readonly", + $derived: "readonly", + $effect: "readonly", + $props: "readonly", + $bindable: "readonly", + $inspect: "readonly", + }, + }, + rules: { + ...js.configs.recommended.rules, + "no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + "no-empty": "off", + }, + }, + { + files: ["**/*.svelte"], + languageOptions: { + parser: svelteParser, + globals: { ...globals.browser, ...globals.es2021 }, + }, + plugins: { svelte }, + rules: { + ...js.configs.recommended.rules, + ...svelte.configs.recommended.rules, + "no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^\\$" }], + "no-empty": "off", + }, + }, +]; diff --git a/trackio/frontend/index.html b/trackio/frontend/index.html new file mode 100644 index 0000000000000000000000000000000000000000..c3d5e2df6bb7db117ed1d554ea7d8d180b076799 --- /dev/null +++ b/trackio/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + Trackio Dashboard + + + +
        + + + diff --git a/trackio/frontend_config.py b/trackio/frontend_config.py new file mode 100644 index 0000000000000000000000000000000000000000..cd40a82e907f7d88dbf9335dc341f999f206f5f0 --- /dev/null +++ b/trackio/frontend_config.py @@ -0,0 +1,175 @@ +import json +import os +import shutil +from dataclasses import dataclass +from pathlib import Path + +from huggingface_hub.constants import HF_HOME + +TRACKIO_USER_HOME = Path(HF_HOME) / "trackio" +TRACKIO_CONFIG_PATH = TRACKIO_USER_HOME / "config.json" +BUNDLED_FRONTEND_DIR = Path(__file__).parent / "frontend" / "dist" +STARTER_FRONTEND_DIR = Path(__file__).parent / "frontend_templates" / "starter" + + +@dataclass(frozen=True) +class ResolvedFrontend: + path: Path + source: str + is_custom: bool + used_fallback: bool = False + requested_path: Path | None = None + + +def _normalize_frontend_path(path: str | Path) -> Path: + return Path(path).expanduser().resolve() + + +def is_valid_frontend_dir(path: str | Path | None) -> bool: + if path is None: + return False + frontend_dir = _normalize_frontend_path(path) + return frontend_dir.is_dir() and (frontend_dir / "index.html").is_file() + + +def _is_empty_directory(path: Path) -> bool: + return path.is_dir() and not any(path.iterdir()) + + +def _copy_starter_template(destination: Path) -> None: + destination.mkdir(parents=True, exist_ok=True) + for child in STARTER_FRONTEND_DIR.iterdir(): + target = destination / child.name + if child.is_dir(): + shutil.copytree(child, target, dirs_exist_ok=True) + else: + shutil.copy2(child, target) + + +def _materialize_argument_frontend_dir(candidate: Path) -> bool: + existed_before = candidate.exists() + if existed_before and not _is_empty_directory(candidate): + return False + + _copy_starter_template(candidate) + state = "did not exist" if not existed_before else "was empty" + print( + f"* Trackio frontend directory from argument {state}: {candidate}. " + "Copied the starter template into it and serving that directory." + ) + return True + + +def load_trackio_config() -> dict: + if not TRACKIO_CONFIG_PATH.is_file(): + return {} + try: + data = json.loads(TRACKIO_CONFIG_PATH.read_text()) + except (json.JSONDecodeError, OSError): + return {} + return data if isinstance(data, dict) else {} + + +def save_trackio_config(config: dict) -> None: + TRACKIO_USER_HOME.mkdir(parents=True, exist_ok=True) + TRACKIO_CONFIG_PATH.write_text(json.dumps(config, indent=2, sort_keys=True) + "\n") + + +def get_persisted_frontend_dir() -> Path | None: + frontend_dir = load_trackio_config().get("frontend_dir") + if not frontend_dir: + return None + return _normalize_frontend_path(frontend_dir) + + +def set_persisted_frontend_dir(path: str | Path) -> Path: + frontend_dir = _normalize_frontend_path(path) + if not is_valid_frontend_dir(frontend_dir): + raise ValueError( + f"Invalid frontend directory: {frontend_dir}. Expected a directory containing index.html." + ) + config = load_trackio_config() + config["frontend_dir"] = str(frontend_dir) + save_trackio_config(config) + return frontend_dir + + +def unset_persisted_frontend_dir() -> bool: + config = load_trackio_config() + if "frontend_dir" not in config: + return False + del config["frontend_dir"] + if config: + save_trackio_config(config) + elif TRACKIO_CONFIG_PATH.exists(): + TRACKIO_CONFIG_PATH.unlink() + return True + + +def _configured_frontend_candidates( + frontend_dir: str | Path | None, +) -> list[tuple[str, Path]]: + candidates: list[tuple[str, Path]] = [] + if frontend_dir is not None: + candidates.append(("argument", _normalize_frontend_path(frontend_dir))) + env_dir = os.environ.get("TRACKIO_FRONTEND_DIR") + if env_dir: + candidates.append(("env", _normalize_frontend_path(env_dir))) + persisted_dir = get_persisted_frontend_dir() + if persisted_dir is not None: + candidates.append(("config", persisted_dir)) + return candidates + + +def _announce_config_frontend(frontend_dir: Path) -> None: + print( + f"* Using Trackio custom frontend from config: {frontend_dir}\n" + " Reset with `trackio config unset frontend`." + ) + + +def resolve_frontend_dir( + frontend_dir: str | Path | None = None, + *, + announce: bool = False, +) -> ResolvedFrontend: + for source, candidate in _configured_frontend_candidates(frontend_dir): + if source == "argument": + if not candidate.exists() or _is_empty_directory(candidate): + _materialize_argument_frontend_dir(candidate) + + if is_valid_frontend_dir(candidate): + if source == "config" and announce: + _announce_config_frontend(candidate) + return ResolvedFrontend( + path=candidate, + source=source, + is_custom=True, + ) + if source == "argument": + print( + f"* Trackio frontend from {source} is invalid: {candidate}. " + f"Falling back to starter template at {STARTER_FRONTEND_DIR}." + ) + return ResolvedFrontend( + path=STARTER_FRONTEND_DIR, + source="starter", + is_custom=True, + used_fallback=True, + requested_path=candidate, + ) + print(f"* Trackio frontend from {source} is invalid: {candidate}. Ignoring it.") + + if is_valid_frontend_dir(BUNDLED_FRONTEND_DIR): + return ResolvedFrontend( + path=BUNDLED_FRONTEND_DIR, + source="bundled", + is_custom=False, + ) + + return ResolvedFrontend( + path=STARTER_FRONTEND_DIR, + source="starter", + is_custom=True, + used_fallback=True, + ) diff --git a/trackio/frontend_server.py b/trackio/frontend_server.py new file mode 100644 index 0000000000000000000000000000000000000000..ddc15bea45a43247bae2243e4644ecb571d8aabf --- /dev/null +++ b/trackio/frontend_server.py @@ -0,0 +1,146 @@ +"""Serves a static frontend alongside the Trackio HTTP API.""" + +import hashlib +import logging +from pathlib import Path + +from starlette.middleware.base import BaseHTTPMiddleware +from starlette.responses import FileResponse, HTMLResponse, JSONResponse +from starlette.routing import Mount, Route +from starlette.staticfiles import StaticFiles + +ASSETS_DIR = Path(__file__).parent / "assets" + +_logger = logging.getLogger(__name__) + +_LIVE_RELOAD_SCRIPT = """ + +""".strip() + + +def _frontend_version(frontend_root: Path) -> str: + digest = hashlib.sha256() + for path in sorted(frontend_root.rglob("*")): + if not path.is_file(): + continue + relative = path.relative_to(frontend_root) + digest.update(str(relative).encode("utf-8")) + stat = path.stat() + digest.update(str(stat.st_mtime_ns).encode("utf-8")) + digest.update(str(stat.st_size).encode("utf-8")) + return digest.hexdigest() + + +def _inject_live_reload(html: str) -> str: + if "/__trackio/frontend_version" in html: + return html + if "" in html: + return html.replace("", f"{_LIVE_RELOAD_SCRIPT}\n ") + return html + _LIVE_RELOAD_SCRIPT + + +def _html_response(path: Path) -> HTMLResponse: + html = path.read_text(encoding="utf-8") + return HTMLResponse(_inject_live_reload(html)) + + +class FrontendMiddleware(BaseHTTPMiddleware): + def __init__(self, app, frontend_root: Path, index_html_path: Path): + super().__init__(app) + self.frontend_root = frontend_root + self.index_html_path = index_html_path + self.reserved_prefixes = ( + "/api/", + "/file", + "/version", + "/artifact_blob/", + "/static/trackio", + "/__trackio/frontend_version", + "/oauth/", + "/login/", + "/mcp", + ) + self.reserved_exact = { + "/api", + "/oauth", + "/login", + } + + async def dispatch(self, request, call_next): + if request.method not in {"GET", "HEAD"}: + return await call_next(request) + + path = request.url.path + if path in self.reserved_exact or path.startswith(self.reserved_prefixes): + return await call_next(request) + + relative_path = path.lstrip("/") + requested_path = (self.frontend_root / relative_path).resolve() + if ( + relative_path + and requested_path.is_file() + and requested_path.is_relative_to(self.frontend_root) + ): + if requested_path.suffix.lower() == ".html": + return _html_response(requested_path) + return FileResponse(requested_path) + + return _html_response(self.index_html_path) + + +def mount_frontend(app, frontend_dir: str | Path): + frontend_root = Path(frontend_dir).resolve() + if not frontend_root.exists(): + _logger.warning( + "Trackio dashboard UI was not mounted: %s is missing. " + "Build the frontend or provide a custom frontend directory.", + frontend_root, + ) + return + + index_html_path = frontend_root / "index.html" + if not index_html_path.exists(): + _logger.warning( + "Trackio dashboard UI was not mounted: %s is missing.", + index_html_path, + ) + return + + async def frontend_version(_request): + return JSONResponse({"version": _frontend_version(frontend_root)}) + + static_assets = StaticFiles(directory=str(ASSETS_DIR)) + + app.add_middleware( + FrontendMiddleware, + frontend_root=frontend_root, + index_html_path=index_html_path, + ) + app.routes.append(Mount("/static/trackio", app=static_assets)) + app.routes.append( + Route("/__trackio/frontend_version", frontend_version, methods=["GET"]) + ) diff --git a/trackio/frontend_templates/logbook/bucket-icon.svg b/trackio/frontend_templates/logbook/bucket-icon.svg new file mode 100644 index 0000000000000000000000000000000000000000..b7ce1dac0d70d7ca8e392aff3a534b756041708d --- /dev/null +++ b/trackio/frontend_templates/logbook/bucket-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/trackio/frontend_templates/logbook/index.html b/trackio/frontend_templates/logbook/index.html new file mode 100644 index 0000000000000000000000000000000000000000..f386be9033f4b4367329ef2e99b6866a3f98f26a --- /dev/null +++ b/trackio/frontend_templates/logbook/index.html @@ -0,0 +1,54 @@ + + + + + + Trackio Logbook + + + +
        + +
        +
        +
        +
        + + + + + + diff --git a/trackio/frontend_templates/logbook/logbook.css b/trackio/frontend_templates/logbook/logbook.css new file mode 100644 index 0000000000000000000000000000000000000000..73d4dc7b77d0db02e4acbc804ca43c68c5189a12 --- /dev/null +++ b/trackio/frontend_templates/logbook/logbook.css @@ -0,0 +1,1522 @@ +:root { + --bg: #ffffff; + --paper: #fdfcf9; + --panel: #ffffff; + --ink: #1f2937; + --muted: #6b7280; + --line: #e5e7eb; + --accent: #f97316; + --accent-strong: #ea580c; + --accent-soft: #fff7ed; + --accent-line: rgba(249, 115, 22, 0.16); + --grid-line: rgba(31, 41, 55, 0.045); + --code-bg: #f3f4f6; + --radius: 12px; + --serif: ui-serif, "Iowan Old Style", "Palatino Linotype", Georgia, serif; + --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, + sans-serif; + --mono: "SFMono-Regular", "Cascadia Mono", "JetBrains Mono", Menlo, Consolas, + ui-monospace, monospace; +} + +* { + box-sizing: border-box; +} + +html, +body { + margin: 0; + padding: 0; +} + +html { + scroll-behavior: smooth; +} + +body { + background: var(--bg); + color: var(--ink); + font-family: var(--sans); + font-size: 16px; + line-height: 1.65; + -webkit-font-smoothing: antialiased; +} + +#app { + display: flex; + min-height: 100vh; +} + +/* ---- sidebar (composition-book cover) ---- */ +#sidebar { + width: 280px; + flex: 0 0 280px; + background: #17181c; + color: #e7e7ea; + position: sticky; + top: 0; + height: 100vh; + overflow-y: auto; + padding: 22px 16px; + display: flex; + flex-direction: column; +} + +#book-head { + display: flex; + align-items: center; + gap: 10px; + padding: 8px; + margin-bottom: 12px; + border-radius: 10px; + cursor: pointer; + transition: background 0.12s; +} +#book-head:hover { + background: rgba(255, 255, 255, 0.05); +} +#book-wordmark { + width: 154px; + height: auto; + object-fit: contain; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +#tree { + flex: 1; + padding-top: 8px; +} + +#tree a { + display: block; + padding: 6px 10px; + border-radius: 8px; + color: #c3c4cb; + text-decoration: none; + font-size: 14px; + transition: background 0.12s, color 0.12s; +} + +#tree a:hover { + background: rgba(255, 255, 255, 0.06); + color: #ffffff; +} + +#tree a.active { + background: rgba(249, 115, 22, 0.16); + color: #fdba74; + font-weight: 600; +} + +#tree .depth-1 { + padding-left: 22px; +} +#tree .depth-2 { + padding-left: 34px; +} +#tree .depth-3 { + padding-left: 46px; +} + + +/* ---- content ---- */ +#content { + flex: 1; + min-width: 0; + padding: 48px 40px 120px; + background-color: var(--paper); + background-image: + linear-gradient(var(--grid-line) 1px, transparent 1px), + linear-gradient(90deg, var(--grid-line) 1px, transparent 1px); + background-size: 26px 26px; + background-position: center top; +} + +#page { + width: 100%; + min-width: 0; + max-width: 1052px; + margin: 0 auto; +} + +.page-section { + scroll-margin-top: 40px; + padding: 0 0 70px; + margin: 0 0 64px; +} + +.page-section:last-child { + margin-bottom: 0; +} + +.page-layout { + display: grid; + grid-template-columns: minmax(0, 760px) 248px; + gap: 44px; + align-items: start; +} + +.page-body { + min-width: 0; +} + +.resource-anchor { + display: block; + height: 0; + overflow: hidden; +} + +/* ---- pinned notes ---- */ +.pinned-notes { + margin: 30px 0 0; +} +.pinned-notes-list .cell { + margin: 0; + border-color: rgba(249, 115, 22, 0.55); +} +.pinned-notes-list .cell + .cell { + margin-top: 12px; +} +.cell.pinned-source { + border-color: rgba(249, 115, 22, 0.55); +} +.book-intro.has-pinned-notes { + border-bottom: none; + padding-bottom: 22px; + margin-bottom: 30px; +} +.book-intro.book-intro-tight { + border-bottom: none; + padding-bottom: 4px; + margin-bottom: 20px; +} + +#page h1 { + font-family: var(--serif); + font-size: 34px; + line-height: 1.15; + letter-spacing: -0.02em; + margin: 0 0 8px; + overflow-wrap: anywhere; +} + +#page h2 { + font-family: var(--serif); + font-size: 24px; + margin: 36px 0 10px; +} + +#page h3 { + font-size: 17px; + font-weight: 700; + margin: 26px 0 2px; + letter-spacing: -0.01em; +} + +#page h3::before { + content: ""; + display: inline-block; + width: 7px; + height: 7px; + border-radius: 2px; + background: var(--accent); + margin-right: 10px; + vertical-align: middle; + transform: translateY(-1px); +} + +#page p { + margin: 10px 0; +} + +#page blockquote { + margin: 14px 0; + padding: 2px 16px; + border-left: 3px solid #fdba74; + color: var(--muted); +} + +#page hr { + display: none; +} + +#page code { + font-family: var(--mono); + font-size: 0.86em; + background: var(--code-bg); + padding: 2px 6px; + border-radius: 6px; +} + +#page pre { + max-width: 100%; + background: var(--code-bg); + border: 1px solid var(--line); + border-radius: var(--radius); + padding: 14px 16px; + overflow-x: auto; +} +#page pre code { + background: none; + padding: 0; + font-size: 11.5px; +} + +/* ---- code blocks + collapsible accordion ---- */ +#page pre.hl { + background: #17181c; + border: none; + color: #e7e7ea; + font-size: 13px; + line-height: 1.58; +} +#page pre.hl code { + color: inherit; + font-family: var(--mono); +} +.code-accordion { + border: 1px solid rgba(249, 115, 22, 0.2); + border-radius: 8px; + overflow: hidden; + margin: 12px 0; + background: #17181c; +} +.code-accordion summary { + list-style: none; + cursor: pointer; + display: flex; + align-items: center; + gap: 9px; + padding: 9px 12px; + font-family: var(--mono); + font-size: 11.5px; + font-weight: 700; + color: #e7e7ea; + background: #1e2027; + user-select: none; + overflow-wrap: anywhere; +} +.code-accordion summary::-webkit-details-marker { + display: none; +} +.code-accordion summary::after { + content: "▸"; + margin-left: auto; + color: var(--accent); + transition: transform 0.12s; + transform: rotate(180deg); +} +.code-accordion[open] summary::after { + transform: rotate(90deg); +} +.code-accordion .code-ico { + color: var(--accent); + font-weight: 700; +} +.code-accordion pre.hl { + margin: 0; + border-radius: 0; + border: none; + border-top: 1px solid rgba(249, 115, 22, 0.16); +} +.tok-comment { + color: #7a7d87; + font-style: italic; +} +.tok-string { + color: #a5d6a7; +} +.tok-keyword { + color: #fdba74; +} +.tok-number { + color: #7fd0e0; +} + +#page a { + color: var(--accent); +} + +#page ul { + padding-left: 20px; +} + +.ts { + font-family: var(--mono); + font-size: 12px; + color: var(--muted); + background: none; + padding: 0; +} + +/* ---- notebook-style cells ---- */ +.cell { + max-width: 100%; + border: 1px solid var(--line); + border-radius: 10px; + background: rgba(255, 255, 255, 0.86); + margin: 18px 0; + overflow: hidden; + box-shadow: 0 2px 10px rgba(31, 41, 55, 0.035); +} +.cell-head { + display: flex; + justify-content: space-between; + gap: 16px; + align-items: center; + padding: 14px 18px; + background: rgba(255, 255, 255, 0.92); + border-bottom: 1px solid var(--line); +} +.cell-head.no-title { + justify-content: flex-end; + padding-top: 10px; + padding-bottom: 10px; +} +.cell-title { + flex: 1; + min-width: 0; + font-size: 15.5px; + font-weight: 650; + color: var(--ink); + line-height: 1.35; + overflow-wrap: anywhere; +} +.cell-meta { + flex: 0 0 auto; + font-family: var(--sans); + font-size: 13px; + color: var(--muted); +} +.cell-body { + min-width: 0; + padding: 14px 18px 18px; +} +#page .cell-body h1, +#page .cell-body h2 { + font-family: var(--sans); + font-size: 17px; + font-weight: 700; + letter-spacing: -0.01em; + line-height: 1.35; + margin: 22px 0 6px; +} +#page .cell-body > :first-child { + margin-top: 0; +} +#page .cell-body > :last-child { + margin-bottom: 0; +} +.cell.code .cell-head { + background: #fbfbfc; +} +.figure-fit { + position: relative; + overflow: hidden; + min-height: 160px; + border: 1px solid var(--line); + border-radius: 8px; + background: #fff; +} +.figure-fit[hidden] { + display: none; +} +.figure-frame { + display: block; + width: 100%; + min-height: 160px; + border: none; + background: #fff; +} +.figure-frame[hidden], +.figure-raw[hidden] { + display: none; +} +.fig-switch { + position: relative; + display: inline-flex; + flex: 0 0 auto; + border: 1px solid var(--line); + border-radius: 999px; + background: var(--code-bg); + padding: 2px; +} +.fig-switch button { + position: relative; + z-index: 1; + flex: 1; + min-width: 62px; + border: none; + background: none; + font-family: var(--sans); + font-size: 12px; + font-weight: 600; + color: var(--muted); + padding: 3px 12px; + border-radius: 999px; + cursor: pointer; + transition: color 0.15s; +} +.fig-switch button.active { + color: var(--accent-strong); +} +.fig-switch-thumb { + position: absolute; + top: 2px; + bottom: 2px; + left: 2px; + width: calc(50% - 2px); + border-radius: 999px; + background: var(--panel); + border: 1px solid rgba(249, 115, 22, 0.35); + box-shadow: 0 1px 4px rgba(31, 41, 55, 0.08); + transition: transform 0.18s ease; +} +.fig-switch.raw .fig-switch-thumb { + transform: translateX(100%); +} +#page .figure-raw pre { + margin: 0; + max-height: 420px; + overflow: auto; + font-family: var(--mono); + font-size: 13px; + line-height: 1.55; + background: var(--code-bg); + border: 1px solid var(--line); + border-radius: 8px; + padding: 12px 14px; +} +/* ---- copyable snippets ---- */ +.snippet { + position: relative; +} +.copy-snippet { + position: absolute; + top: 7px; + right: 8px; + width: 24px; + height: 24px; + border: none; + border-radius: 6px; + background: rgba(255, 255, 255, 0.08); + color: #9a9da8; + font-size: 12px; + line-height: 1; + cursor: pointer; + opacity: 0; + transition: opacity 0.12s, color 0.12s, background 0.12s; +} +.snippet:hover .copy-snippet, +.jp-out:hover .copy-snippet, +.figure-raw:hover .copy-snippet, +.code-accordion summary:hover .copy-snippet { + opacity: 1; +} +.copy-snippet:hover { + color: #ffffff; + background: rgba(255, 255, 255, 0.16); +} +.copy-snippet.copied { + color: #52d08a; + opacity: 1; +} +.code-accordion .code-name { + user-select: text; + cursor: text; +} +.jp-out, +.figure-raw { + position: relative; +} +.jp-out .copy-snippet, +.figure-raw .copy-snippet { + background: var(--code-bg); + color: var(--muted); + border: 1px solid var(--line); +} +.jp-out .copy-snippet:hover, +.figure-raw .copy-snippet:hover { + color: var(--accent-strong); + background: var(--panel); +} + +/* ---- jupyter-style code cells ---- */ +.jp { + border: 1px solid var(--line); + border-radius: 10px; + overflow: hidden; + margin: 12px 0; + background: var(--panel); +} +.jp-gutter { + flex: 0 0 46px; + padding: 13px 0 0 13px; + font-family: var(--mono); + font-size: 10.5px; + letter-spacing: 0.07em; + text-transform: uppercase; + font-weight: 600; + user-select: none; +} +.jp-in { + display: flex; + background: #17181c; +} +.jp-in .jp-gutter { + color: #6f727d; +} +.jp-in-body { + flex: 1; + min-width: 0; +} +#page .jp-in-body pre.hl { + margin: 0; + border: none; + border-radius: 0; + background: none; + padding: 12px 16px 12px 0; +} +.jp-in-body .code-accordion { + margin: 0; + border: none; + border-top: 1px solid rgba(255, 255, 255, 0.09); + border-radius: 0; + background: none; +} +.jp-in-body .code-accordion summary { + background: none; + padding: 9px 16px 9px 0; +} +.jp-in-body .code-accordion pre.hl { + border-top: 1px solid rgba(255, 255, 255, 0.09); +} +.jp-meta { + padding: 5px 14px; + font-family: var(--mono); + font-size: 11.5px; + color: var(--muted); + background: #fbfbfc; + border-top: 1px solid var(--line); +} +.jp-out { + display: flex; + border-top: 1px solid var(--line); + background: var(--panel); +} +.jp-out .jp-gutter { + color: var(--accent-strong); +} +.jp-out-body { + flex: 1; + min-width: 0; +} +#page .jp-out-pre { + min-width: 0; + margin: 0; + border: none; + border-radius: 0; + background: none; + color: var(--ink); + font-family: var(--mono); + font-size: 13px; + line-height: 1.55; + padding: 12px 16px 12px 0; + white-space: pre; + overflow-x: auto; + overflow-y: auto; + max-height: 26em; +} +.jp-artifacts { + display: flex; + flex-direction: column; +} +.jp-out-body .jp-out-pre + .jp-artifacts { + border-top: 1px solid var(--line); +} +.out-artifact { + display: flex; + align-items: baseline; + gap: 8px; + padding: 9px 16px 9px 0; + text-decoration: none; + color: inherit; +} +.out-artifact + .out-artifact { + border-top: 1px solid var(--line); +} +a.out-artifact:hover .out-artifact-name { + color: var(--accent-strong); +} +.out-artifact-ico { + flex: 0 0 auto; + font-size: 13px; +} +.out-artifact-name { + font-family: var(--mono); + font-size: 12.5px; + font-weight: 600; + color: var(--ink); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.out-artifact-meta { + flex: 0 0 auto; + margin-left: auto; + padding-left: 12px; + font-size: 12px; + color: var(--muted); + white-space: nowrap; +} +.out-artifact-state.open { + color: var(--accent); + font-weight: 600; +} +.trackio-embed { + border: 1px solid var(--line); + border-radius: var(--radius); + overflow: hidden; + background: var(--panel); +} +.trackio-cell-meta { + display: flex; + gap: 6px; + flex-wrap: wrap; + justify-content: flex-end; +} + +/* ---- unfurl cards ---- */ +.unfurl { + display: block; + border: 1px solid var(--line); + border-radius: var(--radius); + background: var(--panel); + margin: 12px 0; + overflow: hidden; + text-decoration: none; + color: inherit; + transition: border-color 0.14s, box-shadow 0.14s; +} +.unfurl:hover { + border-color: #cfcbe6; + box-shadow: 0 4px 18px rgba(30, 20, 80, 0.06); +} + +.unfurl-body { + padding: 13px 16px; + display: flex; + gap: 12px; + align-items: flex-start; +} + +.unfurl-ico { + font-size: 20px; + line-height: 1.3; + flex: 0 0 auto; +} + +.unfurl-main { + min-width: 0; + flex: 1; +} + +.unfurl-kind { + font-family: var(--mono); + font-size: 10.5px; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--accent); + font-weight: 600; +} + +.unfurl-title { + font-weight: 650; + font-size: 15px; + margin: 1px 0 2px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.unfurl-desc { + color: var(--muted); + font-size: 13.5px; + line-height: 1.45; +} + +.unfurl-meta { + margin-top: 6px; + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.chip { + font-size: 11.5px; + background: var(--code-bg); + border-radius: 999px; + padding: 2px 9px; + color: var(--muted); + font-family: var(--mono); +} + +.unfurl-raw { + font-family: var(--mono); + font-size: 11px; + color: var(--muted); + border-top: 1px solid var(--line); + padding: 7px 16px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.unfurl.embed { + padding: 0; + overflow: hidden; +} +.embed-head { + display: flex; + align-items: center; + gap: 10px; + padding: 10px 14px; + border-bottom: 1px solid var(--line); +} +.embed-head .unfurl-kind { + flex: 0 0 auto; +} +.embed-title { + flex: 1; + min-width: 0; + font-weight: 650; + font-size: 14px; + color: var(--ink); + text-decoration: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.embed-title:hover { + color: var(--accent); +} +.embed-open { + flex: 0 0 auto; + font-family: var(--mono); + font-size: 12px; + color: var(--accent); + text-decoration: none; +} +.embed-frame { + display: block; + width: 100%; + height: 560px; + border: 0; + background: var(--code-bg); +} + +.unfurl.image { + padding: 0; +} +.unfurl.image img { + display: block; + width: 100%; + height: auto; + max-height: 460px; + object-fit: contain; + background: var(--code-bg); +} + +.artifact-chip { + border: 1px solid var(--line); + background: var(--panel); + border-radius: var(--radius); + padding: 10px 14px; + margin: 8px 0; + font-size: 14px; +} +.artifact-chip code { + color: var(--accent); +} + +/* ---- task board ---- */ +.board-wrap { + overflow-x: auto; + border: 1px solid var(--line); + border-radius: var(--radius); + margin: 12px 0 20px; + background: var(--panel); +} +table.board { + border-collapse: collapse; + width: 100%; + font-size: 14px; +} +table.board th, +table.board td { + text-align: left; + padding: 9px 14px; + border-bottom: 1px solid var(--line); + vertical-align: top; +} +table.board thead th { + background: var(--accent-soft); + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.05em; + color: #9a4a12; + font-weight: 600; + border-bottom: 1px solid var(--line); +} +table.board tbody tr:last-child td { + border-bottom: none; +} +table.board .col-check { + text-align: center; + width: 92px; + white-space: nowrap; +} +table.board tr.section-row td { + background: var(--accent-soft); + text-align: center; + font-weight: 700; + font-size: 13px; + color: var(--accent-strong); + padding: 7px 14px; + letter-spacing: 0.02em; +} +.box { + display: inline-flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + border: 1.5px solid #cfcbe0; + border-radius: 5px; + font-size: 12px; + color: #fff; + line-height: 1; +} +.box.on { + background: var(--accent); + border-color: var(--accent); +} +.who-chip { + display: inline-block; + padding: 3px 12px; + border-radius: 999px; + font-size: 12.5px; + font-weight: 600; + white-space: nowrap; +} +.who-chip.muted { + background: var(--code-bg); + color: var(--muted); + font-weight: 500; +} + +/* ---- status badges + clickable rows ---- */ +table.board .col-status { + width: 130px; + white-space: nowrap; +} +.badge { + display: inline-block; + padding: 3px 11px; + border-radius: 999px; + font-size: 12px; + font-weight: 600; + letter-spacing: 0.01em; +} +.badge.gray { + background: var(--code-bg); + color: var(--muted); +} +.badge.amber { + background: var(--accent-soft); + color: #b45309; +} +.badge.green { + background: #e6f7ee; + color: #1a8a55; +} +.badge.red { + background: #fde8ec; + color: #c62a4b; +} +table.board tr.linked-row { + cursor: pointer; +} +table.board tr.linked-row:hover td { + background: var(--accent-soft); +} +table.board tr.linked-row a { + color: var(--ink); + font-weight: 600; + text-decoration: none; +} +table.board tr.linked-row:hover a { + color: var(--accent-strong); +} + +/* ---- agent read hint ---- */ +.agent-hint { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 8px; + margin: 4px 0 22px; + font-size: 12.5px; + color: var(--muted); +} +#page .agent-hint code { + background: var(--code-bg); + padding: 2px 9px; + border-radius: 6px; + font-family: var(--mono); + font-size: 12px; + font-weight: 500; + color: var(--ink); +} +.agent-hint .copy { + flex: 0 0 auto; + background: none; + color: var(--muted); + border: 1px solid var(--line); + border-radius: 6px; + width: 22px; + height: 22px; + font-size: 11px; + line-height: 1; + cursor: pointer; + transition: color 0.12s, border-color 0.12s; +} +.agent-hint .copy:hover { + color: var(--accent-strong); + border-color: var(--accent); +} +.agent-hint .copy.copied { + color: #1a8a55; + border-color: #1a8a55; +} +.agent-hint-note { + margin-left: auto; + font-size: 12px; + color: var(--muted); +} + +/* ---- logbook summary stats ---- */ +.logbook-stats { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin: 0 0 28px; +} +.stat-tile { + position: relative; + display: inline-flex; + align-items: center; + gap: 12px; + border: 1px solid var(--line); + background: var(--panel); + border-radius: var(--radius); + padding: 14px 26px; + font: inherit; + text-align: left; + cursor: pointer; + transition: border-color 0.12s, box-shadow 0.12s; +} +.stat-tile:hover:not([disabled]) { + border-color: rgba(249, 115, 22, 0.45); + box-shadow: 0 3px 12px rgba(31, 41, 55, 0.06); +} +.stat-tile:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} +.stat-tile[disabled] { + cursor: default; + opacity: 0.7; +} +.stat-tile.open { + border-color: rgba(249, 115, 22, 0.6); + box-shadow: 0 3px 12px rgba(31, 41, 55, 0.08); +} +.stat-icon { + width: 24px; + height: 24px; + flex: 0 0 24px; + object-fit: contain; + align-self: center; +} +.stat-text { + display: flex; + align-items: baseline; + gap: 8px; + white-space: nowrap; + line-height: 1; +} +.stat-num { + font-family: var(--mono); + font-size: 20px; + font-weight: 600; + line-height: 1; + color: var(--accent-strong); +} +.stat-label { + font-size: 15px; + line-height: 1; + color: var(--muted); +} +.stat-caret { + margin-left: 2px; + font-size: 10px; + color: var(--muted); + align-self: center; + transition: transform 0.12s; +} +.stat-tile.open .stat-caret { + transform: rotate(180deg); +} +.stat-popover { + position: absolute; + top: 100%; + left: 0; + margin-top: 6px; + min-width: 300px; + max-width: min(460px, 92vw); + max-height: 340px; + overflow-y: auto; + z-index: 20; + background: var(--panel); + border: 1px solid var(--line); + border-radius: var(--radius); + box-shadow: 0 8px 28px rgba(31, 41, 55, 0.12); + padding: 6px; +} +.stat-popover[hidden] { + display: none; +} +.stat-pop-head { + padding: 6px 10px 8px; + font-size: 11.5px; + font-weight: 700; + letter-spacing: 0.03em; + text-transform: uppercase; + color: var(--muted); +} +.stat-row { + display: flex; + align-items: flex-start; + gap: 10px; + padding: 9px 11px; + border-radius: 9px; + border: 1px solid transparent; + text-decoration: none; + color: inherit; + cursor: pointer; +} +.stat-row:hover { + border-color: rgba(249, 115, 22, 0.4); + background: var(--accent-soft); +} +.stat-row-ico { + font-size: 15px; + line-height: 1.3; + flex: 0 0 auto; +} +.stat-row-main { + min-width: 0; + flex: 1; +} +.stat-row-title { + font-family: var(--mono); + font-size: 12.5px; + font-weight: 600; + color: var(--ink); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.stat-row-meta { + margin-top: 2px; + font-size: 12px; + color: var(--muted); +} +.stat-row-state.open { + color: var(--accent); + font-weight: 600; + border-radius: 5px; + padding: 1px 5px; + margin: -1px -2px; +} +.stat-row-state.open:hover { + background: rgba(249, 115, 22, 0.14); + text-decoration: underline; +} +.art-ico { + width: 1em; + height: 1em; + object-fit: contain; + vertical-align: -0.15em; +} + +/* ---- scroll-to-resource highlight ---- */ +.res-flash { + animation: res-flash 1.5s ease; + border-radius: 8px; +} +@keyframes res-flash { + 0%, + 25% { + box-shadow: 0 0 0 3px var(--accent); + } + 100% { + box-shadow: 0 0 0 3px rgba(249, 115, 22, 0); + } +} + +/* ---- inline resource chips ---- */ +#page .res-chip { + display: inline-flex; + align-items: center; + gap: 5px; + max-width: 100%; + padding: 0 9px 0 6px; + margin: 0 1px; + border: 1px solid var(--line); + border-radius: 999px; + background: var(--panel); + font-family: var(--mono); + font-size: 0.78em; + font-weight: 600; + color: var(--ink); + text-decoration: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: middle; + line-height: 1.65; + transform: translateY(-0.08em); + transition: border-color 0.12s, background 0.12s, color 0.12s; +} +.res-chip-ico { + font-size: 1.05em; + line-height: 1; +} +#page .res-chip:hover, +#page .res-chip.res-hl { + border-color: var(--accent); + background: var(--accent-soft); + color: var(--accent-strong); +} +#page a.res-link.res-hl { + background: var(--accent-soft); + border-radius: 4px; +} +.rail-item.res-hl { + border-color: var(--accent); + background: var(--accent-soft); + box-shadow: 0 3px 12px rgba(249, 115, 22, 0.14); +} +.rail-item.res-hl .rail-title { + color: var(--accent-strong); +} +.rail-item.rail-local { + cursor: default; +} +.artifact-chip.res-hl { + border-color: var(--accent); + background: var(--accent-soft); +} + +/* ---- contextual resources rail ---- */ +.context-rail { + position: relative; + width: 248px; +} +.context-rail[hidden] { + display: none; +} +.rail-kind { + display: flex; + align-items: center; + gap: 5px; + font-family: var(--mono); + font-size: 10px; + text-transform: uppercase; + letter-spacing: 0.08em; + font-weight: 600; + color: var(--accent); + margin-bottom: 4px; +} +.rail-item { + position: absolute; + left: 0; + right: 0; + display: block; + border: 1px solid var(--line); + border-radius: 10px; + background: var(--panel); + padding: 9px 12px; + margin-bottom: 8px; + text-decoration: none; + color: inherit; + transition: border-color 0.14s, box-shadow 0.14s; +} +.rail-item:hover { + border-color: rgba(249, 115, 22, 0.45); + box-shadow: 0 3px 12px rgba(31, 41, 55, 0.06); +} +.rail-title { + font-family: var(--mono); + font-size: 12.5px; + font-weight: 600; + color: var(--ink); + overflow-wrap: anywhere; + line-height: 1.4; +} +.rail-item:hover .rail-title { + color: var(--accent-strong); +} +.rail-meta { + font-size: 11.5px; + color: var(--muted); + margin-top: 2px; +} + +@media (max-width: 1400px) { + .page-layout { + display: block; + } + .context-rail { + width: 100%; + margin-top: 28px; + position: static; + min-height: 0 !important; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 10px; + } + .context-rail[hidden] { + display: none; + } + .context-rail .rail-item { + position: static; + margin-bottom: 0; + } +} + +/* ---- connect footer + modal ---- */ +#sidebar-foot { + margin-top: auto; + padding-top: 14px; + border-top: 1px solid rgba(255, 255, 255, 0.1); +} + +#connect-btn { + width: 100%; + display: flex; + align-items: center; + gap: 8px; + background: rgba(255, 255, 255, 0.05); + color: #c3c4cb; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 9px; + padding: 9px 12px; + font-size: 13.5px; + font-family: var(--sans); + cursor: pointer; + transition: background 0.12s, color 0.12s, border-color 0.12s; +} +#connect-btn:hover { + background: rgba(249, 115, 22, 0.14); + border-color: rgba(249, 115, 22, 0.4); + color: #fdba74; +} +#connect-btn .ico { + font-size: 15px; +} + +#modal[hidden] { + display: none; +} +#modal { + position: fixed; + inset: 0; + z-index: 100; + display: flex; + align-items: center; + justify-content: center; + padding: 24px; +} +.modal-backdrop { + position: absolute; + inset: 0; + background: rgba(20, 18, 30, 0.5); + backdrop-filter: blur(2px); +} +.modal-card { + position: relative; + background: var(--panel); + border-radius: 16px; + width: 100%; + max-width: 620px; + max-height: 85vh; + overflow-y: auto; + box-shadow: 0 24px 70px rgba(20, 15, 50, 0.28); +} +.modal-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 18px 22px; + border-bottom: 1px solid var(--line); + position: sticky; + top: 0; + background: var(--panel); +} +.modal-title { + display: flex; + align-items: center; + gap: 10px; + font-family: var(--serif); + font-size: 21px; + letter-spacing: -0.01em; +} +.modal-logo { + width: 26px; + height: 26px; + object-fit: contain; +} +.modal-actions { + display: flex; + align-items: center; + gap: 8px; +} +.btn { + font-family: var(--sans); + font-size: 13.5px; + font-weight: 600; + border: 1px solid var(--line); + background: var(--panel); + color: var(--ink); + border-radius: 9px; + padding: 8px 13px; + cursor: pointer; + transition: background 0.12s, border-color 0.12s, color 0.12s; +} +.btn:hover { + border-color: var(--accent); + color: var(--accent-strong); +} +.btn.copied { + border-color: #1a8a55; + color: #1a8a55; +} +.btn.icon { + font-size: 18px; + line-height: 1; + padding: 6px 11px; + font-weight: 400; +} +.modal-body { + padding: 20px 22px 26px; +} +.modal-intro { + margin: 0 0 20px; + color: var(--muted); + line-height: 1.55; +} +#connect-steps { + list-style: none; + margin: 0; + padding: 0; +} +#connect-steps li { + margin-bottom: 18px; +} +.step-title { + font-weight: 600; + font-size: 14.5px; + margin-bottom: 8px; +} +.codeblock { + display: flex; + align-items: center; + gap: 8px; + background: #17181c; + border-radius: 10px; + padding: 11px 12px 11px 15px; +} +.codeblock code { + flex: 1; + min-width: 0; + overflow-x: auto; + white-space: nowrap; + font-family: var(--mono); + font-size: 13px; + color: #f0efff; + background: none; + padding: 0; +} +.codeblock .copy { + flex: 0 0 auto; + background: rgba(255, 255, 255, 0.08); + color: #c3c4cb; + border: 1px solid rgba(255, 255, 255, 0.14); + border-radius: 7px; + width: 30px; + height: 30px; + font-size: 14px; + cursor: pointer; + transition: background 0.12s, color 0.12s; +} +.codeblock .copy:hover { + background: rgba(249, 115, 22, 0.2); + color: #fdba74; +} +.codeblock .copy.copied { + color: #52d08a; +} + +@media (max-width: 720px) { + #app { + flex-direction: column; + } + #sidebar { + width: 100%; + flex: none; + height: auto; + position: static; + } + #content { + display: block; + width: 100%; + padding: 28px 20px 80px; + overflow-x: hidden; + } + #page { + width: 100%; + max-width: 100%; + } + #page h1 { + font-size: 30px; + } + .cell-head { + align-items: flex-start; + flex-direction: column; + gap: 4px; + } +} diff --git a/trackio/frontend_templates/logbook/logbook.js b/trackio/frontend_templates/logbook/logbook.js new file mode 100644 index 0000000000000000000000000000000000000000..b3ef6bc2630396c972af23459994e4df7ca64fdc --- /dev/null +++ b/trackio/frontend_templates/logbook/logbook.js @@ -0,0 +1,2162 @@ +(function () { + "use strict"; + + let MANIFEST = null; + const PAGE_CACHE = {}; + const UNFURL_CACHE = {}; + const LIVE_RELOAD_MS = 1500; + + function esc(s) { + return String(s) + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); + } + + function flattenTree(node, depth, acc) { + acc.push({ node: node, depth: depth }); + (node.children || []).forEach((c) => flattenTree(c, depth + 1, acc)); + return acc; + } + + function findNode(node, slug) { + if (node.slug === slug) return node; + for (const c of node.children || []) { + const hit = findNode(c, slug); + if (hit) return hit; + } + return null; + } + + /* -------------------- minimal markdown -------------------- */ + + function inline(text) { + let t = esc(text); + t = t.replace(/`([^`]+)`/g, (_, c) => `${c}`); + t = t.replace(/\*\*([^*]+)\*\*/g, (_, c) => `${c}`); + t = t.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, txt, url) => { + const safe = esc(url); + const attrs = /^https?:/.test(url) ? ' target="_blank" rel="noopener"' : ""; + const item = /^https?:/.test(url) ? classifyResource(url) : null; + const data = item + ? ` class="res-link" data-res-url="${esc(item.url)}"` + : ""; + return `${txt}`; + }); + t = t.replace(/(^|[\s(])(https?:\/\/[^\s<>)"'`]+)/g, (m, pre, url) => { + let rest = ""; + const cut = url.search(/"|'|<|>/); + if (cut !== -1) { + rest = url.slice(cut); + url = url.slice(0, cut); + } + const trailing = (url.match(/[.,;:!?`]+$/) || [""])[0]; + const clean = trailing ? url.slice(0, -trailing.length) : url; + if (!clean) return m; + const item = classifyResource(clean); + if (item) return `${pre}${resChipHtml(item)}${trailing}${rest}`; + return `${pre}${clean}${trailing}${rest}`; + }); + return t; + } + + function resChipHtml(item) { + return ( + `` + + `${RESOURCE_ICONS[item.kind]}` + + `${esc(item.id)}` + ); + } + + const URL_ONLY = /^(https?:\/\/[^\s]+)$/; + const DETECTED_URL = + /(https?:\/\/[^\s<>)\]"'`]+|trackio-local-dashboard:\/\/[^\s<>)\]"'`]+|trackio-artifact:\/\/[^\s<>)\]"'`]+)/g; + + function renderMarkdown(md, container) { + const cellRe = /(^|\n)---\n\n([\s\S]*?)(?=\n---\n/g, "").split("\n"); + let i = 0; + let para = []; + + function flushPara() { + if (!para.length) return; + const joined = para.join(" ").trim(); + para = []; + if (!joined) return; + if (/^trackio-artifact:\/\/\S+$/.test(joined)) return; + if (joined.indexOf("📦 Artifact") !== -1) { + const div = document.createElement("div"); + div.className = "artifact-chip"; + div.innerHTML = ARTIFACT_ICON_IMG + inline(joined.replace(/📦\s*/, "")); + container.appendChild(div); + return; + } + if (URL_ONLY.test(joined) || IMG_PATH.test(joined)) { + const el = renderStandaloneUrl(joined); + if (el) container.appendChild(el); + return; + } + const p = document.createElement("p"); + p.innerHTML = inline(joined); + container.appendChild(p); + } + + while (i < lines.length) { + const line = lines[i]; + const trimmed = line.trim(); + + if (trimmed === "") { + flushPara(); + i++; + continue; + } + const fence = trimmed.match(/^(`{3,}|~{3,})(.*)$/); + if (fence) { + flushPara(); + const marker = fence[1][0]; + const closeRe = new RegExp("^" + marker + "{" + fence[1].length + ",}\\s*$"); + const info = fence[2].trim(); + const buf = []; + i++; + while (i < lines.length && !closeRe.test(lines[i].trim())) { + buf.push(lines[i]); + i++; + } + i++; + const lang = (info.split(/\s+/)[0] || "").toLowerCase(); + const tm = info.match(/title=(\S+)/); + container.appendChild( + renderCode(buf.join("\n"), lang, tm ? tm[1] : null) + ); + continue; + } + if (trimmed === "---") { + flushPara(); + container.appendChild(document.createElement("hr")); + i++; + continue; + } + const h = trimmed.match(/^(#{1,4})\s+(.*)$/); + if (h) { + flushPara(); + const el = document.createElement("h" + h[1].length); + el.innerHTML = inline(h[2]); + container.appendChild(el); + i++; + continue; + } + if ( + trimmed.startsWith("|") && + i + 1 < lines.length && + /^\|?[\s:|-]*-{2,}[\s:|-]*\|?$/.test(lines[i + 1].trim()) + ) { + flushPara(); + const rows = []; + while (i < lines.length && lines[i].trim().startsWith("|")) { + rows.push(parseRow(lines[i].trim())); + i++; + } + renderTable(rows, container); + continue; + } + if (trimmed.startsWith("> ")) { + flushPara(); + const bq = document.createElement("blockquote"); + bq.innerHTML = inline(trimmed.slice(2)); + container.appendChild(bq); + i++; + continue; + } + if (/^`[^`]+`$/.test(trimmed)) { + flushPara(); + const el = document.createElement("div"); + el.className = "ts"; + el.textContent = trimmed.replace(/`/g, ""); + container.appendChild(el); + i++; + continue; + } + if (trimmed.startsWith("- ")) { + flushPara(); + const items = []; + while (i < lines.length && lines[i].trim().startsWith("- ")) { + items.push(lines[i].trim().slice(2).trim()); + i++; + } + renderList(items, container); + continue; + } + para.push(trimmed); + i++; + } + flushPara(); + } + + function renderCell(meta, body, container, artifacts) { + const cell = document.createElement("section"); + cell.className = `cell ${meta.type || "markdown"}`; + if (meta.id) cell.dataset.cellId = meta.id; + if (isPinned(meta)) cell.classList.add("pinned-source"); + + const head = document.createElement("div"); + head.className = "cell-head"; + const rawTitle = (meta.title || "").trim(); + const title = rawTitle && rawTitle.toLowerCase() !== "untitled" ? esc(rawTitle) : ""; + const when = meta.created_at ? `${esc(formatTime(meta.created_at))}` : ""; + head.innerHTML = + (title ? `
        ${title}
        ` : "") + + `
        ${when}
        `; + if (!title) head.classList.add("no-title"); + cell.appendChild(head); + + const bodyEl = document.createElement("div"); + bodyEl.className = "cell-body"; + if (meta.type === "code") { + renderCodeCell(body, bodyEl, artifacts); + } else if (meta.type === "figure") { + cell.dataset.resUrl = `trackio-figure://${(meta.title || "Figure").trim()}`; + renderFigureCell(body, bodyEl, head); + } else if (meta.type === "artifact") { + renderMarkdownPlain(body, bodyEl); + const chip = bodyEl.querySelector(".artifact-chip"); + const uri = body.match( + /(trackio-artifact:\/\/\S+|https:\/\/huggingface\.co\/buckets\/[^\s<)]+#\S+)/ + ); + if (chip && uri) chip.dataset.resUrl = uri[1]; + } else if (meta.type === "dashboard") { + const sp = body.match(/https:\/\/huggingface\.co\/spaces\/[^\s<>)"'`]+/); + cell.dataset.resUrl = sp + ? sp[0] + : `trackio-local-dashboard://${(meta.dashboard_project || "").trim()}`; + renderDashboardCell(meta, body, bodyEl); + } else { + const cleaned = stripDuplicateTitle(body, meta.title); + renderMarkdownPlain(cleaned, bodyEl); + renderDetectedEmbeds(cleaned, bodyEl); + } + cell.appendChild(bodyEl); + container.appendChild(cell); + return cell; + } + + function isPinned(meta) { + return Boolean(meta && (meta.pinned === true || meta.pinned === "true")); + } + + function stripDuplicateTitle(body, title) { + if (!title) return body; + const m = body.match(/^\s*#{1,6}\s+([^\n]+)\n?/); + if (!m) return body; + const norm = (s) => + s + .toLowerCase() + .replace(/[*_`#]/g, "") + .replace(/\s+/g, " ") + .trim(); + return norm(m[1]) === norm(title) ? body.slice(m[0].length) : body; + } + + function formatTime(iso) { + const d = new Date(iso); + if (Number.isNaN(d.getTime())) return iso; + return d.toLocaleString(undefined, { + month: "short", + day: "numeric", + hour: "2-digit", + minute: "2-digit", + }); + } + + function parseFences(text) { + const fenceRe = /(`{3,4}|~{3,4})([^\n]*)\n([\s\S]*?)\n\1/g; + const parts = []; + let pos = 0; + let match; + while ((match = fenceRe.exec(text))) { + if (match.index > pos) { + parts.push({ kind: "text", text: text.slice(pos, match.index) }); + } + const info = match[2].trim(); + const lang = (info.split(/\s+/)[0] || "").toLowerCase(); + const titleMatch = info.match(/title=(\S+)/); + parts.push({ + kind: lang === "result" || lang === "output" ? "output" : "code", + lang, + title: titleMatch ? titleMatch[1] : null, + text: match[3], + }); + pos = match.index + match[0].length; + } + if (pos < text.length) parts.push({ kind: "text", text: text.slice(pos) }); + return parts; + } + + function fitFigureFrame(frame, wrap) { + let doc; + try { + doc = frame.contentDocument; + } catch (e) { + return; + } + if (!doc || !doc.body) return; + frame.style.transform = "none"; + frame.style.width = "100%"; + frame.style.height = "auto"; + const avail = wrap.clientWidth; + const cw = Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth, 1); + const ch = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight, 1); + if (avail && cw > avail + 1) { + const scale = avail / cw; + frame.style.width = `${cw}px`; + frame.style.height = `${ch}px`; + frame.style.transformOrigin = "top left"; + frame.style.transform = `scale(${scale})`; + wrap.style.height = `${Math.ceil(ch * scale)}px`; + } else { + frame.style.width = "100%"; + frame.style.height = `${ch}px`; + wrap.style.height = `${ch}px`; + } + } + + function attachFigureFit(frame, wrap) { + const refit = () => fitFigureFrame(frame, wrap); + frame.addEventListener("load", refit); + if (window.ResizeObserver) { + const ro = new ResizeObserver(() => refit()); + ro.observe(wrap); + } + } + + function renderFigureCell(text, container, head) { + const parts = parseFences(text); + const htmlPart = parts.find((part) => part.lang === "html"); + const rawPart = parts.find((part) => part.lang === "raw"); + if (!htmlPart || !htmlPart.text.trim()) { + const empty = document.createElement("p"); + empty.className = "muted"; + empty.textContent = "No figure HTML."; + container.appendChild(empty); + return; + } + const frame = document.createElement("iframe"); + frame.className = "figure-frame"; + frame.sandbox = "allow-scripts allow-same-origin"; + frame.loading = "lazy"; + frame.srcdoc = htmlPart.text; + const figWrap = document.createElement("div"); + figWrap.className = "figure-fit"; + figWrap.appendChild(frame); + attachFigureFit(frame, figWrap); + if (!rawPart || !rawPart.text.trim()) { + container.appendChild(figWrap); + return; + } + const sw = document.createElement("div"); + sw.className = "fig-switch"; + const thumb = document.createElement("span"); + thumb.className = "fig-switch-thumb"; + const figBtn = document.createElement("button"); + figBtn.type = "button"; + figBtn.className = "active"; + figBtn.textContent = "Figure"; + const rawBtn = document.createElement("button"); + rawBtn.type = "button"; + rawBtn.textContent = "Raw"; + sw.appendChild(thumb); + sw.appendChild(figBtn); + sw.appendChild(rawBtn); + const rawView = document.createElement("div"); + rawView.className = "figure-raw"; + rawView.hidden = true; + const pre = document.createElement("pre"); + const code = document.createElement("code"); + code.textContent = rawPart.text; + pre.appendChild(code); + rawView.appendChild(pre); + rawView.appendChild(copySnippetBtn(rawPart.text)); + const select = (showRaw) => { + sw.classList.toggle("raw", showRaw); + figBtn.classList.toggle("active", !showRaw); + rawBtn.classList.toggle("active", showRaw); + figWrap.hidden = showRaw; + rawView.hidden = !showRaw; + }; + figBtn.addEventListener("click", () => select(false)); + rawBtn.addEventListener("click", () => select(true)); + if (head) { + head.insertBefore(sw, head.querySelector(".cell-meta")); + } else { + container.appendChild(sw); + } + container.appendChild(figWrap); + container.appendChild(rawView); + } + + function extractUrls(text) { + const seen = new Set(); + const urls = []; + let match; + while ((match = DETECTED_URL.exec(text))) { + const url = match[1].replace(/[.,;:!?'"`]+$/, ""); + if (!seen.has(url)) { + seen.add(url); + urls.push(url); + } + } + DETECTED_URL.lastIndex = 0; + return urls; + } + + const IMG_URL = /(\.(png|jpe?g|gif|svg|webp)(\?|$)|\/artifact_blob\/)/i; + + function renderDetectedEmbeds(text, container) { + extractUrls(text).forEach((url) => { + if (url.startsWith("trackio-local-dashboard://")) { + const div = document.createElement("div"); + div.className = "artifact-chip"; + div.dataset.resUrl = url; + div.innerHTML = + "🎯 Local Trackio dashboard — publish the logbook to share it"; + container.appendChild(div); + } else if (IMG_URL.test(url)) { + container.appendChild(renderImage(url)); + } else if (/huggingface\.co\/spaces\//.test(url)) { + maybeEmbedTrackioSpace(url, container); + } + }); + } + + function renderStandaloneUrl(url) { + if (IMG_URL.test(url) || IMG_PATH.test(url)) return renderImage(url); + const item = classifyResource(url); + if (item) { + const marker = document.createElement("span"); + marker.className = "resource-anchor"; + marker.dataset.resUrl = item.url; + marker.setAttribute("aria-hidden", "true"); + return marker; + } + const p = document.createElement("p"); + p.innerHTML = inline(url); + return p; + } + + function renderImage(url) { + const a = document.createElement("a"); + a.className = "unfurl image"; + a.href = url; + a.target = "_blank"; + a.rel = "noopener"; + const img = document.createElement("img"); + img.loading = "lazy"; + img.src = url; + img.alt = "artifact image"; + a.appendChild(img); + return a; + } + + function maybeEmbedTrackioSpace(url, container) { + const id = url.split("/spaces/")[1].split(/[?#]/)[0].replace(/\/$/, ""); + const holder = document.createElement("div"); + container.appendChild(holder); + getJSON(`https://huggingface.co/api/spaces/${id}`).then((d) => { + const tags = (d && d.tags) || []; + if (tags.some((t) => String(t).toLowerCase() === "trackio")) { + renderTrackioSpaceEmbed(holder, url, id); + } else { + holder.remove(); + } + }); + } + + function jpGutter(label) { + const g = document.createElement("div"); + g.className = "jp-gutter"; + g.textContent = label; + return g; + } + + function renderOutArtifact(info) { + const remote = !info.local && !!info.url; + const el = document.createElement(remote ? "a" : "div"); + el.className = "out-artifact"; + if (remote) { + el.href = info.url; + el.target = "_blank"; + el.rel = "noopener"; + } + el.dataset.resUrl = info.resUrl; + const parts = [info.type, info.size].filter(Boolean).map(esc); + const state = remote + ? `Open ↗` + : `publish to share`; + const meta = parts.length ? `${parts.join(" · ")} · ${state}` : state; + el.innerHTML = + `${ARTIFACT_ICON_IMG}` + + `${esc(info.name)}` + + `${meta}`; + return el; + } + + function renderCodeCell(body, container, artifacts) { + const parts = parseFences(body); + const block = document.createElement("div"); + block.className = "jp"; + const input = document.createElement("div"); + input.className = "jp-in"; + const inputBody = document.createElement("div"); + inputBody.className = "jp-in-body"; + input.appendChild(jpGutter("In")); + input.appendChild(inputBody); + let metaEl = null; + let outputEl = null; + let outBody = null; + const ensureOut = () => { + if (outputEl) return; + outputEl = document.createElement("div"); + outputEl.className = "jp-out"; + outputEl.appendChild(jpGutter("Out")); + outBody = document.createElement("div"); + outBody.className = "jp-out-body"; + outputEl.appendChild(outBody); + }; + const embedTexts = []; + parts.forEach((part) => { + if (part.kind === "text") { + const text = part.text.trim(); + if (!text) return; + if (/^exit\s+\S+(\s|·)/.test(text)) { + metaEl = document.createElement("div"); + metaEl.className = "jp-meta"; + metaEl.textContent = text.replace( + /\s*·\s*[A-Z][a-z]{2} \d{1,2}, \d{4}.*$/, + "" + ); + } else { + renderMarkdownPlain(text, container); + embedTexts.push(text); + } + return; + } + if (part.kind === "output") { + ensureOut(); + const pre = document.createElement("pre"); + pre.className = "jp-out-pre"; + const c = document.createElement("code"); + c.textContent = part.text; + pre.appendChild(c); + outBody.appendChild(pre); + outputEl.appendChild(copySnippetBtn(part.text)); + embedTexts.push(part.text); + return; + } + inputBody.appendChild(renderCode(part.text, part.lang, part.title)); + }); + if (artifacts && artifacts.length) { + ensureOut(); + const artWrap = document.createElement("div"); + artWrap.className = "jp-artifacts"; + artifacts.forEach((a) => { + artWrap.appendChild( + renderOutArtifact(artifactInfoFromCell(a.meta, a.body)) + ); + }); + outBody.appendChild(artWrap); + } + if (inputBody.childNodes.length > 0) block.appendChild(input); + if (metaEl) block.appendChild(metaEl); + if (outputEl) block.appendChild(outputEl); + if (block.childNodes.length) container.appendChild(block); + embedTexts.forEach((text) => renderDetectedEmbeds(text, container)); + } + + function parseRow(line) { + let s = line.trim(); + if (s.startsWith("|")) s = s.slice(1); + if (s.endsWith("|")) s = s.slice(0, -1); + return s.split(/(? c.replace(/\\\|/g, "|").trim()); + } + + const TRUTHY = ["x", "✓", "✔", "yes", "done", "true", "[x]"]; + const CHIP_COLORS = [ + ["#e7f0ff", "#2158d0"], + ["#fde8ec", "#c62a4b"], + ["#e6f7ee", "#1a8a55"], + ["#fdf0e0", "#b26a12"], + ["#efe9ff", "#5b3bd6"], + ["#e6f6f8", "#127b88"], + ]; + + function chipColor(name) { + let h = 0; + for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) >>> 0; + return CHIP_COLORS[h % CHIP_COLORS.length]; + } + + const STATUS_MAP = { + "": ["Planned", "gray"], + planned: ["Planned", "gray"], + todo: ["Planned", "gray"], + "to do": ["Planned", "gray"], + backlog: ["Planned", "gray"], + "in progress": ["In progress", "amber"], + "in-progress": ["In progress", "amber"], + wip: ["In progress", "amber"], + running: ["In progress", "amber"], + active: ["In progress", "amber"], + done: ["Done", "green"], + complete: ["Done", "green"], + completed: ["Done", "green"], + blocked: ["Blocked", "red"], + failed: ["Failed", "red"], + abandoned: ["Abandoned", "gray"], + }; + + function statusBadge(val) { + const [label, tone] = STATUS_MAP[val.toLowerCase()] || [val || "—", "gray"]; + return `${esc(label)}`; + } + + function renderTable(rows, container) { + if (rows.length < 2) return; + const header = rows[0]; + const body = rows.slice(2); + const roles = header.map((h) => { + const t = h.toLowerCase(); + if (t.includes("status") || t.includes("state")) return "status"; + if (t.includes("progress") || t.includes("complete") || t.includes("done")) + return "check"; + if (t === "who" || t.includes("assign") || t.includes("owner")) return "who"; + return "text"; + }); + const table = document.createElement("table"); + table.className = "board"; + const thead = document.createElement("thead"); + const htr = document.createElement("tr"); + header.forEach((h, c) => { + const th = document.createElement("th"); + th.textContent = h; + if (roles[c] === "check") th.className = "col-check"; + htr.appendChild(th); + }); + thead.appendChild(htr); + table.appendChild(thead); + const tbody = document.createElement("tbody"); + body.forEach((cells) => { + const nonEmpty = cells.filter((x) => x !== "").length; + if (header.length > 1 && nonEmpty === 1 && cells[0]) { + const tr = document.createElement("tr"); + tr.className = "section-row"; + const td = document.createElement("td"); + td.colSpan = header.length; + td.innerHTML = inline(cells[0]); + tr.appendChild(td); + tbody.appendChild(tr); + return; + } + const tr = document.createElement("tr"); + header.forEach((_, c) => { + const td = document.createElement("td"); + const val = (cells[c] || "").trim(); + if (roles[c] === "status") { + td.className = "col-status"; + td.innerHTML = statusBadge(val); + } else if (roles[c] === "check") { + td.className = "col-check"; + const on = TRUTHY.indexOf(val.toLowerCase()) !== -1; + td.innerHTML = `${on ? "✓" : ""}`; + } else if (roles[c] === "who") { + if (!val || /^to assign$/i.test(val)) { + td.innerHTML = `${esc(val || "—")}`; + } else { + const [bg, fg] = chipColor(val); + td.innerHTML = `${esc(val)}`; + } + } else { + td.innerHTML = inline(val); + } + tr.appendChild(td); + }); + const link = tr.querySelector('a[href^="#/"]'); + if (link) { + tr.classList.add("linked-row"); + tr.addEventListener("click", (e) => { + if (e.target.tagName !== "A") location.hash = link.getAttribute("href"); + }); + } + tbody.appendChild(tr); + }); + table.appendChild(tbody); + const wrap = document.createElement("div"); + wrap.className = "board-wrap"; + wrap.appendChild(table); + container.appendChild(wrap); + } + + const HL_RULES = { + python: [ + ["comment", /#[^\n]*/], + ["string", /'''[\s\S]*?'''|"""[\s\S]*?"""|'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*"/], + [ + "keyword", + /\b(?:def|class|return|if|elif|else|for|while|import|from|as|with|try|except|finally|raise|in|not|and|or|is|None|True|False|lambda|yield|global|nonlocal|assert|pass|break|continue|async|await|print)\b/, + ], + ["number", /\b\d[\d_.eE+-]*\b/], + ], + bash: [ + ["comment", /#[^\n]*/], + ["string", /'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*"/], + ["keyword", /\b(?:if|then|else|fi|for|in|do|done|while|case|esac|function|export|source|echo|cd|return|local)\b/], + ["number", /(?<=\s)-{1,2}[a-zA-Z][\w-]*/], + ], + json: [ + ["string", /"(?:\\.|[^"\\])*"/], + ["keyword", /\b(?:true|false|null)\b/], + ["number", /-?\b\d[\d.eE+-]*\b/], + ], + yaml: [ + ["comment", /#[^\n]*/], + ["string", /'(?:\\.|[^'\\])*'|"(?:\\.|[^"\\])*"/], + ["keyword", /\b(?:true|false|null|yes|no)\b/], + ["number", /-?\b\d[\d.eE+-]*\b/], + ], + }; + HL_RULES.javascript = HL_RULES.python; + HL_RULES.typescript = HL_RULES.python; + HL_RULES.sql = [ + ["comment", /--[^\n]*/], + ["string", /'(?:\\.|[^'\\])*'/], + [ + "keyword", + /\b(?:SELECT|FROM|WHERE|JOIN|LEFT|RIGHT|INNER|OUTER|ON|GROUP|BY|ORDER|LIMIT|INSERT|INTO|VALUES|UPDATE|SET|DELETE|CREATE|TABLE|AS|AND|OR|NOT|NULL|COUNT|DISTINCT|IN)\b/i, + ], + ["number", /\b\d[\d.]*\b/], + ]; + + function highlightCode(code, lang) { + const rules = HL_RULES[lang]; + if (!rules) return esc(code); + const combined = new RegExp(rules.map((r) => "(" + r[1].source + ")").join("|"), "g"); + let out = ""; + let last = 0; + let m; + while ((m = combined.exec(code))) { + if (m[0] === "") { + combined.lastIndex++; + continue; + } + out += esc(code.slice(last, m.index)); + let gi = 1; + while (gi < m.length && m[gi] === undefined) gi++; + out += `${esc(m[0])}`; + last = m.index + m[0].length; + } + out += esc(code.slice(last)); + return out; + } + + function copySnippetBtn(text) { + const btn = document.createElement("button"); + btn.type = "button"; + btn.className = "copy-snippet"; + btn.title = "Copy"; + btn.textContent = "⧉"; + btn.addEventListener("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + copyText(text, btn, "⧉"); + }); + return btn; + } + + function renderCode(code, lang, title) { + const pre = document.createElement("pre"); + pre.className = "hl"; + const c = document.createElement("code"); + c.innerHTML = highlightCode(code, lang); + pre.appendChild(c); + if (!title) { + const wrap = document.createElement("div"); + wrap.className = "snippet"; + wrap.appendChild(pre); + wrap.appendChild(copySnippetBtn(code)); + return wrap; + } + const det = document.createElement("details"); + det.className = "code-accordion"; + det.dataset.resUrl = `trackio-script://${title}`; + const sum = document.createElement("summary"); + sum.innerHTML = + `</>` + + `${esc(title)}`; + sum + .querySelector(".code-name") + .addEventListener("click", (e) => e.preventDefault()); + det.appendChild(sum); + const wrap = document.createElement("div"); + wrap.className = "snippet"; + wrap.appendChild(pre); + wrap.appendChild(copySnippetBtn(code)); + det.appendChild(wrap); + return det; + } + + const IMG_PATH = /^[^\s]+\.(png|jpe?g|gif|svg|webp)$/i; + + function renderList(items, container) { + let ul = null; + items.forEach((item) => { + if (URL_ONLY.test(item) || IMG_PATH.test(item)) { + const el = renderStandaloneUrl(item); + if (el) { + ul = null; + container.appendChild(el); + } + } else if (item.indexOf("📦 Artifact") !== -1) { + ul = null; + const div = document.createElement("div"); + div.className = "artifact-chip"; + div.innerHTML = inline(item.replace("📦", "🪣")); + container.appendChild(div); + } else if (item.indexOf("trackio-local-dashboard://") !== -1) { + ul = null; + const uri = item.match(/trackio-local-dashboard:\/\/\S+/)?.[0] || ""; + const div = document.createElement("div"); + div.className = "artifact-chip"; + if (uri) div.dataset.resUrl = uri; + div.innerHTML = + "🎯 Local dashboard — publish the logbook to share it"; + container.appendChild(div); + } else { + if (!ul) { + ul = document.createElement("ul"); + container.appendChild(ul); + } + const li = document.createElement("li"); + li.innerHTML = inline(item); + ul.appendChild(li); + } + }); + } + + /* -------------------- resources rail -------------------- */ + + function fmt(n) { + if (n == null) return null; + if (n >= 1e6) return (n / 1e6).toFixed(1) + "M"; + if (n >= 1e3) return (n / 1e3).toFixed(1) + "k"; + return String(n); + } + + const RESOURCE_SECTIONS = [ + ["dashboard", "Dashboards", "🎯"], + ["model", "Models", "🤗"], + ["dataset", "Datasets", "📊"], + ["space", "Spaces", "🚀"], + ["artifact", "Artifacts", "🪣"], + ["paper", "Papers", "📄"], + ["repo", "Code", "🐙"], + ["job", "Jobs", "⚙️"], + ["bucket", "Buckets", "🪣"], + ]; + + const RESOURCE_ICONS = Object.fromEntries( + RESOURCE_SECTIONS.map(([kind, , icon]) => [kind, icon]) + ); + + const ARTIFACT_ICON_IMG = ``; + const DASHBOARD_ICON_IMG = ``; + + const RESOURCE_DESC = { + dashboard: "Dashboard", + model: "Model", + dataset: "Dataset", + space: "Space", + artifact: "Artifact — in Bucket", + paper: "Paper", + repo: "Repository", + job: "Job — status & logs", + bucket: "Bucket — artifacts & data", + }; + + const HF_NON_MODEL_PREFIX = + /^(datasets|spaces|jobs|buckets|papers|blog|docs|api|posts|collections|organizations|settings|new|join|login|pricing|tasks|learn|chat|models)(\/|$)/; + + function hfId(url, marker) { + return url.split(marker)[1].split(/[?#]/)[0].replace(/\/$/, ""); + } + + function classifyResource(url) { + if (IMG_URL.test(url)) { + return null; + } + let m; + if (url.startsWith("trackio-local-dashboard://")) { + return { + kind: "dashboard", + id: url.slice("trackio-local-dashboard://".length), + url, + local: true, + }; + } + if (url.startsWith("trackio-artifact://")) { + return { + kind: "artifact", + id: url.slice("trackio-artifact://".length), + url, + local: true, + }; + } + if ((m = url.match(/huggingface\.co\/buckets\/[^#\s]+#(.+)/))) { + return { kind: "artifact", id: decodeURIComponent(m[1]), url }; + } + if (/huggingface\.co\/datasets\/[^/]+\/[^/]+/.test(url)) { + return { kind: "dataset", id: hfId(url, "/datasets/"), url }; + } + if (/huggingface\.co\/spaces\/[^/]+\/[^/]+/.test(url)) { + return { kind: "space", id: hfId(url, "/spaces/"), url }; + } + if (/huggingface\.co\/jobs\//.test(url)) { + const parts = hfId(url, "/jobs/").split("/"); + const jid = parts[1] || ""; + return { + kind: "job", + id: parts[0] + (jid ? ` · ${jid.slice(0, 12)}${jid.length > 12 ? "…" : ""}` : ""), + url, + }; + } + if (/huggingface\.co\/buckets\//.test(url)) { + return { kind: "bucket", id: hfId(url, "/buckets/"), url }; + } + if (/huggingface\.co\/papers\//.test(url)) { + return { kind: "paper", id: `Paper ${hfId(url, "/papers/")}`, url }; + } + if ((m = url.match(/arxiv\.org\/(?:abs|pdf)\/([^?#\s]+)/))) { + return { kind: "paper", id: `arXiv:${m[1].replace(/\.pdf$/, "")}`, url }; + } + if ((m = url.match(/github\.com\/([^/?#]+\/[^/?#]+)/))) { + return { kind: "repo", id: m[1], url }; + } + if ((m = url.match(/huggingface\.co\/([^?#]+)/))) { + const rest = m[1].replace(/\/$/, ""); + if (/^[^/]+\/[^/]+$/.test(rest) && !HF_NON_MODEL_PREFIX.test(rest)) { + return { kind: "model", id: rest, url }; + } + } + return null; + } + + async function fillRailMeta(item, el) { + if (item.local) return; + const meta = el.querySelector(".rail-meta"); + const set = (parts) => { + const text = parts.filter(Boolean).join(" · "); + if (text) meta.textContent = text; + }; + if (item.kind === "model") { + const d = await getJSON(`https://huggingface.co/api/models/${item.id}`); + if (d) set([d.pipeline_tag, `↓ ${fmt(d.downloads)}`, `♥ ${fmt(d.likes)}`]); + } else if (item.kind === "dataset") { + const d = await getJSON(`https://huggingface.co/api/datasets/${item.id}`); + if (d) set([`↓ ${fmt(d.downloads)}`, `♥ ${fmt(d.likes)}`]); + } else if (item.kind === "space" || item.kind === "dashboard") { + const d = await getJSON(`https://huggingface.co/api/spaces/${item.id}`); + if (d) set([d.sdk, `♥ ${fmt(d.likes)}`]); + } else if (item.kind === "repo") { + const d = await getJSON(`https://api.github.com/repos/${item.id}`); + if (d) set([`★ ${fmt(d.stargazers_count)}`, d.language]); + } else if (item.kind === "paper") { + const m = item.id.match(/^(?:arXiv:|Paper )(.+)$/); + if (!m) return; + const arxivId = m[1].replace(/v\d+$/, ""); + const d = await getJSON(`https://huggingface.co/api/papers/${arxivId}`); + if (d && d.id) { + if (el.href) el.href = `https://huggingface.co/papers/${d.id}`; + const title = + d.title && d.title.length > 70 ? `${d.title.slice(0, 69)}…` : d.title; + set([title, d.upvotes ? `▲ ${fmt(d.upvotes)}` : null]); + } + } + } + + const BARE_ID_SKIP_DIRS = new Set([ + "scripts", + "configs", + "config", + "results", + "figures", + "data", + "datasets", + "src", + "tests", + "test", + "examples", + "pages", + "assets", + "docs", + "outputs", + "output", + "checkpoints", + "models", + "utils", + "lib", + "bin", + "tmp", + "node_modules", + "dist", + "build", + ]); + const FILE_EXT_RE = + /\.(py|pyc|js|ts|jsx|tsx|json|jsonl|yaml|yml|csv|tsv|md|txt|sh|bash|html|css|png|jpe?g|svg|gif|webp|ipynb|toml|cfg|ini|lock|pdf|whl|gz|zip|tar|pt|pth|bin|safetensors|db|sqlite)$/i; + + async function detectBareModelIds(text, groups) { + const stripped = text.replace(DETECTED_URL, " "); + DETECTED_URL.lastIndex = 0; + const seen = new Set(); + const candidates = []; + const re = /(^|[\s"'`(=[])([A-Za-z0-9][\w.-]*\/[A-Za-z0-9][\w.-]*)/g; + let m; + while ((m = re.exec(stripped)) && candidates.length < 15) { + const id = m[2].replace(/[.:,]+$/, ""); + if (seen.has(id)) continue; + seen.add(id); + if (FILE_EXT_RE.test(id)) continue; + if (BARE_ID_SKIP_DIRS.has(id.split("/")[0].toLowerCase())) continue; + candidates.push(id); + } + const results = await Promise.all( + candidates.map((id) => getJSON(`https://huggingface.co/api/models/${id}`)) + ); + let added = false; + const confirmed = []; + results.forEach((d, i) => { + if (!d || !d.id) return; + const id = candidates[i]; + confirmed.push(id); + const url = `https://huggingface.co/${id}`; + if (!groups.has("model")) groups.set("model", new Map()); + if (!groups.get("model").has(url)) { + groups.get("model").set(url, { kind: "model", id, url }); + added = true; + } + }); + return { added, confirmed }; + } + + function chipifyBareIds(ids, container) { + if (!ids.length) return; + const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")); + const pattern = new RegExp("(" + escaped.join("|") + ")"); + const splitter = new RegExp(pattern.source, "g"); + container + .querySelectorAll(".cell.markdown .cell-body") + .forEach((body) => { + const walker = document.createTreeWalker(body, NodeFilter.SHOW_TEXT, { + acceptNode(node) { + if (!pattern.test(node.nodeValue)) return NodeFilter.FILTER_REJECT; + for ( + let el = node.parentElement; + el && el !== body; + el = el.parentElement + ) { + if (["A", "CODE", "PRE", "BUTTON"].indexOf(el.tagName) !== -1) { + return NodeFilter.FILTER_REJECT; + } + } + return NodeFilter.FILTER_ACCEPT; + }, + }); + const nodes = []; + while (walker.nextNode()) nodes.push(walker.currentNode); + nodes.forEach((node) => { + const frag = document.createDocumentFragment(); + node.nodeValue.split(splitter).forEach((part) => { + if (ids.indexOf(part) !== -1) { + const holder = document.createElement("span"); + holder.innerHTML = resChipHtml({ + kind: "model", + id: part, + url: `https://huggingface.co/${part}`, + }); + frag.appendChild(holder.firstChild); + } else if (part) { + frag.appendChild(document.createTextNode(part)); + } + }); + node.parentNode.replaceChild(frag, node); + }); + }); + } + + let RAIL_TOKEN = 0; + const RAIL_EXCLUDE_KINDS = new Set(["paper", "repo", "artifact", "dashboard"]); + + function railDashboardItem(it) { + return { + kind: "dashboard", + id: it.id, + url: it.local ? it.resUrl : it.url || it.resUrl, + local: it.local, + railLabel: "Dashboard", + }; + } + + function promoteTrackioSpacesInRail(groups, dashResUrls, body, rail, token) { + const spaceGroup = groups.get("space"); + if (!spaceGroup || !spaceGroup.size) return; + spaceGroup.forEach((item, url) => { + getJSON(`https://huggingface.co/api/spaces/${item.id}`) + .then((d) => { + if (rail.dataset.renderToken !== token) return; + const tags = (d && d.tags) || []; + if (!tags.some((t) => String(t).toLowerCase() === "trackio")) return; + if (dashResUrls.has(url)) return; + spaceGroup.delete(url); + if (!spaceGroup.size) groups.delete("space"); + if (!groups.has("dashboard")) groups.set("dashboard", new Map()); + groups.get("dashboard").set(url, { + kind: "dashboard", + id: item.id, + url: item.url, + local: false, + railLabel: "Dashboard", + }); + dashResUrls.add(url); + paintRail(groups, body, rail); + }) + .catch(() => {}); + }); + } + + function renderRail(md, body, rail) { + const token = String(++RAIL_TOKEN); + rail.dataset.renderToken = token; + const scanText = md.replace( + /(`{3,4}|~{3,4})(html|raw)[^\n]*\n[\s\S]*?\n\1/g, + " " + ); + const groups = new Map(); + const dashMap = new Map(); + const dashResUrls = new Set(); + cellDashboardItems(md).forEach((it) => { + if (dashMap.has(it.resUrl)) return; + dashMap.set(it.resUrl, railDashboardItem(it)); + dashResUrls.add(it.resUrl); + }); + if (dashMap.size) groups.set("dashboard", dashMap); + extractUrls(scanText).forEach((url) => { + const item = classifyResource(url); + if (!item) return; + if (RAIL_EXCLUDE_KINDS.has(item.kind)) return; + if (dashResUrls.has(url)) return; + if (!groups.has(item.kind)) groups.set(item.kind, new Map()); + groups.get(item.kind).set(item.url, item); + }); + const artMap = new Map(); + cellArtifactItems(md).forEach((it) => { + if (artMap.has(it.resUrl)) return; + const label = it.type + ? it.type.charAt(0).toUpperCase() + it.type.slice(1) + : "Artifact"; + artMap.set(it.resUrl, { + kind: "artifact", + id: it.name, + url: it.local ? it.resUrl : it.url || it.resUrl, + local: it.local, + railLabel: label, + size: it.size, + }); + }); + if (artMap.size) groups.set("artifact", artMap); + paintRail(groups, body, rail); + promoteTrackioSpacesInRail(groups, dashResUrls, body, rail, token); + detectBareModelIds(scanText, groups) + .then((result) => { + if (rail.dataset.renderToken !== token) return; + chipifyBareIds(result.confirmed, body); + if (result.added) paintRail(groups, body, rail); + }) + .catch(() => {}); + } + + function paintRail(groups, body, rail) { + rail.innerHTML = ""; + RESOURCE_SECTIONS.forEach(([kind, label, icon]) => { + const group = groups.get(kind); + if (!group || !group.size) return; + group.forEach((item) => { + const el = document.createElement(item.local ? "div" : "a"); + el.className = item.local ? "rail-item rail-local" : "rail-item"; + if (!item.local) { + el.href = item.url; + el.target = "_blank"; + el.rel = "noopener"; + } + el.dataset.resUrl = item.url; + let desc; + if (kind === "artifact") { + const state = item.local ? "publish to share" : "Open ↗"; + desc = item.size ? `${item.size} · ${state}` : state; + } else if (kind === "dashboard") { + desc = item.local ? "publish to share" : "Open ↗"; + } else { + desc = item.local ? "publish to share" : RESOURCE_DESC[kind]; + } + const kindLabel = item.railLabel || label.replace(/s$/, ""); + const iconHtml = + kind === "artifact" + ? ARTIFACT_ICON_IMG + : kind === "dashboard" + ? DASHBOARD_ICON_IMG + : `${icon}`; + el.innerHTML = + `
        ${iconHtml}${esc(kindLabel)}
        ` + + `
        ${esc(item.id)}
        ` + + `
        ${esc(desc)}
        `; + rail.appendChild(el); + fillRailMeta(item, el) + .catch(() => {}) + .finally(() => scheduleRailPosition(body, rail)); + }); + }); + rail.hidden = !rail.childElementCount; + scheduleRailPosition(body, rail); + } + + function resourceAnchor(body, url) { + return body.querySelector(`[data-res-url="${CSS.escape(url)}"]`); + } + + function positionRail(body, rail) { + if (rail.hidden || !rail.isConnected) return; + const bodyRect = body.getBoundingClientRect(); + const items = Array.from(rail.querySelectorAll(".rail-item")).map((el, index) => { + const anchor = resourceAnchor(body, el.dataset.resUrl); + return { + el, + index, + desired: anchor + ? Math.max(0, anchor.getBoundingClientRect().top - bodyRect.top) + : 0, + }; + }); + items.sort((a, b) => a.desired - b.desired || a.index - b.index); + let cursor = 0; + items.forEach(({ el, desired }) => { + const top = Math.max(desired, cursor); + el.style.top = `${top}px`; + cursor = top + el.offsetHeight + 10; + }); + rail.style.minHeight = `${Math.max(body.offsetHeight, cursor)}px`; + } + + function scheduleRailPosition(body, rail) { + cancelAnimationFrame(Number(rail.dataset.positionFrame || 0)); + rail.dataset.positionFrame = String( + requestAnimationFrame(() => positionRail(body, rail)) + ); + } + + function renderTrackioSpaceEmbed(el, url, id) { + const sub = id.toLowerCase().replace(/[^a-z0-9-]/g, "-"); + el.className = "trackio-embed unfurl embed"; + el.dataset.resUrl = url; + el.innerHTML = + `
        ` + + `🎯 Trackio dashboard` + + `${esc(id)}` + + `Open ↗` + + `
        ` + + ``; + } + + let DASHBOARD_INFO = null; + function fetchDashboardInfo() { + if (!DASHBOARD_INFO) { + DASHBOARD_INFO = fetch("./dashboard-info.json", { cache: "no-store" }) + .then((r) => (r.ok ? r.json() : null)) + .catch(() => null); + } + return DASHBOARD_INFO; + } + + function renderLocalDashboardEmbed(el, baseUrl, project) { + const open = baseUrl.replace(/\/$/, "") + "/?project=" + encodeURIComponent(project); + const src = open + "&sidebar=hidden&navbar=hidden"; + el.className = "trackio-embed unfurl embed"; + el.dataset.resUrl = `trackio-local-dashboard://${project}`; + el.innerHTML = + `
        ` + + `🎯 Trackio dashboard` + + `${esc(project)}` + + `Open ↗` + + `
        ` + + ``; + } + + function renderDashboardCell(meta, body, container) { + const project = meta.dashboard_project || ""; + const holder = document.createElement("div"); + container.appendChild(holder); + const space = body.match(/https:\/\/huggingface\.co\/spaces\/[^\s<>)"'`]+/); + if (space) { + const id = space[0].split("/spaces/")[1].split(/[?#]/)[0].replace(/\/$/, ""); + renderTrackioSpaceEmbed(holder, space[0], id); + return; + } + const chip = () => { + holder.className = "artifact-chip"; + holder.dataset.resUrl = `trackio-local-dashboard://${project}`; + holder.innerHTML = + "🎯 Local Trackio dashboard — publish the logbook to share it"; + }; + if (!isLocalPreview()) { + chip(); + return; + } + fetchDashboardInfo().then((info) => { + if (info && info.url) renderLocalDashboardEmbed(holder, info.url, project); + else chip(); + }); + } + + const CACHE_PREFIX = "trackio-logbook:"; + const CACHE_TTL_MS = 24 * 60 * 60 * 1000; + const CACHE_MISS_TTL_MS = 60 * 60 * 1000; + + function cacheGet(url) { + try { + const raw = localStorage.getItem(CACHE_PREFIX + url); + if (!raw) return undefined; + const entry = JSON.parse(raw); + const ttl = entry.d === null ? CACHE_MISS_TTL_MS : CACHE_TTL_MS; + if (Date.now() - entry.t > ttl) { + localStorage.removeItem(CACHE_PREFIX + url); + return undefined; + } + return entry.d; + } catch (e) { + return undefined; + } + } + + function cacheSet(url, data) { + try { + localStorage.setItem( + CACHE_PREFIX + url, + JSON.stringify({ t: Date.now(), d: data }) + ); + } catch (e) {} + } + + async function getJSON(url) { + if (UNFURL_CACHE[url] !== undefined) return UNFURL_CACHE[url]; + const cached = cacheGet(url); + if (cached !== undefined) { + UNFURL_CACHE[url] = cached; + return cached; + } + try { + const r = await fetch(url); + if (!r.ok) throw new Error(r.status); + const j = await r.json(); + UNFURL_CACHE[url] = j; + cacheSet(url, j); + return j; + } catch (e) { + UNFURL_CACHE[url] = null; + cacheSet(url, null); + return null; + } + } + + /* -------------------- routing / render -------------------- */ + + function buildTree() { + const tree = document.getElementById("tree"); + tree.innerHTML = ""; + const nodes = []; + (MANIFEST.root.children || []).forEach((c) => flattenTree(c, 0, nodes)); + nodes.forEach(({ node, depth }) => { + const a = document.createElement("a"); + a.href = "#/" + node.slug; + a.textContent = node.title; + a.className = "depth-" + depth; + a.dataset.slug = node.slug; + tree.appendChild(a); + }); + } + + function highlight(slug) { + document + .querySelectorAll("#tree a") + .forEach((a) => a.classList.toggle("active", a.dataset.slug === slug)); + document + .getElementById("book-head") + .classList.toggle("active", slug === MANIFEST.root.slug); + } + + function clearPageCache() { + Object.keys(PAGE_CACHE).forEach((key) => { + delete PAGE_CACHE[key]; + }); + } + + function isLocalPreview() { + return ["localhost", "127.0.0.1", "::1"].includes(location.hostname); + } + + async function fetchManifest() { + const suffix = isLocalPreview() ? `?t=${Date.now()}` : ""; + return await (await fetch("./logbook.json" + suffix, { cache: "no-store" })).json(); + } + + async function fetchPage(node) { + if (PAGE_CACHE[node.file]) return PAGE_CACHE[node.file]; + try { + const suffix = isLocalPreview() + ? `?rev=${encodeURIComponent(MANIFEST.revision || "")}` + : ""; + const r = await fetch("./" + node.file + suffix, { cache: "no-store" }); + PAGE_CACHE[node.file] = await r.text(); + } catch (e) { + PAGE_CACHE[node.file] = "# " + node.title + "\n\n_Could not load section._"; + } + return PAGE_CACHE[node.file]; + } + + function allNodes() { + const nodes = []; + flattenTree(MANIFEST.root, 0, nodes); + return nodes.map(({ node }) => node); + } + + function collectPinnedCells(markdown, nodes) { + const cells = []; + markdown.forEach((text, index) => { + const cellRe = /(^|\n)---\n\n([\s\S]*?)(?=\n---\n\n([\s\S]*?)(?=\n---\n + + + +
        + +
        +
        + +
        + +
        + + + + + + + + + + + +
        Trace IDRequestRunStepRequest time
        +
        +
        + + + + + + + + diff --git a/trackio/frontend_templates/starter/styles.css b/trackio/frontend_templates/starter/styles.css new file mode 100644 index 0000000000000000000000000000000000000000..51058b424f66a5bacc736f1c7fbc9e4f0290dd74 --- /dev/null +++ b/trackio/frontend_templates/starter/styles.css @@ -0,0 +1,467 @@ +:root { + color-scheme: light; + --background-fill-primary: #ffffff; + --background-fill-secondary: #f9fafb; + --background-fill-tertiary: #f3f4f6; + --border-color-primary: #e5e7eb; + --border-color-accent: #d1d5db; + --body-text-color: #111827; + --body-text-color-subdued: #6b7280; + --body-text-color-soft: #9ca3af; + --accent: #1d4ed8; + --shadow-soft: 0 1px 2px rgba(16, 24, 40, 0.04); +} + +* { + box-sizing: border-box; +} + +html, +body { + margin: 0; + min-height: 100%; + background: var(--background-fill-secondary); + color: var(--body-text-color); + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + sans-serif; +} + +button, +input, +select, +table { + font: inherit; +} + +.app-shell { + display: grid; + grid-template-columns: 320px minmax(0, 1fr); + min-height: 100vh; +} + +.sidebar { + border-right: 1px solid var(--border-color-primary); + background: var(--background-fill-primary); +} + +.sidebar-scroll { + height: 100vh; + overflow-y: auto; + padding: 18px 16px 28px; +} + +.logo-section { + padding: 10px 10px 18px; + border-bottom: 1px solid var(--border-color-primary); +} + +.logo { + display: block; + width: 138px; + max-width: 100%; +} + +.sidebar-section { + padding: 18px 10px 0; +} + +.section-label, +.eyebrow { + margin: 0 0 10px; + color: var(--body-text-color-subdued); + font-size: 12px; + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.run-list { + display: grid; + gap: 8px; +} + +.dropdown-wrap { + position: relative; +} + +.project-select { + width: 100%; + padding: 10px 40px 10px 12px; + border: 1px solid var(--border-color-primary); + border-radius: 10px; + background: var(--background-fill-primary); + color: var(--body-text-color); + appearance: none; + -webkit-appearance: none; +} + +.project-select:focus { + outline: none; + border-color: var(--border-color-accent); + box-shadow: 0 0 0 3px rgba(29, 78, 216, 0.08); +} + +.dropdown-icon { + position: absolute; + top: 50%; + right: 12px; + transform: translateY(-50%); + color: var(--body-text-color-subdued); + pointer-events: none; +} + +.run-option { + display: grid; + grid-template-columns: 18px 10px minmax(0, 1fr); + gap: 10px; + align-items: start; + padding: 10px 12px; + border: 1px solid var(--border-color-primary); + border-radius: 10px; + background: var(--background-fill-primary); + cursor: pointer; +} + +.run-option input { + margin: 2px 0 0; + accent-color: var(--accent); +} + +.run-color-dot { + width: 10px; + height: 10px; + margin-top: 5px; + border-radius: 999px; + background: var(--accent); +} + +.run-option-text strong, +.run-option-text span { + display: block; +} + +.run-option-text strong { + color: var(--body-text-color); + font-size: 14px; + font-weight: 600; +} + +.run-option-text span, +.sidebar-note, +.sidebar-empty { + color: var(--body-text-color-subdued); + font-size: 13px; + line-height: 1.5; +} + +.main-shell { + display: flex; + flex-direction: column; + min-width: 0; +} + +.navbar { + display: flex; + align-items: stretch; + min-height: 44px; + border-bottom: 1px solid var(--border-color-primary); + background: var(--background-fill-primary); +} + +.nav-spacer { + flex: 1 1 0; +} + +.nav-tabs { + display: flex; + padding-right: 8px; +} + +.nav-link { + padding: 10px 16px; + border: none; + border-bottom: 2px solid transparent; + background: none; + color: var(--body-text-color-subdued); + cursor: pointer; +} + +.nav-link.active { + border-bottom-color: var(--body-text-color); + color: var(--body-text-color); + font-weight: 500; +} + +.page { + display: none; + min-width: 0; + padding: 24px 28px 36px; +} + +.page.active { + display: block; +} + +.page-header { + margin-bottom: 22px; +} + +.page-header h1 { + margin: 0; + font-size: 32px; + line-height: 1.1; +} + +.page-subtitle { + margin: 8px 0 0; + color: var(--body-text-color-subdued); + font-size: 15px; +} + +.metrics-grid { + display: grid; + gap: 18px; +} + +.metric-card { + padding: 18px; + border: 1px solid var(--border-color-primary); + border-radius: 14px; + background: var(--background-fill-primary); + box-shadow: var(--shadow-soft); +} + +.metric-card-head { + display: flex; + align-items: start; + justify-content: space-between; + gap: 16px; +} + +.metric-card h3 { + margin: 0; + font-size: 18px; +} + +.metric-run, +.metric-meta, +.metric-empty, +.metric-latest { + color: var(--body-text-color-subdued); + font-size: 13px; +} + +.metric-latest { + color: var(--body-text-color); + max-width: 50%; + font-size: 13px; + font-weight: 600; + text-align: right; +} + +.plot-shell { + margin-top: 14px; + padding: 10px 12px; + border: 1px solid var(--border-color-primary); + border-radius: 12px; + background: linear-gradient(180deg, #ffffff, #f9fafb); +} + +.plot-shell svg { + display: block; + width: 100%; + height: auto; +} + +.plot-axis { + stroke: var(--border-color-accent); + stroke-width: 1.2; +} + +.plot-line { + fill: none; + stroke-width: 2.25; + stroke-linecap: round; + stroke-linejoin: round; +} + +.plot-marker { + fill: var(--background-fill-primary); + stroke: var(--body-text-color); + stroke-width: 1.5; +} + +.metric-legend { + display: flex; + flex-wrap: wrap; + gap: 10px 14px; + margin-top: 12px; +} + +.metric-legend-item { + display: inline-flex; + align-items: center; + gap: 8px; + color: var(--body-text-color-subdued); + font-size: 13px; +} + +.metric-legend-dot { + width: 10px; + height: 10px; + border-radius: 999px; +} + +.traces-table-wrap { + overflow: auto; + border: 1px solid var(--border-color-primary); + border-radius: 14px; + background: var(--background-fill-primary); + box-shadow: var(--shadow-soft); +} + +.traces-table { + width: 100%; + border-collapse: collapse; +} + +.traces-table thead { + background: var(--background-fill-secondary); +} + +.traces-table th, +.traces-table td { + padding: 14px 16px; + border-bottom: 1px solid var(--border-color-primary); + text-align: left; + vertical-align: top; + font-size: 14px; +} + +.traces-table th { + color: var(--body-text-color-subdued); + font-size: 12px; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.trace-summary-row { + cursor: pointer; +} + +.trace-summary-row:hover { + background: var(--background-fill-secondary); +} + +.trace-summary-row.expanded { + background: var(--background-fill-secondary); +} + +.trace-id { + color: var(--body-text-color); + font-family: + ui-monospace, + SFMono-Regular, + Menlo, + monospace; + font-size: 12px; +} + +.trace-request { + max-width: 520px; + color: var(--body-text-color); +} + +.trace-detail-row td { + padding: 0; + background: var(--background-fill-secondary); +} + +.trace-detail-shell { + padding: 18px 20px; + border-top: 1px solid var(--border-color-primary); +} + +.trace-detail-head strong { + display: block; + color: var(--body-text-color); + font-size: 14px; +} + +.trace-detail-meta { + margin-top: 4px; + color: var(--body-text-color-subdued); + font-size: 12px; +} + +.trace-message-list { + display: grid; + gap: 12px; + margin-top: 16px; +} + +.trace-message { + padding: 12px 14px; + border: 1px solid var(--border-color-primary); + border-radius: 12px; + background: var(--background-fill-primary); +} + +.trace-message-role { + margin-bottom: 8px; + color: var(--body-text-color-subdued); + font-size: 12px; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.trace-message-text { + color: var(--body-text-color); + font-size: 14px; + line-height: 1.55; + white-space: pre-wrap; + overflow-wrap: anywhere; +} + +.trace-message-muted { + color: var(--body-text-color-subdued); +} + +.empty-row, +.empty-panel { + color: var(--body-text-color-subdued); + text-align: center; +} + +.empty-panel { + padding: 48px 20px; + border: 1px dashed var(--border-color-accent); + border-radius: 14px; + background: var(--background-fill-primary); +} + +@media (max-width: 960px) { + .app-shell { + grid-template-columns: 1fr; + } + + .sidebar { + border-right: none; + border-bottom: 1px solid var(--border-color-primary); + } + + .sidebar-scroll { + height: auto; + } + + .page { + padding: 18px; + } +} diff --git a/trackio/gpu.py b/trackio/gpu.py new file mode 100644 index 0000000000000000000000000000000000000000..a84d903884069e1133532629aa1c63d22c3c792a --- /dev/null +++ b/trackio/gpu.py @@ -0,0 +1,381 @@ +import os +import threading +import warnings +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from trackio.run import Run + +pynvml: Any = None +PYNVML_AVAILABLE = False +_nvml_initialized = False +_nvml_lock = threading.Lock() +_energy_baseline: dict[int, float] = {} + + +def _ensure_pynvml(): + global PYNVML_AVAILABLE, pynvml + if PYNVML_AVAILABLE: + return pynvml + try: + import pynvml as _pynvml + + pynvml = _pynvml + PYNVML_AVAILABLE = True + return pynvml + except ImportError: + raise ImportError( + "nvidia-ml-py is required for GPU monitoring. " + "Install it with: pip install nvidia-ml-py" + ) + + +def _init_nvml() -> bool: + global _nvml_initialized + with _nvml_lock: + if _nvml_initialized: + return True + try: + nvml = _ensure_pynvml() + nvml.nvmlInit() + _nvml_initialized = True + return True + except Exception: + return False + + +def get_gpu_count() -> tuple[int, list[int]]: + """ + Get the number of GPUs visible to this process and their physical indices. + Respects CUDA_VISIBLE_DEVICES environment variable. + + Returns: + Tuple of (count, physical_indices) where: + - count: Number of visible GPUs + - physical_indices: List mapping logical index to physical GPU index. + e.g., if CUDA_VISIBLE_DEVICES=2,3 returns (2, [2, 3]) + meaning logical GPU 0 = physical GPU 2, logical GPU 1 = physical GPU 3 + """ + if not _init_nvml(): + return 0, [] + + cuda_visible = os.environ.get("CUDA_VISIBLE_DEVICES") + if cuda_visible is not None and cuda_visible.strip(): + try: + indices = [int(x.strip()) for x in cuda_visible.split(",") if x.strip()] + return len(indices), indices + except ValueError: + pass + + try: + total = pynvml.nvmlDeviceGetCount() + return total, list(range(total)) + except Exception: + return 0, [] + + +def get_all_gpu_count() -> tuple[int, list[int]]: + """ + Get the total number of physical GPUs on the machine, ignoring CUDA_VISIBLE_DEVICES. + + Returns: + Tuple of (count, physical_indices) for ALL GPUs on the machine. + e.g., on a 4-GPU machine returns (4, [0, 1, 2, 3]) regardless of + CUDA_VISIBLE_DEVICES setting. + """ + if not _init_nvml(): + return 0, [] + + try: + total = pynvml.nvmlDeviceGetCount() + return total, list(range(total)) + except Exception: + return 0, [] + + +def gpu_available() -> bool: + """ + Check if GPU monitoring is available. + + Returns True if nvidia-ml-py is installed and at least one NVIDIA GPU is detected. + This is used for auto-detection of GPU logging. + """ + try: + _ensure_pynvml() + count, _ = get_gpu_count() + return count > 0 + except ImportError: + return False + except Exception: + return False + + +def reset_energy_baseline(): + """Reset the energy baseline for all GPUs. Called when a new run starts.""" + global _energy_baseline + _energy_baseline = {} + + +def collect_gpu_metrics(device: int | None = None, all_gpus: bool = False) -> dict: + """ + Collect GPU metrics for visible GPUs. + + Args: + device: CUDA device index to collect metrics from. If None, collects + from all GPUs visible to this process (respects CUDA_VISIBLE_DEVICES). + The device index is the logical CUDA index (0, 1, 2...), not the + physical GPU index. + all_gpus: If True and device is None, collect metrics for ALL physical GPUs + on the machine, ignoring CUDA_VISIBLE_DEVICES. Used by GpuMonitor + to report system-wide GPU metrics in distributed training. + + Returns: + Dictionary of GPU metrics. Keys use device indices (gpu/0/, gpu/1/, etc.). + """ + if not _init_nvml(): + return {} + + if all_gpus and device is None: + gpu_count, visible_gpus = get_all_gpu_count() + else: + gpu_count, visible_gpus = get_gpu_count() + if gpu_count == 0: + return {} + + if device is not None: + if device < 0 or device >= gpu_count: + return {} + gpu_indices = [(device, visible_gpus[device])] + else: + gpu_indices = list(enumerate(visible_gpus)) + + metrics = {} + total_util = 0.0 + total_mem_used_gib = 0.0 + total_power = 0.0 + max_temp = 0.0 + valid_util_count = 0 + + for logical_idx, physical_idx in gpu_indices: + prefix = f"gpu/{logical_idx}" + try: + handle = pynvml.nvmlDeviceGetHandleByIndex(physical_idx) + + try: + util = pynvml.nvmlDeviceGetUtilizationRates(handle) + metrics[f"{prefix}/utilization"] = util.gpu + metrics[f"{prefix}/memory_utilization"] = util.memory + total_util += util.gpu + valid_util_count += 1 + except Exception: + pass + + try: + mem = pynvml.nvmlDeviceGetMemoryInfo(handle) + mem_used_gib = mem.used / (1024**3) + mem_total_gib = mem.total / (1024**3) + metrics[f"{prefix}/allocated_memory"] = mem_used_gib + metrics[f"{prefix}/total_memory"] = mem_total_gib + if mem.total > 0: + metrics[f"{prefix}/memory_usage"] = mem.used / mem.total + total_mem_used_gib += mem_used_gib + except Exception: + pass + + try: + power_mw = pynvml.nvmlDeviceGetPowerUsage(handle) + power_w = power_mw / 1000.0 + metrics[f"{prefix}/power"] = power_w + total_power += power_w + except Exception: + pass + + try: + power_limit_mw = pynvml.nvmlDeviceGetPowerManagementLimit(handle) + power_limit_w = power_limit_mw / 1000.0 + metrics[f"{prefix}/power_limit"] = power_limit_w + if power_limit_w > 0 and f"{prefix}/power" in metrics: + metrics[f"{prefix}/power_percent"] = ( + metrics[f"{prefix}/power"] / power_limit_w + ) * 100 + except Exception: + pass + + try: + temp = pynvml.nvmlDeviceGetTemperature( + handle, pynvml.NVML_TEMPERATURE_GPU + ) + metrics[f"{prefix}/temp"] = temp + max_temp = max(max_temp, temp) + except Exception: + pass + + try: + sm_clock = pynvml.nvmlDeviceGetClockInfo(handle, pynvml.NVML_CLOCK_SM) + metrics[f"{prefix}/sm_clock"] = sm_clock + except Exception: + pass + + try: + mem_clock = pynvml.nvmlDeviceGetClockInfo(handle, pynvml.NVML_CLOCK_MEM) + metrics[f"{prefix}/memory_clock"] = mem_clock + except Exception: + pass + + try: + fan_speed = pynvml.nvmlDeviceGetFanSpeed(handle) + metrics[f"{prefix}/fan_speed"] = fan_speed + except Exception: + pass + + try: + pstate = pynvml.nvmlDeviceGetPerformanceState(handle) + metrics[f"{prefix}/performance_state"] = pstate + except Exception: + pass + + try: + energy_mj = pynvml.nvmlDeviceGetTotalEnergyConsumption(handle) + if physical_idx not in _energy_baseline: + _energy_baseline[physical_idx] = energy_mj + energy_consumed_mj = energy_mj - _energy_baseline[physical_idx] + metrics[f"{prefix}/energy_consumed"] = energy_consumed_mj / 1000.0 + except Exception: + pass + + try: + pcie_tx = pynvml.nvmlDeviceGetPcieThroughput( + handle, pynvml.NVML_PCIE_UTIL_TX_BYTES + ) + pcie_rx = pynvml.nvmlDeviceGetPcieThroughput( + handle, pynvml.NVML_PCIE_UTIL_RX_BYTES + ) + metrics[f"{prefix}/pcie_tx"] = pcie_tx / 1024.0 + metrics[f"{prefix}/pcie_rx"] = pcie_rx / 1024.0 + except Exception: + pass + + try: + throttle = pynvml.nvmlDeviceGetCurrentClocksThrottleReasons(handle) + metrics[f"{prefix}/throttle_thermal"] = int( + bool(throttle & pynvml.nvmlClocksThrottleReasonSwThermalSlowdown) + ) + metrics[f"{prefix}/throttle_power"] = int( + bool(throttle & pynvml.nvmlClocksThrottleReasonSwPowerCap) + ) + metrics[f"{prefix}/throttle_hw_slowdown"] = int( + bool(throttle & pynvml.nvmlClocksThrottleReasonHwSlowdown) + ) + metrics[f"{prefix}/throttle_apps"] = int( + bool( + throttle + & pynvml.nvmlClocksThrottleReasonApplicationsClocksSetting + ) + ) + except Exception: + pass + + try: + ecc_corrected = pynvml.nvmlDeviceGetTotalEccErrors( + handle, + pynvml.NVML_MEMORY_ERROR_TYPE_CORRECTED, + pynvml.NVML_VOLATILE_ECC, + ) + metrics[f"{prefix}/corrected_memory_errors"] = ecc_corrected + except Exception: + pass + + try: + ecc_uncorrected = pynvml.nvmlDeviceGetTotalEccErrors( + handle, + pynvml.NVML_MEMORY_ERROR_TYPE_UNCORRECTED, + pynvml.NVML_VOLATILE_ECC, + ) + metrics[f"{prefix}/uncorrected_memory_errors"] = ecc_uncorrected + except Exception: + pass + + except Exception: + continue + + if valid_util_count > 0: + metrics["gpu/mean_utilization"] = total_util / valid_util_count + if total_mem_used_gib > 0: + metrics["gpu/total_allocated_memory"] = total_mem_used_gib + if total_power > 0: + metrics["gpu/total_power"] = total_power + if max_temp > 0: + metrics["gpu/max_temp"] = max_temp + + return metrics + + +class GpuMonitor: + def __init__(self, run: "Run", interval: float = 10.0): + self._run = run + self._interval = interval + self._stop_flag = threading.Event() + self._thread: "threading.Thread | None" = None + + def start(self): + count, _ = get_all_gpu_count() + if count == 0: + warnings.warn( + "auto_log_gpu=True but no NVIDIA GPUs detected. GPU logging disabled." + ) + return + + reset_energy_baseline() + self._thread = threading.Thread(target=self._monitor_loop, daemon=True) + self._thread.start() + + def stop(self): + self._stop_flag.set() + if self._thread is not None: + self._thread.join(timeout=2.0) + + def _monitor_loop(self): + while not self._stop_flag.is_set(): + try: + metrics = collect_gpu_metrics(all_gpus=True) + if metrics: + self._run.log_system(metrics) + except Exception: + pass + + self._stop_flag.wait(timeout=self._interval) + + +def log_gpu(run: "Run | None" = None, device: int | None = None) -> dict: + """ + Log GPU metrics to the current or specified run as system metrics. + + Args: + run: Optional Run instance. If None, uses current run from context. + device: CUDA device index to collect metrics from. If None, collects + from all GPUs visible to this process (respects CUDA_VISIBLE_DEVICES). + + Returns: + dict: The GPU metrics that were logged. + + Example: + ```python + import trackio + + run = trackio.init(project="my-project") + trackio.log({"loss": 0.5}) + trackio.log_gpu() # logs all visible GPUs + trackio.log_gpu(device=0) # logs only CUDA device 0 + ``` + """ + from trackio import context_vars + + if run is None: + run = context_vars.current_run.get() + if run is None: + raise RuntimeError("Call trackio.init() before trackio.log_gpu().") + + metrics = collect_gpu_metrics(device=device) + if metrics: + run.log_system(metrics) + return metrics diff --git a/trackio/histogram.py b/trackio/histogram.py new file mode 100644 index 0000000000000000000000000000000000000000..1e00477907d55f7f5dcc1bf2bff05029d43b3ac1 --- /dev/null +++ b/trackio/histogram.py @@ -0,0 +1,71 @@ +from typing import Sequence + +import numpy as np + + +class Histogram: + """ + Histogram data type for Trackio, compatible with wandb.Histogram. + + Args: + sequence (`np.ndarray` or `Sequence[float]` or `Sequence[int]`, *optional*): + Sequence of values to create the histogram from. + np_histogram (`tuple`, *optional*): + Pre-computed NumPy histogram as a `(hist, bins)` tuple. + num_bins (`int`, *optional*, defaults to `64`): + Number of bins for the histogram (maximum `512`). + + Example: + ```python + import trackio + import numpy as np + + # Create histogram from sequence + data = np.random.randn(1000) + trackio.log({"distribution": trackio.Histogram(data)}) + + # Create histogram from numpy histogram + hist, bins = np.histogram(data, bins=30) + trackio.log({"distribution": trackio.Histogram(np_histogram=(hist, bins))}) + + # Specify custom number of bins + trackio.log({"distribution": trackio.Histogram(data, num_bins=50)}) + ``` + """ + + TYPE = "trackio.histogram" + + def __init__( + self, + sequence: np.ndarray | Sequence[float] | Sequence[int] | None = None, + np_histogram: tuple | None = None, + num_bins: int = 64, + ): + if sequence is None and np_histogram is None: + raise ValueError("Must provide either sequence or np_histogram") + + if sequence is not None and np_histogram is not None: + raise ValueError("Cannot provide both sequence and np_histogram") + + num_bins = min(num_bins, 512) + + if np_histogram is not None: + self.histogram, self.bins = np_histogram + self.histogram = np.asarray(self.histogram) + self.bins = np.asarray(self.bins) + else: + data = np.asarray(sequence).flatten() + data = data[np.isfinite(data)] + if len(data) == 0: + self.histogram = np.array([]) + self.bins = np.array([]) + else: + self.histogram, self.bins = np.histogram(data, bins=num_bins) + + def _to_dict(self) -> dict: + """Convert histogram to dictionary for storage.""" + return { + "_type": self.TYPE, + "bins": self.bins.tolist(), + "values": self.histogram.tolist(), + } diff --git a/trackio/imports.py b/trackio/imports.py new file mode 100644 index 0000000000000000000000000000000000000000..37516dbdc409b91f643ba3b0070c80379bb2252b --- /dev/null +++ b/trackio/imports.py @@ -0,0 +1,305 @@ +import csv +import os +from pathlib import Path + +from trackio import deploy, utils +from trackio.sqlite_storage import SQLiteStorage + + +def import_csv( + csv_path: str | Path, + project: str, + name: str | None = None, + space_id: str | None = None, + dataset_id: str | None = None, + private: bool | None = None, + force: bool = False, +) -> None: + """ + Imports a CSV file into a Trackio project. The CSV file must contain a `"step"` + column, may optionally contain a `"timestamp"` column, and any other columns will be + treated as metrics. It should also include a header row with the column names. + + TODO: call init() and return a Run object so that the user can continue to log metrics to it. + + Args: + csv_path (`str` or `Path`): + The str or Path to the CSV file to import. + project (`str`): + The name of the project to import the CSV file into. Must not be an existing + project. + name (`str`, *optional*): + The name of the Run to import the CSV file into. If not provided, a default + name will be generated. + name (`str`, *optional*): + The name of the run (if not provided, a default name will be generated). + space_id (`str`, *optional*): + If provided, the project will be logged to a Hugging Face Space instead of a + local directory. Should be a complete Space name like `"username/reponame"` + or `"orgname/reponame"`, or just `"reponame"` in which case the Space will + be created in the currently-logged-in Hugging Face user's namespace. If the + Space does not exist, it will be created. If the Space already exists, the + project will be logged to it. + dataset_id (`str`, *optional*): + Deprecated. Use `bucket_id` instead. + private (`bool`, *optional*): + Whether to make the Space private. If None (default), the repo will be + public unless the organization's default is private. This value is ignored + if the repo already exists. + """ + if SQLiteStorage.get_runs(project): + raise ValueError( + f"Project '{project}' already exists. Cannot import CSV into existing project." + ) + + csv_path = Path(csv_path) + if not csv_path.exists(): + raise FileNotFoundError(f"CSV file not found: {csv_path}") + + with csv_path.open(newline="", encoding="utf-8") as csv_file: + reader = csv.DictReader(csv_file) + source_columns = reader.fieldnames or [] + rows = list(reader) + + if not rows: + raise ValueError("CSV file is empty") + + column_mapping = utils.simplify_column_names(source_columns) + normalized_rows = [ + {column_mapping[key]: value for key, value in row.items()} for row in rows + ] + columns = list(normalized_rows[0].keys()) + + step_column = None + for col in columns: + if col.lower() == "step": + step_column = col + break + + if step_column is None: + raise ValueError("CSV file must contain a 'step' or 'Step' column") + + if name is None: + name = csv_path.stem + + metrics_list = [] + steps = [] + timestamps = [] + + numeric_columns = [] + for column in columns: + if column == step_column: + continue + if column == "timestamp": + continue + + try: + for row in normalized_rows: + value = row[column] + if value in ("", None): + continue + float(value) + except (ValueError, TypeError): + continue + numeric_columns.append(column) + + for row in normalized_rows: + metrics = {} + for column in numeric_columns: + value = row[column] + if value not in ("", None): + metrics[column] = float(value) + + if metrics: + metrics_list.append(metrics) + steps.append(int(float(row[step_column]))) + + if "timestamp" in row and row["timestamp"] not in ("", None): + timestamps.append(str(row["timestamp"])) + else: + timestamps.append("") + + if not metrics_list: + raise ValueError( + f"No numeric metric data found in CSV file: {csv_path}. Columns other " + "than 'step' and 'timestamp' must contain numeric values." + ) + + SQLiteStorage.bulk_log( + project=project, + run=name, + metrics_list=metrics_list, + steps=steps, + timestamps=timestamps, + ) + + print( + f"* Imported {len(metrics_list)} rows from {csv_path} into project '{project}' as run '{name}'" + ) + print(f"* Metrics found: {', '.join(metrics_list[0].keys())}") + + space_id, dataset_id, _ = utils.preprocess_space_and_dataset_ids( + space_id, dataset_id + ) + if dataset_id is not None: + os.environ["TRACKIO_DATASET_ID"] = dataset_id + print(f"* Trackio metrics will be synced to Hugging Face Dataset: {dataset_id}") + + if space_id is None: + utils.print_dashboard_instructions(project) + else: + deploy.create_space_if_not_exists( + space_id=space_id, dataset_id=dataset_id, private=private + ) + deploy.wait_until_space_exists(space_id=space_id) + deploy.upload_db_to_space(project=project, space_id=space_id, force=force) + print( + f"* View dashboard by going to: {deploy.SPACE_URL.format(space_id=space_id)}" + ) + + +def import_tf_events( + log_dir: str | Path, + project: str, + name: str | None = None, + space_id: str | None = None, + dataset_id: str | None = None, + private: bool | None = None, + force: bool = False, +) -> None: + """ + Imports TensorFlow Events files from a directory into a Trackio project. Each + subdirectory in the log directory will be imported as a separate run. + + Args: + log_dir (`str` or `Path`): + The str or Path to the directory containing TensorFlow Events files. + project (`str`): + The name of the project to import the TensorFlow Events files into. Must not + be an existing project. + name (`str`, *optional*): + The name prefix for runs (if not provided, will use directory names). Each + subdirectory will create a separate run. + space_id (`str`, *optional*): + If provided, the project will be logged to a Hugging Face Space instead of a + local directory. Should be a complete Space name like `"username/reponame"` + or `"orgname/reponame"`, or just `"reponame"` in which case the Space will + be created in the currently-logged-in Hugging Face user's namespace. If the + Space does not exist, it will be created. If the Space already exists, the + project will be logged to it. + dataset_id (`str`, *optional*): + Deprecated. Use `bucket_id` instead. + private (`bool`, *optional*): + Whether to make the Space private. If None (default), the repo will be + public unless the organization's default is private. This value is ignored + if the repo already exists. + """ + try: + from tbparse import SummaryReader + except ImportError: + raise ImportError( + "The `tbparse` package is not installed but is required for `import_tf_events`. Please install trackio with the `tensorboard` extra: `pip install trackio[tensorboard]`." + ) + + if SQLiteStorage.get_runs(project): + raise ValueError( + f"Project '{project}' already exists. Cannot import TF events into existing project." + ) + + path = Path(log_dir) + if not path.exists(): + raise FileNotFoundError(f"TF events directory not found: {path}") + + # Use tbparse to read all tfevents files in the directory structure + reader = SummaryReader(str(path), extra_columns={"dir_name"}) + df = reader.scalars + + if df.empty: + raise ValueError(f"No TensorFlow events data found in {path}") + + total_imported = 0 + imported_runs = [] + + # Group by dir_name to create separate runs + for dir_name, group_df in df.groupby("dir_name"): + try: + # Determine run name based on directory name + if dir_name == "": + run_name = "main" # For files in the root directory + else: + run_name = dir_name # Use directory name + + if name: + run_name = f"{name}_{run_name}" + + if group_df.empty: + print(f"* Skipping directory {dir_name}: no scalar data found") + continue + + metrics_list = [] + steps = [] + timestamps = [] + + for _, row in group_df.iterrows(): + # Convert row values to appropriate types + tag = str(row["tag"]) + value = float(row["value"]) + step = int(row["step"]) + + metrics = {tag: value} + metrics_list.append(metrics) + steps.append(step) + + # Use wall_time if present, else fallback + if "wall_time" in group_df.columns and not utils.is_missing_value( + row["wall_time"] + ): + timestamps.append(str(row["wall_time"])) + else: + timestamps.append("") + + if metrics_list: + SQLiteStorage.bulk_log( + project=project, + run=str(run_name), + metrics_list=metrics_list, + steps=steps, + timestamps=timestamps, + ) + + total_imported += len(metrics_list) + imported_runs.append(run_name) + + print( + f"* Imported {len(metrics_list)} scalar events from directory '{dir_name}' as run '{run_name}'" + ) + print(f"* Metrics in this run: {', '.join(set(group_df['tag']))}") + + except Exception as e: + print(f"* Error processing directory {dir_name}: {e}") + continue + + if not imported_runs: + raise ValueError("No valid TensorFlow events data could be imported") + + print(f"* Total imported events: {total_imported}") + print(f"* Created runs: {', '.join(imported_runs)}") + + space_id, dataset_id, _ = utils.preprocess_space_and_dataset_ids( + space_id, dataset_id + ) + if dataset_id is not None: + os.environ["TRACKIO_DATASET_ID"] = dataset_id + print(f"* Trackio metrics will be synced to Hugging Face Dataset: {dataset_id}") + + if space_id is None: + utils.print_dashboard_instructions(project) + else: + deploy.create_space_if_not_exists( + space_id, dataset_id=dataset_id, private=private + ) + deploy.wait_until_space_exists(space_id) + deploy.upload_db_to_space(project, space_id, force=force) + print( + f"* View dashboard by going to: {deploy.SPACE_URL.format(space_id=space_id)}" + ) diff --git a/trackio/launch.py b/trackio/launch.py new file mode 100644 index 0000000000000000000000000000000000000000..9fe4843dceb64c7c6ee74f95cbc22e5447a273c6 --- /dev/null +++ b/trackio/launch.py @@ -0,0 +1,202 @@ +from __future__ import annotations + +import os +import secrets +import socket +import threading +import time +import warnings +from pathlib import Path +from typing import Any + +import httpx +import uvicorn +from uvicorn.config import Config + +from trackio._vendor.gradio_exceptions import ChecksumMismatchError +from trackio._vendor.networking import normalize_share_url, setup_tunnel, url_ok +from trackio._vendor.tunneling import BINARY_PATH +from trackio.launch_utils import colab_check, is_hosted_notebook + +INITIAL_PORT_VALUE = int(os.getenv("GRADIO_SERVER_PORT", "7860")) +TRY_NUM_PORTS = int(os.getenv("GRADIO_NUM_PORTS", "100")) +LOCALHOST_NAME = os.getenv("GRADIO_SERVER_NAME", "127.0.0.1") + + +class _UvicornServer(uvicorn.Server): + def install_signal_handlers(self) -> None: + pass + + def run_in_thread(self) -> None: + self.thread = threading.Thread(target=self.run, daemon=True) + self.thread.start() + start = time.time() + while not self.started: + time.sleep(1e-3) + if time.time() - start > 60: + raise RuntimeError( + "Server failed to start. Please check that the port is available." + ) + + +def _bind_host(server_name: str) -> str: + if server_name.startswith("[") and server_name.endswith("]"): + return server_name[1:-1] + return server_name + + +def start_server( + app: Any, + server_name: str | None = None, + server_port: int | None = None, + ssl_keyfile: str | None = None, + ssl_certfile: str | None = None, + ssl_keyfile_password: str | None = None, +) -> tuple[str, int, str, _UvicornServer]: + server_name = server_name or LOCALHOST_NAME + url_host_name = "localhost" if server_name == "0.0.0.0" else server_name + + host = _bind_host(server_name) + + server_ports = ( + [server_port] + if server_port is not None + else range(INITIAL_PORT_VALUE, INITIAL_PORT_VALUE + TRY_NUM_PORTS) + ) + + port_used = None + server = None + for port in server_ports: + try: + socket_family = socket.AF_INET6 if ":" in host else socket.AF_INET + with socket.socket(socket_family, socket.SOCK_STREAM) as s: + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind((host, port)) + config = Config( + app=app, + port=port, + host=host, + log_level="warning", + ssl_keyfile=ssl_keyfile, + ssl_certfile=ssl_certfile, + ssl_keyfile_password=ssl_keyfile_password, + ) + server = _UvicornServer(config=config) + server.run_in_thread() + port_used = port + break + except (OSError, RuntimeError): + continue + else: + raise OSError( + f"Cannot find empty port in range: {min(server_ports)}-{max(server_ports)}. " + "Set GRADIO_SERVER_PORT or pass server_port to trackio.show()." + ) + + assert port_used is not None and server is not None + + if ssl_keyfile is not None: + path_to_local_server = f"https://{url_host_name}:{port_used}/" + else: + path_to_local_server = f"http://{url_host_name}:{port_used}/" + + return server_name, port_used, path_to_local_server, server + + +def launch_trackio_dashboard( + starlette_app: Any, + *, + server_name: str | None = None, + server_port: int | None = None, + share: bool | None = None, + share_server_address: str | None = None, + share_server_protocol: str | None = None, + share_server_tls_certificate: str | None = None, + mcp_server: bool = False, + ssl_verify: bool = True, + quiet: bool = False, +) -> tuple[str | None, str | None, str | None, Any]: + is_colab = colab_check() + is_hosted_nb = is_hosted_notebook() + space_id = os.getenv("SPACE_ID") + + if share is None: + if is_colab or is_hosted_nb: + if not quiet: + print( + "It looks like you are running Trackio on a hosted Jupyter notebook, which requires " + "`share=True`. Automatically setting `share=True` " + "(set `share=False` in `show()` to disable).\n" + ) + share = True + else: + share = os.getenv("GRADIO_SHARE", "").lower() == "true" + + sn = server_name + if sn is None and os.getenv("SYSTEM") == "spaces": + sn = "0.0.0.0" + elif sn is None: + sn = LOCALHOST_NAME + + server_name_r, server_port_r, local_url, uv_server = start_server( + starlette_app, + server_name=sn, + server_port=server_port, + ) + + local_api_url = f"{local_url.rstrip('/')}/api/" + try: + httpx.get(f"{local_url.rstrip('/')}/version", verify=ssl_verify, timeout=10) + except Exception as e: + raise RuntimeError( + f"Could not reach Trackio server at {local_url.rstrip('/')}/version: {e}" + ) from e + + if share and space_id: + warnings.warn("Setting share=True is not supported on Hugging Face Spaces") + share = False + + share_url: str | None = None + if share: + try: + share_tok = secrets.token_urlsafe(32) + proto = share_server_protocol or ( + "http" if share_server_address is not None else "https" + ) + raw = setup_tunnel( + local_host=server_name_r, + local_port=server_port_r, + share_token=share_tok, + share_server_address=share_server_address, + share_server_tls_certificate=share_server_tls_certificate, + ) + share_url = normalize_share_url(raw, proto) + if not quiet: + print(f"* Running on public URL: {share_url}") + print( + "\nThis share link expires in 1 week. For permanent hosting, deploy to Hugging Face Spaces." + ) + except Exception as e: + share_url = None + if not quiet: + if isinstance(e, ChecksumMismatchError): + print( + "\nCould not create share link. Checksum mismatch for frpc binary." + ) + elif Path(BINARY_PATH).exists(): + print( + "\nCould not create share link. Check your internet connection or https://status.gradio.app." + ) + else: + print( + f"\nCould not create share link. Missing frpc at {BINARY_PATH}. {e}" + ) + + if not share_url and not quiet: + print("* To create a public link, set `share=True` in `trackio.show()`.") + + return local_url, share_url, local_api_url, uv_server + + +def url_ok_local(local_url: str) -> bool: + return url_ok(local_url) diff --git a/trackio/launch_utils.py b/trackio/launch_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..4215f7564472ad42441be63ecec13d5d385a20fb --- /dev/null +++ b/trackio/launch_utils.py @@ -0,0 +1,33 @@ +import os + + +def colab_check() -> bool: + is_colab = False + try: + from IPython.core.getipython import get_ipython # noqa: PLC0415 + + from_ipynb = get_ipython() + if "google.colab" in str(from_ipynb): + is_colab = True + except (ImportError, NameError): + pass + return is_colab + + +def is_hosted_notebook() -> bool: + return bool( + os.environ.get("KAGGLE_KERNEL_RUN_TYPE") + or os.path.exists("/home/ec2-user/SageMaker") + ) + + +def ipython_check() -> bool: + is_ipython = False + try: + from IPython.core.getipython import get_ipython # noqa: PLC0415 + + if get_ipython() is not None: + is_ipython = True + except (ImportError, NameError): + pass + return is_ipython diff --git a/trackio/logbook.py b/trackio/logbook.py new file mode 100644 index 0000000000000000000000000000000000000000..1f0e198df6ab8c682edcd22a45ced84e0501d72b --- /dev/null +++ b/trackio/logbook.py @@ -0,0 +1,2043 @@ +from __future__ import annotations + +import html +import json +import os +import re +import shlex +import shutil +import subprocess +import sys +import time +import uuid +from datetime import datetime, timezone +from pathlib import Path + +PROJECT_DIR_NAME = ".trackio" +LOGBOOK_SUBDIR = "logbook" +METADATA_FILE = "metadata.json" +SCHEMA_VERSION = 1 +ROOT_SLUG = "index" +VIEWER_DIR = Path(__file__).parent / "frontend_templates" / "logbook" +VIEWER_FILES = [ + "index.html", + "logbook.css", + "logbook.js", + "trackio-logo.png", + "trackio-logo-light.png", + "trackio-wordmark-dark.png", + "bucket-icon.svg", +] + +TOC_HEADING = "## Pages" +TOC_HEADER = "| Page |" +TOC_SEP = "| --- |" +TOC_PLACEHOLDER_TOKENS = ("logbook note", "logbook cell markdown", "logbook page") +STATUS_COL_RE = re.compile(r"\b(status|state)\b", re.I) +LINK_COL_RE = re.compile(r"\b(page|experiment|name|title)\b", re.I) +CELL_TYPES = {"markdown", "code", "figure", "artifact", "dashboard"} +ARTIFACT_URI_PREFIX = "trackio-artifact://" +LOCAL_DASHBOARD_PREFIX = "trackio-local-dashboard://" +SPACE_URL_RE = re.compile(r"https://huggingface\.co/spaces/[^\s<>)\"'`]+") +DEFAULT_HEAD = 3 +DEFAULT_TAIL = 3 +DEFAULT_RAW_LIMIT = 500 +FENCE_RE = re.compile(r"(`{3,4}|~{3,4})([^\n]*)\n([\s\S]*?)\n\1") +RUN_OUTPUT_LIMIT = 20_000 +RUN_OUTPUT_HEAD = 2_000 +RUN_OUTPUT_TAIL = RUN_OUTPUT_LIMIT - RUN_OUTPUT_HEAD +TRY_NUM_PORTS = int(os.getenv("GRADIO_NUM_PORTS", "100")) +CELL_RE = re.compile( + r"(^|\n)---\n\n([\s\S]*?)(?=\n---\n" + + +def _shorten(text: str, limit: int = 80) -> str: + text = re.sub(r"\s+", " ", text).strip() + if len(text) <= limit: + return text + return text[: limit - 1].rstrip() + "…" + + +def _strip_markdown_title(text: str) -> str: + text = re.sub(r"!\[([^\]]*)\]\([^)]+\)", r"\1", text) + text = re.sub(r"\[([^\]]+)\]\([^)]+\)", r"\1", text) + text = re.sub(r"[*_`>#]+", "", text) + return text.strip(" -:\t") + + +def _default_cell_title(cell_type: str, body: str, metadata: dict) -> str: + command = metadata.get("command") + if command: + try: + return _shorten(f"Run: {shlex.join(command)}") + except TypeError: + return "Run" + if cell_type == "code": + titled = re.search(r"^````\w*\s+title=([^\n]+)", body, re.M) + if titled: + return _shorten(f"Code: {titled.group(1).strip()}") + return "Code cell" + if cell_type == "figure": + return "Figure" + for line in body.splitlines(): + line = line.strip() + if not line or line.startswith("````") or line.startswith("